Роль сценариев компоновщика при написании сборки x86 - PullRequest
1 голос
/ 12 января 2020

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

Когда я проверяю этот пример Hello World , появляется скрипт компоновщика. Я не могу понять, почему именно это требуется? Просто указать адрес загрузки? Мое общее понимание сценариев компоновщика заключалось в том, что они более полезны, когда имеется более одного объектного файла, и сценарии компоновщика можно использовать для определения того, как разделы из нескольких объектных файлов можно объединить в один исполняемый файл. Что если я не укажу скрипт компоновщика в этом примере? (определенно есть как минимум 2 объектных файла - один из .s и один из. c)

1 Ответ

2 голосов
/ 12 января 2020

Обратите внимание, что это чистый пример, означающий отсутствие операционной системы.

Набор инструментов gnu, установленный на вашем компьютере, вероятно, был сборкой или сборкой для этого компьютера, включая операционную систему.

Таким образом, когда вы используете apt-get install build-essential, а затем g cc hello. c -o hello, используемый скрипт компоновщика был частью установленной цепочки инструментов и задавал c to linux Ваш дистрибутив. (даже если вы собираете набор инструментов и lib c из источников, он обнаруживает хост, и если он не создается как кросс-компилятор, по умолчанию будет использоваться стандартный bootstrap и скрипт компоновщика для этого хоста)

Когда вы находите и устанавливаете набор инструментов gnu для windows, сценарий компоновщика, похороненный в этой установке, указан c до windows.

Но если вы хотите использовать цепочку инструментов в качестве кросс-компилятора, в данном случае для «голого металла», вам необходимо создать ссылку для целевой среды, что обычно означает использование собственного сценария компоновщика, этот сценарий слишком сложен, так как обычно, но по крайней мере они предоставили один.

Будучи голым металлом x86 и используя хост x86 для разработки, вы можете (иногда) использовать собственный компилятор в качестве кросс-компилятора. То же самое для сборки для arm на хосте arm (например, raspberry pi), et c.

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

Задача сценария компоновщика - в первую очередь определить адресное пространство для компоновщика. Я хочу .text по этому адресу, я хочу .data по этому адресу и так далее. Вы можете сделать это с помощью командной строки и без сценария компоновщика, но это становится проще, чем сложнее вы хотите получить, и у gnu ld есть некоторые проблемы (ошибки) с командной строкой и сценарием компоновщика. Тогда вторичной причиной является то, что для определенных c языков у вас есть bootstrap, и некоторые языковые предположения должны быть соблюдены в bootstrap, но для облегчения этого вам нужна часть адресного пространства задания компоновщиков, чтобы облегчить скрипт компоновщика. Вы позволяете компоновщику / инструментам делать всю работу за вас.

Так что для C предполагается, что .bss обнуляется, а .data заполняется элементами, которые вы запрашивали до точки входа в ваш код (обычно main (), но в baremetal вы можете делать все, что угодно хочу и часто не хочу использовать это имя функции) вызывается. В качестве трудоемкого устройства вы используете компоновщик для размещения всех элементов, куда вы просили, поэтому весь текст, все bss, данные и данные, и т. Д. c. Он исправляет внешние связи между функциями. Но теперь компоновщик знает, например, где и насколько велик .bss, как вы сообщаете это к коду bootstrap? Хорошо, что gnu и другие наборы инструментов предоставляют механизм (решение gnus не должно быть переносимым на любой другой, предположим, что все языки сценариев компоновщика являются настраиваемыми и не переносимы, поэтому вам нужно написать новые и новые bootstrap для каждого набора инструментов ) для этого. Вы можете создать переменные в скрипте компоновщика, которые компоновщик заполняет, какими бы вы ни были, начальный адрес и конечный адрес .bss или вы можете сделать больше математики в скрипте компоновщика и получить начальный адрес и размер .bss, а затем импортировать эту переменную в bootstrap код языка ассемблера (не могу использовать C, что является проблемой курицы и яйца), и теперь bootstrap может обнулять .bss.

Поэтому я называю это браком между кодом bootstrap и скриптом компоновщика, которые оба задают набор инструментов c по нескольким причинам, язык ассемблера определяется ассемблером, а не целью, поэтому нет причин Предполагается, что язык ассемблера x86 для одной цепочки инструментов (это не имеет ничего общего с Intel против AT & T) совместим с другим ассемблером цепочек инструментов, во-вторых, язык сценариев компоновщика также не должен быть переносимым через цепочки инструментов и указывать c для этой цепочки инструментов. Таким образом, вы используете языки, указывающие c для цепочки инструментов, а для C в качестве примера у вас есть задачи, которые вы должны выполнить перед вызовом любого скомпилированного кода. Два или более файлов, из которых состоят ссылки, и bootstrap тесно связаны между собой.

Обратите внимание, что в этом примере также включен некоторый код bootstrap. Я бы искал более чистый пример реальной сборки против встроенной, особенно если в проекте есть файл на языке ассемблера, часть C могла бы демонстрировать C вместо того, чтобы быть скриптовым языком встроенного языка ассемблера. Похоже, что это ссылка на учебное пособие, которое объясняет, что происходит, поэтому, возможно, все это объясняется.

Прелесть baremetal в том, что вы можете делать все, что хотите, у вас меньше правил, чтобы жить, поэтому Автор сделал это. Лично я не ожидаю, что .bss обнулится и не буду использовать .data, поэтому мои непереносимые части, скрипт компоновщика и bootstrap намного менее сложны. Добро пожаловать в свой собственный стиль и предпочтения, красоту программирования без обработки металла.

...