This question already has answers here:
Why does the PLT exist in addition to the GOT, instead of just using the GOT?

(2个答案)


2年前关闭。





我正在研究如何在动态链接中使用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的目的是什么?

我对该主题的理解是粗略的,因此请指出任何可能有助于解决此问题的说明。

最佳答案

只是要考虑的一件事

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

this文章的最后几段有很大帮助。

关于assembly - 为什么从PLT到GOT蹦床而不是直​​接跳到GOT? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45355013/

10-10 17:54