Смещение карликов и общие объекты против исполняемых файлов

Хорошо, я использовал библиотеку 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 напрямую.

Другие вопросы по тегам