Intereting Posts
Как получить кодировку символов терминала Есть ли шрифт Unicode для Windows, который является таким же полным, как Arial Unicode MS, но бесплатный, даже для коммерческого использования? Как включить заголовочный файл через make-файл Обработчики протоколов в Chrome через реестр Компилировать код C ++ для AIX на Ubuntu? Почему сокет соединяется () с собственным эфемерным портом? Visual Studio 2015 Измените целевую платформу на Windows 7 Как создать удобный фильтр Событие триггера при подключении / отключении монитора HDMI? А как насчет динамиков? Есть ли API для предварительного получения списка доверенных корневых сертификатов в Windows? ICallFactory с 32-разрядными и 64-разрядными библиотеками типов бок о бок jedi-vim не находит python2 dist-packages, но python3 да Будет ли os.fork () использовать копию для записи или выполнить полную копию родительского процесса в Python? Как включить кеширование nginx proxy для мезонинов Преобразование LinearGradientBrush в цвет

значение R_386_32 / R_386_PC32 в разделе .rel.text эльфа

чтобы понять концепцию переseleniumия, я написал простую программу chk.c следующим образом:

1 #include 2 main(){ 3 int x,y,sum; 4 x = 3; 5 y = 4; 6 sum = x + y; 7 printf("sum = %d\n",sum); 8 } 

его эквивалентный код сборки с использованием «objdump -d chk.o»:

 00000000 : 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 e4 f0 and $0xfffffff0,%esp 6: 83 ec 20 sub $0x20,%esp 9: c7 44 24 1c 03 00 00 movl $0x3,0x1c(%esp) 10: 00 11: c7 44 24 18 04 00 00 movl $0x4,0x18(%esp) 18: 00 19: 8b 44 24 18 mov 0x18(%esp),%eax 1d: 8b 54 24 1c mov 0x1c(%esp),%edx 21: 8d 04 02 lea (%edx,%eax,1),%eax 24: 89 44 24 14 mov %eax,0x14(%esp) 28: b8 00 00 00 00 mov $0x0,%eax 2d: 8b 54 24 14 mov 0x14(%esp),%edx 31: 89 54 24 04 mov %edx,0x4(%esp) 35: 89 04 24 mov %eax,(%esp) 38: e8 fc ff ff ff call 39  3d: c9 leave 3e: c3 ret 

и секция .rel.text, видимая с использованием readelf, выглядит следующим образом:

 Relocation section '.rel.text' at offset 0x360 contains 2 entries: Offset Info Type Sym.Value Sym. Name 00000029 00000501 R_386_32 00000000 .rodata 00000039 00000902 R_386_PC32 00000000 printf 

У меня есть следующие вопросы, основанные на этом:

1) из второй записи в разделе .rel.text, я могу понять, что значение в смещении 0x39 в .text-разделе (которое здесь равно 0xfffffffff) должно быть заменено адресом символа, связанного с индексом 9 таблицы символов (& который выходит printf). Но я не могу четко понять смысл 0x02 (ELF32_R_TYPE) здесь. Что здесь задает R_386_PC32? Может кто-нибудь объяснить его смысл ясно.

2) Я также не могу понять первую запись. что нужно заменить при смещении 0x29 в разделе .text и почему здесь неясно. Снова я хочу знать значение R_386_32 здесь. Я нашел один файл pdf elf_format.pdf, но я не могу четко понять значение «Тип» в разделе .rel.text.

3) Также я хочу знать значение сборки inst “lea (% edx,% eax, 1),% eax”. Хотя я нашел очень хорошую ссылку ( какова цель инструкции LEA? ), Описывающая значение lea, но формат lea (то есть 3 скобки внутри arg) не ясен.

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

еще один вопрос. Я показал записи таблицы символов для обоих смещений 5 и 9 ниже.

  Num: Value Size Type Bind Vis Ndx Name 5: 00000000 0 SECTION LOCAL DEFAULT 5 9: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf' 

Информационное поле для первой записи в таблице .rel.text равно 0x05, которая указывает индекс таблицы символов. Я показал запись таблицы символов для индекса 5 выше, но не могу понять, как это говорит нам о том, что это для .rodata.

1), 2): R_386_32 – это перемещение, которое помещает абсолютный 32-разрядный адрес символа в указанную ячейку памяти. R_386_PC32 – это перемещение, которое помещает 32-разрядный адрес символа, соответствующего ПК, в указанную ячейку памяти. R_386_32 полезен для статических данных, как показано здесь, поскольку компилятор просто загружает перемещенный адрес символа в некоторый регистр, а затем обрабатывает его как указатель. R_386_PC32 полезен для ссылок на функции, поскольку он может использоваться как непосредственный аргумент для call . См. Elf_machdep.c для примера того, как обрабатываются перестановки.

3) lea (%edx,%eax,1),%eax означает просто %eax = %edx + 1*%eax если выражено синтаксисом C. Здесь он в основном используется в качестве замены кода операции add .

EDIT: Вот пример.

Предположим, что ваш код загружается в память, начиная с 0x401000, что строка "sum = %d\n" заканчивается на 0x401800 (в начале раздела .rodata ) и что printf находится в 0x1400ab80, в libc.

Затем, перемещение R_386_32 в 0x29 поместит байты 00 18 40 00 на 0x401029 (просто копируя абсолютный адрес символа), делая команду на 0x401028

  401028: b8 00 18 40 00 mov $0x401800,%eax 

R_386_PC32 в 0x39 помещает байты 43 9b c0 13 на 0x401039 (значение 0x1400ab80 – 0x40103d = 0x13c09b43 в шестнадцатеричном формате), что делает эту инструкцию

  401038: e8 43 9b c0 13 call $0x1400ab80  

Мы вычитаем 0x40103d для учета значения% pc (который является адресом инструкции после call ).

Первая запись перемещения – это получить указатель на строку формата ( "sum = ..." ) в процессе настройки вызова printf . Поскольку раздел .rodata перемещается, а также раздел .text , ссылки на строки и другие постоянные данные нуждаются в исправлениях.

Имея это в виду, похоже, что перераспределение R_386_32 связано с данными, а R_386_PC32 с кодовыми адресами, но спецификация ELF (у которой у меня нет удобной копии), вероятно, объясняет различные детали.

Команда lea – это то, что компилятор решил выполнить дополнение для этой процедуры. Он мог бы выбрать add или пару других возможностей, но эта форма lea , по-видимому, используется довольно часто для определенных случаев, поскольку она может сочетать добавление с умножением. Результатом команды является lea (%edx,%eax,1),%eax – это то, что %eax получит значение %edx + 1 * %eax . 1 можно заменить ограниченным набором малых целых чисел. Первоначальной целью команды lea был «Load Effective Address» – взять базовый указатель, индекс и размер и присвоить адрес элемента в массиве. Но, как вы можете видеть, компиляторы могут использовать его для других вещей, а также …