Index: ELF/Arch/X86_64.cpp =================================================================== --- ELF/Arch/X86_64.cpp +++ 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: test/ELF/x86-64-reloc-got.s =================================================================== --- test/ELF/x86-64-reloc-got.s +++ test/ELF/x86-64-reloc-got.s @@ -4,17 +4,34 @@ // 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 -// 0x3070 (.got end) - 0x1007 = 8297 -// CHECK: gotpc32: -// CHECK-NEXT: 1000: {{.*}} leaq 8297(%rip), %r15 -.global gotpc32 -gotpc32: - leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15 +// FIXME: All the _GLOBAL_OFFSET_TABLE_ occurrences below refer to the address +// of GOT base, not the address of the symbol _GLOBAL_OFFSET_TABLE_, as these +// instructions are special and they produce GOT base relative relocations. We +// currently use .got end as the GOT base, which is not equal to +// _GLOBAL_OFFSET_TABLE_. +// 0x3070 (.got end) - 0x1000 = 8304 // CHECK: gotpc64: -// CHECK-NEXT: 1007: {{.*}} movabsq $8297, %r11 +// CHECK-NEXT: 1000: {{.*}} movabsq $8304, %r11 .global gotpc64 gotpc64: movabsq $_GLOBAL_OFFSET_TABLE_-., %r11 + +// The assembly is generated by +// clang++ -S -mcmodel=medium -fPIC a.c +// extern long _DYNAMIC[] __attribute__((visibility("hidden"))); +// long* dynamic() { return _DYNAMIC; } + +// 0x3070 (.got end) - 0x100a = 8287 +// 0x3000 (_DYNAMIC) - 0x3070 (.got end) = -112 +// CHECK: 100a: {{.*}} leaq 8287(%rip), %rdx +// CHECK-NEXT: 1011: {{.*}} movabsq $-112, %rax +.global dynamic +dynamic: + leaq _GLOBAL_OFFSET_TABLE_(%rip), %rdx + movabsq $_DYNAMIC@GOTOFF, %rax + addq %rdx, %rax + ret Index: test/ELF/x86-64-reloc-gotoff64.s =================================================================== --- test/ELF/x86-64-reloc-gotoff64.s +++ /dev/null @@ -1,17 +0,0 @@ -// 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 - -// CHECK: .dynamic DYNAMIC 0000000000002000 002000 -// CHECK: .got PROGBITS 0000000000002070 002070 - -// DISASM: 1000: 48 ba 90 ff ff ff ff ff ff ff movabsq $-112, %rdx - -.global _start -.weak _DYNAMIC -.hidden _DYNAMIC -_start: - movabsq $_DYNAMIC@GOTOFF, %rdx