📅  最后修改于: 2023-12-03 14:58:13.966000             🧑  作者: Mango
在进行程序的编译和链接时,全局符号(例如全局变量、函数)的定义可能散落在不同的源文件中。链接器负责将这些分散的定义整合起来,以便在运行时正确地解析和使用这些全局符号。
链接器通过符号表(Symbol Table)来管理和解析全局符号。符号表是一个包含了全局符号名称和对应地址的数据库。当链接器遇到一个全局符号的引用时,它会在符号表中查找该符号的定义,并将其地址信息填入引用处。下面是链接器解析多个位置定义的全局符号的一般步骤:
预处理:在编译过程中,预处理器会处理源代码中的宏定义、条件编译等指令,生成一个经过预处理的源文件。
编译:编译器将预处理后的源文件转换成目标文件,包含了代码和数据的二进制表示以及符号信息。目标文件中可能包含了未解析的全局符号引用,以及定义了的全局符号。
链接:链接器将多个目标文件组合在一起,解析和整合全局符号的定义和引用。链接器大致可以分为以下几个步骤:
符号解析:链接器首先通过遍历所有目标文件,从中提取全局符号的信息,包括符号名称、类型、大小等,生成符号表。符号表是链接器解析和整合全局符号的核心数据结构。
符号解析算法:链接器使用一种称为"单一定义规则"(One Definition Rule)的算法来解析多个位置定义的全局符号。该规则规定,一个全局符号在整个程序中只能有一个定义,否则就会产生冲突。该规则有多种变体,如C语言中的"强符号"和"弱符号"。
符号解析过程:
符号重定位:当链接器找到了所有未解析的符号引用的定义位置后,它将会进行地址重定位。即根据符号表中的定义地址,修改目标文件中的所有引用处的地址,使之指向正确的定义位置。
可执行文件生成:最后,链接器将解析和重定位后的目标文件生成可执行文件。可执行文件中包含了程序的二进制代码、数据,以及解析后的全局符号。
需要注意的是,链接器在解析多个位置定义的全局符号时,必须保证符号定义的一致性和唯一性。否则,会引发链接错误或运行时错误。因此,在进行程序开发时,应遵循良好的编程实践,避免在多个位置定义相同名称的全局符号。
参考文献: