COFF目标文件中的重定位是如何工作的(不是映像文件)

7
在创建最终映像之前,链接器在解析目标文件中的重定位时采取了哪些步骤?更具体地说,链接器如何处理已经存储在重定位位置的值?它是否总是将其添加到最终VA/RVA中,还是有时会忽略它(例如某些重定位类型)?我在MS PE/COFF Specfication中找不到清晰的解释,在谷歌和实验一段时间后,我所能找到的只有这个:
  1. 在MS COFF规范的第5.6.2章节“基地址重定位类型”中,它说“基地址重定位将32位差异应用于偏移量处的32位字段”,我猜这意味着重定位应该考虑到已经存储在指定偏移量处的任何地址。但是,第5.6章(.reloc部分)只与映像文件有关,而不是目标文件。
  2. 当打印重定位表时,dumpbin实用程序会添加一个名为“Applied To”的列,该列似乎始终(无论重定位类型如何)包含存储在重定位位置处的值。
  3. DJGPP COFF规范中的重定位指令章节清楚地说明,应将当前存储在该位置的值添加到由重定位表条目指向的符号的地址。

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


目标文件的适当部分不是5.6.2节,而是4.2节的“COFF重定位”,5.6.2节仅适用于映像文件,对吗? - legalize
应该是这样的,但是第4.2节没有解释如果重定位位置存储了一个与0不同的值该怎么办,而这实际上是相当常见的,并且可以使用dumpbin轻松查看。 - user2625389
1个回答

6
在“映像文件”中使用的重定位部分与“目标文件”中存在的重定位信息略有不同。
与Linux共享库不同,Windows DLL通常不使用位置无关代码。相反,它们是相对于固定基址定义的。然而,Windows加载程序具有在冲突事件中重新定位DLL的能力。为了支持这一点,DLL映像包含指定在映像重新定位时需要修改哪些数据的重定位部分。许多内部DLL符号引用将使用“eip”(或rip)相对寻址,因此可能不需要在DLL重新定位时进行修改。
映像文件重定位始终相对于可执行映像的基地址指定。目标文件重定位相对于符号表中符号的地址(在图像中,使用首选基地址)指定。映像文件没有符号表(它们有一个IAT,但那不是一个符号表)。目标文件中支持的重定位集比映像文件中支持的重定位集更丰富。
详细信息在PE / COFF规范的“COFF Relocations(仅限对象)”部分中介绍(我正在打字时查看版本3)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接