目标文件 .o
中 text
、 bss
、 data
和 rodata
区别和联系
目标文件只是ELF文件的可重定位文件(Relocatable file),常用分析ELF文件工具如下
- objdump
- readelf
- nm
.text
代码段,也有可能包含一些只读的常数变量,例如字符串常量等。只读。
.bss
没有初始化的和初始化为0的全局变量和静态变量,并不给该段的数据分配空间,只是记录数据所需空间的大小,运行时在栈上分配。
.data
已初始化非0全局变量和静态变量,需要分配空间用于存储数据。
.rodata
ro
表示为只读数据段,存放C中的字符串和常量,优化后会只存储一份。常量并不一定在此段,有可能存放在代码段。
example
static int x1 = 0;
static int x2 = 1234;
int main()
{
return 0;
}
使用 objdump -x -s -d a.out
查找如下
00000000006bb330 l O .bss 0000000000000004 x1
00000000006b90f0 l O .data 0000000000000004 x2
.
Contents of section .data:
6b90e0 00000000 00000000 00000000 00000000 ................
6b90f0 34120000 00000000 00080000 00000000 4...............
x1
放入 .bss
段;x2
放入 .data
段。
nm vs objdump
nm
与 objdump
标志不统一,需要注意区分
nm
nm symbols 类型及程序组成查看详细信息 man nm
objdump
查看详细信息 man objdump
l
localg
globalu
unique global!
both global and localw
weakC
The symbol denotes a constructorW
warningI
The symbol is an indirect reference to another symboli
a function to be evaluated during reloc processingd
a debugging symbolD
a dynamic symbolF
functionf
fileO
object
example
$ tree
.
├── a.out
├── one.c // extern unsigned long start_time;
├── two.c // unsigned long start_time = 0;
└── main.c // start_time = _get_time();
$ nm one.o | grep start_time
00000004 C start_time
$ nm two.o | grep start_time
00000000 B start_time
$ nm main.o | grep start_time
00000004 C start_time
$ nm a.out | grep start_time
97d6c6c4 B start_time
$ objdump -x -s a.out | grep start_time
97d6c6c4 g O .bss 00000004 start_time
0640 0e000067 5f737461 72745f74 696d6500 ...start_time.
1ae0 675f7374 6172745f 74696d65 00df0e00 start_time....
$ objdump -x -s one.o | grep start_time
00000004 O *COM* 00000004 start_time
00000ef5 ADDR32 start_time
0000003c ADDR32 start_time
$ objdump -x -s main.o | grep start_time
00000004 O *COM* 00000004 start_time
00000262 ADDR32 start_time
000000e4 ADDR32 start_time
$ objdump -x -s two.o | grep start_time
32 .bss.start_time 00000004 00000000 00000000 000015c8 2**2
00000000 l d .bss.start_time 00000000 .bss.start_time
00000000 g O .bss.start_time 00000004 start_time
000006d7 ADDR32 .bss.start_time
注意变量 start_time
在各个文件中的标志