3.15 动态链接(2): 全局偏移表

动态链接(2): 全局偏移表

1 相关符号表及结构

  1. 动态链接器(.interp)
  2. 链接所需要信息:.dynamic段
  3. 动态符号表(.dynsyms)
  4. 动态链接重定位表
  5. 过程链接表(PLT)
  6. 全局偏移表(GOT)

2 动态链接器

2.1 interp段

  1. 该段存放一个字符串,用于指明动态链接器的路径
  2. 查看.interp段内容:
arm-linux-gnueabi-objdump –s a.out
# 如 /lib/ld-linux.so.2

2.2 动态链接器

  1. 跟动态链接库一样,本质也是一个共享库
  2. 在运行之前,要首先给自己进行重定位:自举
  3. 在C标准库中实现,是Glibc的一部分

3 .dynamic段

保存了动态链接器所需要的基本信息:

  1. 依赖于哪些共享库
  2. 动态链接符号表位置
  3. 动态链接字符串表的位置
  4. 动态链接重定位表位置
  5. 共享库初始化代码位置
    查看.dynamic段内容:
readelf –d xx.so

4. 动态链接符号表

4.1 dynsyms section

  1. 静态链接的符号表保存了该文件所有的符号定义及引用
  2. 动态链接的符号表只保存动态链接的符号
  3. 查看动态链接符号表:
readelf –s a.out

4.2 动态链接字符串表

  1. 动态链接符号表的辅助表,存储符号名
  2. 符号表.symtab对应.strtab
  3. 动态链接符号表.dynsym对应.dynstr

4.3 符号哈希表

  1. 动态链接文件,提高程序运行查找符号速度
  2. 静态链接无此段
  3. 查看字符串表:$ readelf –sD a.out/xx.so

5 动态链接重定位表

  1. 包括.rel.dyn和.rel.plt
  2. .rel.dyn用于描述数据段的重定位信息
  3. .rel.plt用于代码段的重定位信息
  4. 重定位表中的地址偏移为各个未定义符号在GOT表中的地址

查看重定位表:

readelf -r xx.so

6 过程链接表

  1. 使用.plt后缀,内容是一个跳转命令,跳到GOT对应的项
  2. 过程链接表无法单独工作,跟GOT是关联的
  3. 当引用某个符号时,会从PLT表跳转到GOT表

7 延迟绑定PLT

7.1 动态链接对性能的影响

寄存器间接寻址
程序运行之前的动态链接、重定位

7.2 延迟绑定

当函数第一次用到时才进行绑定
ELF就是采用PLT的方式来实现

7.3 最终形式

动态链接:节省内存
延迟绑定:提高运行速度

8 全局偏移表

8.1 got表

GOT: Global Offset Table
每一个引用外部模块定义的符号在GOT表中有相应的条目
.got:编译器将对外部引用(绝对地址)的符号全部分离出来放到该表中

9 重定位过程

9.1 修改全局偏移表GOT

  1. 第一次调用使用PLT表跳转,跳到GOT,再跳到动态链接器
  2. 动态链接器链接共享库、重定位、修改GOT表符号真实地址
  3. 第二次调用,直接从GOT表中跳转到符号真实地址,执行函数

在这里插入图片描述

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用[1]中的错误信息,报错是因为找不到满足要求的yaml版本。这可能是因为你没有正确安装yaml或者你的Python环境中没有与所需版本兼容的yaml库。你可以尝试以下解决方法: 1. 确保你已经正确安装了yaml库。你可以使用以下命令来安装yaml库: ```shell pip install pyyaml ``` 2. 如果你已经安装了yaml库但仍然报错,可能是因为你的Python环境中没有与所需版本兼容的yaml库。你可以尝试升级你的Python环境或者使用其他兼容的yaml库版本。 根据引用中的错误信息,报错是因为在Ubuntu 16.04.6 LTS下升级cmake到最新版本3.15时,出现了GLIBCXX_3.4.22版本未找到的错误。这可能是因为你的系统中缺少GLIBCXX_3.4.22版本的库。你可以尝试以下解决方法: 1. 确保你的系统已经安装了GLIBCXX_3.4.22版本的库。你可以使用以下命令来安装: ```shell sudo apt-get install libstdc++6 ``` 2. 如果你已经安装了GLIBCXX_3.4.22版本的库但仍然报错,可能是因为你的系统中存在多个版本的libstdc++库,而cmake使用的是其他版本的libstdc++库。你可以尝试使用以下命令来设置cmake使用正确的libstdc++库: ```shell export LD_LIBRARY_PATH=/path/to/your/libstdc++/lib:$LD_LIBRARY_PATH ``` 请注意,上述解决方法可能因系统环境和具体情况而有所不同。如果问题仍然存在,请提供更多详细信息以便我们能够更好地帮助你解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值