我不是 GNU ld 方面的专家,但我在文档中找到了以下信息:
特殊的 secname `/DISCARD/' 可用于丢弃输入部分。分配给名为“/DISCARD/”的输出部分的任何部分都不包含在最终链接输出中。
我希望这能帮到您。
更新:
(这是解决方案的第一个版本,它不起作用,因为 INTERP 部分与标题 PT_INTERP 一起被删除。)
主.c:
int main(int argc, char **argv)
{
return 0;
}
主要的.x:
SECTIONS {
/DISCARD/ : { *(.interp) }
}
构建命令:
$ gcc -nostdlib -pie -static -Wl,-T,main.x main.c
$ readelf -S a.out | grep .interp
不带选项 -Wl,-T,main.x 的构建命令:
$ gcc -nostdlib -pie -static main.c
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000000218
$ readelf -S a.out | grep .interp
[ 1] .interp PROGBITS 00000134 000134 000013 00 A 0 0 1
更新 2:
此解决方案的想法是将原始部分“INTERP”(链接描述文件中的.interp)重命名为.interp1。换句话说,该节的全部内容都放在 .interp1 节中。因此,我们可以安全地删除 INTERP 部分(现在为空),而不必担心丢失默认的链接描述文件设置,因此标题 INTERP_PT 也将被删除。
SECTIONS {
.interp1 : { *(.interp); } : NONE
/DISCARD/ : { *(.interp) }
}
为了显示 INTERP 部分的内容存在于文件中(如 .interp1),但已删除 INTERP_PT 标头,我使用了 readelf + grep 的组合。
$ gcc -nostdlib -pie -Wl,-T,main.x main.c
$ readelf -l a.out | grep interp
00 .note.gnu.build-id .text .interp1 .dynstr .hash .gnu.hash .dynamic .got.plt
$ readelf -S a.out | grep interp
[ 3] .interp1 PROGBITS 0000002e 00102e 000013 00 A 0 0 1