[ELF] Implement X86_64::getImplicitAddend()
authorAlex Richardson <Alexander.Richardson@cl.cam.ac.uk>
Fri, 9 Jul 2021 09:10:33 +0000 (10:10 +0100)
committerAlex Richardson <Alexander.Richardson@cl.cam.ac.uk>
Fri, 9 Jul 2021 09:41:40 +0000 (10:41 +0100)
This allows checking dynamic relocation addends for -z rel and
--apply-dynamic-relocs output.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D101451

lld/ELF/Arch/X86_64.cpp
lld/ELF/Driver.cpp
lld/test/ELF/invalid/broken-relaxation-x64.test
lld/test/ELF/reloc-sec-before-relocated.test

index b3fe26f..2ae80d2 100644 (file)
@@ -37,6 +37,7 @@ public:
                 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 @@ void X86_64::applyJumpInstrMod(uint8_t *loc, JumpModType type,
   }
 }
 
+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:
index defdf66..83d5be5 100644 (file)
@@ -1400,7 +1400,8 @@ static void setConfigs(opt::InputArgList &args) {
   // 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
index 5e11eb6..97a977e 100644 (file)
@@ -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
index 76cd32b..a562312 100644 (file)
@@ -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