仍在努力理解可重定位目标文件中的重定位条目,假设我有一个简单的C程序:
//main1.c
void functionTest();
functionTest(){
...
}
int main()
{
functionTest();
return 0;
}
我的问题是:
Q1。由于main1知道一切,所以main1.o的.rel.text或.rel.data节中没有重定位条目,我的理解正确吗?
Q2。下面是说明DLL如何工作的图片,
对于libc.so来说,一切都是已知的(就像main1一样具有所有定义),那么为什么libc.so中仍然有重定位条目?我了解符号表信息需要复制,因为它们存在,请问如何复制不存在的信息?
Q3。让我们在下面说一下重定位条目的结构;
typedef struct {
int offset; /* Offset of the reference to relocate */
int symbol:24, /* Symbol the reference should point to */
type:8; /* Relocation type */
} Elf32_Rel;
所以我的理解是main2.o中已经有一个针对printf()的重定位条目,因此偏移量将是调用方函数的8或9个字节的偏移量,符号将为'printf',类型为R_386_PC32,因此如果还有一个需要从libc.so复制到main2.o,那么该重定位条目的结构是什么?
答案 0 :(得分:1)
问题1:是的,如果您在问题中编译main1.c
,它将构建而无需链接任何内容,因为它不使用函数在其他地方定义的。
第二季度:该图不适用于构建main1.c
,因为main1.c
不使用外部函数。但是,在确实调用了printf()
的程序中,发生了什么事:该图显示了 about {{1} }被放入 libc.so
。您问“为什么libc.so中仍然存在重定位条目?”但是将重定位条目 not 放入 main2.o
中;它们被放入libc.so
中,并且它们引用 main2.o
中的东西。
第2季度后续行动#1:当您说“对于libc.so,一切都已知”时,这是正确的,仅在 libc.so
之内。任何使用libc.so
中定义的功能的人都会不知道该功能的定义方式, 直到链接发生 。这就是libc.so
的功能:将参考信息从从类似ld
的库复制到正在构建的程序 中,如libc.so
该图。参考信息允许执行main2
的内核也将 main2
加载到内存中,以使执行可以从libc.so
代码流到{{ 1}}代码并返回到main2
,只要libc.so
调用其定义/代码位于main2
的函数。
第3季度:我认为最好的表达方式是:用于{em>填充 main2
中的重定位结构的信息来自 libc.so
。我说重定位条目是从main2.o
复制而来的,这就是我的意思:关于目标(例如libc.so
)的信息是从libc.so
获取的,并用于为以下位置中的重定位条目提供值printf()
的目的是告诉加载程序将从何处加载libc.so
的代码。
第3季度后续跟踪#1:还有另一种感觉,main2.o
具有重定位条目:构建printf()
的事物将重定位条目添加到libc.so
,这样任何想要使用其(可导出的)函数和变量的人都可以使用。 这些不需要复制到任何地方。构建目标文件的一部分是为其他程序可能使用的内部内容创建信息。并且,构建程序的一部分是填充有关外部所使用事物的信息。但是该图在我看来仅是为了显示关于 about libc.so
和libc.so
的信息已添加到libc.so
中,以便加载程序可以加载所有需要的信息。执行libvector.so
时将代码存储到内存中。