3

我正在研究如何在动态链接中使用 GOT 和 PLT。我很困惑为什么每个动态链接的函数调用似乎都会跳转到 PLT 中的某个位置,而该位置总是会跳转到 GOT 中的相同位置。为什么不直接跳到 GOT 中的那个位置呢?为什么需要另一层间接?


我可能从根本上对 GOT 和 PLT 有一些误解,所以这里简要描述一下我对如何使用 PLT 和 GOT 的概念理解。

我们有一个名为 FunctionX 的函数,PLT 中的对应位置为 PLT[X],GOT 中的对应位置为 GOT[X]。PLT 和 GOT 的地址在编译时是已知的,但 FunctionX 的地址不知道。

为了调用 FunctionX:

1) 调用(在汇编意义上)PLT[X] 的地址。

2) PLT[X] 是跳转到 GOT[X] 所包含的值。

3a) 如果 FunctionX 已经解析,GOT[X] 包含函数地址,所以第 2 步是跳转到 FunctionX。

3b) 否则,GOT[X] 包含将在运行时解析 FunctionX 的地址的代码地址,将该地址写入 GOT[X],然后跳转到 FunctionX。在这种情况下,步骤 2 会导致 FunctionX 被解析,然后跳转到。

第 1 步的目的是什么?

我对这个话题的理解是粗略的,所以请指出任何可以帮助这个问题的澄清。

4

1 回答 1

1

只是想一想

想象一下从某个客户端代码(例如 main)第一次调用 GOT[X] 处的任何地址。正如您在 3b) 中所说,这将调用解析 FunctionX 地址的代码。但是解析代码怎么知道你想解析 FunctionX 呢?您像普通函数一样调用它,您没有为解析器提供任何其他信息,即您要修补的 FunctionX 地址。Stub 在跳转到 GOT[X] 之前推送堆栈额外信息。

本文的最后几段帮助很大。

于 2017-07-27T16:14:23.230 回答