Расчет адреса переезда; ELF

Вопрос или проблема

Я изучаю вопросы перемещения из справочника ELF и этого блога, но не могу понять, как вычислить адрес перемещения.

  1. Предположим, у нас есть два файла A и B типа ET_REL, мы хотим объединить их секции под названием S во время компоновки; эти секции содержат символы SA (в файле A) и SB (в файле B). Если у нас есть записи для перемещения и смещения перемещения в A.elf и B.elf, я не понимаю, как компоновщик избегает конфликта адресов перемещения: я предполагаю, что эти смещения могут быть одинаковыми в A.elf и B.elf, так как эти файлы не знают друг о друге во время компиляции.

  2. Какова цель таблицы перемещения в ET_EXEC? Я не вижу, зачем она нужна.

  3. Какова цель добавочного значения в перемещении типа Rela?

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

Я предполагаю, что эти смещения могут быть одинаковыми в A.elf и B.elf, так как эти файлы не знают друг о друге во время компиляции.

Насколько я знаю, для типа ET_REL адреса секций не устанавливаются. Если вы выполните readelf -S file.o, вы увидите все нули в колонке Address. Ситуация меняется для типа ET_EXEC, для которого вы можете установить начальные адреса секций во время компоновки.

Какова цель таблицы перемещения в ET_EXEC? Я не вижу, зачем она нужна.

Для ET_EXEC, насколько я знаю, она нужна только для кода PIE. Если вы компонуете с флагом -no-pie, то таблицы перемещения нет, если только вы не используете флаг --emit-relocs. Существует 2 различных типа перемещений. ET_REL содержит перемещения, которые нужны только компоновщику. Компоновщик разрешает и удаляет их все (если не используется --emit-relocs, в этом случае они не удаляются). Но если используется режим компоновки -pie, то компоновщик может генерировать другой тип перемещений (например, R_386_RELATIVE), которые необходимы для динамического компоновщика ld.so – они отсутствуют в ET_REL, но могут присутствовать в ET_EXEC.

Какова цель добавочного значения в перемещении типа Rela?

Цель такая же, как и в REL, за исключением того, что в случае RELA добавочное значение хранится в самой таблице перемещений. Я думаю, что разница в основном структурная, и скорее всего существуют нетехнические (исторические) причины, почему оба типа существуют. В большинстве (или всех?) случаев достаточно любого из них.

Ответ или решение

Ответ на вопрос о вычислении адреса релокации в формате ELF

1. Отсутствие конфликтов адресов релокации при слиянии файлов ET_REL

Когда мы работаем с файлами типа ET_REL, как файлы A и B в вашем примере, важно понимать, что во время компиляции и сборки секции этих файлов не имеют установленных адресов. При выполнении команды readelf -S file.o вы заметите, что столбец "Address" будет заполнен нулями. Это значит, что компилятор не знает, где именно будет располагаться секция в конечном исполняемом файле, и, следовательно, адреса релокаций могут совпадать, так как они относительны к началу секции.

При слиянии (linkage) в процессе компоновки (linking) линковщик берет все секции из обоих файлов и устанавливает их адреса, начиная с некоторого базового адреса. Поскольку линковщик знает, как организовать секции, он может избежать конфликтов, переопределяя адреса в секциях A и B, если требуется. Таким образом, он гарантирует, что адреса релокации, указанные в обоих ELF-файлах, соотносятся корректно и не конфликтуют в окончательном скомпонованном файле.

2. Цель таблицы релокаций в ET_EXEC

Таблицы релокаций в файлах типа ET_EXEC нужны для корректной загрузки и выполнения программы, особенно когда речь идет о позиционно-независимом коде (PIC) и динамически загружаемых библиотеках. В случае использования PIC линковщик создаёт специальные записи, чтобы загрузчик (dynamic linker) мог корректно разрешать адреса в памяти при запуске. Если при компоновке используется флаг -no-pie, таблица релокаций может не создаваться, за исключением случаев, когда используется опция --emit-relocs.

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

3. Цель адденда в релокации типа Rela

Адденд (addend) в таблице релокаций типа Rela используется для хранения дополнительного значения, которое необходимо для корректного вычисления адреса. В отличие от REL, где адденд возможно хранится в другом месте, в RELA он фиксируется непосредственно в записи таблицы релокаций. Это позволяет менее зависимо хранить информацию и более эффективно её обрабатывать в процессе линковки:

  • В случае REL адденд, как правило, извлекается из данных секции, что требует дополнительных операций.
  • В случае RELA адденд уже присутствует в записи, что упрощает обработку на этапе линковки.

Оба формата (REL и RELA) имеют схожую функциональность, и выбор между ними может определяться предпочтениями разработчика или историческими аспектами его использования.

4. Пошаговое объяснение релокации

Релокация в ELF выполняется следующим образом:

  1. Разрешение символов: Линковщик сначала собирает всю необходимую информацию о символах, включая их адреса и значения, которые будут использоваться.
  2. Обработка таблицы релокаций: Линковщик проходит через таблицу релокаций и для каждой записи определяет, какой символ нужно использовать и какие адреса необходимо изменить.
  3. Вычисление адреса: На основе базового адреса, установленного для секции, и адденда, линковщик вычисляет конечный адрес, по которому должен находиться символ.
  4. Запись адреса: Линковщик записывает этот адрес в нужную часть сегмента или секции конечного файла.

Ресурсы для изучения

Для более глубокого понимания темы, я рекомендую следующие ресурсы:

  • Книга «Linkers and Loaders»ом (обычно доступна в магазинной версии или библиотеках).
  • Документация GNU Binutils, включая readelf и objdump.
  • Онлайн-курсы по системному программированию, посвященные работе с ELF и компоновщиками (например, на платформах Coursera или edX).

Эти материалы помогут вам более детально ознакомиться с процессами компоновки и релокации в формате ELF.

Оцените материал
Добавить комментарий

Капча загружается...