确定目标文件上的BSS大小

Ani*_*tla 10 c linker gcc

维基百科提到"bss部分通常包括在文件范围内声明的所有未初始化的变量." 给出以下文件:

int uninit;

int main() {
    uninit = 1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我将其编译为可执行文件时,我看到正确填充了bss段:

$ gcc prog1.c -o prog1
$ size prog1
text       data     bss     dec     hex filename
1115        552       8    1675     68b prog1
Run Code Online (Sandbox Code Playgroud)

但是,如果我将其编译为目标文件,我看不到bss段(我希望它是4):

$ gcc -c prog1.c
$ size prog1.o 
text       data     bss     dec     hex filename
  72          0       0      72      48 prog1.o
Run Code Online (Sandbox Code Playgroud)

有什么明显的东西我不见了吗?

我使用的是gcc版本4.8.1.

Jon*_*art 7

如果我们readelf -s用来查看符号表,我们会看到:

$ readelf -s prog1.o

Symbol table '.symtab' contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS bss.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     8: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM uninit      <<<<
     9: 0000000000000000    16 FUNC    GLOBAL DEFAULT    1 main
Run Code Online (Sandbox Code Playgroud)

我们看到你的uninit符号("变量")在这个阶段是一个"共同的"符号.它尚未"分配"给BSS.

有关"常用"符号的更多信息,请参阅此问题:"COM"在.symtab部分的Ndx列中的含义是什么?

一旦您的最终可执行文件链接在一起,它将按预期放入BSS.


您可以通过将-fno-common标志传递给GCC 来绕过此行为:

$ gcc -fno-common -c bss.c
$ size bss.o
   text    data     bss     dec     hex filename
     72       0       4      76      4c bss.o
Run Code Online (Sandbox Code Playgroud)

相反,你可以标记uninitstatic.这样,编译器就会知道没有其他.o文件可以引用它,所以它不会是一个"通用"符号.相反,它会立即放入BSS,如您所愿:

$ cat bss.c
Run Code Online (Sandbox Code Playgroud)
static int uninit;

int main() {
    uninit = 1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
$ gcc -c bss.c 
$ size bss.o
   text    data     bss     dec     hex filename
     72       0       4      76      4c bss.o
Run Code Online (Sandbox Code Playgroud)