1.目标文件有三种形式:
可重定位目标文件(二进制码和数据组成,其形式可以在编译时与其他可重定位目标文件合并起来,创建一个可执行目标文件)
可执行目标文件(二进制码和数据组成,可以直接被复制到内存并执行)
共享目标文件(特殊的可重定位目标文件,在加载或运行时被动态加载到内存并进行链接)
编译器和汇编器生成可重定位目标文件包括共享目标文件
链接器生成可执行目标文件
2.当前PC平台流行的可执行文件的格式为:
Windows下的PE格式和Linux下的ELF格式都是COFF格式的变种。目标文件与可执行文件由于内容和结构很相似所以广义上将他们看成一种类型的文件。除此之外动态链接库(Windows的.dll和Linux下的.so)和静态链接库(Windows的.lib和Linux下的.a)
第一代UNIX系统中可执行文件格式为a.out,直到今天,可执行文件任然称为a.out
3.ELF可重定位目标文件的格式:
与可执行目标文件的格式大部分相同,但是也有不同。可执行目标文件有一个.init节定义了一个小函数叫做_init,程序代码初始化会调用它,而且因为可执行目标文件时已被重定位的完全链接文件,所以它不再需要rel节
(1)ELF头:
以一个16字节的序列开始,这个序列描述了生成该文件的系统的字的大小和字节顺序。ELF头部剩下的部分包含帮助链接器语法分析和解释目标文件的信息。其中包括例如ELF头放入大小、目标文件的类型、机器类型、节头部表的文件偏移。
(2).text:
已编译程序的机器代码
(3).rodata:
只读数据段,比如printf语句中的格式串和开关语句的跳转表(运行时加载到内存的有只读数据段,因此动多态发生时就是将虚表放在只读数据段中然后加载到内存中,同时运行时会有虚函数指针指向该虚表)
(4).data:
已初始化且初始化不为0的全局和静态变量。局部变量运行时被保存在栈中,即不出现在.data也不会出现在.bss段
(5).bss段:
未初始化的全局和静态变量以及初始化为0的全局或静态变量。这个节在目标文件中不占实际的空间,仅仅是一个占位符。目标文件格式区分已初始化和未初始化变量是为了空间效率:在目标文件中,未初始化的变量不需要占据任何实际的磁盘空间,运行时,在内存中分配这些变量初始值为0.
(6).symtab:
一个符号表,它存放在程序中定义和引用的函数和全局变量的信息。并非只有编译之后才能得到符号表信息。实际上每个重定位目标文件在.symtab中都有一张符号表(可以用STRIP命令去掉)。但是它和编译器中的符号表不同,.symtab不包含局部变量的条目
(7).rel.text:
(8).rel.data:
(9).debug:
一个调试符号表,其条目是程序中定义的局部变量和类型定义,程序中定义和引用的全局变量,以及原始的C源文件。只有以-g选项调用编译器是=驱动程序时才会得到这场表
(10).line:
(11).strtab: