Объединить разделы с ld

Я хотел бы объединить несколько файлов .o в один файл .o, а также объединить некоторые разделы.

Если я выполню

ld -r first.o second.o -o result.o

затем он правильно объединяет объектные файлы, но мне также нужно объединить различные разделы .text. Эта функция объединения разделов доступна сценарием компоновщика по умолчанию в ld, когда вы связываете общий объект, но мне не удалось принудительно использовать собственный скрипт компоновщика при использовании -r. ld, похоже, игнорирует все сценарии, которые я пробовал. Я попытался изменить сценарий компоновщика по умолчанию и заменил блок раздела .text на этот

.text           :
{
    *(.text.unlikely .text.*_unlikely)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
} =0x90909090

Как я могу объединить объектные файлы, а также объединить разделы .text с помощью ld?


person Kamu Flazs    schedule 17.04.2015    source источник
comment
Как вы пришли к выводу (вероятно, неправильному) о том, что ld -r не объединяет .text разделы? Кроме того, какую версию ld на какой платформе вы использовали?   -  person Employed Russian    schedule 18.04.2015
comment
Я использую следующую версию ld: GNU ld (GNU Binutils) 2.20.0.20100122-0.7.9. Пробовал и более новые версии, результат тот же. Я не говорю о том, что ld не объединяет .text разделы разных объектных файлов, но и не объединяет все .text* разделы объектных файлов, например .text, .text._ZN13somenamespace3FooD1Ev, .text._ZN13somenamespace3FooD0Ev, .text._ZNSt8_Rb_treeIPN13somenamespace3BarES2_St9_IdentityIS2_ENS1_6isLessESaIS2_EE8_M_eraseEPSt13_Rb_tree_nodeIS2_E и т. д.   -  person Kamu Flazs    schedule 18.04.2015


Ответы (1)


но не объединяя все разделы .text* объектных файлов, например .text, .text._ZN13somenamespace3FooD1Ev

Наличие .text._ZN13somenamespace3FooD1Ev, скорее всего, означает, что вы компилируете с -ffunction-sections, и действительно, сценарий компоновщика по умолчанию не будет объединять такие разделы: если вы хотите, чтобы они были объединены, вам вообще не следовало использовать -ffunction-sections!

Тем не менее, мне удалось объединить все .text разделы следующим образом:

ld -r -o t.o t1.o t2.o --verbose > /tmp/script

Примечание: скрипт компоновщика для ссылки ld -r отличается от обычного скрипта компоновщика (который вы, похоже, изменили).

Отредактируйте /tmp/script, чтобы удалить не скриптовые части, а также изменить:

  .text         0 :
  {
    *(.text .stub)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
  }

К этому:

  .text         0 :
  {
    *(.text .stub .text.*)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
  }

Окончательно,

ld -r -o t.o t1.o t2.o -T /tmp/script

дает мне t.o со всеми объединенными разделами .text.

person Employed Russian    schedule 18.04.2015
comment
Я не использую опцию -ffunction-sections при компиляции. Большинство функций находятся в разделе .text, но некоторые виртуальные и шаблонные функции имеют свои собственные разделы. Я пытался найти параметр gcc, который отключает это поведение, но не смог. Ваше предложение в основном такое же, с которым я экспериментировал. В любом случае, я попробовал вашу версию (добавив только .text.*), но она не работает. - person Kamu Flazs; 18.04.2015