在你的终端里敲下readelf -S a.out,屏幕会吐出将近 30 行——.text、.rodata、.data、.bss、.symtab、.strtab、.rela.dyn、.rela.plt、.init_array、.fini_array……一个看似简单的 C++ 程序,编译器和链接器在它体内塞了三十个形状各异的"隔间",每个隔间有自己的名字、大小、对齐要求和访问权限。但如果你紧接着敲下readelf -l a.out,画风突变:整个程序被压缩成了 4 个 Segment,其中真正需要映射到内存的PT_LOAD类型只有 2 个——一个承载只读的代码和常量数据(.text+.rodata+.eh_frame),另一个承载可读写的全局变量和未初始化数据(.data+.bss+.got+.got.plt)。这就是第一个让人困惑的事实:内核在执行execve系统调用时,完全不看 Section Header Table——它只读 Program Header Table 里的 Segment 描述。链接器辛辛苦苦维护的 30 个 Section,在程