Index: lld/trunk/ELF/Arch/X86_64.cpp =================================================================== --- lld/trunk/ELF/Arch/X86_64.cpp +++ lld/trunk/ELF/Arch/X86_64.cpp @@ -106,7 +106,7 @@ case R_X86_64_GOTTPOFF: return R_GOT_PC; case R_X86_64_GOTOFF64: - return R_GOTREL; + return R_GOTREL_FROM_END; case R_X86_64_GOTPC32: case R_X86_64_GOTPC64: return R_GOTONLY_PC_FROM_END; Index: lld/trunk/test/ELF/x86-64-reloc-got.s =================================================================== --- lld/trunk/test/ELF/x86-64-reloc-got.s +++ lld/trunk/test/ELF/x86-64-reloc-got.s @@ -1,20 +0,0 @@ -// REQUIRES: x86 -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: ld.lld %t.o -shared -o %t.so -// RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION -// RUN: llvm-objdump -d %t.so | FileCheck %s - -// SECTION: .got PROGBITS 0000000000003070 003070 000000 - -// 0x3070 (.got end) - 0x1007 = 8297 -// CHECK: gotpc32: -// CHECK-NEXT: 1000: {{.*}} leaq 8297(%rip), %r15 -.global gotpc32 -gotpc32: - leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15 - -// CHECK: gotpc64: -// CHECK-NEXT: 1007: {{.*}} movabsq $8297, %r11 -.global gotpc64 -gotpc64: - movabsq $_GLOBAL_OFFSET_TABLE_-., %r11 Index: lld/trunk/test/ELF/x86-64-reloc-gotoff64.s =================================================================== --- lld/trunk/test/ELF/x86-64-reloc-gotoff64.s +++ lld/trunk/test/ELF/x86-64-reloc-gotoff64.s @@ -1,17 +1,32 @@ // REQUIRES: x86 - // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: ld.lld -shared -o %t.so %t.o -// RUN: llvm-readelf -sections %t.so | FileCheck %s -// RUN: llvm-objdump -d %t.so | FileCheck -check-prefix=DISASM %s +// RUN: ld.lld %t.o -shared -o %t.so +// RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION +// RUN: llvm-objdump -d %t.so | FileCheck %s + +// SECTION: .dynamic DYNAMIC 0000000000003000 +// SECTION: .got PROGBITS 0000000000003070 003070 000000 -// CHECK: .dynamic DYNAMIC 0000000000002000 002000 -// CHECK: .got PROGBITS 0000000000002070 002070 +// All the _GLOBAL_OFFSET_TABLE_ occurrences below refer to the address +// of GOT base, not the address of the symbol _GLOBAL_OFFSET_TABLE_. These +// instructions are special and produce GOT base relative relocations. We +// currently use .got end as the GOT base, which is not equal to +// the address of the special symbol _GLOBAL_OFFSET_TABLE_. -// DISASM: 1000: 48 ba 90 ff ff ff ff ff ff ff movabsq $-112, %rdx +// The assembly is generated by +// gcc -O2 -S -mcmodel=medium -fPIC a.c +// This computes the pc-relative address (runtime address) of _DYNAMIC. +// +// extern long _DYNAMIC[] __attribute__((visibility("hidden"))); +// long* dynamic() { return _DYNAMIC; } -.global _start -.weak _DYNAMIC -.hidden _DYNAMIC -_start: - movabsq $_DYNAMIC@GOTOFF, %rdx +// 0x3070 (.got end) - 0x1007 = 8297 +// 0x3000 (_DYNAMIC) - 0x3070 (.got end) = -112 +// CHECK: 1000: {{.*}} leaq 8297(%rip), %rdx +// CHECK-NEXT: 1007: {{.*}} movabsq $-112, %rax +.global dynamic +dynamic: + leaq _GLOBAL_OFFSET_TABLE_(%rip), %rdx + movabsq $_DYNAMIC@GOTOFF, %rax + addq %rdx, %rax + ret Index: lld/trunk/test/ELF/x86-64-reloc-gotpc64.s =================================================================== --- lld/trunk/test/ELF/x86-64-reloc-gotpc64.s +++ lld/trunk/test/ELF/x86-64-reloc-gotpc64.s @@ -0,0 +1,14 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -shared -o %t.so +// RUN: llvm-readelf -s %t.so | FileCheck %s -check-prefix=SECTION +// RUN: llvm-objdump -d %t.so | FileCheck %s + +// SECTION: .got PROGBITS 0000000000003070 003070 000000 + +// 0x3070 (.got end) - 0x1000 = 8304 +// CHECK: gotpc64: +// CHECK-NEXT: 1000: {{.*}} movabsq $8304, %r11 +.global gotpc64 +gotpc64: + movabsq $_GLOBAL_OFFSET_TABLE_-., %r11