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

问题描述

在处理 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 生成的二进制文件一个 80 字节的 .bss 部分,这大致是我所期望的,因为我预计会有一些小开销。

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

解决方法

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

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

尝试执行 readelf -s test.o 以显示符号表。