-
未初始化变量(.bss节)
-
C语言规定:未初始化的全局变量和局部静态变量的默认初始值为0
-
将未初始化变量(.bss节)和已初始化变量(.data节)分开的好处
-
.data节中存放具体的初始值,需要占磁盘空间
-
.bss节中无需存放初始值,只要说明.bss节中的每个变量将来在执行时占用几个字节即可,因此,.bss节实际上不占用磁盘空间,提高了磁盘空间利用率
-
-
BSS(Block Started by Symbol)最初是由UA-SAP汇编程序中所用·的一个伪指令,用于为符号预留一块内存空间,可以看成是 ”更好地节省空间(Better Save Space)“的缩写
-
所有未初始化的全局变量和局部静态变量都被汇总到.bss节中,通过专门的 ”节头表(Section header table) “ 来说明应该为.bss节预留多大的空间。
-
-
可重定位目标文件格式
ELF头 | 包括16字节标识信息,文件类型(.o, exec, .so),机器类型(如IA-32),节头表的偏移,节头表的表项大小以及表项个数 |
---|---|
.text节 | 已编译程序的机器代码 |
.rodata | 只读数据,如printf格式串,switch跳转表 |
.data节 | 已初始的全局和静态变量,局部变量放在sta栈中 |
.bss节 | 未初始化全局变量和静态变量,仅仅是占位符,不占任何实际磁盘空间。区分初始化和未初始化是为了空间效率。运行时,在内存中分配这些变量,初始值为0 |
.symtab节 | 一个符号表,存放在程序中定义和引用的函数和全局变量的信息(每个可重定位目标文件在.symtab中都有一张符号表,不包含局部变量的条目) |
.rel.text节 | .text节的重定位信息,用于重新修改代码段的指令中的地址信息 |
.rel.data节 | .data节的重定位信息,用于对被模块引用或定义的全局变量进行重定位的信息 |
.debug节 | 调试用符号表(gcc -g 选项才会产生) |
.line节 | 原始C程序中的行号和.text节中机器指令之间的映射。(gcc -g 才有) |
.strtab节 | 字符串表,包含.symtab和.debug节中符号及节名,以null结尾的字符串序列 |
Section header table(节头表) | 每个节的节名、偏移和大小,访问属性等 |
查看ELF头的内容:
[gyhlf@localhost csapp]$ readelf -h main.o
ELF Header://魔数的前几个字节是用来文件的类型或格式:如下; 7f 45 4c 46确定为ELF文件
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 // 01H 07H为 a.out 4DH 5AH为PE格式
Class: ELF64
Data: 2's complement, little endian//表中数据补码表示,小端法
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file) //可重定位文件
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0 //程序的入口地址为0,因为是可重定位目标文件,给出的是链接视图
Start of program headers: 0 (bytes into file)//没有链接,没有程序头表
Start of section headers: 1008 (bytes into file) //节头表的起始位置,在文件开始偏移量1008的地方
Flags: 0x0
Size of this header: 64 (bytes) //ELF头的大小 64
Size of program headers: 0 (bytes)//程序头表大小为0,实际就是没有程序头表
Number of program headers: 0 //程序头表中没有任何表项,因为本来就没有程序头表
Size of section headers: 64 (bytes)//节头表的每个表项的大小为64bytes
Number of section headers: 13 //13 个表项 //所有节头表的大小为 13 * 64 bytes
Section header string table index: 12 //.strtab节在节头表中的索引