https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98112
--- Comment #2 from Fangrui Song <i at maskray dot me> --- Note: -fdirect-access-external-data is architecture-independent. For example, currently Clang on aarch64 can perform the following optimization: // clang -target aarch64 -fPIE -O3 adrp x8, :got:var ldr x8, [x8, :got_lo12:var] ldr w0, [x8] ret // clang -target aarch64 -fPIE -O3 -mpie-copy-relocations adrp x8, var ldr w0, [x8, :lo12:var] ret A better name for -mpie-copy-relocations is -fno-direct-access-external-data: 1. the option can affect -fno-pic and -fpic 2. for -no-pie and -pie links, there is not necessary a copy relocation (-fpic can use this option as well, but keep in mind that DSOs do not support copy relocations. So if such code is used for -shared links and the data turns out to be undefined, the linker will reject the object file) --- The second thing about the feature request is that x86-64 should default to -fno-direct-access-external-data for -fpie to address the protected symbol issues. (-fno-direct-access-external-data for -fpie is the behavior on most architectures.) (1): PC32 referencing a protected function is unnecessarily rejected in a -shared link (this also affects aarch64) // gcc -fpic -fuse-ld=bfd -shared -fvisibility=protected b.c => relocation R_X86_64_PC32 against protected symbol `f' can not be used when making a shared object // aarch64-linux-gnu-gcc -fpic -fuse-ld=bfd -shared -fvisibility=protected b.c => relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `f' which may bind externally can not be used when making a shared object; recompile with -fPIC // gold is good void f() {} void *g() { return &f; } This can be fixed by making GNU ld more permissive. (2) protected data access can use slightly more efficient PC32. Currently it uses the slightly pessimized REX_GOTPCRELX. int a __attribute__((visibility("protected"))); int f() { return a; }