解读《深入理解计算机系统(CSAPP)》第7章链接

 前言

📫作者简介小明Java问道之路,专注于研究计算机底层/Java/Liunx 内核,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计📫 

🏆CSDN专家博主/Java领域优质创作者、阿里云专家/签约博主、InfoQ签约博主、华为云专家、51CTO专家🏆

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~

导读

链接是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载到内存并执行。链接可以执行于编译时、加载时或者运行时。链接是由链接器自动执行的。

大多数编译器提供编译器驱动程序(compiler driver),他代表用户在需要时调用语言预处理器、编译器、汇编器和链接器

重点解读:

一、静态链接

使用编译器驱动程序进行程序的翻译和链接
linux> gcc -Og -o prog main.c sum.c
linux> ./prog
下图静态链接结构图

为了构造可执行文件,链接器必须完成两个主要任务:
符号解析(我们在代码中会声明变量及函数,之后会调用变量及函数,所有的符号声明都会被保存在符号表(symbol table)中,而符号表会保存在由汇编器生成的 object 文件中(也就是 .o 文件)。符号表实际上是一个结构体数组,每一个元素包含名称、大小和符号的位置。)
重定位(这一步所做的工作是把原先分开的代码和数据片段汇总成一个文件,会把原先在 .o 文件中的相对位置转换成在可执行程序的绝对位置,并且据此更新对应的引用符号(才能找到新的位置))

二、动态连接

目标文件有三种形式:一、可重定位目标文件:包含二进制代码和数据。其形式可以在编译时与其他可重定位目标文件合并起来,创建一个可执行目标文件。二、可执行目标文件:包含二进制代码和数据。其形式可以被直接复制到内存并执行。三、共享目标文件:一种特殊类型的可重定位目标文件,可以在加载或者运行时被动态地加载进内存并链接。

目标文件纯粹是字节块的集合。这些块中,有些包含程序代码,有些包含程序数据,而其他的则包含引导链接器和加载器的数据结构。

三、编译系统

四、可重定位目标文件

上面提到的三种对象文件有统一的格式,即 ELF,下图展示了一个典型的ELF可重定位目标文件的格式。

ELF头:以16字节的序列表述了生成该文件的系统的字大小和字节顺序。剩下的部分包括文件类型、机器类型、节头表位置等。(可以用readelf -l main查看)
.text:代码
.rodata:只读数据,如printf的格式串、swich的跳转表。
.data:已初始化的全局和静态变量。
.bss:未初始化/初始化为0的全局和静态变量。仅有节头,节本身不占用磁盘空间,仅仅是一个占位符。
.symtab:符号表,函数和全局/静态变量的信息。
.rel.text:.text节中的可重定位信息。包括在合并后的可执行文件中需要修改的指令地址。
.rel.data:.data节中的可重定位信息。包括在合并后的可执行文件中需要修改的指针数据的地址。
.debug:调试符号表。(gcc -g)
节头部表:每个节的偏移量、大小。

注:

当汇编器遇到对最终位置未知的目标引用,它就会生成一个重定位条目,告诉链接器在将目标文件合并成可执行文件时如何修改这个引用。代码的重定位条目放在.rel.text中,已初始化数据的重定位条目放在.rel.data中。

ELF重定位条目的格式:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小 明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值