【发布时间】: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