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

     

Создание и определение имен при редактировании связей


Операторы присваивания ld(1) нужны для того, чтобы имя могло получить значение, которое вычисляется при редактировании связей. Обычно употребляются три вида операторов присваивания:

  • С символом . в левой части - для управления счетчиком размещения.
  • С символом . в правой части - для присваивания имени настраиваемого значения.
  • Без символа . - для присваивания имени абсолютного значения.

Первый вид присваиваний обсуждался в предыдущем разделе.

В операторах второго вида имени присваивается адрес, который становится известным только после размещения. Пример:

SECTIONS { outsc1: { ... } outsc2: { file1.o (s1) s2_start = . ; file2.o (s2) s2_end = . - 1; } }

Значением s2_start будет адрес начала секции file2.o (s2), а значением s2_end - адрес последнего байта file2.o (s2).

Рассмотрим следующий пример.

SECTIONS { outsc1: { file1.o (.data) mark = .; . += 4; file2.o (.data) } }

Здесь создается имя mark и его значением становится адрес байта, следующего за окончанием секции .data из file1.o. Затем резервируются четыре байта для будущего использования mark при выполнении. Тип имени mark - длинное целое (32 бита).

Значение выражения, содержащего счетчик размещения, вычисляется в процессе размещения, поэтому такие выражения могут встречаться только внутри предложений SECTIONS. В предложениях SECTIONS

могут быть и операторы присваивания, не содержащие ., хотя обычно так не делается. Значения выражений из правых частей таких операторов определяются после окончания размещения. Изменять подобным образом адрес какого-либо имени опасно. Пусть, например, имя определено в секции .data, где для него отведен и проинициализирован некоторый участок памяти. Тогда, если редактируется ряд объектных файлов, содержащих ссылки на это имя, соответствующий ему элемент таблицы имен с момента присваивания будет отражать новый, измененный адрес этого имени. В то же время инициализированные данные не переписываются по новому адресу; кроме того, могут остаться ссылки на старый адрес. ld(1) выдает предупреждение при изменении значения каждого имени, ранее уже определенного. Заметим, однако, что присваивание абсолютных значений новым именам совершенно безопасно, так как с такими именами не связаны ни ссылки, ни данные.



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