Смещение карликов и общие объекты против исполняемых файлов
Хорошо, я использовал библиотеку Linux Dwarf ldw для преобразования вывода backtrace_symbols в исходный код и номера строк, но я столкнулся с проблемой. backtrace_symbols дает смещения в памяти, из которых я вычитаю базовый адрес (полученный с помощью dladdr ()) перед использованием в качестве входных данных в Dwarf. Но, похоже, что для родительского исполняемого файла, я НЕ должен вычитать базовый адрес, потому что смещения Dwarf, кажется, включают его.
Итак, как мне различать EXE и SO в моем коде (я надеюсь, что есть что-то лучше, чем 'искать конец.so') или есть другая функция, которую я могу вызвать, которая получит базовый адрес или ноль для родителя EXE?
2 ответа
Да ты прав. Если исполняемый файл является ET_EXEC
(не DT_DYN
то есть это не независимый от позиции исполняемый файл), то виртуальные адреса в DWARF являются реальными виртуальными адресами в образе вашей программы. За DT_DYN
адреса в DWARF являются смещениями от базового адреса модуля.
Это объясняется в 7.3 спецификации DWARF:
Перемещенные адреса в отладочной информации для исполняемого объекта являются виртуальными адресами, а перемещенные адреса в отладочной информации для общего объекта смещены относительно начала самой низкой области памяти, загруженной из этой общей памяти.
Вы должны использовать e_type
в заголовке ELF, чтобы различать их.
Не уверен, что это лучший способ, но в ldw есть функция dwarf_getelf (), которая может помочь вам получить информацию об ELF, оттуда используйте elf32/64_getehdr() и оттуда посмотрите на поле e_type. Если e_type - ET_DYN, то это общий объект, и вы должны продолжить и использовать dladdr, чтобы найти смещение для удаления из адресов, иначе просто используйте адреса, сгенерированные backtrace напрямую.