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

标签 gcc linker ld elf dynamic-linking

我目前正在试验 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 脚本进行管理。

最佳答案

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

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

如果你想改变这一点,你必须改变脚本。没有解决办法!

关于gcc - 链接的 ELF 二进制文件可以包含多个 .text.* 部分(自动),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22655342/

相关文章:

c++ - Link Error : xxx is already defined in *****.LIB::究竟是什么错误?

c - 动态链接一个简单的二进制文件

linux - 为什么 gcc 默认链接 '-z now',尽管延迟绑定(bind)是 ld 的默认值?

c++ - 将 C++ 类及其派生类放在特定部分

c - 正确sscanf使用麻烦

c - 使用 libavcodec、C 解码 H264 视频

c - 将自定义 assert() 与 AddressSanitizer 集成

链接器将不正确的 LMA 分配给节(使用 AT>)

gcc - 如何正确避免有关 ".ARM.exidx"部分未设置 sh_link 的警告?

C++ : calling BIOS interrupt 0x21