深入理解静态链接的过程

静态链接的过程

各个文件之间都是单独编译的。编译生成可重定位目标文件后,目标文件格

式也是ELF可执行文件格式但是并不能运行:根本原因是在编译的时候目标文件并没有分配虚拟地址

原因如下:

如果是定义在本文件的函数和变量编译器可以为它分配地址,但是如果当前的源文件引用其他文件的函数或者是全局变量,这个时候就无法确定其地址了。所以就把虚拟地址的确定同意推迟到链接的过程。就需要调用系统的链接器将目标文件进行链接生成可执行文件。处于简单考虑,这里以静态链接进行分析链接过程做了哪些事情:链接过程主要包括了地址和空间分配、符号决议、重定位。    

一、空间与地址分配:

    扫描所有的目标文件,获得它们各个段的长度,属性和起始地址。

    合并各个目标文件的符号表:将目标文件的所有符号表统一放到一个全局的符号表中进行合并。采用相似段合并的策略也就是说将所有目标文件的.text段都合并到输出文件的.text段接着是所有目标文件.data,.bss段进行合并到输出文件对应的段。通过这一步,链接器将能够获得所有输入目标文件的段长度,并且将他们合并计算出目标文件的所有长度和位置。此后所有函数和变量的虚拟地址都可以确定。ELF是从0X08048000(32位)0x400000开始分配虚拟地址的。

二、符号解析和重定位

使用第一步时收集的所有符号信息放在全局符号表中,有些是符号的引用,有些是符号的声明。符号的引用需要进行符号解析和地址重定位,调整引用符号的虚拟地址。其中地址的重定位是链接过程的核心。

符号解析:对于指令中引用其他目标文件中的符号找到符号的正确地址,也就是在全局符号表中找对应的地址。找不到则报符号未定义错误,重复则报符号重定义错误。这个过程和重定位过程一起进行。重定位过程伴随着符号解析。

重定位:就是修正指令对引用其它目标文件的函数或变量的地址,未确定之前用的都是假地址。这个时候因为有第一步合并的全局符号表,所有的符号都有自己的地址可以进行重定位。重定位的过程也参照ELF文件也就是目标文件中的重定位表进行的,该表记录哪些段中包含着需要进行重新定位的函数和变量。也伴随着符号解析的过程。并且也伴随符号的解析过程。

<<程序员的自我修养>>

猜你喜欢

转载自blog.csdn.net/run32875094/article/details/78198179