Как перестановки работают в объектных (не графических) файлах COFF
Какие именно шаги предпринимаются компоновщиком при разрешении перемещений в объектном файле перед созданием окончательного изображения? В частности, как компоновщик обрабатывает значение, которое уже хранится на сайте перемещения? Всегда ли он добавляется в окончательный вариант VA/RVA или иногда игнорируется (например, определенные типы перемещения)?
Я не смог найти четкого объяснения в спецификации MS PE/COFF, и после того, как я некоторое время гуглил и экспериментировал, все, что я мог узнать, это:
- В спецификации MS COFF, глава 5.6.2 "Базовые типы перемещения" сказано, что "Базовое перемещение применяет все 32 бита разницы к 32-битному полю со смещением", что, как я полагаю, означает, что перемещение должно занять учитывать, какой адрес уже сохранен по указанному смещению. Однако глава 5.6 (раздел.reloc) относится только к файлам изображений, а не к объектным файлам.
- Утилита dumpbin добавляет столбец с именем "Applied To" при печати таблицы перемещений, который, кажется, всегда (независимо от типа перемещения) содержит значение, которое хранится на сайте перемещения.
- В главе "Директивы о перемещении" в спецификации DJGPP COFF четко указано, что значение, хранящееся в данный момент в этом местоположении, должно быть добавлено к адресу символа, указанному в записи таблицы перемещения.
Можете ли вы указать мне какую-либо (соответствующую) документацию, которая объясняет, как компоновщик обрабатывает перемещения?
1 ответ
Секция перемещения, используемая в "файлах изображений", имеет несколько иное назначение, чем информация о перемещении, представленная в "объектных файлах".
В отличие от общих библиотек Linux, библиотеки Windows обычно не используют код, независимый от позиции. Вместо этого они определены относительно фиксированного адреса. Однако загрузчик Windows имеет возможность перемещать DLL в случае конфликта. Чтобы поддержать это, образы DLL содержат разделы перемещения, которые определяют, какие данные необходимо изменить при перемещении образа. Многие ссылки на символы внутри dll будут использовать относительную адресацию "eip" (или rip), поэтому их не нужно изменять при перемещении DLL.
Перемещения файлов изображений всегда указываются относительно базового адреса исполняемого образа. Перемещения объектного файла указываются относительно адреса (в пределах изображения, используя предпочтительный адрес изображения) символа в таблице символов. Файлы изображений не имеют таблицы символов (у них есть IAT, но это не таблица символов). Набор поддерживаемых перемещений в объектных файлах богаче, чем набор, поддерживаемый в файлах изображений.
Подробности описаны в разделе "Перемещение COFF (только для объектов)" спецификации PE/COFF (я смотрю на версию 3, когда я набираю это).