博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
总结(三)
阅读量:5088 次
发布时间:2019-06-13

本文共 1784 字,大约阅读时间需要 5 分钟。

目录

静态链接

链接过程主要包括地址和空间的分配、符号决议、重定位

1191370-20180607220424014-1873466889.png

空间和地址分配

分配的空间是指虚拟地址空间的分配。

  • 将这连个文件编译之后链接在一块儿成为ab的过程中,a.o和b.o的内容如何合并,换句话说如何在ab中储存两个.o文件的内容?
    相似段合并: 将所有文件中的代码段.text合并在一块儿,.data合并到一块儿等等。
  • 将文件合并之后之前文件的相对偏移地址发生变化,如何在新的文件中对其内容进行定位?
    在链接的过程中,合并多个文件会根据所的信息对其内容碱性符号解析和重定位。

综上所述,链接器分配空间的策略是采用相似段合并,并采用两步链接的方法。

  1. 空间地址分配 扫描输入文件,获得段长度属性位置,将输入文件中的符号定义和引用都收集起来放到全局符号表中。 链接器获得输入文件的段长度,并将它们合并起来,计算输出文件的各个段长度和位置,建立映射关系。
  2. 符号解析和重定位 使用第一步的信息,对合成的输出文件的符号信息进行解析调节,调整代码中的地址等。
    1191370-20180607220437732-1674206898.png

查看各个文件的属性,可以看到ab的.text的大小正好是两个文件的.text大小和

符号地址的确定
因为各个符号在段内的相对位置是固定的,所以其实在合并之后的各个符号的地址就一定确定了,在段基址加上一个偏移值,或者原本的偏移值加上一个偏移值。

符号解析和重定位

重定位 起始对于符号地址以及各个代码段的地址在上面部份已经解决,但是在代码段中的引用的外部符号的地址会在新的输出文件中发生改变,所以代码段中的引用外部符号的地址也需要进行改变,这个也就是重定位的过程。

1191370-20180607220453395-827989206.png

0x14 向esi传入0x00 和 0x21 的main的地址也是0x00, 这些在a.o中作为符号保留位置,在链接成为ab之后,他们的地址被改写

1191370-20180607220506157-1696113687.png

可以看到shared的地址是0x00601000所以填入00 10 60 00

call指令是下一个指令的地址加上调用的偏移值所以 swap地址等于 0040010d + 00000002 = 40010f

问题: 如何确定在重定位的时候的每个符号的地址信息,就是如何找到代码段中哪些地方需要修改?

使用重定位表

对于可重定位的ELF文件来说,他必须包含重定位表,用来专门保存重定位信息(重定位包含但不局限于代码段)。
可以使用objdump的-r选项查看重定位表信息,重定位的数据结构:
1191370-20180607220525815-1605138755.png

r_offset 重定位入口地址

r_info 重定位符号类型

符号解析

使用objdump -s 查看符号信息符号表 .symtab

指令修正方式

  • 绝对寻址修正 S+A
    S是符号的实际地址, A 是修正位置的值,比如shared的修正
  • 相对寻址修正 S + A - P

S是符号的实际地址, P是被修正的位置地址, A是修正位置的值

A是目的地址相对于下一条指令的偏移量
我的理解是 如果D是要填的值的话, 那么有使用call调用函数的地址是D+(-P+A) = S
所以有D = S + A -P

COMMON块

用于解决符号冲突问题,是对弱符号机制问题解决得办法

对于多个符号定义类型不一致情况:

  • 两个或者两个以上得强符号类型不一致
  • 一个强符号,其他的弱符号,类型不一致
  • 两个或者两个以上弱符号类型不一致
    解决办法:
    第一种情况连接器报错, 后面两种情况,参照强符号弱符号得处理方式来进行处理。

API 和 ABI


可以使用ar命令查看lib.a这样得文件内部所存在得.o文件得种类

每个.o文件中只包含一个函数,这样来避免浪费,因为链接器链接静态库的单位是目标文件

链接控制脚本

使用链接器得方法:

  1. 使用命令行 ld collect2之类
  2. 将连接指令存放在目标文件里面
  3. 使用连接控制脚本
    ENTRY(函数名) 入口函数
    STARTUP(filename) 第一个输入文件
    SEARCH_DIR(path) 将路径加入ld链接器得库查找目录
    INPUT(file,file,...) 将指定文件作为链接输入文件
    INCLUDE filename 指定文件包含进本链接脚本
    PROVIDE(symbol) 在链接脚本中定义某个符号

Windows上得可执行文件PE类型,大体和Linux得Elf一样

转载于:https://www.cnblogs.com/Alruddy/p/9153049.html

你可能感兴趣的文章
1-5色彩模式的选择
查看>>
RABBITMQ安装注意点
查看>>
python学习笔记-17 返回函数
查看>>
运行npm run eject报错解决方法
查看>>
php接入支付宝的流程(转载)
查看>>
简单请求和非简单请求
查看>>
ubuntu必备软件安装
查看>>
心得1--js加强dom介绍与node使用
查看>>
js计算时间差
查看>>
ROS学习笔记十:URDF详解
查看>>
软件测试计划
查看>>
IOS Audio开发集合
查看>>
mysql并发控制之快照读和当前读
查看>>
DirectX11 With Windows SDK--27 计算着色器:双调排序
查看>>
POJ1456 Supermarket
查看>>
Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F
查看>>
jQuery $.each的使用方法
查看>>
leetcode 198-234 easy
查看>>
Matlab中给figure添加图例(legend),标题(title)和颜色(color)...
查看>>
window.location详解
查看>>