diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -37,6 +37,7 @@ uint64_t pltEntryAddr) const override; void relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const override; + int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override; void applyJumpInstrMod(uint8_t *loc, JumpModType type, unsigned size) const override; @@ -675,6 +676,55 @@ } } +int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { + switch (type) { + case R_X86_64_8: + case R_X86_64_PC8: + return SignExtend64<8>(*buf); + case R_X86_64_16: + case R_X86_64_PC16: + return SignExtend64<16>(read16le(buf)); + case R_X86_64_32: + case R_X86_64_32S: + case R_X86_64_TPOFF32: + case R_X86_64_GOT32: + case R_X86_64_GOTPC32: + case R_X86_64_GOTPC32_TLSDESC: + case R_X86_64_GOTPCREL: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: + case R_X86_64_PC32: + case R_X86_64_GOTTPOFF: + case R_X86_64_PLT32: + case R_X86_64_TLSGD: + case R_X86_64_TLSLD: + case R_X86_64_DTPOFF32: + case R_X86_64_SIZE32: + return SignExtend64<32>(read32le(buf)); + case R_X86_64_64: + case R_X86_64_TPOFF64: + case R_X86_64_DTPOFF64: + case R_X86_64_DTPMOD64: + case R_X86_64_PC64: + case R_X86_64_SIZE64: + case R_X86_64_GLOB_DAT: + case R_X86_64_GOT64: + case R_X86_64_GOTOFF64: + case R_X86_64_GOTPC64: + case R_X86_64_IRELATIVE: + case R_X86_64_RELATIVE: + return read64le(buf); + case R_X86_64_JUMP_SLOT: + case R_X86_64_NONE: + // These relocations are defined as not having an implicit addend. + return 0; + default: + internalLinkerError(getErrorLocation(buf), + "cannot read addend for relocation " + toString(type)); + return 0; + } +} + void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { switch (rel.type) { case R_X86_64_8: diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1400,7 +1400,8 @@ // enable the debug checks for all targets, but currently not all targets // have support for reading Elf_Rel addends, so we only enable for a subset. #ifndef NDEBUG - bool checkDynamicRelocsDefault = m == EM_ARM || m == EM_386 || m == EM_MIPS; + bool checkDynamicRelocsDefault = + m == EM_ARM || m == EM_386 || m == EM_MIPS || m == EM_X86_64; #else bool checkDynamicRelocsDefault = false; #endif diff --git a/lld/test/ELF/invalid/broken-relaxation-x64.test b/lld/test/ELF/invalid/broken-relaxation-x64.test --- a/lld/test/ELF/invalid/broken-relaxation-x64.test +++ b/lld/test/ELF/invalid/broken-relaxation-x64.test @@ -1,6 +1,4 @@ # REQUIRES: x86 -# Needs https://reviews.llvm.org/D101451 to read the implicit addends. -# XFAIL: * # RUN: yaml2obj %s -o %t.o # RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s diff --git a/lld/test/ELF/reloc-sec-before-relocated.test b/lld/test/ELF/reloc-sec-before-relocated.test --- a/lld/test/ELF/reloc-sec-before-relocated.test +++ b/lld/test/ELF/reloc-sec-before-relocated.test @@ -4,9 +4,6 @@ ## want to use this feature, which is not restricted by ELF gABI. ## GNU ld supports this as well. -# Needs https://reviews.llvm.org/D101451 to read the implicit addends. -# XFAIL: * - # RUN: yaml2obj %s -DTYPE=SHT_RELA -o %t1.o # RUN: ld.lld -shared %t1.o -o %t1 # RUN: llvm-readelf --relocs %t1 | FileCheck %s