c - 如何读取目标文件的重定位记录

标签 c object linker relocation

我正在尝试了解 C 工具链的链接阶段。我编写了一个示例程序并剖析了生成的目标文件。虽然这有助于我更好地理解所涉及的过程,但仍有一些事情我不清楚。

这里是:

第 1 部分:初始化变量的处理。

这些重定位表条目是否正确...

RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE
0000002b dir32             .data
00000035 dir32             .data
0000003f dir32             .data

... 基本上是告诉链接器,地址存储在 .text 的偏移量 2b353f 不是绝对地址,而是相对于 .data 的相对地址(= 偏移量)?据我了解,这使链接器能够

  • 将这些相对地址转换为绝对地址以创建不可重定位的目标文件,
  • 或者只是相应地调整它们,以防目标文件与其他目标文件链接。

第 2 部分:处理未初始化的变量。

我不明白为什么未初始化变量的处理方式与已初始化变量的处理方式如此不同。为什么寄存器地址存储在操作码中,

  • 等于所有未初始化的变量(0x0、0x0 和 0x0),同时
  • 所有初始化变量(0x0、0x4 和 0x8)都不同吗?

我也完全不清楚他们重定位表条目的值字段。我原以为会在那里引用 .bss 部分。

RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE
0000000d dir32             _var1_zeroed-0x00000004
00000017 dir32             _var2_zeroed-0x00000004
00000021 dir32             _var3_zeroed-0x00000004

最佳答案

... are basically telling the linker, that the addresses stored at offset ...

不,链接器不再参与其中。重定位表将地址告知加载器,这是操作系统的一部分,负责将可执行镜像加载到内存中。

链接器构建可执行镜像的基础是假设一切都是理想的并且镜像可以加载到预期的地址。如果是这样的话,那么一切都很好,不需要做任何事情。但是,如果存在冲突,虚拟地址空间已被其他东西使用,则需要将镜像重新定位到不同的地址。

这需要对地址进行修补,需要添加理想加载地址和实际加载地址之间的偏移量。因此,如果 .data 部分在另一个地址结束,则必须更改地址 .text+0x2b、.text+0x35 等。对于未初始化的变量没有什么不同,链接器已经为它们选择了一个地址,但是当 _var1_zeroed-0x00000004 在另一个地址结束时,.text+0x0d、.text+0x17 等需要更改。

关于c - 如何读取目标文件的重定位记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26205948/

相关文章:

c - 将球队名称字符串按照球队获得的分数顺序排列

python - 有没有办法让numpy矩阵来存储对象?

c++ - 在 C++ 中将字符串打印到临时流对象

c++ - 与库的 c 绑定(bind)链接

c++ - mavericks osx 10.9 上的 VTK 编译错误

c++ - 类方法内部链接

c - 如何将内存数据从指针复制到数组 ASSEMBLY 8086

c - 为什么这段 C 代码不更改字符串并导致缓冲区溢出?

c++ - 如何使用 C 终止远程计算机上的进程?

java - 对象转换模式