*逐个分析各段。。。*
第三章 目标文件里面有什么
真正了不起的程序员对自己的程序的每一个字节都了如指掌。
//Test.c
int global_init_var = 84;
int global_uninit_var;
void func1(int i)
{
printf("%d\n", i);
}
int main()
{
static int static_var = 85;
static int static_var2;
int a = 1;
int b
func1(static_var + static_var2 + a + b);
return 0;
}
示例程序中包括代码段、数据段、BSS段、只读数据段(.rodata)、注释信息段(.comment)。
代码段:
- .text段中存放的是Test.c中函数func()和main()的指令。
数据段和只读数据段:
.data段保存初始化了的全局变量和局部静态变量(上述代码中的global_init_var和static_var)。
.rodata段存放只读数据,一般是程序的只读变量(const修饰的变量)和字符串常量(上述代码中”%d\n“是一种只读数据)。单独设立.rodata段从语义上支持C++的const关键字,也在加载时将属性映射成只读,保证安全性。有时编译器会把字符串常量放到.data段,而不会单独放在.rodata段。
BSS段:
.bss段中存放的是未初始化的全局变量和局部静态变量(上述代码中的global_uninit_var和static_var2),准确的说是.bss段为他们预留了空间。
有些编译器将未初始化的全局变量存放在目标文件.bss段,有些不存放只是预留一个未定义的全局变量符号”COMMON 符号“,到最终链接成可执行文件的时候再在.bss段·分配空间。
但编译单元内部可见的静态变量(如·global_uninit_var加上static修饰),是存放在.bss段。
static int x1 = 0;
x1被放在.bss段,因为可以认为是未初始化的,所以被优化放在.bss段。static int x2 = 1;
x2被放在.data段,因为初始化值为1,所以放在.data段。
其他段:
自定义段:
_attribute_((section("FOO"))) int global = 42;
_attribute_((section("BAR"))) void foo()
在全局变量和函数之前加上_attribute_((section("name")))
属性可以把相应的变量或函数放到以”name“作为的段中。
*以上为主要段,下一次总结ELF文件结构,包括文件头、段表。。。*