I'm trying to understand the linking stage of C toolchain. I wrote a sample program and dissected the resulting object file. While this helped me to get a better understanding of the processes involved, there are some things which remain unclear to me.
我试图理解C工具链的链接阶段。我编写了一个示例程序并剖析了结果对象文件。虽然这有助于我更好地理解所涉及的过程,但有些事情我仍然不清楚。
Here are:
这里有:
- My (blazingly simple) sample program
- 我的示例程序(非常简单)
- Relevant parts of the object disassembly
- 物体拆卸的相关部件。
- The objects symbol table
- 符号表的对象
- The objects relocation table
- 安置的对象表
Part 1: Handling of initialized variables.
Is it correct, that theses relocation table entries...
这些搬迁表条目是正确的吗?
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000002b dir32 .data
00000035 dir32 .data
0000003f dir32 .data
... are basically telling the linker, that the addresses stored at offset 2b
, 35
and 3f
from .text
are not absolute adresses, but relative adresses (= offsets) in relation to .data
? It is my understanding that this enables the linker to
…基本上是在告诉链接器,存储在.text的偏移量2b、35和3f的地址不是绝对的adresses,而是相对的adresses(=偏移量)相对于.data?我的理解是,这使链接器能够
- either convert these relative adresses to absolute adresses for creation of a non-relocatable object file,
- 或者将这些相对adresses转换为绝对adresses以创建不可重定位对象文件,
- or just adjust them accordingly in case the object file gets linked with some other object file.
- 或者只要相应地调整它们,以防对象文件与其他对象文件链接。
Part 2: Handling of uninitialized variables.
I don't understand why uninitalized variables are handled so differently to initialized variables. Why are the register adresses stored in the opcode,
我不明白为什么初始化变量的处理方式与初始化变量的处理方式如此不同。为什么寄存器地址存储在操作码中,
- equal for all the uninitialized variables (0x0, 0x0 and 0x0), while being
- 等于所有未初始化的变量(0x0、0x0和0x0),同时
- different for all the initialized variables (0x0, 0x4 and 0x8)?
- 所有初始化的变量(0x0、0x4和0x8)都不一样吗?
Also the value field of their relocation table entries is entirely unclear to me. I would have expected the .bss
section to be referenced there.
而且他们的重定位表条目的值字段对我来说是完全不清楚的。我希望。bss部分在那里被引用。
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000d dir32 _var1_zeroed-0x00000004
00000017 dir32 _var2_zeroed-0x00000004
00000021 dir32 _var3_zeroed-0x00000004
1 个解决方案
#1
2
... are basically telling the linker, that the addresses stored at offset ...
…主要是告诉链接器,存储在偏移量中的地址…
No, the linker is no longer involved with this. The relocation tables tell the loader, the part of the operating system that's responsible for loading the executable image into memory about the addresses.
不,链接器不再涉及这个。重新定位表告诉加载程序,这是操作系统的一部分,负责将可执行映像加载到有关地址的内存中。
The linker builds the executable image based on the assumption that everything is ideal and the image can be loaded at the intended address. If that's the case then everything is hunky-dory, nothing needs to be done. If there's a conflict however, the virtual address space is already in use by something else, then the image needs to be relocated at a different address.
链接器基于一切都是理想的假设构建可执行映像,并且可以在预期的地址加载映像。如果是这样的话,那么一切都很顺利,什么都不需要做。但是,如果存在冲突,则虚拟地址空间已经被其他东西使用,则需要将映像重新定位到另一个地址。
That requires addresses to be patched, the offset between the ideal and the actual load address needs to be added. So if the .data section ends up at another address then addresses .text+0x2b, .text+0x35, etcetera, must be changed. No different for the uninitialized variables, the linker already picked an address for them but when _var1_zeroed-0x00000004 ends up at another address then .text+0x0d, .text+0x17, etcetera, need to be changed.
这需要对地址进行修补,需要添加理想地址和实际负载地址之间的偏移量。因此,如果.data部分以另一个地址结束,那么必须修改。text+0x2b、.text+0x35等地址。对于未初始化的变量,链接器已经为它们选择了一个地址,但是当_var1_zero -0x00000004以另一个地址结束时,则需要更改.text+0x0d、.text+0x17等等。
#1
2
... are basically telling the linker, that the addresses stored at offset ...
…主要是告诉链接器,存储在偏移量中的地址…
No, the linker is no longer involved with this. The relocation tables tell the loader, the part of the operating system that's responsible for loading the executable image into memory about the addresses.
不,链接器不再涉及这个。重新定位表告诉加载程序,这是操作系统的一部分,负责将可执行映像加载到有关地址的内存中。
The linker builds the executable image based on the assumption that everything is ideal and the image can be loaded at the intended address. If that's the case then everything is hunky-dory, nothing needs to be done. If there's a conflict however, the virtual address space is already in use by something else, then the image needs to be relocated at a different address.
链接器基于一切都是理想的假设构建可执行映像,并且可以在预期的地址加载映像。如果是这样的话,那么一切都很顺利,什么都不需要做。但是,如果存在冲突,则虚拟地址空间已经被其他东西使用,则需要将映像重新定位到另一个地址。
That requires addresses to be patched, the offset between the ideal and the actual load address needs to be added. So if the .data section ends up at another address then addresses .text+0x2b, .text+0x35, etcetera, must be changed. No different for the uninitialized variables, the linker already picked an address for them but when _var1_zeroed-0x00000004 ends up at another address then .text+0x0d, .text+0x17, etcetera, need to be changed.
这需要对地址进行修补,需要添加理想地址和实际负载地址之间的偏移量。因此,如果.data部分以另一个地址结束,那么必须修改。text+0x2b、.text+0x35等地址。对于未初始化的变量,链接器已经为它们选择了一个地址,但是当_var1_zero -0x00000004以另一个地址结束时,则需要更改.text+0x0d、.text+0x17等等。