I am reading this article on PLT (Process Linkage Table) and GOT (Global Offset Table). While the purpose of PLT is clear to me, I'm still confused about GOT. What I've understood from the article is that GOT is only necessary for variables declared as extern
in a shared library. For global variables declared as static
in a shared library code, it is not required.
我正在阅读有关PLT(流程链接表)和GOT(全球抵消表)的这篇文章。虽然PLT的目的对我来说很清楚,但我仍然对GOT感到困惑。我从文章中了解到,只有在共享库中声明为extern的变量才需要GOT。对于在共享库代码中声明为static的全局变量,它不是必需的。
Is my understanding right, or am I completely missing the point.
我的理解是正确的,还是我完全忽略了这一点。
1 个解决方案
#1
17
Perhaps your confusion is with the meaning of extern
. Since the default linkage is extern
, any variable declared outside function scope without the static
keyword is extern
.
也许你的困惑与外在的意义有关。由于默认链接是extern,因此在没有static关键字的情况下在函数范围外声明的任何变量都是extern。
The reason the GOT is necessary is because the address of variables accessed by the shared library code is not known at the time the shared library is generated. It depends either on the load address the library gets loaded at (if the definition is in the library itself) or the third-party code the variable is defined in (if the definition is elsewhere). So rather than putting the address inline in the code, the compiler generates code to read the shared library's GOT and then loads the address from the GOT at runtime.
GOT必要的原因是因为共享库代码访问的变量的地址在生成共享库时是未知的。它取决于库加载的加载地址(如果定义在库本身中)或定义变量的第三方代码(如果定义在其他地方)。因此,编译器生成代码以读取共享库的GOT,然后在运行时从GOT加载地址,而不是将地址放在代码中。
If the variable is known to be defined within the same shared library (either because it's static
or the hidden
or protected
visibility attribute it used) then the address relative to the code in the library can be fixed at the time the shared library file is generated. In this case, rather than performing a lookup through the GOT, the compiler just generates code to access the variable with program-counter-relative addressing. This is less expensive both at runtime and at load time (because the whole symbol lookup and relocation process can be skipped at load time).
如果已知变量在同一共享库中定义(因为它是静态的或它使用的隐藏或受保护的可见性属性),则可以在生成共享库文件时修复相对于库中代码的地址。 。在这种情况下,编译器不是通过GOT执行查找,而是生成用于通过程序计数器相对寻址访问变量的代码。这在运行时和加载时都比较便宜(因为在加载时可以跳过整个符号查找和重定位过程)。
#1
17
Perhaps your confusion is with the meaning of extern
. Since the default linkage is extern
, any variable declared outside function scope without the static
keyword is extern
.
也许你的困惑与外在的意义有关。由于默认链接是extern,因此在没有static关键字的情况下在函数范围外声明的任何变量都是extern。
The reason the GOT is necessary is because the address of variables accessed by the shared library code is not known at the time the shared library is generated. It depends either on the load address the library gets loaded at (if the definition is in the library itself) or the third-party code the variable is defined in (if the definition is elsewhere). So rather than putting the address inline in the code, the compiler generates code to read the shared library's GOT and then loads the address from the GOT at runtime.
GOT必要的原因是因为共享库代码访问的变量的地址在生成共享库时是未知的。它取决于库加载的加载地址(如果定义在库本身中)或定义变量的第三方代码(如果定义在其他地方)。因此,编译器生成代码以读取共享库的GOT,然后在运行时从GOT加载地址,而不是将地址放在代码中。
If the variable is known to be defined within the same shared library (either because it's static
or the hidden
or protected
visibility attribute it used) then the address relative to the code in the library can be fixed at the time the shared library file is generated. In this case, rather than performing a lookup through the GOT, the compiler just generates code to access the variable with program-counter-relative addressing. This is less expensive both at runtime and at load time (because the whole symbol lookup and relocation process can be skipped at load time).
如果已知变量在同一共享库中定义(因为它是静态的或它使用的隐藏或受保护的可见性属性),则可以在生成共享库文件时修复相对于库中代码的地址。 。在这种情况下,编译器不是通过GOT执行查找,而是生成用于通过程序计数器相对寻址访问变量的代码。这在运行时和加载时都比较便宜(因为在加载时可以跳过整个符号查找和重定位过程)。