链接中的重定位条目(C编程)

时间:2018-11-08 23:48:53

标签: c linker dynamic-linking

仍在努力理解可重定位目标文件中的重定位条目,假设我有一个简单的C程序:

//main1.c

void functionTest();

functionTest(){
   ...
}

int main()
{
   functionTest();
   return 0;
}

我的问题是:

Q1。由于main1知道一切,所以main1.o的.rel.text或.rel.data节中没有重定位条目,我的理解正确吗?

Q2。下面是说明DLL如何工作的图片,

enter image description here

对于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,那么该重定位条目的结构是什么?

1 个答案:

答案 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.solibc.so的信息已添加到libc.so中,以便加载程序可以加载所有需要的信息。执行libvector.so时将代码存储到内存中。