目标文件、ELF文件的一点小总结 《程序员的自我修养》·笔记
2015-08-12 21:31
1041 查看
目标文件
源代码编译后但是没有进行链接的那些中间文件,比如win下的.obj文件、linux下的.o文件,与可执行文件的内容以及格式很类似。目标文件中的内容至少有编译后的机器指令代码、数据。还包括连接时所需要的一些信息,比如符号表、调试信息、字符串等。一般,目标文件会将这些信息按照不同的属性进行分段(其实就是多个一定长度的区域)。
下面主要对linux下的可执行文件的ELF格式进行分析
ELF文件的结构
ELF文件主要由文件头(ELF header)、代码段(.text)、数据段(.data)、.bss段、只读数据段(.rodata)、段表(section table)、符号表(symtab)、字符串表()、重定位表(.rel.text)如下图所示:代码段与数据段分开的原因:
1.对进程来说,数据段是可读写的,指令段是只读的。这样可以防止程序指令被改写。
2.指令区与数据区的分离有助于提高程序的局部性,有助于对CPU缓存命中率的提高。
3.当系统运行多个改程序的副本的时候,他们对应的指令都是一样的,此时内存只需要保留一份改程序的指令即可。当然,每个副本进程的数据区域是不一样的,他们是进程私有的
结合下图进行分析
代码段
如上图所示,一般C语言编译后的执行语句都编译成机器代码,保存在.text段。
.data段
已经初始化的全局变量和局部静态变量(虽然默认会初始化为0,或者手动初始化为0,都没有必要在数据段分配空间,直接放在.bss段,就默认值为0了)都保存在.data段。
大体来说,该section包含了在内存中的程序的初始化数据;data段包含三个部分:heap(堆)、stack(栈)和静态数据区。即.data还会存放其他类型的数据,比如局部变量。
数据段只是存放数据,变量名存放在字符串表中。
.bss段
未初始化的全局变量和局部静态变量都保存在.bss段。
大体来说该section包含了在内存中的程序的未初始化的数据。
由于程序加载(一般是指main之前)时,bss会被操作系统清零,所以未赋初值或初值为0的全局变量都在bss。.bss段只是为未初始化的全局变量和局部静态变量预留位置而已,它并没有内容,所以它在文件中也不占据空间,这样可减少目标文件体积。
但程序运行时需为变量分配内存空间,故目标文件必须记录所有未初始化的静态分配变量大小总和(通过start_bss和end_bss地址写入机器代码)。当加载器(loader)加载程序时,将为BSS段分配的内存初始化为0。
.rodata段
存放只读数据,一般是程序里面的只读变量(如const修饰的变量),以及字符串常量(不一定,也可能放在.data中)。
自定义段
程序员可以指定变量所处的段。
__attribute__((section(“FOO”))) int global = 42;
则将变量放入名字为FOO的段中。
ELF文件头
ELF魔数:文件头最开始的四个字节,第一个字节是DEL控制符的ASCII码,后三个字节是ELF字母的ASCII码。这种魔数用来确认文件的类型,操作系统加载可执行文件时会确认魔数是否正确。
文件类型:枚举表示
段表偏移:段表在文件中的偏移。
等
段表
描述ELF文件各个段的信息,你如每个段的段名、段长度、在文件中的偏移、读写权限以及段的其他属性。是用一个数据结构来描述的。
重定位表
链接器在处理目标文件的时候,需要对目标文件的某些部位进行重定位操作,即代码段数据段中那些绝对地址的引用位置。
字符串表
字符串表中包含若干以 null 结尾的字符串,这些字符串通常是 symbol 或 section 的名字。当 ELF 文件的其它部分需要引用字符串时,只需提供该字符串在字符串表中的位置索引即可。
字符串表中首先是一个空串,用于表示一个空名字,所以字符串表的第一个字节是“\0”。
一个字符串表可能涉及该 section 中的任意字节。一个字符串可能引用不止一次;引用子串的情况是可能存在的;一个字符串也可能被引用若干次;而不被引用的字符串也是允许存在的。
如下图所示
符号表
在链接的过程中,将函数和变量统称为符号。
每一个目标文件都有一个对应的符号表。符号表主要包括:
1.符号名,也即该符号名在符号串表中的下标。
2.符号值:一般是函数或者是变量的地址(.data段)。
3.该符号所在的段。
4.等等
相关文章推荐
- 黑马程序员------C和OC的差异
- 黑马程序员--java基础--IO流(一)
- 黑马程序员------OC中NSLog与printf的区别
- 黑马程序员------OC中类的声明和实现
- 程序员如何掌握新技术与时俱进
- 剑指offer——面试题20:顺时针打印矩阵
- 一个程序员如何做到结构上胸有成竹
- 黑马程序员——java复习总结——异常和包
- 面试题:字符串截取
- 黑马程序员----java基础之流程控制语句
- 【面试总结】百度知道后台开发实习生
- JAVA真实企业面试题
- 黑马程序员——面向对象(this关键字)-第11天
- 黑马程序员--java基础--集合(三)
- 只会编程的程序员没有前途
- 只会编程的程序员没有前途
- 面试题5
- 黑马程序员--java技术blog---第六篇:IO流(5)
- 【黑马程序员】Foundation框架NSString
- 老菜鸟致青春,程序员应该选择 Java 还是 C#