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

relocation entry in linking (C programming)

仍在努力理解 Relocatable 目标文件中的重定位条目,假设我有这个简单的 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中还有重定位条目呢?我能理解符号 table 信息需要复制,因为它们存在,你怎么能复制不存在的东西?

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' ,type是R_386_PC32,那么如果还有一个需要从libc.so复制到main2.o,那个重定位项的结构是什么?

Q1: 是的,如果您编译问题中的 main1.c,它将构建 而无需 link 在任何地方,因为它没有使用别处定义的函数。

问题 2: 该图不适用于构建 main1.c,因为 main1.c 不使用外部函数。但是,在一个 确实 调用 printf() 的程序中,这是发生了什么:图表显示重定位条目 about libc.so 被放置 main2.o 中。你问 "why there is still relocation entries in libc.so?" 但重定位条目是 而不是 被放入 libc.so;它们被放入 main2.o,它们 引用 libc.so 中的东西。

Q2 跟进 #1: 当你说 "for libc.so, everything is known" 时,那是真的 仅在 libc.so.任何使用 libc.so 中定义的函数的东西都 不会 知道该函数是如何定义的, 直到 linking 发生。这就是 ld 的功能:将参考信息 库(如 libc.so)复制到 正在构建的程序 中,例如main2 在图中。参考信息允许内核执行 main2 也将 libc.so 加载到内存中,这样执行就可以从 main2 代码流向libc.so 代码并返回到 main2,只要 main2 调用定义/代码位于 libc.so.

中的函数

Q3: 我认为最好的表述方式是:用于填充重定位结构的信息[= =15=] 来自 libc.so。我说重定位条目是从 libc.so 复制的,这就是我的意思:有关目标的信息(例如 printf())取自 libc.so 并用于为重定位条目提供值main2.o 其目的是告诉加载程序从何处加载 printf() 的代码。

Q3 后续 #1: libc.so 有重定位条目还有另一种意义:构建 libc.so 的东西添加了重定位条目到libc.so,这样任何想要使用它的(可导出的)函数和变量的东西都可以这样做。 这些不需要复制到任何地方。构建目标文件的一部分是为其他程序可能使用的内部事物创建信息;并且,构建程序的一部分是填充有关 外部 它使用的事物的信息。但是这张图在我看来只是为了显示信息 about libc.solibvector.so 被添加到 main2.o 以便加载程序可以加载当执行 main2 时,所有需要的代码都会进入内存。