首页 > 解决方案 > 为什么“.shstrtab”部分是强制性的?

问题描述

我正在编译一个像这样的静态可执行文件:

ld.lld out/main.o -o out/sm -Tstatic.ld -static
strip --strip-all out/sm

这是我正在使用的链接器脚本:

ENTRY(_start)
SECTIONS
{
    . = 0x100e8;
    .all : {
       *(.bss*)
       *(.text*)
       *(.data*)
       *(.rodata*)
       *(COMMON*)
    } :code
    .shstrtab : {
       *(.shstrtab)
    }
    /DISCARD/ : {
      *(*)
    }
}
PHDRS
{
  code PT_LOAD FILEHDR PHDRS ;
}

可执行文件按预期工作,但 strip 命令不会.shstrtab从可执行文件中删除部分。

如果我.shstrtab从链接描述文件中删除该部分,我会收到以下错误:

ld.lld out/main.o -o out/.sm -Tstatic.ld -static
ld.lld: error: discarding .shstrtab section is not allowed

为什么需要该.shstrtab部分?我已经替换了所有标准节名,并且可执行文件仍然按预期工作,因此程序加载代码并不关心节名。

顺便说一句,是否可以在链接描述文件中完全排除节标题,因为静态可执行文件不需要它。

注意:.shstrtab即使它被丢弃,GNU 链接器也会默默地放入输出可执行文件。

标签: linuxldlinker-scriptslld

解决方案


为什么“.shstrtab”部分是强制性的?

节表中的每个节都有一个节名。它存储为对节名表 ( .shstrtab) 的引用。

因此,只要 ELF 文件中至少有一个部分,就必须有一个.shstrtab部分(但是,它的名称可能不同)。

实际上,它可以构建一个没有任何节的 ELF 文件(但只有程序头)。

但是,我从未见过这样一个由常规链接器链接的 ELF 文件(仅是有意创建为尽可能小或类似的文件)。


推荐阅读