程序成为链接状态的过程主要涉及以下几个步骤:
静态链接
在程序运行之前,将各目标模块及它们所需的库函数链接成一个完整的可执行程序。以后不再拆开。
装入时动态链接
用户源程序编译后得到一组目标模块,在装入内存时,采用边装入边链接的方式。
运行时动态链接
对某些目标模块的链接,是在程序执行中需要该目标模块时,才对它进行的链接。其优点是便于修改和更新,便于实现对目标模块的共享。
链接器在链接过程中会完成以下任务:
确定符号引用关系:确定程序中使用的符号(如变量、函数)及其地址。
合并相关目标文件:将同一地址空间中的目标文件合并,并安排虚拟地址空间。
确定每个符号的地址:为程序中的每个符号分配一个虚拟地址。
在指令中填入新的地址:将符号的实际地址替换为虚拟地址,生成可执行文件。
动态链接的基本实现过程如下:
动态链接器自举:动态链接器自身也是一个动态共享库文件,在加载动态链接的可执行文件时,必须先加载动态链接器,并由动态链接器完成自身的初始化。
重定位:动态链接器将程序依赖的动态共享库加载到进程的虚拟地址空间中,并更新所有相关的符号引用。
初始化:动态链接器调用动态库中的`.init`代码,以实现动态库特有的初始化流程。
通过这些步骤和过程,程序最终成为链接状态,并可以在操作系统上运行。