Copy relocation doesn't work with protected symbol and BFD linker enforces it. GCC 5 uses copy relocation in PIE. It either causes linker error or run-time error: [hjl@gnu-6 copyreloc-prot]$ cat x.c extern int a; extern void bar (void); int main() { bar (); if (a != 30) __builtin_abort(); return 0; } [hjl@gnu-6 copyreloc-prot]$ cat bar.c int a; __attribute__((visibility("protected"))) int a; void bar () { a = 30; } [hjl@gnu-6 copyreloc-prot]$ make /export/build/gnu/gcc/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc/build-x86_64-linux/gcc/ -pie -O3 -fpie -c -o x.o x.c /export/build/gnu/gcc/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc/build-x86_64-linux/gcc/ -pie -O3 -fpic -c -o bar.o bar.c /export/build/gnu/gcc/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc/build-x86_64-linux/gcc/ -pie -shared -o libbar.so bar.o /export/build/gnu/gcc/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc/build-x86_64-linux/gcc/ -pie -O3 -o x x.o libbar.so -Wl,-R,. /usr/local/bin/ld: copy reloc against protected `a' is invalid /usr/local/bin/ld: failed to set dynamic section sizes: Bad value collect2: error: ld returned 1 exit status make: *** [x] Error 1 [hjl@gnu-6 copyreloc-prot]$ /export/build/gnu/gcc/build-x86_64-linux/gcc/xgcc -B/export/build/gnu/gcc/build-x86_64-linux/gcc/ -pie -O3 -o x x.o libbar.so -Wl,-R,. -fuse-ld=gold [hjl@gnu-6 copyreloc-prot]$ ./x Aborted [hjl@gnu-6 copyreloc-prot]$
A patch is posted at https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01746.html
It never worked with normal executable. I proposed a solution: https://groups.google.com/forum/#!topic/x86-64-abi/Nbfw6bX0DpI
BInutils, glibc and GCC patches are posted at https://gcc.gnu.org/ml/gcc-patches/2015-03/msg00257.html
*** Bug 55012 has been marked as a duplicate of this bug. ***
Author: hjl Date: Fri Mar 27 18:11:00 2015 New Revision: 221742 URL: https://gcc.gnu.org/viewcvs?rev=221742&root=gcc&view=rev Log: Add default_binds_local_p_2 and use it for x86 Protected data symbol means that it can't be pre-emptied. It doesn't mean its address won't be external. This is true for pointer to protected function. With copy relocation, address of protected data defined in the shared library may also be external. We only know that for sure at run-time. TARGET_BINDS_LOCAL_P should return false on protected data symbol. gcc/ PR target/65248 * output.h (default_binds_local_p_2): New. * varasm.c (default_binds_local_p_2): Renamed to ... (default_binds_local_p_3): This. Don't return true on protected data symbol if protected data may be external. (default_binds_local_p): Use default_binds_local_p_3. (default_binds_local_p_1): Likewise. (default_binds_local_p_2): New. * config/i386/i386.c (TARGET_BINDS_LOCAL_P): Set to default_binds_local_p_2 if TARGET_MACHO is undefined. gcc/testsuite/ PR target/65248 * gcc.target/i386/pr65248-1.c: New file. * gcc.target/i386/pr65248-2.c: Likewise. * gcc.target/i386/pr65248-3.c: Likewise. * gcc.target/i386/pr65248-4.c: Likewise. Added: trunk/gcc/testsuite/gcc.target/i386/pr65248-1.c trunk/gcc/testsuite/gcc.target/i386/pr65248-2.c trunk/gcc/testsuite/gcc.target/i386/pr65248-3.c trunk/gcc/testsuite/gcc.target/i386/pr65248-4.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/i386/i386.c trunk/gcc/output.h trunk/gcc/testsuite/ChangeLog trunk/gcc/varasm.c
Fixed for GCC 5. No plan for backport.
(In reply to H.J. Lu from comment #6) > Fixed for GCC 5. No plan for backport. reading the commit message here https://sourceware.org/bugzilla/show_bug.cgi?id=17709#c5 Does this mean now binutils >= 2.26 will be broken for older gcc ? If thats the case, I would like to request a backport of this to atleast for gcc 4.9 and 4.8 which are not EOLed yet.
(In reply to Khem Raj from comment #7) > (In reply to H.J. Lu from comment #6) > > Fixed for GCC 5. No plan for backport. > > reading the commit message here > > https://sourceware.org/bugzilla/show_bug.cgi?id=17709#c5 > > Does this mean now binutils >= 2.26 will be broken for older gcc ? > > If thats the case, I would like to request a backport of this to atleast for > gcc 4.9 and 4.8 which are not EOLed yet. I second this.
Thirded. At the very least there should be a huge note in binutils NEWS about this. A subtle, unadvertised incompatibility of a new binutils with a not-very-old GCC is the sort of horror show that gives free software a bad name. At the very least make more noise about it.
Could someone please explain what this means for binutils >= 2.26 and gcc 4.9.3?
The symptoms are failures to link with "relocation against protected symbol is invalid" errors which go away when you use gold. (You can see it if you try to build firefox, for instance.)
Yes, that's why I'm using binutils 2.25.1 to link firefox. I was just wondering whether binutils >= 2.26 and gcc 4.9.3 might cause harm. From what I understand will binutils >= 2.26 with gcc 4.9.3 alert you by causing a link error whereas binutils < 2.26 will link the way it has been done for all these years (trusting that neither the shared library nor the executable updates its copy). So binutils >= 2.26 isn't broken for older gcc, it's just drawing attention to a possible problem. Is that right?
Ping (I hope this can be reopened) Since we have R_*_GOTPCRELX now, we should fix the protected data issue properly (by deleting the default HAVE_LD_PIE_COPYRELOC=1 behavior introduced in gcc 5). See https://gcc.gnu.org/ml/gcc/2019-05/msg00215.html