ELF格式的文件:
目标文件中的内容除了至少有编译后的机器代码,数据,还要有链接时一些必要的信息,比如符号表,调试信息,字符串等。
程序源代码编译后的指令经常放在代码段,代码段常见的名字有”.code”或者”.text”,全局变量和局部静态变量放在数据段(.data)、
ELF文件的开头是一个“文件头”,描述整个文件的文件属性,包括文件是否可以执行,是静态链接还是动态链接及入口地址,目标硬件,目标操作系统等信息,文件头还包括一个段表(一个描述文件中各个段的数组),段表描述了文件中各个段在文件中的偏移位置及段的位置等,从段表里面可以得到每个段的所有信息。
程序源代码被编译后主要分成两个段:程序指令和程序数据。代码段属于程序指令,数据段和.bss段属于程序数据。
程序和指令分开写的原因:
(1)程序和指令映射到两个虚存区域,防止程序的指令被有意无意的改写。
(2)指令和数据的分离有利于提高程序的局部性。
(3)内存中只需保留一份该程序的指令部分,其余的要使用可以共享。
分析下述的源代码:
int printf(const char* format, ...);
int global_init_var = 84; //已初始化全局变量
int global_uninit_var; //未初始化全局变量
void fun1(int i)
{
printf("%d\n", i);
}
int main()
{
static int static_var = 85; //已初始化静态局部变量
static int static_var2; //未初始化静态局部变量
int a = 1; //已初始化局部变量
int b; //未初始化局部变量
fun1(static_var + static_var2 + a + b);
return 0;
}
ELF结构:
代码段:
数据段和只读数据段:
.data段保存那些已经初始化的全局静态变量和局部静态变量
.rodata段存放只读数据段,一般是程序中的只读变量(const修饰的变量)和字符串常量。
BSS段:
其他段: