Динамическое связывание: значение смещения, используемое для индексации таблицы перемещений.

Я пытаюсь понять процесс динамической компоновки... вызов библиотечной функции (назовем ее func) проходит через таблицу plt. Я знаю, что когда символ еще не перемещен, вызов функции проходит из таблицы plt, которая содержит структуру (скажем, i1), например jmp *function_in_GOT, которая указывает на следующую инструкцию после i1, которая выглядит как push $offset: после того, как управление передается динамическому компоновщику который исправляет относительную запись GOT с адресом функции. offset должен быть индексом записи в таблице перемещений, но я не понимаю... как это значение можно найти, прочитав эльф исполняемого файла. возможно с

objdump --dynamic-reloc prog

найти что-то? Например, я написал очень простую программу, которая использует только printf и strcpy, и вывод предыдущей команды:

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE 
08049ff0 R_386_GLOB_DAT    __gmon_start__
0804a000 R_386_JUMP_SLOT   __gmon_start__
0804a004 R_386_JUMP_SLOT   __libc_start_main
0804a008 R_386_JUMP_SLOT   strcpy
0804a00c R_386_JUMP_SLOT   printf

Например, прочитав с gdb инструкции, начинающиеся с printf@plt:

0x8048324 <printf@plt>: jmp    *0x804a00c
0x804832a <printf@plt+6>:   push   $0x18
0x804832f <printf@plt+11>:  jmp    0x80482e4

мы можем видеть, что значение для offset равно 0x18 (24 в десятичной системе), но при чтении вывода objdump кажется, что смещение printf от первой записи reloc равно 0x1c.

Некоторые идеи?


person MirkoBanchi    schedule 31.08.2011    source источник


Ответы (2)


На самом деле PLT работает не так. Чтобы понять, как это действительно работает, я рекомендую начать с читает эту статью.

person Eli Bendersky    schedule 05.11.2011
comment
Спасибо большое, Эли, очень полезная статья! Однако я не понимаю, где ошибка в моем ответе. Читая статью (и, очевидно, другие статьи), кажется, что GOT и PLT работают таким образом. Итак, не могли бы вы объяснить мне, что это за значения, помещаемые в стек для динамического загрузчика? Спасибо большое - person MirkoBanchi; 11.11.2011
comment
@MirkoBanchi: честно говоря, я этого не изучал. Я считаю, что самый надежный способ узнать это — прочитать исходный код динамического загрузчика. Есть также несколько онлайн-ресурсов, пытающихся объяснить это на более высоком уровне. Моя цель в статье — объяснить, как работает PIC, а не вдаваться в детали реализации динамического загрузчика. - person Eli Bendersky; 11.11.2011

Да, смещение — это индекс в таблице перемещения файлов.

Из спецификации ELF версии 1.2:

5 . Следовательно, программа помещает смещение перемещения (offset) в стек. Смещение перемещения представляет собой 32-битное неотрицательное смещение байтов в таблице перемещений. Назначенная запись перемещения будет иметь тип R_386_JMP_SLOT, а ее смещение будет указывать запись глобальной таблицы смещений, использованную в предыдущей инструкции jmp. Запись о перемещении также содержит индекс таблицы символов, таким образом сообщая динамическому компоновщику, на какой символ ссылается, в данном случае name1.

Но я не знаю, почему расхождения в ваших результатах.

person JohnTortugo    schedule 02.09.2012