Index: ELF/Arch/X86_64.cpp =================================================================== --- ELF/Arch/X86_64.cpp +++ ELF/Arch/X86_64.cpp @@ -105,6 +105,11 @@ case R_X86_64_REX_GOTPCRELX: case R_X86_64_GOTTPOFF: return R_GOT_PC; + case R_X86_64_GOTPC32: + case R_X86_64_GOTPC64: + return R_GOTONLY_PC_FROM_END; + case R_X86_64_GOTOFF64: + return R_GOTREL_FROM_END; case R_X86_64_NONE: return R_NONE; default: @@ -300,6 +305,7 @@ case R_X86_64_32S: case R_X86_64_TPOFF32: case R_X86_64_GOT32: + case R_X86_64_GOTPC32: case R_X86_64_GOTPCREL: case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: @@ -319,6 +325,7 @@ case R_X86_64_PC64: case R_X86_64_SIZE64: case R_X86_64_GOT64: + case R_X86_64_GOTOFF64: write64le(Loc, Val); break; default: Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -495,11 +495,11 @@ case R_GOTONLY_PC: return InX::Got->getVA() + A - P; case R_GOTONLY_PC_FROM_END: - return InX::Got->getVA() + A - P + InX::Got->getSize(); + return InX::GotPlt->getVA() + A - P; case R_GOTREL: return Sym.getVA(A) - InX::Got->getVA(); case R_GOTREL_FROM_END: - return Sym.getVA(A) - InX::Got->getVA() - InX::Got->getSize(); + return Sym.getVA(A) - InX::GotPlt->getVA(); case R_GOT_FROM_END: case R_RELAX_TLS_GD_TO_IE_END: return Sym.getGotOffset() + A - InX::Got->getSize(); Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -347,9 +347,9 @@ if (isRelExprOneOf(E)) + R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL_FROM_END, + R_PLT_PC, R_TLSGD_PC, R_TLSGD, R_PPC_CALL_PLT, + R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E)) return true; // These never do, except if the entire file is position dependent or if Index: test/ELF/x86_64/relocation/shared.s =================================================================== --- /dev/null +++ test/ELF/x86_64/relocation/shared.s @@ -0,0 +1,18 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -shared -soname t -o %t.so +// RUN: llvm-objdump -d %t.so | FileCheck %s + +// 0x3000 (.dynamic) - 0x2000 (.got.plt) = 4096 +// CHECK: R_X86_64_GOTOFF64: +// CHECK-NEXT: 1000:{{.*}}movabsq $4096, %rax +.global R_X86_64_GOTOFF64 +R_X86_64_GOTOFF64: + movabsq $_DYNAMIC@GOTOFF, %rax + +// 0x100a + 7 (instruction length) + 4079 = 0x2000 (.got.plt) +// CHECK: R_X86_64_GOTPC32: +// CHECK-NEXT: 100a:{{.*}}leaq 4079(%rip), %rax +.global R_X86_64_GOTPC32 +R_X86_64_GOTPC32: + leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax