在创建最终镜像之前,链接器在解析目标文件中的重定位时究竟采取了哪些步骤?更具体地说,链接器如何处理已存储在重定位站点的值?它是否总是将其添加到最终的 VA/RVA 中,还是有时会被忽略(例如某些重定位类型)?
我在 MS PE/COFF Specfication 中找不到明确的解释,经过谷歌搜索和试验一段时间后,我能找到的是:
您能否指出任何(相关)文档来解释链接器如何处理重定位?
最佳答案
“图像文件”中使用的重定位部分与“目标文件”中存在的重定位信息的用途略有不同。
与 Linux 共享库不同,Windows DLL 通常不使用位置无关代码。相反,它们是相对于固定地址定义的。但是,Windows 加载程序能够在发生冲突时重新定位 DLL。为了支持这一点,DLL 镜像包含重定位部分,用于指定在重定位镜像时需要修改哪些数据。许多 dll 内符号引用将使用“eip”(或 rip)相对寻址,因此它们可能不需要在 DLL 重定位时进行修改。
镜像文件重定位总是相对于可执行镜像的基地址指定。目标文件重定位是相对于符号表中符号的地址(在图像内,使用基于图像首选的地址)指定的。图像文件没有符号表(它们有 IAT,但这不是符号表)。目标文件中支持的重定位集比图像文件中支持的集更丰富。
PE/COFF 规范的“COFF 重定位(仅对象)”部分涵盖了详细信息(我在键入此内容时正在查看第 3 版)。
关于relocation - 重定位如何在 COFF 对象(非图像)文件中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17896989/