Bug 14091 - Gold doesn't handle R_X86_64_64 properly for x32
Summary: Gold doesn't handle R_X86_64_64 properly for x32
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Ian Lance Taylor
URL: http://sourceware.org/ml/binutils/201...
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-10 14:04 UTC by H.J. Lu
Modified: 2012-05-11 15:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2012-05-10 14:04:07 UTC
[hjl@gnu-6 gold]$ cat main.c 
extern void foo (void);

int
main (void)
{
  foo ();
  return 0;
}
[hjl@gnu-6 gold]$ cat tst-quadmod2.S
#define BIAS 0x7fff0000

	.section	.data.rel.local,"aw",@progbits
	.align 8
.Ljmp:
	.quad	func + BIAS
	.text
	.type	func, @function
func:
	.cfi_startproc
	xorl	%edi, %edi
	jmp	exit@PLT
	.cfi_endproc
	.size	func, .-func
	.globl	foo
	.type	foo, @function
foo:
	.cfi_startproc
	.cfi_def_cfa_register 6
	movq	.Ljmp(%rip), %rax
	subq	$BIAS, %rax
	jmp	*%rax
	.cfi_endproc
	.size	foo, .-foo
[hjl@gnu-6 gold]$ make
gcc -B./ -mx32 -g   -c -o main.o main.c
gcc -B./ -mx32 -c -g -o tst-quadmod2.o tst-quadmod2.S
./ld -shared -m elf32_x86_64 -o libtst-quadmod2.so tst-quadmod2.o
gcc -B./ -mx32 -g -o x2 main.o libtst-quadmod2.so -Wl,-rpath,.
./readelf -r --wide libtst-quadmod2.so

Relocation section '.rela.dyn' at offset 0x164 contains 1 entries:
 Offset     Info    Type                Sym. Value  Symbol's Name + Addend
000012f0  00000008 R_X86_64_RELATIVE                  7fff01a0

Relocation section '.rela.plt' at offset 0x170 contains 1 entries:
 Offset     Info    Type                Sym. Value  Symbol's Name + Addend
000012e8  00000107 R_X86_64_JUMP_SLOT     00000000   exit + 0
./x2
make: *** [all] Segmentation fault
[hjl@gnu-6 gold]$ 

The problem is

[hjl@gnu-6 gold]$ readelf -rW tst-quadmod2.o
...
 Offset     Info    Type                Sym. Value  Symbol's Name + Addend
00000000  00000101 R_X86_64_64            00000000   .text + 7fff0000

Symbol value + addend > 32bits at run-time.  BFD linker generates:

[hjl@gnu-6 gold]$ make LD=ld
gcc -B./ -mx32 -g   -c -o main.o main.c
gcc -B./ -mx32 -c -g -o tst-quadmod2.o tst-quadmod2.S
ld -shared -m elf32_x86_64 -o libtst-quadmod2.so tst-quadmod2.o
gcc -B./ -mx32 -g -o x2 main.o libtst-quadmod2.so -Wl,-rpath,.
./readelf -r --wide libtst-quadmod2.so

Relocation section '.rela.dyn' at offset 0x158 contains 1 entries:
 Offset     Info    Type                Sym. Value  Symbol's Name + Addend
002002b0  00000026 R_X86_64_RELATIVE64                 7fff0190

Relocation section '.rela.plt' at offset 0x164 contains 1 entries:
 Offset     Info    Type                Sym. Value  Symbol's Name + Addend
[hjl@gnu-6 gold]$ 

The difference is R_X86_64_RELATIVE64 vs R_X86_64_RELATIVE.  For
R_X86_64_64, we need to generate R_X86_64_RELATIVE64.
Comment 1 H.J. Lu 2012-05-11 04:08:46 UTC
A patch is posted at

http://sourceware.org/ml/binutils/2012-05/msg00126.html
Comment 2 Sourceware Commits 2012-05-11 11:10:23 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl@sourceware.org	2012-05-11 11:10:19

Modified files:
	elfcpp         : ChangeLog x86_64.h 
	gold           : ChangeLog x86_64.cc 

Log message:
	Handle R_X86_64_64 properly for x32
	
	elfcpp/
	
	PR gold/14091
	* x86_64.h (R_X86_64_RELATIVE64): New.
	
	gold/
	
	PR gold/14091
	* x86_64.cc (Target_x86_64::Scan::local): For x32, generate
	R_X86_64_RELATIVE64 instead of R_X86_64_RELATIVE in case of
	R_X86_64_64.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/elfcpp/ChangeLog.diff?cvsroot=src&r1=1.46&r2=1.47
http://sourceware.org/cgi-bin/cvsweb.cgi/src/elfcpp/x86_64.h.diff?cvsroot=src&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gold/ChangeLog.diff?cvsroot=src&r1=1.910&r2=1.911
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gold/x86_64.cc.diff?cvsroot=src&r1=1.152&r2=1.153
Comment 3 H.J. Lu 2012-05-11 15:49:45 UTC
Fixed.