[llvm] 9a99d23 - [lib/Object] - Generalize the RelocationResolver API.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 19 23:33:12 PST 2020


Author: Georgii Rymar
Date: 2020-11-20T10:32:49+03:00
New Revision: 9a99d23a1b06894da6e772b76fcf5b0ccc5a8f53

URL: https://github.com/llvm/llvm-project/commit/9a99d23a1b06894da6e772b76fcf5b0ccc5a8f53
DIFF: https://github.com/llvm/llvm-project/commit/9a99d23a1b06894da6e772b76fcf5b0ccc5a8f53.diff

LOG: [lib/Object] - Generalize the RelocationResolver API.

This allows to reuse the RelocationResolver from the code
that doesn't want to deal with `RelocationRef` class.

I am going to use it in llvm-readobj. See the description
of D91530 for more details.

Differential revision: https://reviews.llvm.org/D91533

Added: 
    

Modified: 
    lld/ELF/DWARF.cpp
    llvm/include/llvm/Object/ELFObjectFile.h
    llvm/include/llvm/Object/RelocationResolver.h
    llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
    llvm/lib/Object/RelocationResolver.cpp
    llvm/lib/XRay/InstrumentationMap.cpp
    llvm/test/Object/invalid.test
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/DWARF.cpp b/lld/ELF/DWARF.cpp
index 5767f6020f93..707a6ebd1695 100644
--- a/lld/ELF/DWARF.cpp
+++ b/lld/ELF/DWARF.cpp
@@ -77,18 +77,23 @@ template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
 namespace {
 template <class RelTy> struct LLDRelocationResolver {
   // In the ELF ABIs, S sepresents the value of the symbol in the relocation
-  // entry. For Rela, the addend is stored as part of the relocation entry.
-  static uint64_t resolve(object::RelocationRef ref, uint64_t s,
-                          uint64_t /* A */) {
-    return s + ref.getRawDataRefImpl().p;
+  // entry. For Rela, the addend is stored as part of the relocation entry and
+  // is provided by the `findAux` method.
+  // In resolve() methods, the `type` and `offset` arguments would always be 0,
+  // because we don't set an owning object for the `RelocationRef` instance that
+  // we create in `findAux()`.
+  static uint64_t resolve(uint64_t /*type*/, uint64_t /*offset*/, uint64_t s,
+                          uint64_t /*locData*/, int64_t addend) {
+    return s + addend;
   }
 };
 
 template <class ELFT> struct LLDRelocationResolver<Elf_Rel_Impl<ELFT, false>> {
-  // For Rel, the addend A is supplied by the caller.
-  static uint64_t resolve(object::RelocationRef /*Ref*/, uint64_t s,
-                          uint64_t a) {
-    return s + a;
+  // For Rel, the addend is extracted from the relocated location and is
+  // supplied by the caller.
+  static uint64_t resolve(uint64_t /*type*/, uint64_t /*offset*/, uint64_t s,
+                          uint64_t locData, int64_t /*addend*/) {
+    return s + locData;
   }
 };
 } // namespace

diff  --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 7d0002f38451..3a4937235d5b 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -313,14 +313,6 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
   uint64_t getSectionOffset(DataRefImpl Sec) const override;
   StringRef getRelocationTypeName(uint32_t Type) const;
 
-  /// Get the relocation section that contains \a Rel.
-  const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
-    auto RelSecOrErr = EF.getSection(Rel.d.a);
-    if (!RelSecOrErr)
-      report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
-    return *RelSecOrErr;
-  }
-
   DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
     DataRefImpl DRI;
     if (!SymTable) {
@@ -419,6 +411,14 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
     return *Ret;
   }
 
+  /// Get the relocation section that contains \a Rel.
+  const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
+    auto RelSecOrErr = EF.getSection(Rel.d.a);
+    if (!RelSecOrErr)
+      report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
+    return *RelSecOrErr;
+  }
+
   const Elf_Shdr *getSection(DataRefImpl Sec) const {
     return reinterpret_cast<const Elf_Shdr *>(Sec.p);
   }

diff  --git a/llvm/include/llvm/Object/RelocationResolver.h b/llvm/include/llvm/Object/RelocationResolver.h
index 1246dcc5ec73..46f74e90a91b 100644
--- a/llvm/include/llvm/Object/RelocationResolver.h
+++ b/llvm/include/llvm/Object/RelocationResolver.h
@@ -31,11 +31,17 @@
 namespace llvm {
 namespace object {
 
-using RelocationResolver = uint64_t (*)(RelocationRef R, uint64_t S, uint64_t A);
+using SupportsRelocation = bool (*)(uint64_t);
+using RelocationResolver = uint64_t (*)(uint64_t Type, uint64_t Offset,
+                                        uint64_t S, uint64_t LocData,
+                                        int64_t Addend);
 
-std::pair<bool (*)(uint64_t), RelocationResolver>
+std::pair<SupportsRelocation, RelocationResolver>
 getRelocationResolver(const ObjectFile &Obj);
 
+uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
+                           uint64_t S, uint64_t LocData);
+
 } // end namespace object
 } // end namespace llvm
 

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index ab62ec1d04dc..749d738af9c1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1780,7 +1780,7 @@ class DWARFObjInMemory final : public DWARFObject {
 
       // Symbol to [address, section index] cache mapping.
       std::map<SymbolRef, SymInfo> AddrCache;
-      bool (*Supports)(uint64_t);
+      SupportsRelocation Supports;
       RelocationResolver Resolver;
       std::tie(Supports, Resolver) = getRelocationResolver(Obj);
       for (const RelocationRef &Reloc : Section.relocations()) {

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index fa0ceb4bbc01..da6f6ad903f4 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -53,14 +53,16 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
 
   ErrorAsOutParameter ErrAsOut(Err);
   Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
-  uint64_t A = getUnsigned(Off, Size, Err);
+  uint64_t LocData = getUnsigned(Off, Size, Err);
   if (!E || (Err && *Err))
-    return A;
+    return LocData;
   if (SecNdx)
     *SecNdx = E->SectionIndex;
-  uint64_t R = E->Resolver(E->Reloc, E->SymbolValue, A);
+
+  uint64_t R =
+      object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData);
   if (E->Reloc2)
-    R = E->Resolver(*E->Reloc2, E->SymbolValue2, R);
+    R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R);
   return R;
 }
 

diff  --git a/llvm/lib/Object/RelocationResolver.cpp b/llvm/lib/Object/RelocationResolver.cpp
index f39262bc9061..52c4979c93f6 100644
--- a/llvm/lib/Object/RelocationResolver.cpp
+++ b/llvm/lib/Object/RelocationResolver.cpp
@@ -39,20 +39,21 @@ static bool supportsX86_64(uint64_t Type) {
   }
 }
 
-static uint64_t resolveX86_64(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
+                              uint64_t LocData, int64_t Addend) {
+  switch (Type) {
   case ELF::R_X86_64_NONE:
-    return A;
+    return LocData;
   case ELF::R_X86_64_64:
   case ELF::R_X86_64_DTPOFF32:
   case ELF::R_X86_64_DTPOFF64:
-    return S + getELFAddend(R);
+    return S + Addend;
   case ELF::R_X86_64_PC32:
   case ELF::R_X86_64_PC64:
-    return S + getELFAddend(R) - R.getOffset();
+    return S + Addend - Offset;
   case ELF::R_X86_64_32:
   case ELF::R_X86_64_32S:
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+    return (S + Addend) & 0xFFFFFFFF;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -70,16 +71,17 @@ static bool supportsAArch64(uint64_t Type) {
   }
 }
 
-static uint64_t resolveAArch64(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
+                               uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_AARCH64_ABS32:
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+    return (S + Addend) & 0xFFFFFFFF;
   case ELF::R_AARCH64_ABS64:
-    return S + getELFAddend(R);
+    return S + Addend;
   case ELF::R_AARCH64_PREL32:
-    return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
+    return (S + Addend - Offset) & 0xFFFFFFFF;
   case ELF::R_AARCH64_PREL64:
-    return S + getELFAddend(R) - R.getOffset();
+    return S + Addend - Offset;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -95,12 +97,13 @@ static bool supportsBPF(uint64_t Type) {
   }
 }
 
-static uint64_t resolveBPF(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
+                           uint64_t LocData, int64_t /*Addend*/) {
+  switch (Type) {
   case ELF::R_BPF_64_32:
-    return (S + A) & 0xFFFFFFFF;
+    return (S + LocData) & 0xFFFFFFFF;
   case ELF::R_BPF_64_64:
-    return S + A;
+    return S + LocData;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -118,16 +121,17 @@ static bool supportsMips64(uint64_t Type) {
   }
 }
 
-static uint64_t resolveMips64(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,
+                              uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_MIPS_32:
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+    return (S + Addend) & 0xFFFFFFFF;
   case ELF::R_MIPS_64:
-    return S + getELFAddend(R);
+    return S + Addend;
   case ELF::R_MIPS_TLS_DTPREL64:
-    return S + getELFAddend(R) - 0x8000;
+    return S + Addend - 0x8000;
   case ELF::R_MIPS_PC32:
-    return S + getELFAddend(R) - R.getOffset();
+    return S + Addend - Offset;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -143,12 +147,13 @@ static bool supportsMSP430(uint64_t Type) {
   }
 }
 
-static uint64_t resolveMSP430(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,
+                              uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_MSP430_32:
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+    return (S + Addend) & 0xFFFFFFFF;
   case ELF::R_MSP430_16_BYTE:
-    return (S + getELFAddend(R)) & 0xFFFF;
+    return (S + Addend) & 0xFFFF;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -166,16 +171,17 @@ static bool supportsPPC64(uint64_t Type) {
   }
 }
 
-static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,
+                             uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_PPC64_ADDR32:
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+    return (S + Addend) & 0xFFFFFFFF;
   case ELF::R_PPC64_ADDR64:
-    return S + getELFAddend(R);
+    return S + Addend;
   case ELF::R_PPC64_REL32:
-    return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
+    return (S + Addend - Offset) & 0xFFFFFFFF;
   case ELF::R_PPC64_REL64:
-    return S + getELFAddend(R) - R.getOffset();
+    return S + Addend - Offset;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -191,12 +197,13 @@ static bool supportsSystemZ(uint64_t Type) {
   }
 }
 
-static uint64_t resolveSystemZ(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,
+                               uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_390_32:
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+    return (S + Addend) & 0xFFFFFFFF;
   case ELF::R_390_64:
-    return S + getELFAddend(R);
+    return S + Addend;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -214,13 +221,14 @@ static bool supportsSparc64(uint64_t Type) {
   }
 }
 
-static uint64_t resolveSparc64(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,
+                               uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_SPARC_32:
   case ELF::R_SPARC_64:
   case ELF::R_SPARC_UA32:
   case ELF::R_SPARC_UA64:
-    return S + getELFAddend(R);
+    return S + Addend;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -236,11 +244,12 @@ static bool supportsAmdgpu(uint64_t Type) {
   }
 }
 
-static uint64_t resolveAmdgpu(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,
+                              uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_AMDGPU_ABS32:
   case ELF::R_AMDGPU_ABS64:
-    return S + getELFAddend(R);
+    return S + Addend;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -257,14 +266,15 @@ static bool supportsX86(uint64_t Type) {
   }
 }
 
-static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,
+                           uint64_t LocData, int64_t /*Addend*/) {
+  switch (Type) {
   case ELF::R_386_NONE:
-    return A;
+    return LocData;
   case ELF::R_386_32:
-    return S + A;
+    return S + LocData;
   case ELF::R_386_PC32:
-    return S - R.getOffset() + A;
+    return S - Offset + LocData;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -280,12 +290,13 @@ static bool supportsPPC32(uint64_t Type) {
   }
 }
 
-static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,
+                             uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_PPC_ADDR32:
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+    return (S + Addend) & 0xFFFFFFFF;
   case ELF::R_PPC_REL32:
-    return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF;
+    return (S + Addend - Offset) & 0xFFFFFFFF;
   }
   llvm_unreachable("Invalid relocation type");
 }
@@ -300,12 +311,13 @@ static bool supportsARM(uint64_t Type) {
   }
 }
 
-static uint64_t resolveARM(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
+                           uint64_t LocData, int64_t /*Addend*/) {
+  switch (Type) {
   case ELF::R_ARM_ABS32:
-    return (S + A) & 0xFFFFFFFF;
+    return (S + LocData) & 0xFFFFFFFF;
   case ELF::R_ARM_REL32:
-    return (S + A - R.getOffset()) & 0xFFFFFFFF;
+    return (S + LocData - Offset) & 0xFFFFFFFF;
   }
   llvm_unreachable("Invalid relocation type");
 }
@@ -320,12 +332,13 @@ static bool supportsAVR(uint64_t Type) {
   }
 }
 
-static uint64_t resolveAVR(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,
+                           uint64_t /*LocData*/, int64_t Addend) {
+  switch (Type) {
   case ELF::R_AVR_16:
-    return (S + getELFAddend(R)) & 0xFFFF;
+    return (S + Addend) & 0xFFFF;
   case ELF::R_AVR_32:
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+    return (S + Addend) & 0xFFFFFFFF;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -335,9 +348,10 @@ static bool supportsLanai(uint64_t Type) {
   return Type == ELF::R_LANAI_32;
 }
 
-static uint64_t resolveLanai(RelocationRef R, uint64_t S, uint64_t A) {
-  if (R.getType() == ELF::R_LANAI_32)
-    return (S + getELFAddend(R)) & 0xFFFFFFFF;
+static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,
+                             uint64_t /*LocData*/, int64_t Addend) {
+  if (Type == ELF::R_LANAI_32)
+    return (S + Addend) & 0xFFFFFFFF;
   llvm_unreachable("Invalid relocation type");
 }
 
@@ -351,13 +365,13 @@ static bool supportsMips32(uint64_t Type) {
   }
 }
 
-static uint64_t resolveMips32(RelocationRef R, uint64_t S, uint64_t A) {
+static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,
+                              uint64_t LocData, int64_t /*Addend*/) {
   // FIXME: Take in account implicit addends to get correct results.
-  uint32_t Rel = R.getType();
-  if (Rel == ELF::R_MIPS_32)
-    return (S + A) & 0xFFFFFFFF;
-  if (Rel == ELF::R_MIPS_TLS_DTPREL32)
-    return (S + A) & 0xFFFFFFFF;
+  if (Type == ELF::R_MIPS_32)
+    return (S + LocData) & 0xFFFFFFFF;
+  if (Type == ELF::R_MIPS_TLS_DTPREL32)
+    return (S + LocData) & 0xFFFFFFFF;
   llvm_unreachable("Invalid relocation type");
 }
 
@@ -371,20 +385,21 @@ static bool supportsSparc32(uint64_t Type) {
   }
 }
 
-static uint64_t resolveSparc32(RelocationRef R, uint64_t S, uint64_t A) {
-  uint32_t Rel = R.getType();
-  if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32)
-    return S + getELFAddend(R);
-  return A;
+static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,
+                               uint64_t LocData, int64_t Addend) {
+  if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
+    return S + Addend;
+  return LocData;
 }
 
 static bool supportsHexagon(uint64_t Type) {
   return Type == ELF::R_HEX_32;
 }
 
-static uint64_t resolveHexagon(RelocationRef R, uint64_t S, uint64_t A) {
-  if (R.getType() == ELF::R_HEX_32)
-    return S + getELFAddend(R);
+static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,
+                               uint64_t /*LocData*/, int64_t Addend) {
+  if (Type == ELF::R_HEX_32)
+    return S + Addend;
   llvm_unreachable("Invalid relocation type");
 }
 
@@ -410,15 +425,17 @@ static bool supportsRISCV(uint64_t Type) {
   }
 }
 
-static uint64_t resolveRISCV(RelocationRef R, uint64_t S, uint64_t A) {
-  int64_t RA = getELFAddend(R);
-  switch (R.getType()) {
+static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
+                             uint64_t LocData, int64_t Addend) {
+  int64_t RA = Addend;
+  uint64_t A = LocData;
+  switch (Type) {
   case ELF::R_RISCV_NONE:
-    return A;
+    return LocData;
   case ELF::R_RISCV_32:
     return (S + RA) & 0xFFFFFFFF;
   case ELF::R_RISCV_32_PCREL:
-    return (S + RA - R.getOffset()) & 0xFFFFFFFF;
+    return (S + RA - Offset) & 0xFFFFFFFF;
   case ELF::R_RISCV_64:
     return S + RA;
   case ELF::R_RISCV_SET6:
@@ -456,11 +473,12 @@ static bool supportsCOFFX86(uint64_t Type) {
   }
 }
 
-static uint64_t resolveCOFFX86(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,
+                               uint64_t LocData, int64_t /*Addend*/) {
+  switch (Type) {
   case COFF::IMAGE_REL_I386_SECREL:
   case COFF::IMAGE_REL_I386_DIR32:
-    return (S + A) & 0xFFFFFFFF;
+    return (S + LocData) & 0xFFFFFFFF;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -476,12 +494,13 @@ static bool supportsCOFFX86_64(uint64_t Type) {
   }
 }
 
-static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
+                                  uint64_t LocData, int64_t /*Addend*/) {
+  switch (Type) {
   case COFF::IMAGE_REL_AMD64_SECREL:
-    return (S + A) & 0xFFFFFFFF;
+    return (S + LocData) & 0xFFFFFFFF;
   case COFF::IMAGE_REL_AMD64_ADDR64:
-    return S + A;
+    return S + LocData;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -497,11 +516,12 @@ static bool supportsCOFFARM(uint64_t Type) {
   }
 }
 
-static uint64_t resolveCOFFARM(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,
+                               uint64_t LocData, int64_t /*Addend*/) {
+  switch (Type) {
   case COFF::IMAGE_REL_ARM_SECREL:
   case COFF::IMAGE_REL_ARM_ADDR32:
-    return (S + A) & 0xFFFFFFFF;
+    return (S + LocData) & 0xFFFFFFFF;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -517,12 +537,13 @@ static bool supportsCOFFARM64(uint64_t Type) {
   }
 }
 
-static uint64_t resolveCOFFARM64(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,
+                                 uint64_t LocData, int64_t /*Addend*/) {
+  switch (Type) {
   case COFF::IMAGE_REL_ARM64_SECREL:
-    return (S + A) & 0xFFFFFFFF;
+    return (S + LocData) & 0xFFFFFFFF;
   case COFF::IMAGE_REL_ARM64_ADDR64:
-    return S + A;
+    return S + LocData;
   default:
     llvm_unreachable("Invalid relocation type");
   }
@@ -532,8 +553,9 @@ static bool supportsMachOX86_64(uint64_t Type) {
   return Type == MachO::X86_64_RELOC_UNSIGNED;
 }
 
-static uint64_t resolveMachOX86_64(RelocationRef R, uint64_t S, uint64_t A) {
-  if (R.getType() == MachO::X86_64_RELOC_UNSIGNED)
+static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
+                                   uint64_t LocData, int64_t /*Addend*/) {
+  if (Type == MachO::X86_64_RELOC_UNSIGNED)
     return S;
   llvm_unreachable("Invalid relocation type");
 }
@@ -573,8 +595,9 @@ static bool supportsWasm64(uint64_t Type) {
   }
 }
 
-static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
+                              uint64_t LocData, int64_t /*Addend*/) {
+  switch (Type) {
   case wasm::R_WASM_FUNCTION_INDEX_LEB:
   case wasm::R_WASM_TABLE_INDEX_SLEB:
   case wasm::R_WASM_TABLE_INDEX_I32:
@@ -589,14 +612,15 @@ static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
   case wasm::R_WASM_GLOBAL_INDEX_I32:
   case wasm::R_WASM_TABLE_NUMBER_LEB:
     // For wasm section, its offset at 0 -- ignoring Value
-    return A;
+    return LocData;
   default:
     llvm_unreachable("Invalid relocation type");
   }
 }
 
-static uint64_t resolveWasm64(RelocationRef R, uint64_t S, uint64_t A) {
-  switch (R.getType()) {
+static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,
+                              uint64_t LocData, int64_t Addend) {
+  switch (Type) {
   case wasm::R_WASM_MEMORY_ADDR_LEB64:
   case wasm::R_WASM_MEMORY_ADDR_SLEB64:
   case wasm::R_WASM_MEMORY_ADDR_I64:
@@ -604,13 +628,13 @@ static uint64_t resolveWasm64(RelocationRef R, uint64_t S, uint64_t A) {
   case wasm::R_WASM_TABLE_INDEX_I64:
   case wasm::R_WASM_FUNCTION_OFFSET_I64:
     // For wasm section, its offset at 0 -- ignoring Value
-    return A;
+    return LocData;
   default:
-    return resolveWasm32(R, S, A);
+    return resolveWasm32(Type, Offset, S, LocData, Addend);
   }
 }
 
-std::pair<bool (*)(uint64_t), RelocationResolver>
+std::pair<SupportsRelocation, RelocationResolver>
 getRelocationResolver(const ObjectFile &Obj) {
   if (Obj.isCOFF()) {
     switch (Obj.getArch()) {
@@ -701,5 +725,38 @@ getRelocationResolver(const ObjectFile &Obj) {
   llvm_unreachable("Invalid object file");
 }
 
+uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
+                           uint64_t S, uint64_t LocData) {
+  if (const ObjectFile *Obj = R.getObject()) {
+    int64_t Addend = 0;
+    if (Obj->isELF()) {
+      auto GetRelSectionType = [&]() -> unsigned {
+        if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
+          return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
+        if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
+          return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
+        if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
+          return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
+        auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
+        return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
+      };
+
+      if (GetRelSectionType() == ELF::SHT_RELA)
+        Addend = getELFAddend(R);
+    }
+
+    return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
+  }
+
+  // Sometimes the caller might want to use its own specific implementation of
+  // the resolver function. E.g. this is used by LLD when it resolves debug
+  // relocations and assumes that all of them have the same computation (S + A).
+  // The relocation R has no owner object in this case and we don't need to
+  // provide Type and Offset fields. It is also assumed the DataRefImpl.p
+  // contains the addend, provided by the caller.
+  return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
+                  R.getRawDataRefImpl().p);
+}
+
 } // namespace object
 } // namespace llvm

diff  --git a/llvm/lib/XRay/InstrumentationMap.cpp b/llvm/lib/XRay/InstrumentationMap.cpp
index de0a9e60a511..9202e2870bdf 100644
--- a/llvm/lib/XRay/InstrumentationMap.cpp
+++ b/llvm/lib/XRay/InstrumentationMap.cpp
@@ -109,28 +109,32 @@ loadObj(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
         return static_cast<uint32_t>(0);
     }(ObjFile.getBinary());
 
-    bool (*SupportsRelocation)(uint64_t);
+    object::SupportsRelocation Supports;
     object::RelocationResolver Resolver;
-    std::tie(SupportsRelocation, Resolver) =
+    std::tie(Supports, Resolver) =
         object::getRelocationResolver(*ObjFile.getBinary());
 
     for (const object::SectionRef &Section : Sections) {
       for (const object::RelocationRef &Reloc : Section.relocations()) {
         if (ObjFile.getBinary()->getArch() == Triple::arm) {
-          if (SupportsRelocation && SupportsRelocation(Reloc.getType())) {
+          if (Supports && Supports(Reloc.getType())) {
             Expected<uint64_t> ValueOrErr = Reloc.getSymbol()->getValue();
             if (!ValueOrErr)
               return ValueOrErr.takeError();
-            Relocs.insert({Reloc.getOffset(), Resolver(Reloc, *ValueOrErr, 0)});
+            Relocs.insert(
+                {Reloc.getOffset(),
+                 object::resolveRelocation(Resolver, Reloc, *ValueOrErr, 0)});
           }
-        } else if (SupportsRelocation && SupportsRelocation(Reloc.getType())) {
+        } else if (Supports && Supports(Reloc.getType())) {
           auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend();
           auto A = AddendOrErr ? *AddendOrErr : 0;
           Expected<uint64_t> ValueOrErr = Reloc.getSymbol()->getValue();
           if (!ValueOrErr)
             // TODO: Test this error.
             return ValueOrErr.takeError();
-          Relocs.insert({Reloc.getOffset(), Resolver(Reloc, *ValueOrErr, A)});
+          Relocs.insert(
+              {Reloc.getOffset(),
+               object::resolveRelocation(Resolver, Reloc, *ValueOrErr, A)});
         } else if (Reloc.getType() == RelativeRelocation) {
           if (auto AddendOrErr = object::ELFRelocationRef(Reloc).getAddend())
             Relocs.insert({Reloc.getOffset(), *AddendOrErr});

diff  --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test
index e38c5e8b755b..74ad8fcc9c72 100644
--- a/llvm/test/Object/invalid.test
+++ b/llvm/test/Object/invalid.test
@@ -43,13 +43,14 @@ Sections:
 
 # INVALID-STRTAB-SIZE: error: '[[FILE]]': section [index 1] has a sh_offset (0x70) + sh_size (0xffffff) that is greater than the file size (0x218)
 
-## Check that llvm-dwarfdump reports an error during relocation resolution
-## when instead of expected SHT_RELA section it locates a section of a 
diff erent type.
+## Document that llvm-dwarfdump doesn't reports errors/warnings during relocation resolution
+## when instead of SHT_RELA section we have a SHT_REL section in an object.
+## In this case it just doesn't try to read relocation addends and assumes they are 0.
 
+## Note: we don't check the output, because the intention of this test is just to check the
+## exit code and to document the fact that no warnings are reported.
 # RUN: yaml2obj %s --docnum=3 -o %t3
-# RUN: not --crash llvm-dwarfdump -debug-line %t3 2>&1 | FileCheck --check-prefix=RELA %s
-
-# RELA: LLVM ERROR: Section is not SHT_RELA
+# RUN: llvm-dwarfdump -debug-line %t3 2>&1 | FileCheck --implicit-check-not=warning: %s
 
 --- !ELF
 FileHeader:

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 255e633ec2e3..1cad74205371 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -5849,7 +5849,7 @@ void DumpStyle<ELFT>::printStackSize(RelocationRef Reloc,
   }
 
   uint64_t Addend = Data.getAddress(&Offset);
-  uint64_t SymValue = Resolver(Reloc, RelocSymValue, Addend);
+  uint64_t SymValue = resolveRelocation(Resolver, Reloc, RelocSymValue, Addend);
   this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data,
                                &Offset);
 }
@@ -5947,7 +5947,8 @@ void DumpStyle<ELFT>::printRelocatableStackSizes(
     // described in it.
     const Elf_Shdr *FunctionSec = unwrapOrError(
         this->FileName, Obj.getSection(StackSizesELFSec->sh_link));
-    bool (*IsSupportedFn)(uint64_t);
+
+    SupportsRelocation IsSupportedFn;
     RelocationResolver Resolver;
     std::tie(IsSupportedFn, Resolver) = getRelocationResolver(ElfObj);
     ArrayRef<uint8_t> Contents =


        


More information about the llvm-commits mailing list