计算机系统篇之链接(10):.bss.data 和 .rodata section 之间的区别

Posted csstormq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机系统篇之链接(10):.bss.data 和 .rodata section 之间的区别相关的知识,希望对你有一定的参考价值。

计算机系统篇之链接(10):.bss、.data 和 .rodata section 之间的区别

Author:stormQ

Friday, 08. May 2020 10:20PM


Section 名称区别1:用途不同区别2:在目标文件中占用的空间不同
.rodata用于维护只读数据,比如:常量字符串、带 const 修饰的全局变量和静态变量等在目标文件中占用空间
.data用于维护初始化的且初始值非0的全局变量和静态变量(不带 const 修饰)在目标文件中占用空间
.bss用于维护未初始化的或初始值为0的全局变量和静态变量(不带 const 修饰)不占用目标文件的空间

注:

  • 对于未初始化的全局变量和静态变量的初始值在运行期会被赋为0。从而,达到 .bss section 用于减少目标文件的大小的目的。

  • 临时变量(即局部非静态变量)既不出现在.data中,也不出现在.bss中。它由运行期栈维护。

  • 严格地讲,gcc 将 C 程序(以 .c 结尾的源文件)中的未初始化的全局变量标记为COMMON,而不是放到.bsssection 中。对于 C++ 程序,无论是 gcc 还是 g++,都会将程序中未初始化的全局变量放到.bsssection 中。关于这一点,有兴趣的可以自己验证下。

区别1和区别2的验证过程:

# 查看 sum.cpp
$ cat sum.cpp 
int sum(int a, int b)

  static int val_1;
  static int val_2 = 0;
  static int val_3 = 1;
  static int val_4 = 0;
  static int val_5 = 2;
  const static int val_6 = 0;
  return a + b;

# 生成可重定位目标文件 sum.o
$ g++ -c sum.cpp -o sum.o
# 查看 sum.o 的 sections
$ readelf -S sum.o
There are 12 section headers, starting at offset 0x340:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000014  0000000000000000  AX       0     0     1
  [ 2] .data             PROGBITS         0000000000000000  00000054
       0000000000000008  0000000000000000  WA       0     0     4
  [ 3] .bss              NOBITS           0000000000000000  0000005c
       000000000000000c  0000000000000000  WA       0     0     4
  [ 4] .rodata           PROGBITS         0000000000000000  0000005c
       0000000000000004  0000000000000000   A       0     0     4
  [ 5] .comment          PROGBITS         0000000000000000  00000060
       0000000000000033  0000000000000001  MS       0     0     1
  [ 6] .note.GNU-stack   PROGBITS         0000000000000000  00000093
       0000000000000000  0000000000000000           0     0     1
  [ 7] .eh_frame         PROGBITS         0000000000000000  00000098
       0000000000000038  0000000000000000   A       0     0     8
  [ 8] .rela.eh_frame    RELA             0000000000000000  000002c8
       0000000000000018  0000000000000018   I      10     7     8
  [ 9] .shstrtab         STRTAB           0000000000000000  000002e0
       000000000000005c  0000000000000000           0     0     1
  [10] .symtab           SYMTAB           0000000000000000  000000d0
       0000000000000180  0000000000000018          11    15     8
  [11] .strtab           STRTAB           0000000000000000  00000250
       0000000000000078  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

从上面的 sum.o 的 sections 信息,可以看出:

1).data的大小为 8(Size 列的值为 0000000000000008),在目标文件中占用 8 字节(00000054~0000005c);

2).bss的大小为 12(Size 列的值为 000000000000000c),在目标文件中占用 0 字节(.bss在目标文件中的偏移量为 0000005c,.bss下一个 section——comment在目标文件中的偏移量为 0000005c)。因此,可以得出结论:.bss不占用目标文件的空间。

3).rodata的大小为 4(Size 列的值为 0000000000000004),在目标文件中占用 4 字节(0000005c~00000060)。从而,验证了"区别2:在目标文件中占用的空间不同"

4)sum.cpp 中初始化的且初始值非0的变量(不带 const 修饰)有两个:val_3、val_5,占用 8 字节,与.data的大小一致;未初始化的或初始值为0的变量(不带 const 修饰)有三个:val_1、val_2、val_4,占用 12 字节,与.bss的大小一致;带 const 修饰的全局变量和静态变量有一个:val_6,占用 4 字节,与.rodata的大小一致。从而,验证了"区别1:用途不同"

最后,可以总结出对于 C++ 程序中一个全局变量或静态变量到底存放在.rodata.data.bss中哪一个 section 的判断规则为:首先判断全局变量或静态变量是否带 const 修饰。如果带 const 修饰, 无论初始值是否为0,都会存放到.rodatasection 中;否则,判断是否已初始化且初始值是否为0。如果已初始化且初始值非0,则存放到.datasection 中;否则,存放到.bsssection 中。

如果你觉得本文对你有所帮助,欢迎关注公众号,支持一下!

以上是关于计算机系统篇之链接(10):.bss.data 和 .rodata section 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

计算机系统篇之链接(12):Chapter 7 Linking 习题与解答

计算机系统篇之链接:动态链接

计算机系统篇之链接:静态链接(中)——符号解析

计算机系统篇之链接:静态链接(上)

计算机系统篇之链接:静态链接(上)

计算机系统篇之链接:静态链接(下)——重定位