深入理解计算机操作系统(1):链接器

链接器定义:
链接是将各种代码和数据片段收集起来组合成为一个单一文件的过程。可能发生在编译、加载到内存、程序执行时候
在这里插入图片描述
首先使用预编译器将mian.cpp翻译成main.i(ASCII码的中间文件),再使用编译器翻译成main.s(汇编文件),再使用汇编器翻译成可重定位目标文件main.o,最后使用链接器将main.o和sum.o链接成可执行文件。最后使用加载器把生成的可执行文件加载到内存中。

**目标文件:**每个目标文件的地址都从0开始,相当于每个section的地址是相对于该目标文件的起始位置的偏移
1)可重定位目标文件:包含二进制代码和数据,可在编译的时候与其他可重定位目标文件合并,生成可执行目标文件
2)可执行目标文件:包含二进制代码和数据,可以被复制到内存中执行
3)共享目标文件:特殊的可重定位目标文件,可以在加载或者运行的时候加载入内存中链接

这三种文件具有统一的格式:
在这里插入图片描述
ELF header:生成该文件的字的大小,字节顺序,文件的类型,操作系统的类型、程序入口点;
segment header table:代码段在内存中的位置
text:被编译的代码块,函数,二进制码
rodata section:只读数据部分,const修饰的变量,以及字符串常量
data:初始化的全局变量,大小为存储的变量大小之和,两个int为8个字节
bss:未初始化的全局静态变量不占据实际的磁盘空间,只在段表中记录大小,在符号表中记录符号,当文件加载运行时,才分配空间以及初始化
symtab:符号表,只会为静态局部变量、全局变量和函数定义符号,不包含非静态局部变量,这些存在栈中编译器和汇编器一起创建,主要包含了符号的名字和值(地址),如果之后有一个同名的符号引用则会使用该地址
rel.txt和txt.data:重定位信息
section header table:所有section的信息,名字,长度,偏移
common:未初始化的全局变量,因为可能其他文件进行了初始化,因此编译器交给了链接器来完成

链接步骤:
1)空间与地址分配:扫描所有的输入目标文件,获得各个section长度、位置,将符号表统一放到一个符号表中,同时将同类型的section合并,确定每个section的偏移,每个符号有对应的偏移,这样就能计算每一个符号的虚拟地址
2)符号解析和重定位:链接器会去全局符号表找到相对应的符号,将每个引用符号进行地址修改(重定位表记录了哪些指令需要被重定位),采用绝对地址和相对地址的方法。

一、符号解析:
符号:
1)全局符号:在当前模块中定义,且可以被其他模块引用
2)外部符号:全局符号的一种,是在其他模块中定义。
3)本地符号:在当前模块中定义,并且只能由当前模块引用,静态全局变量,静态局部变量

如果定义了两个同名的静态变量
1)在同一个文件中定义了两个同名静态变量,会有不同的符号定义。
2)在不同的文件中定义了两个同名全局,会根据是否初始化分配强弱符号(已经初始化的变量、函数为强符号,没有初始化的为弱符号),编译器编译的时候会把强弱符号传递给汇编器,汇编器会把这些符号包含在可重定位目标文件的符号表中
i)不能同时出现同名强符号,会出现链接错误
ii)同名强符号和弱符号,会选择强符号
iii)多个弱符号,会选择所占内存最大的一个

静态库的链接: 链接器会自动寻找相关的.o文件进行链接
首先会定义3个集合,包含目标文件的集合E,引用但没有定义的符号集合U,有定义的符号集合D。
1)如果是可重定位文件,直接加入E,并且修改U和E
2)如果是Linux下的存档文件(相当于静态库),判断该文件中有没有定义U中的符号,有的话加入E,并修改U和D;如果该文件中出现了未被引用的符号的定义,则会报错。 因此编译命令包含符号引用的文件应该在前面,比如mian中调用了sum,则main.o在sum.o前面
如果最后U非空则会出现错误

二、可执行目标文件:
在这里插入图片描述
ELF头部:存在程序入口点,即第一条指令的地址。加载器会把这个文件的代码和数据部分加载到内存里面,然后跳转到程序入口点

三、动态链接
动态库可以在可执行文件加载到内存或者运行的时候进行链接。
在这里插入图片描述
第一步的链接会把.so文件里的符号表等信息复制过去。
第二步的链接会把.so里的代码段和数据段加载到一个内存上,然后对可执行文件进行重定位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值