[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.
A patch is posted at http://sourceware.org/ml/binutils/2012-05/msg00126.html
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
Fixed.