Формат файла ELF - PullRequest
       31

Формат файла ELF

13 голосов
/ 13 мая 2011

Если не копаться в источнике GDB, где я могу найти документацию о формате, используемом для создания основных файлов?

Спецификация ELF оставляет формат основного файла открытым, поэтому я предполагаю, что этодолжен быть частью спецификации GDB!К сожалению, я не нашел никакой помощи в этом отношении в документации GNU по gdb.

Вот что я пытаюсь сделать: сопоставить виртуальные адреса с именами функций в исполняемых файлах / библиотеках, которые составляли запущенный процесс.Чтобы сделать это, я сначала хотел бы выяснить, из основного файла, карту из виртуального адресного пространства в имя исполняемого файла / библиотек, а затем покопаться в соответствующем файле, чтобы получить символическую информацию.

Теперь 'readelf -a core' говорит мне, что почти все сегменты в файле core имеют тип 'load' - я думаю, это сегменты .text и .bss / .data из всех участвующих файлов.плюс сегмент стека.За исключением этих сегментов нагрузки, есть один сегмент заметки, но, похоже, он не содержит карту.Так как же информация о том, какому файлу соответствует сегмент, хранится в основном файле?Являются ли эти сегменты 'загрузки' форматом особым образом для включения информации о файле?

Ответы [ 5 ]

8 голосов
/ 02 сентября 2015

Формат файла дампа основной памяти использует формат ELF, но не описан в стандарте ELF. AFAIK, на это нет авторитетной ссылки.

Так как же информация о том, какому файлу соответствует сегмент, хранится в основном файле?

В примечаниях ELF содержится много дополнительной информации. Вы можете использовать readelf -n, чтобы увидеть их.

Примечание CORE / NT_FILE определяет связь между диапазоном адресов памяти и файлом (+ смещение):

Page size: 1
             Start                 End         Page Offset
0x0000000000400000  0x000000000049d000  0x0000000000000000
    /usr/bin/xchat
0x000000000069c000  0x00000000006a0000  0x000000000009c000
    /usr/bin/xchat
0x00007f2490885000  0x00007f24908a1000  0x0000000000000000
    /usr/share/icons/gnome/icon-theme.cache
0x00007f24908a1000  0x00007f24908bd000  0x0000000000000000
    /usr/share/icons/gnome/icon-theme.cache
0x00007f24908bd000  0x00007f2490eb0000  0x0000000000000000
    /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf
[...]

Для каждого потока у вас должна быть заметка CORE/NT_PRSTATUS, в которой указаны регистры потока (включая указатель стека). Из этого вы можете определить положение стеков.

Дополнительная информация о формате основных файлов ELF:

3 голосов
/ 13 мая 2011

Дамп ядра - это образ процесса в памяти, когда он произошел сбой.Он включает в себя программные сегменты, стек, кучу и другие данные.Вам все еще понадобится исходная программа, чтобы разобраться в содержании: таблицы символов и другие данные делают необработанные адреса и структуры в образе памяти значимыми.

2 голосов
/ 22 июня 2011

Более простым решением вашей проблемы может быть анализ текста из / proc / $ pid / maps, чтобы определить, к какому файлу относится данный виртуальный адрес. Затем вы можете разобрать соответствующий файл.

VDB (отладчик) с открытым исходным кодом Kenshoto использует этот подход, если вы можете читать python, это хороший пример.

2 голосов
/ 21 мая 2011

Дополнительная информация о процессе, который сгенерировал основной файл, хранится в разделе примечаний ELF, хотя и в зависимости от операционной системы. Например, см. Справочную страницу core (5) для NetBSD .

2 голосов
/ 13 мая 2011

Не столько gdb, сколько библиотека bfd, используемая gdb, binutils и т. Д.

...