Компоновщики и архитектуры
Почему у нас есть компоновщики для разных архитектур? Служба компоновщика заключается в разрешении адресов. Итак, как это связано с инструкциями целевой архитектуры?
5 ответов
есть много, много причин, и я не могу исчерпывающе перечислить их все.
компоновщикам нужно делать намного больше работы, когда архитектура не поддерживает независимый от позиции код. В таких случаях даже прыжки внутри функции должны быть решены.
компоновщикам необходимо создавать заголовки, специфичные для архитектуры, такие как ELF или PE.
компоновщикам необходимо включить ресурсы, вилки данных или похожие вещи на платформах, которые их поддерживают
линкеры должны инстанцировать экспортируемых шаблонов C++
компоновщикам также необходимо иметь дело с адресами, которые еще не могут быть разрешены. Это может включать системные вызовы или динамически загружаемые библиотеки.
при связывании динамической библиотеки компоновщику необходимо экспортировать более одной функции ввода. Разные архитектуры используют разные методы для указания функций для экспорта
компоновщикам может потребоваться вставить фактические последовательности вызовов, если они не могут быть определены во время компиляции. Например. для архитектур, поддерживающих два набора инструкций, необходимо вставлять" переключатель набора инструкций " всякий раз, когда вызывающий и вызываемый отличаются используемым набором инструкций.
оптимизация компоновщика может основываться на деталях, зависящих от архитектуры. Е. Г. если функция звонки в пределах 4КБ региона быстрее, имеет смысл ставить вызывающий и вызываемый близко друг к другу.
встраивание между объектными файлами может быть сделано, но требует удаления настройки вызова, callee prolog, callee epilog и обработки возвращаемого значения. Они специфичны для архитектуры, поэтому для их распознавания уже требуется компоновщик, специфичный для архитектуры.
различные архитектуры имеют разные форматы адресов в своих инструкциях, которые компоновщик должен знать, чтобы манипулировать ими.
относительная адресация может привести к различным инструкциям в зависимости от величины относительного адреса.
более сложные схемы также существуют, например, для ARM.
обычно это описано в дополнении к спецификации формата компоновщика, например, взгляните на документы, связанные с эта статья Википедии о формате ELF.
для разрешения адресов компоновщику необходимо, по крайней мере, знать конечность и размер адресов. Некоторые архитектуры, такие как x86 real-mode, имеют более сложные схемы адресации, некоторые адреса встраиваются в инструкцию, поэтому компоновщику может потребоваться знать адрес или поле смещения.
некоторые компоновщики могут быть построены для понимания нескольких архитектур. Например, я использую gnu ld, gdb, binutils и ассемблеры для моего проекта кросс-компилятора,http://ellcc.org. У меня есть ассемблер, специфичный для каждой цели, но компоновщик, отладчик и binutils понимают все процессоры. Поддерживаемые процессоры довольно разнообразны: рукоятка, CellSPU, Мипс и MSP430, Nios2, семейства pic16, для PowerPC, PowerPC64, SPARC и х86 архитектуру x86_64,.
некоторые toolchains построены так, что огромная часть оптимизаций откладывается до времени соединения, когда доступна информация о всей программе. Преимущества инлайнинга, постоянного распространения и многих других традиционных оптимизаций наиболее применимы при применении ко всему двоичному файлу, а не только к каждому объекту.