For X86, in PIE mode, when accessing extern global variables, an extra load from the GOT can be avoided if the linker allows copy relocations for PIE. This patch makes it possible. This is already available in the GCC compiler.
This patch looks for "PIE Copy Relocs" in the module flags to optimize the access to the global variable. The Clang patch that adds a new option "-mpiecopyrelocs" to indicate copy relocation support and add the module flag when the option is passed is here : http://reviews.llvm.org/D19996
GCC patch discussing this : https://gcc.gnu.org/ml/gcc-patches/2014-05/msg01215.html
Short summary:
- When linking executables in non-PIE mode, references to external globals do not use the GOT. They are treated as if the globals were defined in the executable. If it so happens that the global is not defined in the executable, a copy relocation is used to duplicate the definition in the executable.
- Currently, in PIE mode, all accesses to external globals use an extra load from the GOT to get its address which is then dereferenced. This is particularly inefficient if it turns out at link time that the global ends up being defined in the executable from a different compilation unit. It turns out that copy relocations can be used here just like non-PIE mode to always avoid the extra load from the GOT and directly access the global.
- Gold and GNU ld started supporting copy relocations for pie only recently. Gold supports via this patch : https://sourceware.org/ml/binutils/2014-05/msg00092.html
- Since this technique cannot be used to avoid the extra load if the linker does not support it, I am creating a clang patch to add an extra option '-mpiecopyrelocs' which can be used to specify support.
- Support for linker copy relocations will be specified in bit code as a module flag "PIE Copy Relocations".
- This technique can be used for 32 and 64 bit x86. However, gold still does not support copy relocations for 32-bit PIE. I will do that separately.
What if it is a global alias to a function?