编译链接之一 目标文件

来源:互联网 发布:js取小数点前面的数字 编辑:程序博客网 时间:2024/05/17 13:14

预编译、编译、汇编、链接,这是由代码到生成最终的可执行文件(或链接库等),所要经历的四个阶段。而目标文件,在整个过程中充当着极为重要的角色。本文即对目标文件的产生、格式等加以总结。

关键词:可执行文件格式、目标文件

一. 产生

目标文件,就是源代码在经过预编译、编译,但还未进行链接的那些中间文件。在Windows 下,就是.obj 文件;Linux 下就是.o 文件。 实际上它们与可执行文件的格式很相似。

PC 上流行的可执行文件格式,Windows 平台下是PE(Portable Executable)和Linux 平台下的ELF(Executable Linkable Format)。它们都是COFF(Common file format)格式的变种。

从广义上讲,目标文件、可执行文件可以看成是同一类型的文件。事实上,不光是可执行文件,包括动态链接库(Windows 下的.dll 及Linux 下的.so)和静态链接库(Windows 下的.lib及Linux 下的.a) 也都是按可执行文件格式存储的。

ELF 格式的文件可以分成四种类型:

ELF 文件类型说明实例可重定位文件静态链接库文件就属于这一类。这类文件包含代码和数据,可以被用来链接成可执行文件或共享目标文件。Windows 下的.obj, .lib;Linux 下的.o, .a可执行文件这类文件包含可以直接执行的程序。windows 下的.exe共享目标文件这类文件也包含代码和数据。有两种用途:链接器可以使用这种文件跟其他可重定位文件和共享目标文件链接,产生新的目标文件;也可以将几个这类文件与可执行文件结合,作为进程映像的一部分来运行。Winows 下的.dll;
Linux 下.so核心转储文件当进程意外终止时,系统会将该进程的地址空间的内容及终止时的一些信息转储到核心转储文件中Linux 下的core dump

二. 目标文件的格式

目标文件中的内容大体包括编译后生成的机器指令、数据,当然还有链接所需要的一些其它信息:符号表、调试信息、字符串等。目标文件,会把这些信息按不同的属性,分段(segment)存储。我们常讲的代码段、数据段、只读数据段等,就是指目标文件中的这些段。

目标文件的段包括(这里主要是以Linux 下的ELF 文件为例):

常用的段名说明.text(或.code),代码码程序源代码经编译后的机器指令.data,数据段经初始化的全局变量及局部静态变量.bss,未初始化数据段未初始化的全局变量及局部静态变量.rodata,只读数据段存放只读数据,如:字符串常量、全局常量.commont存放编译器的版本信息.debug调试信息.dynamic动态链接信息.hash符号哈希表.line调试时的行号表,即源代码行号与编译后指令的对应表.note额外的编译器信息,比如发布程序的公司名、版本号等.strtabString table,用于存储ELF 文件中用到的各个字符串.symtabSymbol table.shstrtabSection string table,段名表.plt, .got动态链接的跳转表和全局入口表.init, .fini程序初始化与终结代码表。

目标文件对不同的内容分段管理的好处在于:

1. 程序被装载时,数据与指令分别被映射到不同的虚拟内存区域。由于数据是可读写的,而指令对于进程来讲,是只读的。因此把指令与代码分别映射到不同的区域,把这两个区域分别设置与只读与可读写,这样可以防止程序指令被有意或无意地改变。

2. 最为重要的原因还在于:同一程序的不同副本,其指令段数据都应该是相同的,而数据段则不同。这些分开存储,便于所有副本,都共享一份代码码,这将有助于降低占用的系统资源。

原创粉丝点击