- 静态链接与动态链接
静态链接
- 输入一组可重定位目标文件(包括系统目标文件),和命令参数, 输出可执行目标文件。
- 符号解析
- 将每一个符号引用正好与一个符号定义关联起来
- 重定位
- 编译汇编产生的代码节都是从0开始,连接器把每个符号定义与一个内存位置关联起来,重定位这些节。
- 符号解析
- 符号与符号表
- 可重定位目标文件里面包含三种符号
- 有模块自己定义的全局变量,函数
- 其他模块定义,自己引用的全局符号
- 自己定义的局部符号,static的函数,变量
- static有保护当前模块内 全局变量,函数的作用,static对象不能被其他模块访问。
- 符号解析
- 将每一个符号引用与某一个可重定位目标文件符号表里的一项联系起来
- 关键在于处理全局符号:
- C++/Java都对符号表的名字进行重整(mangling), 以实现函数重载 .
函数和已经初始化的全局变量是强符号, 未初始化的全局变量是弱符号 规则1——多个强符号不能重名, 2——强符号.与弱符号重名,则选择强符号 3——多个弱符号重名,随机选择一个
-
静态库
- 静态库是多个可重定位目标文件的打包,链接器按照命令行参数从左到右的顺序,以此确定每个符号对应的符号定义,但是库文件只会选择其中某几个目标文件添加(如果扫过之后,才发现需要库文件某一项,则失败),因此库文件一般放最后面,且库文件之间的顺序很关键。
-
重定位
- 在编译的时候就生成重定位条目,放在.rel.data, .rel.text中。(在重定位这时候已经确定每一个符号的位置了)。
-
加载可执行目标文件
- 可执行目标文件里面妹有rel(符号引用),将他的data和text复制到内存中,每一个运行的程序都有自己的内存影响,就是虚拟地址空间的分配情况
-
使用动态链接库
- 在内存中,一个库的。text副本被多个运行程序共享,节省内存。 .so共享库文件,是内存无关代码生成的.
- 运行前链接: 可执行目标文件在被装入运行时,先加载运行动态连接器,重定位so库文件里面文本数据,重定位程序中对库文件的引用,在此之后,共享库在程序内存地址空间中的位置就确定下来.
- 运行中链接: