流程链接表和全局偏移表

时间:2012-03-13 16:31:29

标签: c linux gcc x86-64

我正在阅读this article on PLT (Process Linkage Table) and GOT (Global Offset Table)。虽然PLT的目的对我来说很清楚,但我仍然对GOT感到困惑。我从文章中了解到,只有在共享库中声明为extern的变量才需要GOT。对于在共享库代码中声明为static的全局变量,它不是必需的。

我的理解是正确的,还是我完全忽略了这一点。

1 个答案:

答案 0 :(得分:18)

也许你的混淆与extern的含义有关。由于默认链接为extern,因此在没有static关键字的函数范围外声明的任何变量都是extern

GOT必要的原因是因为共享库代码访问的变量的地址在生成共享库时是未知的。它取决于库加载的加载地址(如果定义在库本身中)或定义变量的第三方代码(如果定义在其他地方)。因此,编译器不是将地址内联到代码中,而是生成代码来读取共享库的GOT,然后在运行时从GOT加载地址。

如果变量已知要在同一个共享库中定义(因为它是static或它使用的hiddenprotected可见性属性然后,可以在生成共享库文件时修复相对于库中的代码的地址。在这种情况下,编译器不是通过GOT执行查找,而是生成用于通过程序计数器相对寻址访问变量的代码。这在运行时和加载时都比较便宜(因为在加载时可以跳过整个符号查找和重定位过程)。