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
.
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.
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).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…