【问题标题】:Why do .o files appear to have a .bss section of size 0 when compiled with GCC?为什么 .o 文件在使用 GCC 编译时似乎有一个大小为 0 的 .bss 部分?
【发布时间】:2020-12-20 22:01:51
【问题描述】:

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

我可以用一个简单的程序 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 目标文件的性质有一些误解,但我不太确定我错过了什么。

【问题讨论】:

  • 您使用什么命令来获取部分大小?对我来说:size test.o 报告大小为 42 字节的 bss,而 size test 报告 80 字节
  • @Expolarity;就我而言,我使用了 readelf。然而,我在尺寸上也看到了同样的情况。 RE: 80的大小,不好意思,我不小心忘记从十六进制转换了。
  • 哦,我认为 readelf 报告了两组不同的大小,一个应该在第一列(名为 Size)的部分名称下,一个在第二列(名为 EntSize)。 EntSize 经常被归零。有没有可能你读到了另一个为零的尺寸?
  • @Expolarity 这是个好主意,但不!它是第一列中的常规大小字段。我还仔细检查了size 命令,确定。
  • 请注意,gcc 实现了附件 J.5.11,它允许将未初始化的全局变量与另一个翻译单元中的已初始化全局变量混合在一起,因此该数组在最终可执行文件中可能根本不会出现在 BSS 中

标签: c gcc compilation linker static-libraries


【解决方案1】:

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

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

尝试使用readelf -s test.o 来显示符号表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-05
    • 2015-12-01
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多