链接的ELF二进制文件是否可以包含多个.text。*部分(自动)

时间:2014-03-26 08:35:08

标签: gcc linker ld elf dynamic-linking

我目前正在尝试使用GNU LD链接器脚本。

我希望在编译的&中有多个.text。*部分。链接Linux x64 ELF二进制文件。 我通过

将我的示例代码编译成.o对象文件
gcc -ffunction-sections -fdata-sections -c sample.c

现在每个函数都放在一个单独的.text中。目标文件中的部分:

<...>
8 .text.main    0000003b  0000000000000000  0000000000000000  00000098  2**0
              CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
9 .text.printString 0000001f  0000000000000000  0000000000000000  000000d3  2**0
              CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .text.addPrintNumbers 00000032  0000000000000000  0000000000000000  000000f2  2**0
              CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
11 .text.getAnotherNumber 0000000b  0000000000000000  0000000000000000  00000124  2**0
              CONTENTS, ALLOC, LOAD, READONLY, CODE
<...>

将此与LD和自定义脚本相关联,导致所有代码合并到ELF二进制文件中的一个单片.text部分。 我尝试了两种变体.text。*合并:

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

(我知道这个KEEP参数仅供LD垃圾收集器在代码中保留此部分,而不是将其放在单独的部分中。

当我尝试这个实验性结构时:

<...>
.text.addPrintNumbers :
{
  KEEP(*(.text.addPrintNumbers))
}
.text.printString :
{
  KEEP(*(.text.printString))
}
.text           :
{
  KEEP (*(.text .text.*))
  KEEP (*(.text.unlikely .text.*_unlikely .text.unlikely.*))
  KEEP (*(.text.exit .text.exit.*))
  KEEP (*(.text.startup .text.startup.*))
  KEEP (*(.text.hot .text.hot.*))
  KEEP (*(.stub .gnu.linkonce.t.*))
  /* .gnu.warning sections are handled specially by elf32.em.  */
  KEEP (*(.gnu.warning))
}
<...>

我取得了一些成功(objdump -x ./sample | less):

 <...>
 11 .text.addPrintNumbers 00000032  0000000000400400  0000000000400400  00000400  2**0
              CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .text.printString 0000001f  0000000000400432  0000000000400432  00000432  2**0
              CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .text         00000112  0000000000400460  0000000000400460  00000460  2**4
              CONTENTS, ALLOC, LOAD, READONLY, CODE
 <...>

两个手动链接的部分放在ELF二进制文件中,仍可执行。

是否可以自动编译和链接二进制文件中的所有.text。*部分,而无需手动编辑的LD脚本。 我正在寻找一个自动执行的标志,我使用手动编辑的LD脚本管理的内容。

2 个答案:

答案 0 :(得分:2)

关于避免使用自定义链接描述文件,我认为不可能。如果你想摆弄部分,你需要一个链接器脚本。

在我的机器中,命令ld --verbose输出:

  .text           :
  {
    *(.text.unlikely .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)
  }

如果要更改它,则必须更改脚本。没有解决方法!

答案 1 :(得分:0)

尝试启用优化功能。以某种方式开启优化,例如-O2标志,指示编译器和链接器不合并.text。* sections