《Linux内核分析》第七周 读书笔记
《深入理解计算机系统》CHAPTER7阅读梳理
【学习时间:3hours】
【学习内容:链接需要的代码&数据;链接机制;链接生成的目标文件】
一、链接概述
1.链接
- 定义:链接是将各种数据和代码收集起来成并组合成为一个单一文件的过程(这个文件可以被拷贝到存储器并且执行)
- 场合:
- 编译时:即源代码被翻译成机器代码
- 加载时:程序被加载器加载到存储器并执行
- 运行时
- 作用:
- 使得分离编译成为可能(将大型应用程序分解为若干个小模块)
2.铺垫——编译驱动程序以及目标文件、符号表
编译驱动程序代表用户调用语言预处理器、编译器、汇编器和连接器
- 预处理器将.c文件翻译成ASCII码中间文件.i;
- 编译器将.i文件翻译成ASCII码汇编语言文件.s;
- 汇编器将.s文件翻译成可重定位目标文件.o;
- 链接器程序将.o文件以及一些必要的文件组合起来创建一个可执行目标文件;
- 加载器拷贝可执行文件代码和数据到存储器然后将控制转移到程序头
目标文件有三种形式:
- 可重定位目标文件
- 包括如下内容
- ELF头:描述文件系统的字的大小和字节顺序,ELF头的大小,目标文件类型,机器类型等
- 节:.text已编译程序的机器代码,.data&.bss分别是已初始化和未初始化的变量,.symtab一个符号表存放在程序中定义和引用的全局变量信息
- 符号表中三种不同的符号:
- 由本模块定义并被其他模块引用的全局符号(即不带static的全局变量)
- 由其他模块定义并被本模块引用的全局符号(即定义在其他模块中的C函数变量)
- 只被本模块定义和引用的本地符号
- 另外,本地程序非静态变量不在符号表中,它们在运行时在栈中被管理;编译器把初始化为0的变量放在.bss而非.data中
- 符号表中三种不同的符号:
- 节头部表:描述目标文件的节
- 可执行目标文件
- 包括如下内容:
- ELF头部:描述总体格式,包括程序的入口点也就是程序运行的时候要执行的第一条指令
- 段头部表:描述可执行文件连续片和存储器段的映射关系
- 其他
- 共享目标文件(特殊的可重定位目标文件)
3.静态链接
链接器的两个主要任务
- 符号解析:将每个符号引用刚好和一个符号定义联系起来
- 重定位:链接器通过把每个符号定义与一个存储器位置联系起来
4.符号解析
- 对于那些和引用定义在相同模块的本地符号;编译器只允许每个模块中每个本地符号有一个定义
- 对于全局符号的解析
- 当编译器遇到一个不是在当前模块中定义的符号时,它会假设该符号是在某个模块中定义的,生成一个链接器符号表条目然后交给链接器处理
- 如果在链接器的任何模块中都找不到这个被引用的符号,它就输出一条错误信息然后终止
- 对于多重定义的全局符号:
- 函数和已经初始化的全局变量是强符号,未初始化的全局变量是弱符号
- 规则:
- 不允许有多个强符号
- 如果有一个强符号和多个弱符号,那么选择强符号
- 如果有多个弱符号,那么从其中任选一个
5.重定位
重定位由两个步骤组成
- 重定位节和符号定义:链接器将所有相同类型的节合并为同一类型的新的聚合节
- 重定位节中的符号引用:链接器修改代码节和数据节中对每个符号的引用,使得它们指向正确的运行时的地址
重定位条目:
无论何时汇编器遇到对最终位置的目标引用,它就会生成一个重定位条目,告诉链接器将目标文件合并成可执行文件的时候如何修改这个引用
6.与静态库连接
- 概述:编译系统提供一种机制,将所有相关的目标模块打包为一个单独的文件,称为静态库,它可以用做链接器的输入
- 优点:
- 相关的函数可以被编译为独立的目标模块,然后封装成一个单独的静态库文件
- 链接器只拷贝被引用程序引用的目标模块,这就减少了可执行文件在磁盘和存储器中的大小
- 图示
7.加载可执行文件
- 加载器将可执行目标文件中的代码和数据从磁盘拷贝到存储器中,然后通过跳转到程序的第一条指令来运行程序
- 存储器映像
- 每个Unix程序都要加一个运行时存储器映像
《Linux内核分析》第七周 读书笔记的更多相关文章
- linux内核分析 第七周读书笔记
第七章 链接 1.链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载到存储器并执行. 2.链接可以执行于编译时,加载时,运行时. 7.1编译器驱动程序 1.大多数编译系统 ...
- Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序
Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...
- Linux内核分析——第七周学习笔记20135308
第七周 可执行程序的装载 一.预处理.编译.链接和目标文件的格式 1.可执行程序是怎么来的 C代码—>预处理—>汇编代码—>目标代码—>可执行文件 .asm汇编代码 .o目标码 ...
- linux内核分析 第六周读书笔记
第三章 进程管理 3.1 进程 进程:处于执行期的程序 线程是在进程活动中的对象:内核调度的对象是线程而不是进程,在Linux系统中,并不区分线程和进程 在现代操作系统中, 进程提供两种虚拟机制:虚拟 ...
- linux内核分析 第八周读书笔记
第四章 进程调度 4.1 多任务 1.多任务操作系统就是能同时并发的交互执行多个进程的操作系统. 2.多任务操作系统使多个进程处于堵塞或者睡眠状态,实际不被投入执行,这些任务尽管位于内存,但是并不处于 ...
- linux内核分析 第五周读书笔记
第18章 调试 内核调试的难度大于用户级 一.准备开始 开始之前需要的是: 一个行为可靠且定义明确的bug 一个隐匿bug的内核版本 相关内核代码的知识和运气 想要成功的调试,取决于能不能将这些bug ...
- LINUX内核分析第七周学习总结:可执行程序的装载
LINUX内核分析第七周学习总结:可执行程序的装载 韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...
- Linux内核分析第四章 读书笔记
Linux内核分析第四章 读书笔记 第一部分--进程调度 进程调度:操作系统规定下的进程选取模式 面临问题:多任务选择问题 多任务操作系统就是能同时并发地交互执行多个进程的操作系统,在单处理器机器上这 ...
- Linux内核分析 第七周 可执行程序的装载
张嘉琪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核分析 第七 ...
- LINUX内核分析第七周学习总结
LINUX内核分析第七周学习总结 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.c ...
随机推荐
- HTML5属性运用
HTML5 接触移动端,或专注于支持HTML5浏览器进行前端开发的工作者都不会陌生,这个已经普及很广,对于我专注于PC端开发的人来说,觉得陌生但又觉得很熟悉,大家都知道做PC前端开发为了兼容IE老版本 ...
- 关于在C#中构造函数中调用虚函数的问题
在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...
- Intellij IDEA tomcat相关
可能遇到的问题: tomcat7启动报错 java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addFilter h ...
- BZOJ3723 : PA2014Final Gra w podwajanie
暴力搜索出所有可行的形状,可以发现本质不同的形状数只有6000个左右. 对于每个形状,它的大小不超过$8\times 8$,故可以按照右下角为原点重建坐标系,用一个unsigned long long ...
- html5调用手机相机并压缩、上传
近日刚做的一个功能,要在app里使用内嵌页面进行图像的上传.从功能上看,原生的实现应该是最好的.毕竟页面上所有的东西都隔着一个浏览器,所有的实现都要依赖浏览器提供的接口,不同的浏览器对接口的实现又有差 ...
- Android MultiDex
出现的原因: 当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt.DexOpt的执行过程是在第一次加载Dex文件的时候执行的.这个过程会生 ...
- 查看那个进程占用了端口号(LINUX与AIX)
在LINUX中: netstat命令 [root@limt ~]# netstat -tulp Active Internet connections (only servers) Proto Rec ...
- 【转】C#进阶系列——WebApi 接口参数不再困惑:传参详解
原文地址:http://www.cnblogs.com/landeanfen/archive/2016/04/06/5337072.html 阅读目录 一.get请求 1.基础类型参数 2.实体作为参 ...
- 使用IE建多个会话的小技巧
1 按F10出现菜单 2 选择文件----新建会话即可
- MVVM deep dive
You can get a different instance each time by passing a different key to the GetInstance method. How ...