The commit https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=222184 changed a true to false in varasm.c: bool default_binds_local_p_2 (const_tree exp) { - return default_binds_local_p_3 (exp, flag_shlib != 0, true, true); + return default_binds_local_p_3 (exp, flag_shlib != 0, true, false, + !flag_pic); } where default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate, - bool extern_protected_data) + bool extern_protected_data, bool common_local_p) { false means that extern protected data binds locally, which is wrong if the target can have copy relocations against it (then the address must be loaded from GOT otherwise the main executable will see different address). Currently S/390, ARM and AArch64 targets use this predicate and the current default is wrong for all of them (they can have copy relocs) so I changed the default instead of doing it in a target specific way. The equivalent x86_64 bug was https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248 the default was changed for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65780 now i opened https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66912 for arm and aarch64. Needs a further binutils patch too to emit R_*_GLOB_DAT instead of R_*_RELATIVE relocs for protected data. The glibc elf/tst-protected1a and elf/tst-protected1b tests depend on this. Tested ARM and AArch64 targets. gcc/ChangeLog: 2015-07-22 Szabolcs Nagy PR target/66912 * varasm.c (default_binds_local_p_2): Turn on extern_protected_data. gcc/testsuite/ChangeLog: 2015-07-22 Szabolcs Nagy PR target/66912 * gcc.target/aarch64/pr66912.c: New. * gcc.target/arm/pr66912.c: New.