【问题标题】:Can a linked ELF binary contain multiple .text.* sections (automatically)链接的 ELF 二进制文件是否可以包含多个 .text.* 部分(自动)
【发布时间】:2014-05-04 12:30:52
【问题描述】:

我目前正在试验 GNU LD 链接器脚本。

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

将我的示例代码编译成一个 .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 脚本进行管理。

【问题讨论】:

  • 您是否尝试添加.text.whatever 部分定义之前 .text 之一?
  • 是的,我已经尝试过了,因此我编辑了这个问题。谢谢:)

标签: gcc linker ld elf dynamic-linking


【解决方案1】:

关于避免使用自定义链接器脚本,我认为这是不可能的。如果你想修改部分,你需要一个链接器脚本。

在我的机器中,命令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)
  }

如果你想改变它,你必须改变脚本。没有解决方法!

【讨论】:

  • 看来确实是这样。
【解决方案2】:

尝试开启优化。不知何故打开优化,例如-O2 标志,指示编译器和链接器不要合并 .text.* 节

【讨论】:

    猜你喜欢
    • 2017-03-20
    • 1970-01-01
    • 2012-05-15
    • 2012-02-06
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    相关资源
    最近更新 更多