.data段包含了初始化的全局和局部静态变量,即int global_init_var = 84; 和static int static_var=85;而从.data段的基本信息可以看到
可以看到,size只有4,这和代码中有两个未初始化的全局和局部静态变量相矛盾。实际上,全局未初始化的变量global_uninit_var 没有被放在这里,通过后面的符号表可以看出来。
2. 查看所有段表
- [lizhuohua@lizhuohua-phy Program]$ readelf -S SimpleSection.o
- There are 13 section headers, starting at offset 0x190:
- 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 0000000000000050 0000000000000000 AX 0 0 4
- [ 2] .rela.text RELA 0000000000000000 000006b8 0000000000000078 0000000000000018 11 1 8
- [ 3] .data PROGBITS 0000000000000000 00000090 0000000000000008 0000000000000000 WA 0 0 4
- [ 4] .bss NOBITS 0000000000000000 00000098 0000000000000004 0000000000000000 WA 0 0 4
- [ 5] .rodata PROGBITS 0000000000000000 00000098 0000000000000004 0000000000000000 A 0 0 1
- [ 6] .comment PROGBITS 0000000000000000 0000009c 000000000000002d 0000000000000001 MS 0 0 1
- [ 7] .note.GNU-stack PROGBITS 0000000000000000 000000c9 0000000000000000 0000000000000000 0 0 1
- [ 8] .eh_frame PROGBITS 0000000000000000 000000d0 0000000000000058 0000000000000000 A 0 0 8
- [ 9] .rela.eh_frame RELA 0000000000000000 00000730 0000000000000030 0000000000000018 11 8 8
- [10] .shstrtab STRTAB 0000000000000000 00000128 0000000000000061 0000000000000000 0 0 1
- [11] .symtab SYMTAB 0000000000000000 000004d0 0000000000000180 0000000000000018 12 11 8
- [12] .strtab STRTAB 0000000000000000 00000650 0000000000000066 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)
这时候可以画出一个完整的文件结构图
可以看到,总共有13个段表(从0开始)。
Type:
PROGBITS: 表示程序段,代码段,数据段
RELA: 表示重定向表。比如.rela.text,该段使用的可重定向符号表在段表11(Link为11),即.symtab段表中。而该重定向表所作用的段是1号表(Info为),即.text段表。
SYMTAB:该段的内容为符号表
STRTAB:该段的内容为字符串表
NOBITS:表示该段无内容
Flag:
W (write):表示该段在进程空间中可写
A (alloc):表示该段在进程空间中需要分配空间。
X (execute):表示该段可被执行,比如代码段
- [lizhuohua@lizhuohua-phy Program]$ readelf -s SimpleSection.o
- Symbol table '.symtab' contains 16 entries:
- Num: Value Size Type Bind Vis Ndx Name
- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
- 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS SimpleSection.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 5
- 6: 0000000000000004 4 OBJECT LOCAL DEFAULT 3 static_var.1596
- 7: 0000000000000000 4 OBJECT LOCAL DEFAULT 4 static_var2.1597
- 8: 0000000000000000 0 SECTION LOCAL DEFAULT 7
- 9: 0000000000000000 0 SECTION LOCAL DEFAULT 8
- 10: 0000000000000000 0 SECTION LOCAL DEFAULT 6
- 11: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 global_init_var
- 12: 0000000000000004 4 OBJECT GLOBAL DEFAULT COM global_uninit_var
- 13: 0000000000000000 33 FUNC GLOBAL DEFAULT 1 func1
- 14: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
- 15: 0000000000000021 47 FUNC GLOBAL DEFAULT 1 main
Bind:
LOCAL: 局部符号,对于外部文件都不可见
GLOBAL:全局符号,外部可见
Type:
FILE: 该符号表示文件名
SECTION: 该符号表示一个段,必须与LOCAL结合
FUNC: 该符号表示函数或其他可执行代码
OBJECT:该符号是个数据对象,比如变量,数组等。
NOTYPE: 未知符号
Ndx:
一般来说表示该符号所在段在段表中的下标。比如global_init_var在3号段表,即.data段表
COM:表示该符号是一个"COMMON"类型的符号,一般来说,未初始化的全局变量即为这个。如global_uninit_var
UND:未定义符号,如printf。它在我们的代码里被调用,但是没有被定义。