开发者在c/c++源文件和头文件中编写程序。部分程序可用汇编编写,并放在相应的汇编源文件中。开发者为make工具创建一个makefile文件,这样可以轻松追踪文件的修改并根据需要调用编译器和汇编器重新build源文件。编译器和汇编器从这些源文件中生成包含机器码和程序数据的目标文件。归档工具连接一组目标文件形成一个库。链接器把这些目标文件作为输入并生成一个可执行映像或是可被用于和其他目标文件链接的目标文件。链接器命令文件指示链接器怎样组合目标文件以及把二进制码和数据放在目标嵌入式系统的哪个位置。
链接器的主要功能是把多个目标文件组合成一个更大的可重定位的目标文件、一个共享目标文件或是一个最终的可执行映像。在一个典型的程序里,一个源文件中的一段代码可引用另一个源文件中定义的变量。一个函数在某个源文件中可调用另一个源文件中的函数。这些全局变量和非静态函数就是通常所说的全局符号。在源文件中,这些符号有不同的名称。在最终的可执行二进制映像中,一个符号对应一个内存中的地址。这个内存地址的内容是变量的数据或者是函数的可执行代码。
编译器创建一个包含符号名到地址的映射的符号表作为它生成的目标文件的一部分。当创建可重定位的输出文件时,编译器为每个符号生成一个与被编译文件相关的地址。因此,这些地址是按照0偏移量生成的。符号表包含定义在被编译文件中的全局符号以及在此文件中被引用的外部符号,这些外部符号要由链接器解析。由链接器执行的链接过程调用符号解析和符号重定位。
符号解析 是这样一个过程:链接器进入每个目标文件并为该目标文件检查其外部符号在哪个或哪些其他目标文件中定义的。有时,当链接器试图解析所有的外部符号时,它必须多次处理这些目标文件。若外部符号定义在一个静态库中,链接器将从库中复制目标文件并写入最终的映像(静态链接)。
符号重定位 是链接器把一个符号引用映射到它的定义的过程。链接器修改被链接目标文件的机器代码,以便对应于那些符号的代码反映出分配给这些符号的实际地址。对于很多符
号,在多个目标文件被合并后,它的相对偏移量就变了。符号重定位要求代码修改,因为链接器调整引用这些符号机器的代码来反映它们最终的地址。重定位表告诉链接器在程序代码中哪里要求重定位。重定位表中的每个入口包含一个对符号表的引用。链接器可以使用这个引用检索符号的实际地址并把它用于程序中那个由重定位入口指定的位置。对于重定位表,同时包含符号地址和重定位入口信息是可以的,这种情况下就没有重定位表和符号表之间的引用了。
对于可执行映像,所有的外部符号必须被解析以便每个符号有一个绝对的内存地址,因为可执行映像是准备执行的。也有例外,那些符号如果被定义在共享库中将依然包含相对地址。这些符号将在运行时解析(动态链接)。
阅读(1665) | 评论(0) | 转发(0) |