CSAPP-链接
主要任务:
1.符号解析
在声明变量和函数之后,所有的符号声明都被保存到符号表。
而符号解析阶段会给每个符号一个定义。
2.重定位:
把每个符号的定义与一个内存位置关联起来,然后修改所有对这些符号的引用,让他们
指向内存位置。
符号解析:
会将符号引用和可重定位目标文件的符号表中的确定符号定义关联起来。
对于相同模块的局部符号(static属性),可以简单解决。
对于全局符号的引用,如果不是在当前模块定义的,会假设在其它模块中,然后通过链接器去查找,找不到则报错。
重载函数:
对于重载函数,会将每个函数和参数列表组合成一个对链接器来说唯一的名字。
多重定义的全局符号:
函数和已初始化的全局符号是强符号,未初始化的全局变量是弱符号。
如果有一个强和多个弱,那么选择强符号;若是多个弱符号,则随机选一个;不允许多个强符号。
/*foo1.c*/
int x = 15151;
int main
{}
/*foo2.c*/
int x = 15151;
void f(){}
如上面的代码会报错,x被多次定义。
/*foo1.c*/
int x = 15151;
int y = 111;
void f();
int main
{}
/*foo2.c*/
double x ;
void f()
{
x = 0.0;
}
double是8字节,int是4字节。因为强弱符号的关系,x=0.0中的x是foo的,于是双精度浮点会覆盖掉x,y的位置。
静态库:
相关的函数会被编译成独立的目标模块,然后封装成一个独立的静态库文件。
在链接的时候,连接器只会复制被程序引用的目标模块,以减小可执行文件的大小。
--
如何解析静态库:
链接器在根据命令行中输入的可重定位目标文件和静态库的顺序从左到右的扫描这些文件。然后维护三个集合:
E:会被合并的文件
U:未解析的符号集合
D:已经定义的文件集合
根据命令行的输入,判断f是目标文件还是存档文件
- 目标文件:链接器会把f加入E,然后修改U,D。
- 存档文件:在U中进行匹配,如果匹配到了,将存档文件成员 添加到E,然后修改UD。
--
如果不使用静态库:
1.将所有标程放到一个目标模块中
但是这样会导致每个可执行文件都包含所有的函数副本,浪费空间。而且任何函数被修改了,都要
重新编译库整个源文件。
2.将所有标程放到一个目录下
可以解决空间浪费的问题,但是这样需要我们显示地链接合适的目标模块,如果函数过多,容易出现错误,而且
浪费时间。
重定位:
1.重定位会将所有同一类型的合并为聚合节。然后将运行时地址赋予它们

2.修改代码节和数据节中对每个符号的引用,使它们指向正确的地址(相对引用 or 绝对引用重定位 等等)。
共享库:
静态库也有一定缺陷,需要定期维护更新。
几乎每个C都会使用IO,那么printf和scanf会被复制到每个运行进程的文本。那么在一个运行了上百个进程的系统上,无疑是一种浪费。
共享库不是像静态库那样将代码和数据嵌入到执行文件中,而是在内存中有一个共享库的.text节的副本,可以被不同的正在运行
的进程共享。
--
在共享库下,创建一个可执行程序:
会先静态执行一些链接,然后在程序加载的时候,动态地完成链接过程。
在加载运行的时候,会主要到.interp节(有动态链接器的路径)。然后加载这个动态链接器
- 重定位共享库的数据文本到某个内存段
- 重定位执行文件中所有对由 共享库定义的符号的引用也可以通过dlopen在应用程序中加载和链接共享库
参考资料:
不周山之读薄CSAPP
《深入理解计算机系统 》
多个进程间共享动态链接库原理
CSAPP-链接的更多相关文章
- 链接器(linker)的作用——CSAPP第7章读书笔记
首先说说我为什么要去读这一章.这个学期开OS的课,在Morden Operating System上读到和Process有关的内容时看到这样一句话:“Process is fundamentally ...
- CSAPP CH7链接的应用:静动态库制作与神奇的库打桩机制
目录 创建静态库 创建动态库 库打桩机制 编译时打桩: 链接时打桩 运行时打桩 运行时打桩的printf与malloc循环调用debug 使用LD_PRELOAD对任意可执行程序调用运行时打桩 总结 ...
- 【CSAPP笔记】13. 链接
下面就要进入本书的第二部分--在系统上运行程序.书的第一部分,主要是研究单个应用程序,关注的是数据类型.机器指令.程序性能.存储器系统等话题.在书的第二部分,我们继续对计算机系统的探索.现代操作系统与 ...
- CSAPP阅读笔记-链接-第七章-P464-P500
链接概述 经预处理器->编译器->汇编器处理后,源文件可被转化为一组可重定位目标文件,链接器将它们组合起来形成可执行文件. 每个可重定位目标文件由不同的“代码节”和“数据节”组成,每一个节 ...
- 菜鸟在C语言编译,链接时可能遇到的两个问题
最近在看 CSAPP (Computer Systems A Programmers Perspective 2nd) 的第七章 链接.学到了点东西,跟大家分享.下文中的例子都是出自CSAPP第七章. ...
- 在Ubuntu下使用 csapp.h 和 csapp.c
它山之石可以攻玉. 对于<深入理解计算机系统>这本神人写就的神书, 我等凡人就不评论什么啦. 这本书的 第二,三 部分, 真的真的对我理解操作系统有很大的帮助. (当然, 如果你不看第一部 ...
- CSAPP读书随笔之一:为什么汇编器会将call指令中的引用的初始值设置为-4
CSAPP,即<深入理解计算机系统:程序员视角>第三版,是一本好书,但读起来确需要具备相当的基本功.而且,有的表述(中译文)还不太直白. 比如,第463页提到,(对于32位系统)为什么汇编 ...
- [CSAPP-II] 链接[符号解析和重定位] 静态链接 动态链接 动态链接接口
1 平台 转http://blog.csdn.net/misskissc/article/details/43063419 1.1 硬件 Table 1. 硬件(lscpu) Architecture ...
- [CSAPP笔记][第九章虚拟存储器][吐血1500行]
9.虚拟存储器 为了更加有效地管理存储器且少出错,现代系统提供了对主存的抽象概念,叫做虚拟存储器(VM). 虚拟存储器是硬件异常,硬件地址翻译,主存,磁盘文件和内核软件的完美交互. 为每个进程提供一个 ...
- [CSAPP笔记][第十一章网络编程]
第十一章 网络编程 我们需要理解基本的客户端-服务端编程模型,以及如何编写使用因特网提供的服务的客户端-服务端程序. 最后,我们将把所有这些概念结合起来,开发一个小的但功能齐全的Web服务器,能够为真 ...
随机推荐
- Python实现网站模拟登陆
一.实验简介 1.1 基本介绍 本实验中我们将通过分析登陆流程并使用 Python 实现模拟登陆到一个实验提供的网站,在实验过程中将学习并实践 Python 的网络编程,Python 实现模拟登陆的方 ...
- C++类型萃取
stl中的迭代器和C++中的类型萃取: http://www.itnose.net/detail/6487058.html 赐教!
- 大数据技术Hadoop笔试题
Hadoop有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上.以下是由应届毕业生网小编J.L为您整理推荐的面试笔试题目和经验,欢迎参考阅读. 单项选择题 1. 下面哪个程序负责 H ...
- Flask学习 三 web表单
web表单 pip install flask-wtf 实现csrf保护 app.config['SECRET_KEY']='hard to guess string' # 可以用来存储框架,扩展,程 ...
- Codeforces 837E. Vasya's Function
http://codeforces.com/problemset/problem/837/E 题意: f(a, 0) = 0; f(a, b) = 1 + f(a, b - gcd(a, b)) ...
- JAVA_SE基础——1.JDK&JRE下载及安装
这是我学了JAVA来写的第一篇博客: 我首先是在传智播客领了张.毕向东老师的免费JAVA学习光盘来学习! 下面我来教大家安装使用JAVA时候必备的JDK 1.首先上甲骨文公司的官方网站下载JDK的安装 ...
- restful架构风格设计准则(二)以资源为中心,一个url
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 1.REST是一种架构风格,其核心是面向资源,简化设计,降低开发的复杂性 ...
- oracle sequence 异常
对于数据量较大的序列进行分析 ,出现风险有两种情况1. 序列号随着业务增加变大时,DB的字段空间不足.>>产生后果:插入报错.>>解决方案:给存储序列号的字段进行扩容,且字段长 ...
- 生成git私钥
在git已经安装的情况下,输入命令: 一.设置git的user name和email git config —(此处两个横杠)global user.name “XXX” git config —(此 ...
- java内部类、接口、集合框架、泛型、工具类、实现类
.t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.内部类 1.成员内部类. (1)成员内部类的实例化: 外部类名.内部类 ...