Где информация о перемещении в формате ELF?

#linux #linker #elf

#linux #компоновщик #elf

Вопрос:

Цитирование «Компоновщиков и загрузчиков» в части загрузчиков

«перемещение во время загрузки намного проще, чем перемещение во время соединения, потому что вся программа перемещается как единое целое. […] После считывания программы в память загрузчик просматривает элементы перемещения в объектном файле и исправляет ячейки памяти, на которые указывают элементы»

Возможно, я неправильно понял этот момент, и это только в некоторых архитектурах, но мой вопрос таков: где в формате ELF указано, какие элементы нуждаются в перемещении во время загрузки? как я могу запросить этот список?

Ответ №1:

Перемещения можно найти в специальных разделах перемещения в файле ELF. Вы можете использовать readelf --sections команду, чтобы узнать, какие разделы есть в исполняемом файле или общей библиотеке, и какие разделы типа REL содержат инструкции по перемещению. Содержимое этих разделов перемещения может быть отображено с помощью readelf --relocs . Например:

 $ readelf --relocs /bin/ls

Relocation section '.rela.dyn' at offset 0x16c8 contains 5 entries:
  Offset          Info           Type           Sym. Value    Sym. Name   Addend
00000061afd8  000c00000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__   0
00000061b540  006d00000005 R_X86_64_COPY     000000000061b540 optind   0
00000061b548  006e00000005 R_X86_64_COPY     000000000061b548 optarg   0
00000061b550  006a00000005 R_X86_64_COPY     000000000061b550 stderr   0
00000061b560  006600000005 R_X86_64_COPY     000000000061b560 stdout   0

Relocation section '.rela.plt' at offset 0x1740 contains 99 entries:
  Offset          Info           Type           Sym. Value    Sym. Name   Addend
00000061b000  000100000007 R_X86_64_JUMP_SLO 0000000000000000 strcoll   0
00000061b008  000200000007 R_X86_64_JUMP_SLO 0000000000000000 mktime   0
...
  

.rela.dyn Раздел содержит ссылки на ссылки в коде программы или символы данных, которые должны быть перемещены во время загрузки, в то время как .rela.plt содержит в основном слоты перехода, которые используются для вызова функций в совместно используемых объектах. Обратите внимание, что обычно только общие объекты компилируются как код, не зависящий от позиции, в то время как обычные исполняемые файлы — нет. Это связано с тем, что код PIC немного медленнее, чем код без PIC.