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

时间:2013-07-27 10:54:56

标签: relocation coff dumpbin

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

我在MS PE/COFF Specfication找不到明确的解释,经过谷歌搜索和实验一段时间后,我能找到的就是:

  1. 在MS COFF规范第5.6.2节“基本重定位类型”中,据说“基址重定位将所有32位差异应用于偏移量的32位字段”,我猜这意味着重定位应考虑已存储在指定偏移处的任何地址。但是,第5.6章(.reloc部分)仅与图像文件有关,而与目标文件无关。
  2. dumpbin实用程序在打印重定位表时添加一个名为“Applied To”的列,该列似乎始终(无论重定位类型)是否包含存储在重定位站点的值。
  3. Relocation Directives chapter in the DJGPP COFF Specification明确指出当前存储在该位置的值应该添加到重定位表条目指向的符号的地址。
  4. 您能否指出哪些(相关的)文档解释了链接器如何处理重定位?

1 个答案:

答案 0 :(得分:5)

“图像文件”中使用的重定位部分与“目标文件”中的重定位信息略有不同。

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

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

细节在PE / COFF规范的“COFF Relocations(Object Only)”部分中介绍(我在查看版本3时输入此内容)。