为什么 .o 文件在使用 GCC 编译时看起来有一个大小为 0 的 .bss 部分?

Why do .o files appear to have a .bss section of size 0 when compiled with GCC?

在处理 C 程序时,我更改了构建以生成 .o 文件而不是独立的二进制文件。这样做时,根据 readelf -S,我注意到生成的 .o 文件的 .bss 部分的大小为 0,即使源代码中显然存在未初始化的全局变量。

我可以用一个简单的程序复制它,test.c:

char arr[42];
int main(int argc, char **argv){
  return 0;
}

根据 readelf 的说法,gcc -o test test.c 产生的二进制文件有一个八十字节的 .bss 部分,这大致是我所期望的,因为我预计会有一些小的开销。

但是,如果我使用 gcc -c -o test.o test.c 构建 .o 文件,bss 部分的大小报告为零。显然我对 ELF 目标文件的性质有一些误解,但我不太确定我错过了什么。

ELF 目标文件有一个虚拟的 .bss 段。它们不能直接加载(不像 executable 或共享库)。

关于全局变量的信息存储在 .symtab 部分,链接器使用它来构造最终二进制文件中的 .bss 和其他部分。

尝试 readelf -s test.o 来显示符号 table。