一、什么是目标文件
——源代码经过编译后产生的文件,经过链接后会成为可执行文件;目标文件其实已经具备了可执行文件的特征,只是在地址方面没有进行明确规定。
二、目标文件的格式
windows:PE-COFF
LInux:ELF
它们都源自Unix的COFF文件格式,因此在文件格式上具有很大的相似性;
不仅目标文件遵循这种格式,DLL/so,Lib/a 也遵循这种COFF的存储格式;
三、目标文件的段式结构
我们知道,程序分为数据和指令,所以在目标文件中主要存储了不同的数据段、指令段及一些辅助功能段;
其简略分段如下所示:
1。File Header
(1)文件属性信息:文件类型、目标硬件与操作系统、是否可执行等
(2)段表:文件中各段的偏移地址及属性
2. txt section
程序指令
3. data section
初始化的数据
4. bss section
未初始话的数据
思考:为什么会进行分段
在cs领域,遇到复杂的问题常采用分层的方法进行化简;分段有利于在代码载入时,将代码与数据进行区分,从而将运行时的工作放在编译时来进行。以java为例子,类文件在载入内存时,被分为:堆与方法区;而方法区中的数据是不许要保存多份的,因为方法是不变的。但是在堆中存放着每个类对应的多个实例化对象,该部分数据是多样性的。
数据的r-w的,而指令是read only的,所以分段有利于在存储时对权限进行区分;
在现代cup中,在进行缓存时,都是将指令缓存能与数据缓存进行区分,指令和数据的分离有利于提高CPU中数据的命中率。
5.其它段与自定义段
自定义段可以自己在c语言程序中自定义,而且可以存放任何内容(比如一副图像等);
其它段如 rodata段,用于存放只读数据等,它们都有这各自不同的存放数据。
6.段表
段表是目标文件中除了文件头之外最重要的结构;它在逻辑及物理存储上是与各个段并列的。段表按照特定结构体Elf32_Shdr的内容,存放着每个段的属性信息(开始与结尾地址,段的类型等)。
7.重定位表 .rel.txt / .rel.data
链接器将目标文件转化为可执行文件的时候,所做的主要的工作就是就是将代码段和数据段那些绝对地址的引用位置转化为实际地址。而绝对地址的引用就存放在重定位表中。
四、数据存放方式
在目标文件中数据以二进制放方式存放,该二进制内容相当于汇编后的二进制,可以使用相关指令进行反汇编。
五、链接浅谈——符号
链接的内容将主要在下面文章中谈到,下面要大体介绍下链接的接口----符号。
从上面我们可知,链接就是将绝对地址转换为实际的计算机中的地址,并将不同的目标文件进行“粘接”。
目标文件的“粘接”其实是对各自内容的地址的相互引用。如果目标文件A中用到了B中的方法foo,我们就称A引用了B中的方法。在链接中我们将函数和变量统称为符号,函数名或变量名就是符号名。
符号存放在符号表中,符号的值就是符号的地址。
符号的分类:
(1)定义在目标文件中的全局符号---例如目标文件中的方法
(2)定义在外部的全局符号---例如其它目标文件中的方法
(3)局部符号---eg:局部变量
(4)行号信息---目标文件指令与源代码行的对应信息
在链接过程中,主要涉及到不同目标文件的粘和,所以主要处理的符号为(1)和(2)的全局符号。上图!