关于动态链接的装载时重定位

sicofield 2013-05-23 04:59:31
在《程序员的自我修养》7.3.2节中有这么一段话“动态链模块被装载映射到虚拟空间后,指令部分是再多个进程之间共享的,由于装载时重定位的方法能需要修改指令,所以没有办法做到同一份指令被多个进程共享,因为指令被重定位后对于每个进程来讲是不同的。”
对于这段话,我一直都不太明白,首先同一份指令应当是指的共享模块中的指令吧?如果是的话,那么各个进程无论将共享模块装载至进程虚拟地址空间的何处,只要在该进程装载时对共享模块中地址的引用执行重定位,即使装载的地址不一样,重定位之后也是各个进程的中的代码对共享模块引用地址的不同,而共享模块中的代码是不需要变化的呀。。并且通过页映射机制,不同进程中共享模块的页可以映射到内存中的同一页,这样不就实现了共享吗??
请问我上述的分析哪里有问题???
...全文
275 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
A280104758 2014-05-27
  • 打赏
  • 举报
回复
我也遇到了这个问题,请问你找到解决的方案了吗?
www_adintr_com 2013-05-24
  • 打赏
  • 举报
回复
你说错了, 是使用内部模块的全局变量. 使用外部模块的全局变量,是通过输入表才能引入的, 使用它们不需要修改代码. 你大概是想, 使用模块内部的全局变量, 可以像 call/jmp 那样使用偏移量来进行, 这样不管 dll 加载到哪里, 偏移量是不变的, 就不需要修改代码. 但事实是, 数据操作指令使用的不是偏移量! 数据段和代码段是分开的, 用代码段的地址偏移多少去获取数据段是不合理的, 如果你手写汇编, 或许可以通过额外的指令来达到这样的效果, 但是一般人写的代码, 或是编译器生成的代码, 操作数据段都使用数据段的完整地址, 而不是相对于代码的偏移!
sicofield 2013-05-24
  • 打赏
  • 举报
回复
引用 1 楼 adlay 的回复:
dll 里面指令的重定位, 不是 dll 导出函数或是输入表的定位. 比如 dll 里面的指令引用一个它的全局变量: mov eax, [0x123456] 这个全局变量的地址就会随着 dll 加载的位置不同而有变化, 那么这条指令里面的立即数就需要修改才行.
嗯,如果是模块内部全局变量的话,是可以不变的,如果是外部模块的全局变量,是会改变代码的。 谢谢你的思路。
www_adintr_com 2013-05-24
  • 打赏
  • 举报
回复
编译器不可能把你的每次数据访问都去翻译成一个函数调用再加若干计算偏移的指令吧. 这个是 x86 的寻址方式决定的, jmp/call 这些使用偏移是因为硬件执行上可以直接把后面的立即数加到 EIP 上就完了. 你随便写一个访问全局变量的函数, 反汇编出来, 看看他的汇编代码和机器码即可验证. 用不着去做各种假设猜想, 翻理论验证.
sicofield 2013-05-24
  • 打赏
  • 举报
回复
引用 3 楼 adlay 的回复:
你说错了, 是使用内部模块的全局变量. 使用外部模块的全局变量,是通过输入表才能引入的, 使用它们不需要修改代码. 你大概是想, 使用模块内部的全局变量, 可以像 call/jmp 那样使用偏移量来进行, 这样不管 dll 加载到哪里, 偏移量是不变的, 就不需要修改代码. 但事实是, 数据操作指令使用的不是偏移量! 数据段和代码段是分开的, 用代码段的地址偏移多少去获取数据段是不合理的, 如果你手写汇编, 或许可以通过额外的指令来达到这样的效果, 但是一般人写的代码, 或是编译器生成的代码, 操作数据段都使用数据段的完整地址, 而不是相对于代码的偏移!
ELF文件中有一个函数 __i686.get_pc_thunk.cx这个函数可以得到当时的PC值,之后加上一定的偏移,就可以由代码段跳至数据段,事实上ELF文件也是这么执行的,不知道dll文件有没有这种技术。应该不至于没有吧。
www_adintr_com 2013-05-23
  • 打赏
  • 举报
回复
dll 里面指令的重定位, 不是 dll 导出函数或是输入表的定位. 比如 dll 里面的指令引用一个它的全局变量: mov eax, [0x123456] 这个全局变量的地址就会随着 dll 加载的位置不同而有变化, 那么这条指令里面的立即数就需要修改才行.

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧