Операционная система UNIX. Руководство программиста

Группировка выходных секций


Подразумеваемый алгоритм размещения секций для редактора связей ld(1) таков:

  • В одну выходную секцию помещаются все входные секции .init, а за ними все входные секции .text. Эта выходная секция получает имя .text; она связывается с адресом, равным 0x0 плюс размер всех заголовков выходного файла.
  • Все входные секции .data помещаются в одну выходную. Этой выходной секции дается имя .data, и, в системах со страничной виртуальной памятью, она связывается с адресом, который получается выравниванием на машинно-зависимую границу плюс величина, определяемая размерами заголовков и секции .text.
  • Все секции неинициализированных данных .bss, а также все неинициализированные и неразмещаемые глобальные имена помещаются в одну выходную секцию с именем .bss, которая располагается сразу после секции .data без выравнивания по какой-либо границе.

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

SECTIONS { .text размер_заголовков : { *(.init) *(.text) } } GROUP BIND (NEXT (граница_выравнивания) + (SIZEOF (.text) + ADDR (.text)) % 0x2000) : { .data : { } .bss : { } } }

где граница_выравнивания есть машинно-зависимая константа. Предложение GROUP обеспечивает группировку, то есть последовательное размещение, двух выходных секций, .data и .bss. Связывание с конкретным адресом и выравнивание по определенной границе производится для группы в целом, а не для отдельных входящих в нее секций. Секции, образующие группу, размещаются последовательно в том порядке, в котором они указываются в предложении GROUP.

Если необходимо сгруппировать секции .text, .data и .bss, следует использовать такое предложение SECTIONS:

SECTIONS { GROUP: { .text: {} .data: {} .bss: {} } }


При этом выходной файл будет по-прежнему содержать три различные секции (.text, .data и .bss), однако теперь они будут размещаться в последовательных участках виртуальной памяти.

Группу выходных секций как единое целое можно связать с конкретным адресом или произвести ее выравнивание на определенную границу, просто указав нужный адрес в предложении GROUP. Так, для связывания с адресом 0xС0000 достаточно воспользоваться конструкцией

GROUP 0xС0000: {

а для выравнивания на границу, кратную 0x10000, - конструкцией

GROUP ALIGN (0x10000): {

Если сделать одно из этих добавлений к указанному выше примеру, то выходная секция .text будет размещена по адресу 0xС0000 (соответственно выравнена на границу 0x10000); затем остальные члены группы, в порядке их указания, размещаются по ближайшим доступным адресам.

Если предложение GROUP не используется, то каждая выходная секция рассматривается отдельно:

SECTIONS { .text: {} .data ALIGN (0x2000): {} .bss: {} }

Секция .text связывается с виртуальным адресом 0x0 (если он находится в пределах конфигурируемой памяти). Секция .data связывается с виртуальным адресом, кратным 0x2000. Если хватит места, секция .bss будет следовать сразу за секцией .text, если же не хватит - то сразу за секцией .data. Порядок, в котором имена выходных секций появляются в предложении SECTIONS, не определяет порядка следования этих секций в выходном файле.




Содержание раздела