Bug 65248 - Copy relocation against protected symbol doesn't work
Summary: Copy relocation against protected symbol doesn't work
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 5.0
: P1 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 55012 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-02-27 23:21 UTC by H.J. Lu
Modified: 2019-06-17 09:06 UTC (History)
4 users (show)

See Also:
Host:
Target: x86_64-*-*, i?86-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-02-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2015-02-27 23:21:04 UTC
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]$
Comment 1 H.J. Lu 2015-02-28 16:43:11 UTC
A patch is posted at

https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01746.html
Comment 2 H.J. Lu 2015-03-04 14:13:18 UTC
It never worked with normal executable.  I proposed a solution:

https://groups.google.com/forum/#!topic/x86-64-abi/Nbfw6bX0DpI
Comment 3 H.J. Lu 2015-03-04 23:34:27 UTC
BInutils, glibc and GCC patches are posted at

https://gcc.gnu.org/ml/gcc-patches/2015-03/msg00257.html
Comment 4 H.J. Lu 2015-03-06 13:28:11 UTC
*** Bug 55012 has been marked as a duplicate of this bug. ***
Comment 5 hjl@gcc.gnu.org 2015-03-27 18:11:32 UTC
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
Comment 6 H.J. Lu 2015-03-27 18:13:51 UTC
Fixed for GCC 5. No plan for backport.
Comment 7 Khem Raj 2015-05-29 02:07:48 UTC
(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.
Comment 8 jb999 2016-04-01 14:51:40 UTC
(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.
Comment 9 Nix 2016-06-18 18:50:55 UTC
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.
Comment 10 jb999 2016-07-01 14:22:48 UTC
Could someone please explain what this means for binutils >= 2.26 and gcc 4.9.3?
Comment 11 Nix 2016-07-01 18:06:06 UTC
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.)
Comment 12 jb999 2016-07-03 00:36:42 UTC
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?
Comment 13 Fangrui Song 2019-06-17 09:06:24 UTC
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