《程序员的自我修养》第四章——静态链接

  链接就是将几个输入目标文件,加工并合并在一起组成一个输出文件的过程。静态链接主要有两个步骤,空间及地址分配符号解析与重定位

4.1 空间和地址分配

  1. 扫描所有输入目标文件,获得各段长度、属性和位置,并收集所有符号表中的符号定义和符号引用,放在一个统一的全局符号表内。
  2. 将输入文件中相同性质的段合并成输出文件的一个段,比如将输入文件所有的“.text”段合并成输出文件的“.text”。
  3. 为输出文件各段确定空间地址。空间地址有两种,一种是各段在可执行文件中的偏移地址,另一个是指进程的虚拟空间地址,链接过程主要关注虚拟空间地址。(这个过程实际上就是指定可执行文件与进程执行时的虚拟地址空间的映射关系)
  4. 由符号在段中的偏移值,确定各符号定义的虚拟地址。
    空间和地址分配关系图

4.2 符号解析与重定位

  1. 进行符号解析: 将各符号引用与输入文件某一个确定的符号定义联系在一起,如果找不到就报未定义错误。从普通程序员角度看,符号解析占链接的主要部分。
  2. 根据重定位表和符号定义的地址,确定每一个重定位入口的地址。
    输入文件进行符号引用处,由于不知道相应符号的地址,所以需要将符号标记下来进行重定位,这个记录表就成为重定位表,或者重定位段。重定位表实质上是一个具有特定结构的数组,每一个数组元素都包含几点信息,重定位入口的偏移值、符号和重定位入口的类型。
    输入文件中每一个引用了外部符号的段都对应一个重定位段,如代码段“.text”对应的重定位段叫“.rel.text”.
  3. 指令地址修正。
    由于不同cpu的寻址方式不同,所以每一个重定位入口处的实际地址都需要修正。指令修正由两个要素决定,该重定位入口的类型以及其虚拟地址。入口类型决定了指令修正方式,主要有绝对寻址修正和相对寻址修正两种。

4.3 静态库链接

  静态库即一组目标文件打包后的集合。链接时,链接器会自动寻找到所有需要链接的符号,将相应的目标文件从静态库中解压出来。
  一般静态库一个目标文件只包含一个函数实现。因为链接是以单个目标文件为基本单位,如果同一个文件定义了多个函数,但只使用一个,链接时就会将其他函数也链接进来,就会造成空间的浪费。
  静态库对应的头文件,一般在外部定义,不包含在库里。

4.4 链接过程控制

  使用链接脚本,可以指定链接时各段的大小、属性、段名、存放位置等一系列参数,是最强大也最灵活的链接控制方法。
  常用的是Ld链接脚本,相关语法此处暂不介绍。

4.5 BFD库

  全称 Binary File Descriptor library , 是一个GNU项目,旨在提供一组统一的接口来兼容不同类型的目标文件格式,是一个中间层。
  现在的GCC、链接器ld,调试器GDB以及binutils的其他工具都是通过BFD库来处理目标文件,而不直接操作目标文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值