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);
if (a != 30)
[hjl@gnu-6 copyreloc-prot]$ cat bar.c
__attribute__((visibility("protected"))) int a;
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
A patch is posted at
It never worked with normal executable. I proposed a solution:
BInutils, glibc and GCC patches are posted at
*** Bug 55012 has been marked as a duplicate of this bug. ***
Date: Fri Mar 27 18:11:00 2015
New Revision: 221742
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
* 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.
* config/i386/i386.c (TARGET_BINDS_LOCAL_P): Set to
default_binds_local_p_2 if TARGET_MACHO is undefined.
* 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.
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
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
> 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).