星空网 > 软件开发 > 操作系统

了解动态链接(六)—— 重定位表

柳条青青,南风熏熏,幻化奇峰瑶岛,一天的黄云白云,那边麦浪中间,有农妇笑语殷殷。问后园豌豆肥否,问杨梅可有鸟来偷;好几天不下雨了,玫瑰花还未曾红透;梅夫人今天进城去,且看她有新闻无有。—— 徐志摩·夏日田间即景

无论是可执行文件还是 so,只要它依赖于其他 so(.dynsym 动态符号表中有导入符号存在),那么在编译链接阶段,这些符号的地址未知,所以只能在动态链接阶段对其进行地址重定位。

注意:以 PIC 编译的 so,虽然称“地址无关代码”,但也需要重定位。因为对于 PIC 的 so 来说,只不过是把代码中的绝对地址提出来,放到了数据段的 GOT 表中。所以,虽然代码段不需重定位,但数据段的 GOT 表需要重定位。(以 PIC 编译 so,是为了复用 so 的代码段)

android liblog.so 为例。在代码中调用 memset 时,实际上会跳转到标号 memset_ptr 指向的内存。

 了解动态链接(六)—— 重定位表images/loading.gif' data-original="http://images0.cnblogs.com/blog2015/763648/201507/122301342367246.png" />

而标号 memset_ptr 指向的内存就定义在 GOT 表中:

 了解动态链接(六)—— 重定位表

那么如何为 GOT 表做重定位呢?GOT 表中的每一项应该指向哪一个符号在内存中的地址呢?这些信息就由重定位表来描述。具体到 android 来说,重定位表保存在 .rel.dyn 和 .rel.plt 中。

 了解动态链接(六)—— 重定位表

从表中可以看出,位于 .rel.dyn 中的主要是 R_ARM_GLOB_DAT 类型的重定位项,而位于 .rel.plt 中的主要是 R_ARM_JUMP_SLOT 类型的重定位项。前者用于对数据引用做重定位,而后者用于对函数引用做重定位。除此之外,还看到了 R_ARM_RELATIVE 类型的重定位。

在 android linker 的源码中,调用了两次 soinfo_relocate 函数,分别为 .rel.dyn 和 .rel.plt 做重定位:

 了解动态链接(六)—— 重定位表

在 soinfo_relocate 函数的源码中可以看到,对于不同类型的重定位,计算符号地址的方式也有所不同。

 了解动态链接(六)—— 重定位表

实际上对于 R_ARM_GLOB_DAT、R_ARM_JUMP_SLOT 这两种重定位类型来说,只需将符号地址填入被修正的内存即可。而 R_ARM_RELATIVE 类型看起来特殊些,它的作用是进行基址重置 (Rebasing) 。

比如指针 p 指向静态变量 a,而静态变量 a 相对于 so 基址的偏移为 A。在编译时,so 的基址为 0,此时 p 的值为 A。而当 so 被装载到内存中时,p 的值就需要加上一个 so 在内存中的基址 base。R_ARM_RELATIVE 类型的重定位就是用来干这个的。

对于 android linker 的重定位细节,以及其他重定位类型,在后面写 android linker 源码分析笔记时再描述。

学习资料: 《程序员的自我修养——链接、装载和库》




原标题:了解动态链接(六)—— 重定位表

关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

Mizzen+Main:https://www.ikjzd.com/w/4667
美设国际物流集团股份有限公司:https://www.ikjzd.com/w/4668
原色咨询:https://www.ikjzd.com/w/4669
eBay优秀评级卖家:eBay Top-rated Seller:https://www.ikjzd.com/w/467
TiChoo数据:https://www.ikjzd.com/w/4670
乐聊chat++:https://www.ikjzd.com/w/4671
TikTok斥资210万美元游说美国参议院阻止法案通过 :https://www.goluckyvip.com/news/188220.html
北京飞机票查询(快速查询北京至各地机票价格和航班信息):https://www.vstour.cn/a/366178.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流