[ELF] Implement RISCV::getImplicitAddend()
authorAlex Richardson <Alexander.Richardson@cl.cam.ac.uk>
Fri, 9 Jul 2021 09:12:43 +0000 (10:12 +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/D101455

lld/ELF/Arch/RISCV.cpp
lld/ELF/Driver.cpp

index 0bb0792..dad23ff 100644 (file)
@@ -24,6 +24,7 @@ class RISCV final : public TargetInfo {
 public:
   RISCV();
   uint32_t calcEFlags() const override;
+  int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
   void writeGotHeader(uint8_t *buf) const override;
   void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
   void writeIgotPlt(uint8_t *buf, const Symbol &s) const override;
@@ -134,6 +135,28 @@ uint32_t RISCV::calcEFlags() const {
   return target;
 }
 
+int64_t RISCV::getImplicitAddend(const uint8_t *buf, RelType type) const {
+  switch (type) {
+  default:
+    internalLinkerError(getErrorLocation(buf),
+                        "cannot read addend for relocation " + toString(type));
+    return 0;
+  case R_RISCV_32:
+  case R_RISCV_TLS_DTPMOD32:
+  case R_RISCV_TLS_DTPREL32:
+    return SignExtend64<32>(read32le(buf));
+  case R_RISCV_64:
+    return read64le(buf);
+  case R_RISCV_RELATIVE:
+  case R_RISCV_IRELATIVE:
+    return config->is64 ? read64le(buf) : read32le(buf);
+  case R_RISCV_NONE:
+  case R_RISCV_JUMP_SLOT:
+    // These relocations are defined as not having an implicit addend.
+    return 0;
+  }
+}
+
 void RISCV::writeGotHeader(uint8_t *buf) const {
   if (config->is64)
     write64le(buf, mainPart->dynamic->getVA());
index 83d5be5..ef48637 100644 (file)
@@ -1400,8 +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 || m == EM_X86_64;
+  bool checkDynamicRelocsDefault = m == EM_ARM || m == EM_386 || m == EM_MIPS ||
+                                   m == EM_X86_64 || m == EM_RISCV;
 #else
   bool checkDynamicRelocsDefault = false;
 #endif