ELF - Понимание перемещений R_386_PC32 - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь понять перемещения в ELF, но у меня возникли некоторые проблемы с документацией по этому вопросу, которая довольно загадочна.Например, уравнения перемещения описывают 3 параметра, S, A и P. Теперь я понял, что A - это просто добавление, которое является некоторым числом, используемым для помощи в расчете перемещения, а S - это "Значение символа, для которогоindex находится в записи перемещения " (что совпадает с именем функции, верно?), но как насчет P?Руководство описывает его как «место перемещения блока хранения», но что это вообще означает?

Я только что нашел пример, чтобы проиллюстрировать это: предположим, у нас есть 2 объектных файла, obj1.o и obj2.o .Первый ссылается на функцию foo (), которая находится внутри obj2.o .

objdump -d obj1.o выход:

Disassembly of section .text:
00000000 <func>:
0:   55                      push   %ebp
1:   89 e5                   mov    %esp,%ebp
3:   83 ec 08                sub    $0x8,%esp
6:   e8 fc ff ff ff          call 7 <func+0x7>
b:   c9                      leave  
c:   c3                      ret   

Теперь, readelf показывает, что это перемещение R_386_PC32 , уравнение которого: S + A - P .

После объединениядва файла для создания полноценного исполняемого файла, перемещены , записи перемещения, по-видимому, исправлены:

objdump -d relocated
test:     file format elf32-i386
Disassembly of section .text:
080480d8 <func>:
80480d8:   55                      push   %ebp
80480d9:   89 e5                   mov    %esp,%ebp
80480db:   83 ec 08                sub    $0x8,%esp
80480de:   e8 05 00 00 00          call   80480e8 <foo>
80480e3:   c9                      leave  
80480e4:   c3                      ret    
80480e5:   90                      nop
80480e6:   90                      nop
80480e7:   90                      nop
080480e8 <foo>:
80480e8:   55                      push   %ebp
80480e9:   89 e5                   mov    %esp,%ebp
80480eb:   5d                      pop    %ebp
80480ec:   c3                      ret

Так что, похоже, компоновщик выполнил следующие вычисления: S +A - P: 0x80480e8 + 0xfffffffc - 0x80480df

Мои вопросы:

  • Откуда берется значение P?
  • Какой смысл иметьа добавление?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

S = 0x80480e8 - начальный адрес символа (адрес входа foo ()) P = 0x80480df - адрес, значение которого необходимо изменить (переместить)

То есть S-P - это расстояние (в байтах) между этими двумя адресами

Однако инструкция call rel32 считает расстояние (rel32), начиная со следующей инструкции, и смещение P равно 4 байтам, поэтому -4.

0 голосов
/ 18 мая 2018

P - это программный счетчик, так что это перенос на ПК.Я не проверял, что именно ELF32 использует в качестве ориентира.Судя по fc ff ff ff = -4 в несвязанном call rel32, это, вероятно, начало 4-байтового смещения.В машинном коде относительные переходы, такие как call rel32 конец инструкции (т. Е. Начало следующей инструкции) в качестве базы, объясняют смещение в 4 байта.

Это один из вариантов использования для добавления.

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

Так что у вас может быть что-то вроде

call get_eip_into_ebx
mov $table - this_instruction + 40(%ebx), %ecx

Или, например, real , посмотрите, что gcc и clang делают для -m32 -PIE для загрузки глобала.(Но имена символов таблицы глобальных смещений получают специальную обработку, поэтому я не собираюсь воспроизводить вывод asm компилятора.)

...