【问题标题】:How the linker calculate the size of .bss section?链接器如何计算 .bss 部分的大小?
【发布时间】:2012-07-12 07:52:34
【问题描述】:

我想知道链接器如何计算.bss 部分的大小?

我有一个包含两个变量的测试程序,一个初始化为零,另一个是 初始化为非零。我希望 .bss 的大小是 4,确实如此。

# cat test.c && gcc -o test.o -c test.c && ld -o test test.o && readelf -Ss test
int _start=0;
int a = 2;
......
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 1] .data             PROGBITS         00000000006000b0  000000b0
       0000000000000004  0000000000000000  WA       0     0     4
  [ 2] .bss              NOBITS           00000000006000b4  000000b4
       0000000000000004  0000000000000000  WA       0     0     4
.....
Symbol table '.symtab' contains 11 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     6: 00000000006000b4     4 OBJECT  GLOBAL DEFAULT    2 _start
    10: 00000000006000b0     4 OBJECT  GLOBAL DEFAULT    1 a

然后我添加第二个零初始化变量。这次我希望.bss的大小是 是 8,但它是 12(0xc)。

# cat test.c && gcc -o test.o -c test.c && ld -o test test.o && readelf -Ss test
int _start=0;
int a = 2;
int b = 0;
......
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 1] .data             PROGBITS         00000000006000b0  000000b0
       0000000000000004  0000000000000000  WA       0     0     4
  [ 2] .bss              NOBITS           00000000006000b4  000000b4
       000000000000000c  0000000000000000  WA       0     0     4
......
Symbol table '.symtab' contains 12 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     6: 00000000006000b8     4 OBJECT  GLOBAL DEFAULT    2 b
     7: 00000000006000b4     4 OBJECT  GLOBAL DEFAULT    2 _start
    11: 00000000006000b0     4 OBJECT  GLOBAL DEFAULT    1 a

我继续添加第三个零初始化变量。这次我希望.bss的大小是 是 12 并且是。

# cat test.c && gcc -o test.o -c test.c && ld -o test test.o && readelf -Ss test
int _start=0;
int a = 2;
int b = 0;
int c = 0;
......
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .data             PROGBITS         00000000006000b0  000000b0
       0000000000000004  0000000000000000  WA       0     0     4
  [ 2] .bss              NOBITS           00000000006000b4  000000b4
       000000000000000c  0000000000000000  WA       0     0     4
......
Symbol table '.symtab' contains 13 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     6: 00000000006000b8     4 OBJECT  GLOBAL DEFAULT    2 b
     7: 00000000006000b4     4 OBJECT  GLOBAL DEFAULT    2 _start
     8: 00000000006000bc     4 OBJECT  GLOBAL DEFAULT    2 c
    12: 00000000006000b0     4 OBJECT  GLOBAL DEFAULT    1 a

我继续添加第四个零初始化变量。这次我希望.bss的大小是 是 16,但它是 20(0x14)。

# cat test.c && gcc -o test.o -c test.c && ld -o test test.o && readelf -Ss test
int _start=0;
int a = 2;
int b = 0;
int c = 0;
int d = 0;
......
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 1] .data             PROGBITS         00000000006000b0  000000b0
       0000000000000004  0000000000000000  WA       0     0     4
  [ 2] .bss              NOBITS           00000000006000b4  000000b4
       0000000000000014  0000000000000000  WA       0     0     4
......
Symbol table '.symtab' contains 14 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     6: 00000000006000b8     4 OBJECT  GLOBAL DEFAULT    2 b
     7: 00000000006000b4     4 OBJECT  GLOBAL DEFAULT    2 _start
     8: 00000000006000bc     4 OBJECT  GLOBAL DEFAULT    2 c
    10: 00000000006000c0     4 OBJECT  GLOBAL DEFAULT    2 d
    13: 00000000006000b0     4 OBJECT  GLOBAL DEFAULT    1 a

有时结果符合我的预期,有时不符合。 是否有其他因素影响链接器的输出?

【问题讨论】:

  • 检查第二个 LOAD 段的 memsz 是否符合您的预期。

标签: c gcc ld gnu-assembler


【解决方案1】:

实际上是对齐。在您的示例中,bss 的大小不是您期望的 8 字节对齐的,但那是因为您有 4 个字节的data。如果添加另一个初始化变量,您将看到 bss 段的大小为 8 字节对齐。

【讨论】:

  • I'm not sure why you expect the 5 variables to be 16 bytes. 在 5 个变量中,一个用非零值初始化并放在 .data 中,其他 4 个变量是零初始化并放在 .bss 中,所以我期望 16 个字节。
  • 看我修改后的答案,其实是对齐的。
猜你喜欢
  • 1970-01-01
  • 2019-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-08
  • 2013-05-25
  • 2019-02-11
  • 1970-01-01
相关资源
最近更新 更多