assembly - 为什么要蹦床从PLT跳到GOT而不是直接跳到GOT?

标签 assembly linker dynamic-linking plt got

我正在研究如何在动态链接中使用 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 地址。 stub 在跳转到 GOT[X] 之前压入堆栈额外信息。

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

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

相关文章:

assembly - x86 汇编中 "align"关键字/指令的语法是什么?

c - 即使重命名符号后全局变量的地址也不会改变

c++ - 在 Debug 中覆盖 memcpy 工作但在 Release 中不工作?

c++ - arm-linux libstdc++ 调试和发布的区别

macos - ghc 动态库中的_closure 和_info 符号

assembly - 使用函数参数进行 x86 内存寻址

c - 为什么asm代码在C中的函数比c代码函数花费更多的时间?

linux - 如何将 **long_options option <offset aHelp, 0, 0, 68h>** 翻译成重新汇编代码?

gcc 配置选项说明

c++ - 如何在主程序中解析共享库的外部符号?