重定位如何在COFF对象(非图像)文件中工作

use*_*389 5 coff relocation dumpbin

在创建最终图像之前,链接器在解析目标文件中的重定位时会采取哪些步骤?更具体地说,链接器如何处理已经存储在重定位站点的值?它总是将它添加到最终的VA/RVA中,还是有时会被忽略(例如某些重定位类型)?

我在MS PE/COFF Specfication中找不到清晰的解释,经过谷歌搜索和实验一段时间后,我所能发现的是:

  1. 在MS COFF规范的第5.6.2节"基本重定位类型"中,据说"基址重定位将所有32位差异应用于偏移量的32位字段",我猜这意味着重定位应该采取考虑已经存储在指定偏移处的任何地址.但是,第5.6章(.reloc部分)仅与图像文件有关,而与目标文件无关.
  2. dumpbin实用程序在打印重定位表时添加名为"应用于"的列,该列似乎始终(无论重定位类型)是否包含存储在重定位站点的值.
  3. DJGPP COFF规范中的重定位指令章节明确指出,当前存储在该位置的值应该添加到重定位表条目指向的符号的地址中.

您能否指出我的任何(相关)文档,它解释了链接器如何处理重定位?

Sco*_*ski 5

"图像文件"中使用的重定位部分与"目标文件"中存在的重定位信息略有不同.

与Linux共享库不同,Windows DLL通常不使用与位置无关的代码.相反,它们是相对于固定的地址定义的.但是,Windows加载程序能够在发生冲突时重定位DLL.为了支持这一点,DLL映像包含重定位部分,用于指定重定位映像时需要修改的数据.许多intra-dll符号引用将使用"eip"(或rip)相对寻址,因此可能不需要在DLL重定位时修改它们.

始终相对于可执行映像的基址指定映像文件重定位.对象文件重定位是相对于符号表中符号的地址(在图像内,使用图像首选地址)指定的.图像文件没有符号表(它们有IAT,但这不是符号表).目标文件中支持的重定位集比图像文件中支持的集更丰富.

详细信息在PE/COFF规范的"COFF Relocations(仅对象)"部分中介绍(我在查看版本3时输入此内容).