我目前正在试验 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/