为什么从PLT到GOT的蹦床而不是直​​接跳到GOT?

时间:2017-07-27 15:24:58

标签: assembly linker dynamic-linking plt got

我正在研究如何在动态链接中使用GOT和PLT。我很困惑为什么每个动态链接的函数调用似乎跳转到PLT中的位置,该位置将始终跳转到GOT中的相同位置。为什么不首先跳到GOT中的那个位置?为什么需要另一层间接?

我可能从根本上误解了关于GOT和PLT的一些内容,所以这里简要介绍了我对如何使用PLT和GOT的概念性理解。

我们有一个名为FunctionX的函数,一个名为PLT [X]的PLT中的相应位置,以及一个名为GOT [X]的GOT中的相应位置。 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步的目的是什么?

我对这个主题的理解是粗略的,所以请指出任何有助于解决问题的澄清。

1 个答案:

答案 0 :(得分:0)

只需考虑一下

想象一下,从某些客户端代码(例如main)调用GOT [X]中的任何地址。正如您在3b中所说,这将调用将解析FunctionX地址的代码。但解析代码如何知道您要解析FunctionX?您将其称为普通函数,您不为解析程序提供任何其他信息,即它是要修补的FunctionX地址。 Stub会在跳转到GOT [X]之前推送堆栈额外信息。

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