[llvm] [BOLT] Move target-specific relocation logic into target handlers (PR #217926)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 11:19:59 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: RachinskiyMaksim (maksimra)

<details>
<summary>Changes</summary>

This PR cleans up BOLT's target-specific relocation handling.

Move relocation logic directly into the X86, AArch64, and RISC-V handlers located in their corresponding `lib/Target` directories. This removes the remaining target-specific relocation helpers from the generic Relocation.cpp implementation.

This is a behavior-preserving refactoring.

---

Patch is 113.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217926.diff


29 Files Affected:

- (modified) bolt/include/bolt/Core/BinaryContext.h (+8) 
- (modified) bolt/include/bolt/Core/BinarySection.h (+1-4) 
- (modified) bolt/include/bolt/Core/Relocation.h (+87-93) 
- (modified) bolt/lib/Core/BinaryContext.cpp (+3-1) 
- (modified) bolt/lib/Core/BinaryEmitter.cpp (+3-2) 
- (modified) bolt/lib/Core/BinaryFunction.cpp (+8-6) 
- (modified) bolt/lib/Core/BinarySection.cpp (+33-15) 
- (modified) bolt/lib/Core/CMakeLists.txt (+3) 
- (modified) bolt/lib/Core/Relocation.cpp (+29-993) 
- (modified) bolt/lib/Rewrite/LinuxKernelRewriter.cpp (+4-2) 
- (modified) bolt/lib/Rewrite/MachORewriteInstance.cpp (-1) 
- (modified) bolt/lib/Rewrite/RSeqRewriter.cpp (+1-1) 
- (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+40-35) 
- (modified) bolt/lib/Target/AArch64/AArch64MCSymbolizer.cpp (+3-2) 
- (added) bolt/lib/Target/AArch64/AArch64RelocationHandler.cpp (+448) 
- (modified) bolt/lib/Target/AArch64/CMakeLists.txt (+3) 
- (modified) bolt/lib/Target/RISCV/CMakeLists.txt (+3) 
- (added) bolt/lib/Target/RISCV/RISCVRelocationHandler.cpp (+343) 
- (modified) bolt/lib/Target/X86/CMakeLists.txt (+3) 
- (modified) bolt/lib/Target/X86/X86MCSymbolizer.cpp (+14-5) 
- (added) bolt/lib/Target/X86/X86RelocationHandler.cpp (+224) 
- (modified) bolt/unittests/Core/BinaryContext.cpp (+16-3) 
- (modified) bolt/unittests/Core/MCPlusBuilder.cpp (-1) 
- (modified) bolt/unittests/Core/MemoryMaps.cpp (-1) 
- (modified) bolt/unittests/Passes/LivenessAnalysis.cpp (-1) 
- (modified) bolt/unittests/Passes/PointerAuthCFIFixup.cpp (-1) 
- (modified) bolt/unittests/Profile/DataAggregator.cpp (-1) 
- (modified) bolt/unittests/Profile/PerfScripts.cpp (-1) 
- (modified) bolt/unittests/Profile/PerfSpeEvents.cpp (-1) 


``````````diff
diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 92cd853870cae..16ef236bbe816 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -722,6 +722,10 @@ class BinaryContext {
 
   std::unique_ptr<Triple> TheTriple;
 
+private:
+  std::unique_ptr<RelocationHandler> RelocHandler;
+
+public:
   std::shared_ptr<orc::SymbolStringPool> SSP;
 
   const Target *TheTarget;
@@ -975,6 +979,10 @@ class BinaryContext {
 
   bool isMachO() const { return TheTriple->isOSBinFormatMachO(); }
 
+  const RelocationHandler &getRelocationHandler() const {
+    return *RelocHandler;
+  }
+
   bool isAArch64() const {
     return TheTriple->getArch() == llvm::Triple::aarch64;
   }
diff --git a/bolt/include/bolt/Core/BinarySection.h b/bolt/include/bolt/Core/BinarySection.h
index 4609105d8b5ba..163c3aec4a32c 100644
--- a/bolt/include/bolt/Core/BinarySection.h
+++ b/bolt/include/bolt/Core/BinarySection.h
@@ -372,10 +372,7 @@ class BinarySection {
         Relocation{Offset, Symbol, Type, Addend, Value, IsRELR});
   }
 
-  void addDynamicRelocation(const Relocation &Reloc) {
-    assert(Reloc.Offset < getSize() && "offset not within section bounds");
-    DynamicRelocations.emplace(Reloc);
-  }
+  void addDynamicRelocation(const Relocation &Reloc);
 
   /// Add relocation against the original contents of this section.
   void addPendingRelocation(const Relocation &Rel) {
diff --git a/bolt/include/bolt/Core/Relocation.h b/bolt/include/bolt/Core/Relocation.h
index 9bc94d6484b70..38c064f27b25c 100644
--- a/bolt/include/bolt/Core/Relocation.h
+++ b/bolt/include/bolt/Core/Relocation.h
@@ -17,6 +17,7 @@
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/TargetParser/Triple.h"
+#include <memory>
 
 namespace llvm {
 class MCSymbol;
@@ -34,23 +35,91 @@ enum { R_X86_64_converted_reloc_bit = 0x80 };
 
 namespace bolt {
 
+/// Target-specific relocation operations. One handler is owned by each
+/// BinaryContext, while Relocation remains a lightweight value type.
+class RelocationHandler {
+public:
+  virtual ~RelocationHandler() = default;
+
+  /// Check if \p Type is a supported relocation type.
+  virtual bool isSupported(uint32_t Type) const = 0;
+
+  /// Return size in bytes of the given relocation \p Type.
+  virtual size_t getSizeForType(uint32_t Type) const = 0;
+
+  /// Skip relocations that we don't want to handle in BOLT
+  virtual bool skipRelocationType(uint32_t Type) const = 0;
+
+  /// Adjust value depending on relocation type (make it PC relative or not).
+  virtual uint64_t encodeValue(uint32_t Type, uint64_t Value,
+                               uint64_t PC) const = 0;
+
+  /// Return true if there are enough bits to encode the relocation value.
+  virtual bool canEncodeValue(uint32_t Type, uint64_t Value,
+                              uint64_t PC) const = 0;
+
+  /// Extract current relocated value from binary contents. This is used for
+  /// RISC architectures where values are encoded in specific bits depending
+  /// on the relocation value. For X86, we limit to sign extending the value
+  /// if necessary.
+  virtual uint64_t extractValue(uint32_t Type, uint64_t Contents,
+                                uint64_t PC) const = 0;
+
+  /// Return true if relocation type implies the creation of a GOT entry
+  virtual bool isGOT(uint32_t Type) const = 0;
+
+  /// Return true if relocation type is NONE
+  bool isNone(uint32_t Type) const { return Type == getNone(); }
+
+  /// Return true if relocation type is RELATIVE
+  virtual bool isRelative(uint32_t Type) const = 0;
+
+  /// Return true if relocation type is IRELATIVE
+  virtual bool isIRelative(uint32_t Type) const = 0;
+
+  /// Return true if relocation type is for thread local storage.
+  virtual bool isTLS(uint32_t Type) const = 0;
+
+  /// Return true of relocation type is for referencing a specific instruction
+  /// (as opposed to a function, basic block, etc).
+  virtual bool isInstructionReference(uint32_t Type) const { return false; }
+
+  /// Return code for a NONE relocation
+  virtual uint32_t getNone() const = 0;
+
+  /// Return code for a PC-relative 4-byte relocation
+  virtual uint32_t getPC32() const = 0;
+
+  /// Return code for a PC-relative 8-byte relocation
+  virtual uint32_t getPC64() const = 0;
+
+  /// Return true if relocation type is PC-relative. Return false otherwise.
+  virtual bool isPCRelative(uint32_t Type) const = 0;
+
+  /// Return code for a ABS 8-byte relocation
+  virtual uint32_t getAbs64() const = 0;
+
+  /// Return code for a RELATIVE relocation
+  virtual uint32_t getRelative() const = 0;
+  virtual MCBinaryExpr::Opcode getComposeOpcodeFor(uint32_t Type) const;
+  virtual void printType(raw_ostream &OS, uint32_t Type) const = 0;
+};
+
+std::unique_ptr<RelocationHandler>
+createRelocationHandler(Triple::ArchType Arch);
+
 /// Relocation class.
 class Relocation {
 public:
   Relocation(uint64_t Offset, MCSymbol *Symbol, uint32_t Type, uint64_t Addend,
              uint64_t Value, bool IsRELR = false)
       : Offset(Offset), Symbol(Symbol), Type(Type), Optional(false),
-        IsRELR(IsRELR), Addend(Addend), Value(Value) {
-    assert((isRelative() || !isRELR()) &&
-           "Only relative relocations can be relr.");
-  }
+        IsRELR(IsRELR), Addend(Addend), Value(Value) {}
 
   Relocation()
       : Offset(0), Symbol(0), Type(0), Optional(0), IsRELR(0), Addend(0),
         Value(0) {}
 
-  static Triple::ArchType Arch; /// set by BinaryContext ctor.
-
   /// The offset of this relocation in the object it is contained in.
   uint64_t Offset;
 
@@ -79,9 +148,6 @@ class Relocation {
   /// Used to validate relocation correctness.
   uint64_t Value;
 
-  /// Return size in bytes of the given relocation \p Type.
-  static size_t getSizeForType(uint32_t Type);
-
   void setOptional() { Optional = true; }
 
   bool isOptional() { return Optional; }
@@ -89,91 +155,23 @@ class Relocation {
   bool isRELR() const { return IsRELR; }
 
   /// Return size of this relocation.
-  size_t getSize() const { return getSizeForType(Type); }
-
-  /// Skip relocations that we don't want to handle in BOLT
-  static bool skipRelocationType(uint32_t Type);
-
-  /// Adjust value depending on relocation type (make it PC relative or not).
-  static uint64_t encodeValue(uint32_t Type, uint64_t Value, uint64_t PC);
-
-  /// Return true if there are enough bits to encode the relocation value.
-  static bool canEncodeValue(uint32_t Type, uint64_t Value, uint64_t PC);
-
-  /// Extract current relocated value from binary contents. This is used for
-  /// RISC architectures where values are encoded in specific bits depending
-  /// on the relocation value. For X86, we limit to sign extending the value
-  /// if necessary.
-  static uint64_t extractValue(uint32_t Type, uint64_t Contents, uint64_t PC);
-
-  /// Return true if relocation type is PC-relative. Return false otherwise.
-  static bool isPCRelative(uint32_t Type);
-
-  /// Check if \p Type is a supported relocation type.
-  static bool isSupported(uint32_t Type);
-
-  /// Return true if relocation type implies the creation of a GOT entry
-  static bool isGOT(uint32_t Type);
-
-  /// Special relocation type that allows the linker to modify the instruction.
-  static bool isX86GOTPCRELX(uint32_t Type);
-  static bool isX86GOTPC64(uint32_t Type);
-
-  /// Return true if relocation type is NONE
-  static bool isNone(uint32_t Type);
-
-  /// Return true if relocation type is RELATIVE
-  static bool isRelative(uint32_t Type);
-
-  /// Return true if relocation type is IRELATIVE
-  static bool isIRelative(uint32_t Type);
-
-  /// Return true if relocation type is for thread local storage.
-  static bool isTLS(uint32_t Type);
-
-  /// Return true of relocation type is for referencing a specific instruction
-  /// (as opposed to a function, basic block, etc).
-  static bool isInstructionReference(uint32_t Type);
-
   /// Return the relocation type of \p Rel from llvm::object. It checks for
   /// overflows as BOLT uses 32 bits for the type.
   static uint32_t getType(const object::RelocationRef &Rel);
 
-  /// Return code for a NONE relocation
-  static uint32_t getNone();
-
-  /// Return code for a PC-relative 4-byte relocation
-  static uint32_t getPC32();
-
-  /// Return code for a PC-relative 8-byte relocation
-  static uint32_t getPC64();
-
-  /// Return code for a ABS 8-byte relocation
-  static uint32_t getAbs64();
-
-  /// Return code for a RELATIVE relocation
-  static uint32_t getRelative();
-
-  /// Return true if this relocation is PC-relative. Return false otherwise.
-  bool isPCRelative() const { return isPCRelative(Type); }
-
-  /// Return true if this relocation is R_*_RELATIVE type. Return false
-  /// otherwise.
-  bool isRelative() const { return isRelative(Type); }
-
-  /// Return true if this relocation is R_*_IRELATIVE type. Return false
-  /// otherwise.
-  bool isIRelative() const { return isIRelative(Type); }
+  size_t getSize(const RelocationHandler &RH) const { return RH.getSizeForType(Type);
+  }
 
   /// Emit relocation at a current \p Streamer' position. The caller is
   /// responsible for setting the position correctly.
-  size_t emit(MCStreamer *Streamer) const;
+  size_t emit(MCStreamer *Streamer, const RelocationHandler &RH) const;
 
   /// Emit a group of composed relocations. All relocations must have the same
   /// offset. If std::distance(Begin, End) == 1, this is equivalent to
   /// Begin->emit(Streamer).
   template <typename RelocIt>
-  static size_t emit(RelocIt Begin, RelocIt End, MCStreamer *Streamer) {
+  static size_t emit(RelocIt Begin, RelocIt End, MCStreamer *Streamer,
+                     const RelocationHandler &RH) {
     if (Begin == End)
       return 0;
 
@@ -182,23 +180,24 @@ class Relocation {
     for (auto RI = Begin; RI != End; ++RI) {
       assert(RI->Offset == Begin->Offset &&
              "emitting composed relocations with different offsets");
-      Value = RI->createExpr(Streamer, Value);
+      Value = RI->createExpr(Streamer, Value, RH);
     }
 
     assert(Value && "failed to create relocation value");
-    auto Size = std::prev(End)->getSize();
+    auto Size = std::prev(End)->getSize(RH);
     Streamer->emitValue(Value, Size);
     return Size;
   }
 
   /// Print a relocation to \p OS.
-  void print(raw_ostream &OS) const;
+  void print(raw_ostream &OS, const RelocationHandler &RH) const;
 
 private:
-  const MCExpr *createExpr(MCStreamer *Streamer) const;
   const MCExpr *createExpr(MCStreamer *Streamer,
-                           const MCExpr *RetainedValue) const;
-  static MCBinaryExpr::Opcode getComposeOpcodeFor(uint32_t Type);
+                           const RelocationHandler &RH) const;
+  const MCExpr *createExpr(MCStreamer *Streamer,
+                           const MCExpr *RetainedValue,
+                           const RelocationHandler &RH) const;
 };
 
 /// Relocation ordering by offset.
@@ -210,11 +209,6 @@ inline bool operator<(const Relocation &A, uint64_t B) { return A.Offset < B; }
 
 inline bool operator<(uint64_t A, const Relocation &B) { return A < B.Offset; }
 
-inline raw_ostream &operator<<(raw_ostream &OS, const Relocation &Rel) {
-  Rel.print(OS);
-  return OS;
-}
-
 } // namespace bolt
 } // namespace llvm
 
diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp
index d911f8191f791..f13ae8eae7ecb 100644
--- a/bolt/lib/Core/BinaryContext.cpp
+++ b/bolt/lib/Core/BinaryContext.cpp
@@ -164,7 +164,9 @@ BinaryContext::BinaryContext(std::unique_ptr<MCContext> Ctx,
                              std::unique_ptr<MCDisassembler> DisAsm,
                              JournalingStreams Logger)
     : Ctx(std::move(Ctx)), DwCtx(std::move(DwCtx)),
-      TheTriple(std::move(TheTriple)), SSP(std::move(SSP)),
+      TheTriple(std::move(TheTriple)),
+      RelocHandler(createRelocationHandler(this->TheTriple->getArch())),
+      SSP(std::move(SSP)),
       TheTarget(TheTarget), TripleName(TripleName), MCE(std::move(MCE)),
       MOFI(std::move(MOFI)), AsmInfo(std::move(AsmInfo)), MII(std::move(MII)),
       STI(std::move(STI)), InstPrinter(std::move(InstPrinter)),
diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index 29dbcab7945ec..504125038d33d 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -597,9 +597,10 @@ void BinaryEmitter::emitConstantIslands(BinaryFunction &BF, bool EmitColdPart,
             dbgs() << "BOLT-DEBUG: emitting constant island relocation"
                    << " for " << BF << " at offset 0x"
                    << Twine::utohexstr(Relocation.Offset) << " with size "
-                   << Relocation::getSizeForType(Relocation.Type) << '\n');
+                   << BC.getRelocationHandler().getSizeForType(Relocation.Type)
+                   << '\n');
 
-        FunctionOffset += Relocation.emit(&Streamer);
+        FunctionOffset += Relocation.emit(&Streamer, BC.getRelocationHandler());
       }
 
       assert(FunctionOffset <= EndOffset && "overflow error");
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index a81fa2f45c206..b50f8929a005a 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -706,7 +706,9 @@ void BinaryFunction::printRelocations(raw_ostream &OS, uint64_t Offset,
 
   auto RI = Relocations.lower_bound(Offset);
   while (RI != Relocations.end() && RI->first < Offset + Size) {
-    OS << Sep << "(R: " << RI->second << ")";
+    OS << Sep << "(R: ";
+    RI->second.print(OS, BC.getRelocationHandler());
+    OS << ")";
     Sep = ", ";
     ++RI;
   }
@@ -1509,7 +1511,7 @@ Error BinaryFunction::disassemble() {
         const Relocation &Relocation = Itr->second;
         MCSymbol *Symbol = Relocation.Symbol;
 
-        if (Relocation::isInstructionReference(Relocation.Type)) {
+        if (BC.getRelocationHandler().isInstructionReference(Relocation.Type)) {
           uint64_t RefOffset = Relocation.Value - getAddress();
           LabelsMapType::iterator LI = InstructionLabels.find(RefOffset);
 
@@ -1525,8 +1527,8 @@ Error BinaryFunction::disassemble() {
 
         // For GOT relocations, create a reference against GOT entry ignoring
         // the relocation symbol.
-        if (Relocation::isGOT(Relocation.Type)) {
-          assert(Relocation::isPCRelative(Relocation.Type) &&
+        if (BC.getRelocationHandler().isGOT(Relocation.Type)) {
+          assert(BC.getRelocationHandler().isPCRelative(Relocation.Type) &&
                  "GOT relocation must be PC-relative on RISC-V");
           Symbol = BC.registerNameAtAddress("__BOLT_got_zero", 0, 0, 0);
           Addend = Relocation.Value + Relocation.Offset + getAddress();
@@ -1876,7 +1878,7 @@ bool BinaryFunction::scanExternalRefs() {
       if (ignoreReference(Rel->Symbol))
         continue;
 
-      if (Relocation::getSizeForType(Rel->Type) < 4) {
+      if (BC.getRelocationHandler().getSizeForType(Rel->Type) < 4) {
         // If the instruction uses a short form, then we might not be able
         // to handle the rewrite without relaxation, and hence cannot reliably
         // create an external reference relocation.
@@ -2141,7 +2143,7 @@ bool BinaryFunction::validateInternalRefDataRelocations() {
       const Relocation *Relocation = BC.getRelocationAt(RelocationAddress);
       BC.errs() << "  ";
       if (Relocation)
-        BC.errs() << *Relocation;
+        Relocation->print(BC.errs(), BC.getRelocationHandler());
       else
         BC.errs() << "<missing relocation>";
       BC.errs() << '\n';
diff --git a/bolt/lib/Core/BinarySection.cpp b/bolt/lib/Core/BinarySection.cpp
index a8620ba83ebfb..e17a2bad4a47a 100644
--- a/bolt/lib/Core/BinarySection.cpp
+++ b/bolt/lib/Core/BinarySection.cpp
@@ -29,6 +29,14 @@ extern cl::opt<bool> PrintRelocations;
 
 uint64_t BinarySection::Count = 0;
 
+void BinarySection::addDynamicRelocation(const Relocation &Reloc) {
+  assert(Reloc.Offset < getSize() && "offset not within section bounds");
+  assert(
+      (!Reloc.isRELR() || BC.getRelocationHandler().isRelative(Reloc.Type)) &&
+      "Only relative relocations can be relr.");
+  DynamicRelocations.emplace(Reloc);
+}
+
 bool BinarySection::isELF() const { return BC.isELF(); }
 
 bool BinarySection::isMachO() const { return BC.isMachO(); }
@@ -60,7 +68,7 @@ BinarySection::hash(const BinaryData &BD,
         Hash, hash_value(Contents.substr(Offset, Begin->Offset - Offset)));
     if (BinaryData *RelBD = BC.getBinaryDataByName(Rel.Symbol->getName()))
       Hash = hash_combine(Hash, hash(*RelBD, Cache));
-    Offset = Rel.Offset + Rel.getSize();
+    Offset = Rel.Offset + Rel.getSize(BC.getRelocationHandler());
   }
 
   Hash = hash_combine(Hash,
@@ -129,11 +137,12 @@ void BinarySection::emitAsData(MCStreamer &Streamer,
                                          : StringRef("<none>"))
                    << " at offset 0x" << Twine::utohexstr(Relocation.Offset)
                    << " with size "
-                   << Relocation::getSizeForType(Relocation.Type) << '\n');
+                   << BC.getRelocationHandler().getSizeForType(Relocation.Type)
+                   << '\n');
       }
 #endif
 
-      size_t RelocationSize = Relocation::emit(ROI, ROE, &Streamer);
+      size_t RelocationSize = Relocation::emit(ROI, ROE, &Streamer, BC.getRelocationHandler());
       SectionOffset += RelocationSize;
     }
     assert(SectionOffset <= SectionContents.size() && "overflow error");
@@ -185,23 +194,24 @@ void BinarySection::flushPendingRelocations(raw_fd_ostream &OS,
 
     // Safely skip any optional pending relocation that cannot be encoded.
     if (Reloc.isOptional() &&
-        !Relocation::canEncodeValue(Reloc.Type, Value,
+        !BC.getRelocationHandler().canEncodeValue(
+            Reloc.Type, Value,
                                     SectionAddress + Reloc.Offset)) {
 
       ++SkippedPendingRelocations;
       continue;
     }
-    Value = Relocation::encodeValue(Reloc.Type, Value,
+    Value = BC.getRelocationHandler().encodeValue(
+        Reloc.Type, Value,
                                     SectionAddress + Reloc.Offset);
 
     safePWrite(OS, reinterpret_cast<const char *>(&Value),
-               Relocation::getSizeForType(Reloc.Type),
+               BC.getRelocationHandler().getSizeForType(Reloc.Type),
                SectionFileOffset + Reloc.Offset);
 
-    LLVM_DEBUG(
-        dbgs() << "BOLT-DEBUG: writing value 0x" << Twine::utohexstr(Value)
-               << " of size " << Relocation::getSizeForType(Reloc.Type)
-               << " at section offset 0x" << Twine::utohexstr(Reloc.Offset)
+    LLVM_DEBUG(dbgs() << "BOLT-DEBUG: writing value 0x" << Twine::utohexstr(Value)
+               << " of size " << BC.getRelocationHandler().getSizeForType(Reloc.Type)
+                      << " at section offset 0x" << Twine::utohexstr(Reloc.Offset)
                << " address 0x"
                << Twine::utohexstr(SectionAddress + Reloc.Offset)
                << " file offset 0x"
@@ -236,8 +246,10 @@ void BinarySection::print(raw_ostream &OS) const {
     OS << " (tls)";
 
   if (opts::PrintRelocations)
-    for (const Relocation &R : relocations())
-      OS << "\n  " << R;
+    for (const Relocation &R : relocations()) {
+      OS << "\n  ";
+      R.print(OS, BC.getRelocationHandler());
+    }
 }
 
 BinarySection::RelocationSetType
@@ -258,8 +270,13 @@ BinarySection::reorderRelocations(bool Inplace) const {
     uint64_t RelOffset = RelAddr - BD->getAddress();
     NewRel.Offset = BD->getOutputOffset() + RelOffset;
     assert(NewRel.Offset < getSize());
-    LLVM_DEBUG(dbgs() << "BOLT-DEBUG: moving " << Rel << " -> " << NewRel
-                      << "\n");
+    LLVM_DEBUG({
+      dbgs() << "BOLT-DEBUG: moving ";
+      Rel.print(dbgs(), BC.getRelocationHandler());
+      dbgs() << " -> ";
+      NewRel.print(dbgs(), BC.getRelocationHandler());
+      dbgs() << "\n";
+    });
     NewRelocations.emplace(std::move(NewRel));
   }
   return NewRelocations;
@@ -292,7 +309,8 @@ void BinarySection::reorderContents(const std::vector<BinaryData *> &Order,
     // of the reordered segment to force LLVM to recognize and map this
     // section.
     MCSymbol *ZeroSym = BC.registerNameAtAddress("Zero", 0, 0, 0);
-    addRelocation(OS.tell(), ZeroSym, Relocation::getAbs64(), 0xdeadbeef);
+    addRelocation(O...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/217926


More information about the llvm-commits mailing list