22/8/9 深入理解计算机系统 笔记
7.6.3 链接器使用静态库来解析引用
链接器维护三个集合:E、D、U。
E:可重定位目标文件的集合
D:已定义的符号集合
U:未解析的符号的集合
第一步:链接器判断输入文件f的类型,如果是目标文件,则放入集合E中,同时根据f更新D和U。
第二步:如果f是一个文档文件,那么链接器使用f中的每个存档文件成员 对U中的符号进行匹配,如果某个存档文件成员m定义了集合U中的一个引用,则将m添加到E中,同时更新集合D与U。
第三步:如果链接器处理完了所有文件之后,集合U非空,则链接器会报错,如果U为空,则它会合并和重定位E中的目标文件,构建可执行文件。
PS:如果库的成员是相互独立的,则库可以以任意的位置写在命令行中,如果库不是相互独立的,则要注意依赖关系。
比如foo.c调用了libx.a和libz.a的函数,同时这两个库又调用了liby.a的函数,那么命令行中libx.a和libz.a必须处于liby.a之前。
循环包含要写成循环的,重复写。
7.7重定位
建立定义和引用对应关系之后,就可以进行重定位了,合并输入模块,并为每个符号分配运行时内存。
重定位包括两步:
重定位节和符号定义:合并所有目标文件的类型相同的节,同时链接器把运行时内存的地址赋给新的节和输入模块定义的每个符号。这一步完成之后程序的每条指令和全局变量都有唯一的运行时内存地址了(虚拟内存)
重定位节中的符号引用:
这一步,链接器修改代码节和数据节中每个符号的引用,使它们指向正确的运行时地址。这一步链接器依赖与可重定位目标模块中的重定位条目的数据结构。
7.7.1 重定位条目
浙公网安备 33010602011771号