https://github.com/redstar updated 
https://github.com/llvm/llvm-project/pull/167054

>From 1f9bfbbd5e893bcab320dc26c71e49779ef7d04d Mon Sep 17 00:00:00 2001
From: Kai Nacke <[email protected]>
Date: Fri, 7 Nov 2025 11:13:49 -0500
Subject: [PATCH 1/2] [GOFF] Write out relocations in the GOFF writer

Add support for writing relocations. Since the symbol numbering is only
available after the symbols are written, the relocations are collected
in a vector. At write time, the relocations are converted using the
symbols ids, compressed and written out. A relocation data record is
limited to 32K-1 bytes, which requires making sure that larger relocation
data is written into multiple records.
---
 llvm/include/llvm/BinaryFormat/GOFF.h         |  26 ++
 llvm/include/llvm/MC/MCGOFFObjectWriter.h     |  37 ++-
 llvm/lib/MC/GOFFObjectWriter.cpp              | 266 +++++++++++++++++-
 .../MCTargetDesc/SystemZGOFFObjectWriter.cpp  |  24 ++
 .../SystemZ/MCTargetDesc/SystemZMCAsmInfo.h   |   1 +
 llvm/test/CodeGen/SystemZ/zos-section-1.ll    |  23 +-
 llvm/test/CodeGen/SystemZ/zos-section-2.ll    |  16 +-
 7 files changed, 378 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h 
b/llvm/include/llvm/BinaryFormat/GOFF.h
index 49d2809cb6524..08bdb5d624fca 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -157,6 +157,32 @@ enum ESDAlignment : uint8_t {
   ESD_ALIGN_4Kpage = 12,
 };
 
+enum RLDReferenceType : uint8_t {
+  RLD_RT_RAddress = 0,
+  RLD_RT_ROffset = 1,
+  RLD_RT_RLength = 2,
+  RLD_RT_RRelativeImmediate = 6,
+  RLD_RT_RTypeConstant = 7,
+  RLD_RT_RLongDisplacement = 9,
+};
+
+enum RLDReferentType : uint8_t {
+  RLD_RO_Label = 0,
+  RLD_RO_Element = 1,
+  RLD_RO_Class = 2,
+  RLD_RO_Part = 3,
+};
+
+enum RLDAction : uint8_t {
+  RLD_ACT_Add = 0,
+  RLD_ACT_Subtract = 1,
+};
+
+enum RLDFetchStore : uint8_t {
+  RLD_FS_Fetch = 0,
+  RLD_FS_Store = 1
+};
+
 enum ENDEntryPointRequest : uint8_t {
   END_EPR_None = 0,
   END_EPR_EsdidOffset = 1,
diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h 
b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index ec07637dd2847..408d432a8f54f 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -11,9 +11,13 @@
 
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCValue.h"
+#include <memory>
+#include <vector>
 
 namespace llvm {
 class MCObjectWriter;
+class MCSectionGOFF;
+class MCSymbolGOFF;
 class raw_pwrite_stream;
 
 class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
@@ -21,8 +25,19 @@ class MCGOFFObjectTargetWriter : public MCObjectTargetWriter 
{
   MCGOFFObjectTargetWriter() = default;
 
 public:
+  enum RLDRelocationType {
+    Reloc_Type_ACon = 0x1,   // General address.
+    Reloc_Type_RelImm = 0x2, // Relative-immediate address.
+    Reloc_Type_QCon = 0x3,   // Offset of symbol in class.
+    Reloc_Type_VCon = 0x4,   // Address of external symbol.
+    Reloc_Type_RCon = 0x5,   // PSECT of symbol.
+  };
+
   ~MCGOFFObjectTargetWriter() override = default;
 
+  virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
+                                bool IsPCRel) const = 0;
+
   Triple::ObjectFormatType getFormat() const override { return Triple::GOFF; }
 
   static bool classof(const MCObjectTargetWriter *W) {
@@ -30,6 +45,23 @@ class MCGOFFObjectTargetWriter : public MCObjectTargetWriter 
{
   }
 };
 
+struct GOFFSavedRelocationEntry {
+  const MCSectionGOFF *Section;
+  const MCSymbolGOFF *SymA;
+  const MCSymbolGOFF *SymB;
+  unsigned RelocType;
+  uint64_t FixupOffset;
+  uint32_t Length;
+  uint64_t FixedValue; // Info only.
+
+  GOFFSavedRelocationEntry(const MCSectionGOFF *Section,
+                           const MCSymbolGOFF *SymA, const MCSymbolGOFF *SymB,
+                           unsigned RelocType, uint64_t FixupOffset,
+                           uint32_t Length, uint64_t FixedValue)
+      : Section(Section), SymA(SymA), SymB(SymB), RelocType(RelocType),
+        FixupOffset(FixupOffset), Length(Length), FixedValue(FixedValue) {}
+};
+
 class GOFFObjectWriter : public MCObjectWriter {
   // The target specific GOFF writer instance.
   std::unique_ptr<MCGOFFObjectTargetWriter> TargetObjectWriter;
@@ -37,6 +69,9 @@ class GOFFObjectWriter : public MCObjectWriter {
   // The stream used to write the GOFF records.
   raw_pwrite_stream &OS;
 
+  // Saved relocation data.
+  std::vector<GOFFSavedRelocationEntry> SavedRelocs;
+
 public:
   GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
                    raw_pwrite_stream &OS);
@@ -44,7 +79,7 @@ class GOFFObjectWriter : public MCObjectWriter {
 
   // Implementation of the MCObjectWriter interface.
   void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
-                        MCValue Target, uint64_t &FixedValue) override {}
+                        MCValue Target, uint64_t &FixedValue) override;
 
   uint64_t writeObject() override;
 };
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 07aecf13bce37..b4640ed7871f0 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -10,7 +10,9 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCGOFFAttributes.h"
 #include "llvm/MC/MCGOFFObjectWriter.h"
@@ -280,13 +282,42 @@ class GOFFSymbol {
   }
 };
 
+// A GOFFRelocationEntry describes a single relocation.
+struct GOFFRelocationEntry {
+  uint32_t REsdId;  // The R pointer.
+  uint32_t PEsdId;  // The P pointer.
+  uint64_t POffset; // The offset within the element described by the P 
pointer.
+
+  uint32_t TargetLength; // The byte length of the target field.
+
+  // Details of the relocation.
+  GOFF::RLDReferenceType ReferenceType : 4;
+  GOFF::RLDReferentType ReferentType : 2;
+  GOFF::RLDAction Action : 1;
+  GOFF::RLDFetchStore FetchStore : 1;
+
+  GOFFRelocationEntry() = default;
+  GOFFRelocationEntry(uint32_t REsdId, uint32_t PEsdId, uint64_t POffset,
+                      GOFF::RLDReferenceType ReferenceType,
+                      GOFF::RLDReferentType ReferentType,
+                      GOFF::RLDAction Action, GOFF::RLDFetchStore FetchStore,
+                      uint32_t TargetLength)
+      : REsdId(REsdId), PEsdId(PEsdId), POffset(POffset),
+        TargetLength(TargetLength), ReferenceType(ReferenceType),
+        ReferentType(ReferentType), Action(Action), FetchStore(FetchStore) {}
+};
+
 class GOFFWriter {
   GOFFOstream OS;
   MCAssembler &Asm;
 
+  /// Saved relocation data collected in recordRelocations().
+  const std::vector<GOFFSavedRelocationEntry> &SavedRelocs;
+
   void writeHeader();
   void writeSymbol(const GOFFSymbol &Symbol);
   void writeText(const MCSectionGOFF *MC);
+  void writeRelocations();
   void writeEnd();
 
   void defineSectionSymbols(const MCSectionGOFF &Section);
@@ -295,13 +326,15 @@ class GOFFWriter {
   void defineSymbols();
 
 public:
-  GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm);
+  GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
+             const std::vector<GOFFSavedRelocationEntry> &SavedRelocs);
   uint64_t writeObject();
 };
 } // namespace
 
-GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
-    : OS(OS), Asm(Asm) {}
+GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm,
+                       const std::vector<GOFFSavedRelocationEntry> 
&SavedRelocs)
+    : OS(OS), Asm(Asm), SavedRelocs(SavedRelocs) {}
 
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
   if (Section.isSD()) {
@@ -502,6 +535,169 @@ void GOFFWriter::writeText(const MCSectionGOFF *Section) {
   Asm.writeSectionData(S, Section);
 }
 
+namespace {
+// RelocDataItemBuffer provides a static buffer for relocation data items.
+class RelocDataItemBuffer {
+  char Buffer[GOFF::MaxDataLength];
+  char *Ptr;
+
+public:
+  RelocDataItemBuffer() : Ptr(Buffer) {}
+  const char *data() { return Buffer; }
+  size_t size() { return Ptr - Buffer; }
+  void reset() { Ptr = Buffer; }
+  bool fits(size_t S) { return size() + S < GOFF::MaxDataLength; }
+  template <typename T> void writebe(T Val) {
+    assert(fits(sizeof(T)) && "Out-of-bounds write");
+    support::endian::write<T, llvm::endianness::big>(Ptr, Val);
+    Ptr += sizeof(T);
+  }
+};
+} // namespace
+
+void GOFFWriter::writeRelocations() {
+  // Transform a GOFFSavedRelocationEntry to 1 or 2 GOFFRelocationEntry
+  // instances. An expression like SymA - SymB + Const is implemented by 
storing
+  // Const in the memory (aka the FixedValue), and then having a relocation to
+  // add SymA, and another relocation to subtract SymB.
+  std::vector<GOFFRelocationEntry> Relocations;
+  for (auto &RelocEntry : SavedRelocs) {
+    auto *PSection = RelocEntry.Section;
+    auto RelocType = RelocEntry.RelocType;
+    auto *A = RelocEntry.SymA;
+    auto *B = RelocEntry.SymB;
+    auto FixupOffset = RelocEntry.FixupOffset;
+    auto Length = RelocEntry.Length;
+
+    auto GetRptr = [](const MCSymbolGOFF *Sym) -> uint32_t {
+      if (Sym->isTemporary())
+        return static_cast<MCSectionGOFF &>(Sym->getSection())
+            .getBeginSymbol()
+            ->getIndex();
+      return Sym->getIndex();
+    };
+
+    const uint32_t Pptr = PSection->getOrdinal();
+    uint32_t RptrA = GetRptr(A);
+    uint32_t RptrB = B ? GetRptr(B) : 0;
+
+    // UseQCon causes class offsets versus absolute addresses to be used. This
+    // is analogous to using QCONs in older OBJ object file format.
+    bool UseQCon = RelocType == MCGOFFObjectTargetWriter::Reloc_Type_QCon;
+
+    GOFF::RLDFetchStore FetchStore =
+        (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon ||
+         RelocType == MCGOFFObjectTargetWriter::Reloc_Type_VCon)
+            ? GOFF::RLDFetchStore::RLD_FS_Store
+            : GOFF::RLDFetchStore::RLD_FS_Fetch;
+    assert(FetchStore == GOFF::RLDFetchStore::RLD_FS_Fetch ||
+           RptrB == 0 && "No dependent relocations expected");
+
+    enum GOFF::RLDReferenceType ReferenceType = GOFF::RLD_RT_RAddress;
+    enum GOFF::RLDReferentType ReferentType = GOFF::RLD_RO_Label;
+    if (UseQCon) {
+      ReferenceType = GOFF::RLD_RT_ROffset;
+      ReferentType = GOFF::RLD_RO_Class;
+    }
+    if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon)
+      ReferenceType = GOFF::RLD_RT_RTypeConstant;
+
+    if (RptrA) {
+      LLVM_DEBUG(dbgs() << "Reloc A: " << (UseQCon ? "QCon" : "ACon")
+                        << " Rptr: " << RptrA << " Pptr: " << Pptr
+                        << " Offset: " << FixupOffset
+                        << " Fixed Imm: " << RelocEntry.FixedValue << "\n");
+      Relocations.emplace_back(RptrA, Pptr, FixupOffset, ReferenceType,
+                               ReferentType, GOFF::RLD_ACT_Add, FetchStore,
+                               Length);
+    }
+    if (RptrB) {
+      LLVM_DEBUG(dbgs() << "Reloc B: " << (UseQCon ? "QCon" : "ACon")
+                        << " Rptr: " << RptrA << " Pptr: " << Pptr
+                        << " Offset: " << FixupOffset
+                        << " Fixed Imm: " << RelocEntry.FixedValue << "\n");
+      Relocations.emplace_back(RptrB, Pptr, FixupOffset, ReferenceType,
+                               ReferentType, GOFF::RLD_ACT_Subtract,
+                               GOFF::RLDFetchStore::RLD_FS_Fetch, Length);
+    }
+  }
+
+  // Sort relocation data items by the P pointer to save space.
+  std::sort(
+      Relocations.begin(), Relocations.end(),
+      [](const GOFFRelocationEntry &Left, const GOFFRelocationEntry &Right) {
+        return std::tie(Left.PEsdId, Left.REsdId, Left.POffset) <
+               std::tie(Right.PEsdId, Right.REsdId, Right.POffset);
+      });
+
+  // Construct the compressed relocation data items, and write them out.
+  RelocDataItemBuffer Buffer;
+  for (auto I = Relocations.begin(), E = Relocations.end(); I != E;) {
+    Buffer.reset();
+
+    uint32_t PrevResdId = -1;
+    uint32_t PrevPesdId = -1;
+    uint64_t PrevPOffset = -1;
+    for (; I != E; ++I) {
+      const GOFFRelocationEntry &Rel = *I;
+
+      bool SameREsdId = (Rel.REsdId == PrevResdId);
+      bool SamePEsdId = (Rel.PEsdId == PrevPesdId);
+      bool SamePOffset = (Rel.POffset == PrevPOffset);
+      bool EightByteOffset = ((Rel.POffset >> 32) & 0xffffffff);
+
+      // Calculate size of relocation data item, and check if it still fits 
into
+      // the record.
+      size_t ItemSize = 8; // Smallest size of a relocation data item.
+      if (!SameREsdId)
+        ItemSize += 4;
+      if (!SamePEsdId)
+        ItemSize += 4;
+      if (!SamePOffset)
+        ItemSize += (EightByteOffset ? 8 : 4);
+      if (!Buffer.fits(ItemSize))
+        break;
+
+      GOFF::Flags RelocFlags[6];
+      RelocFlags[0].set(0, 1, SameREsdId);
+      RelocFlags[0].set(1, 1, SamePEsdId);
+      RelocFlags[0].set(2, 1, SamePOffset);
+      RelocFlags[0].set(6, 1, EightByteOffset);
+
+      RelocFlags[1].set(0, 4, Rel.ReferenceType);
+      RelocFlags[1].set(4, 4, Rel.ReferentType);
+
+      RelocFlags[2].set(0, 7, Rel.Action);
+      RelocFlags[2].set(7, 1, Rel.FetchStore);
+
+      RelocFlags[4].set(0, 8, Rel.TargetLength);
+
+      for (auto F : RelocFlags)
+        Buffer.writebe<uint8_t>(F);
+      Buffer.writebe<uint16_t>(0); // Reserved.
+      if (!SameREsdId)
+        Buffer.writebe<uint32_t>(Rel.REsdId);
+      if (!SamePEsdId)
+        Buffer.writebe<uint32_t>(Rel.PEsdId);
+      if (!SamePOffset) {
+        if (EightByteOffset)
+          Buffer.writebe<uint64_t>(Rel.POffset);
+        else
+          Buffer.writebe<uint32_t>(Rel.POffset);
+      }
+
+      PrevResdId = Rel.REsdId;
+      PrevPesdId = Rel.PEsdId;
+      PrevPOffset = Rel.POffset;
+    }
+
+    OS.newRecord(GOFF::RT_RLD);
+    OS.writebe<uint8_t>(0);                 // Reserved.
+    OS.writebe<uint16_t>(Buffer.size());    // Length (of the relocation data).
+    OS.write(Buffer.data(), Buffer.size()); // Relocation Directory Data Items.
+  }
+}
+
 void GOFFWriter::writeEnd() {
   uint8_t F = GOFF::END_EPR_None;
   uint8_t AMODE = 0;
@@ -528,6 +724,8 @@ uint64_t GOFFWriter::writeObject() {
   for (const MCSection &Section : Asm)
     writeText(static_cast<const MCSectionGOFF *>(&Section));
 
+  writeRelocations();
+
   writeEnd();
 
   // Make sure all records are written.
@@ -545,8 +743,68 @@ GOFFObjectWriter::GOFFObjectWriter(
 
 GOFFObjectWriter::~GOFFObjectWriter() = default;
 
+void GOFFObjectWriter::recordRelocation(const MCFragment &F,
+                                        const MCFixup &Fixup, MCValue Target,
+                                        uint64_t &FixedValue) {
+  const MCFixupKindInfo &FKI =
+      Asm->getBackend().getFixupKindInfo(Fixup.getKind());
+  const uint32_t Length = FKI.TargetSize / 8;
+  assert(FKI.TargetSize % 8 == 0 && "Target Size not multiple of 8");
+  const uint64_t FixupOffset = Asm->getFragmentOffset(F) + Fixup.getOffset();
+  bool IsPCRel = Fixup.isPCRel();
+
+  unsigned RelocType = TargetObjectWriter->getRelocType(Target, Fixup, 
IsPCRel);
+
+  const MCSectionGOFF *PSection = static_cast<MCSectionGOFF *>(F.getParent());
+  const auto &A = *static_cast<const MCSymbolGOFF *>(Target.getAddSym());
+  const MCSymbolGOFF *B = static_cast<const MCSymbolGOFF 
*>(Target.getSubSym());
+  if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RelImm) {
+    if (A.isUndefined()) {
+      Asm->reportError(
+          Fixup.getLoc(),
+          Twine("symbol ")
+              .concat(A.getName())
+              .concat(" must be defined for a relative immediate relocation"));
+      return;
+    }
+    if (&A.getSection() != PSection) {
+      Asm->reportError(Fixup.getLoc(),
+                       Twine("relative immediate relocation section mismatch: 
")
+                           .concat(A.getSection().getName())
+                           .concat(" of symbol ")
+                           .concat(A.getName())
+                           .concat(" <-> ")
+                           .concat(PSection->getName()));
+      return;
+    }
+    if (B) {
+      Asm->reportError(
+          Fixup.getLoc(),
+          Twine("subtractive symbol ")
+              .concat(B->getName())
+              .concat(" not supported for a relative immediate relocation"));
+      return;
+    }
+    FixedValue = Asm->getSymbolOffset(A) - FixupOffset + Target.getConstant();
+    return;
+  }
+  FixedValue = Target.getConstant();
+
+  // The symbol only has a section-relative offset if it is a temporary symbol.
+  FixedValue += A.isTemporary() ? Asm->getSymbolOffset(A) : 0;
+  A.setUsedInReloc();
+  if (B) {
+    FixedValue -= B->isTemporary() ? Asm->getSymbolOffset(*B) : 0;
+    B->setUsedInReloc();
+  }
+
+  // Save relocation data for later writing.
+  SavedRelocs.emplace_back(PSection, &A, B, RelocType, FixupOffset, Length,
+                           FixedValue);
+}
+
 uint64_t GOFFObjectWriter::writeObject() {
-  uint64_t Size = GOFFWriter(OS, *Asm).writeObject();
+  uint64_t Size = GOFFWriter(OS, *Asm, SavedRelocs).writeObject();
   return Size;
 }
 
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp 
b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
index 205066814fbd0..8c042d1dbb014 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
@@ -7,6 +7,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/SystemZMCTargetDesc.h"
+#include "SystemZMCAsmInfo.h"
 #include "llvm/MC/MCGOFFObjectWriter.h"
 #include <memory>
 
@@ -16,12 +17,35 @@ namespace {
 class SystemZGOFFObjectWriter : public MCGOFFObjectTargetWriter {
 public:
   SystemZGOFFObjectWriter();
+
+  unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
+                        bool IsPCRel) const override;
 };
 } // end anonymous namespace
 
 SystemZGOFFObjectWriter::SystemZGOFFObjectWriter()
     : MCGOFFObjectTargetWriter() {}
 
+unsigned SystemZGOFFObjectWriter::getRelocType(const MCValue &Target,
+                                               const MCFixup &Fixup,
+                                               bool IsPCRel) const {
+  switch (Target.getSpecifier()) {
+  case SystemZ::S_PLT:  // TODO This doen't make sense.
+    return Reloc_Type_RelImm;
+  case SystemZ::S_RCon:
+    return Reloc_Type_RCon;
+  case SystemZ::S_VCon:
+    return Reloc_Type_VCon;
+  case SystemZ::S_QCon:
+    return Reloc_Type_QCon;
+  case SystemZ::S_None:
+    if (IsPCRel)
+      return Reloc_Type_RelImm;
+    return Reloc_Type_ACon;
+  }
+  llvm_unreachable("Modifier not supported");
+}
+
 std::unique_ptr<MCObjectTargetWriter> llvm::createSystemZGOFFObjectWriter() {
   return std::make_unique<SystemZGOFFObjectWriter>();
 }
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h 
b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
index 11c2833b8ada8..668158b896856 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.h
@@ -51,6 +51,7 @@ enum {
   // https://www.ibm.com/docs/en/hla-and-tf/1.6?topic=value-address-constants
   S_RCon, // Address of ADA of symbol.
   S_VCon, // Address of external function symbol.
+  S_QCon, // Class-based offset.
 };
 } // namespace SystemZ
 
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll 
b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index cae371b07d0eb..f4e245addc2c3 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -145,9 +145,22 @@ entry:
 ; CHECK:      000550 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
 
+; The relocation data directory.
+; CHECK:      0005a0 03 21 00 00 00 5c 00 00 02 00 04 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 08 00 00 00 02 00 00 00 5a 60 00 00 00 04 00
+; CHECK-NEXT: 0005c0 00 00 00 00 00 09 00 00 00 00 08 00 00 00 00 00
+; CHECK-NEXT: 0005d0 00 08 00 00 00 04 00 00 00 00 60 00 02 00 08 00
+; CHECK-NEXT: 0005e0 00 00 00 00 00 09 20 70 01 00 08 00 00 00 00 00
+; Continuation of the relocation data directory.
+; CHECK-NEXT: 0005f0 03 22 00 00 0b 00 00 00 06 c0 00 01 00 08 00 00
+; CHECK-NEXT: 000600 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
 ; End record.
-; CHECK:      0005a0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK:      000640 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll 
b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index f59bace65ca73..d3eb6d9505340 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -175,9 +175,15 @@ source_filename = "test.ll"
 ; CHECK:      000640 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 000650 00 00 00 00 00 00 00 {{..}} {{.*}}
 
+; The relocation data directory
+; CHECK:      000690 03 20 00 00 00 40 00 00 02 00 04 00 00 00 00 00
+; CHECK-NEXT: 0006a0 00 0e 00 00 00 02 00 00 00 04 60 00 00 00 04 00
+; CHECK-NEXT: 0006b0 00 00 00 00 00 0f 00 00 00 00 08 00 00 00 00 00
+; CHECK-NEXT: 0006c0 00 0e 00 00 00 04 00 00 00 00 60 00 02 00 08 00
+; CHECK-NEXT: 0006d0 00 00 00 00 00 0f 00 00 00 00 00 00 00 00 00 00
+
 ; End record.
-; CHECK:      000690 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0006d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK:      0006e0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000700 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

>From 32fc1b7d949408bcd4717f7a033e9f40dd005820 Mon Sep 17 00:00:00 2001
From: Kai Nacke <[email protected]>
Date: Mon, 17 Nov 2025 11:16:45 -0500
Subject: [PATCH 2/2] Remove `IsPCRel` parameter

Information can be retrieved from `Fixup`.
---
 llvm/include/llvm/MC/MCGOFFObjectWriter.h             |  4 ++--
 llvm/lib/MC/GOFFObjectWriter.cpp                      |  3 +--
 .../SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp  | 11 +++++------
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFObjectWriter.h 
b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index 408d432a8f54f..e8a81fc61330a 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -35,8 +35,8 @@ class MCGOFFObjectTargetWriter : public MCObjectTargetWriter {
 
   ~MCGOFFObjectTargetWriter() override = default;
 
-  virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
-                                bool IsPCRel) const = 0;
+  virtual unsigned getRelocType(const MCValue &Target,
+                                const MCFixup &Fixup) const = 0;
 
   Triple::ObjectFormatType getFormat() const override { return Triple::GOFF; }
 
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index b4640ed7871f0..6b9543fdc1a62 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -751,9 +751,8 @@ void GOFFObjectWriter::recordRelocation(const MCFragment &F,
   const uint32_t Length = FKI.TargetSize / 8;
   assert(FKI.TargetSize % 8 == 0 && "Target Size not multiple of 8");
   const uint64_t FixupOffset = Asm->getFragmentOffset(F) + Fixup.getOffset();
-  bool IsPCRel = Fixup.isPCRel();
 
-  unsigned RelocType = TargetObjectWriter->getRelocType(Target, Fixup, 
IsPCRel);
+  unsigned RelocType = TargetObjectWriter->getRelocType(Target, Fixup);
 
   const MCSectionGOFF *PSection = static_cast<MCSectionGOFF *>(F.getParent());
   const auto &A = *static_cast<const MCSymbolGOFF *>(Target.getAddSym());
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp 
b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
index 8c042d1dbb014..cfbdd5d4780ab 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGOFFObjectWriter.cpp
@@ -18,8 +18,8 @@ class SystemZGOFFObjectWriter : public 
MCGOFFObjectTargetWriter {
 public:
   SystemZGOFFObjectWriter();
 
-  unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
-                        bool IsPCRel) const override;
+  unsigned getRelocType(const MCValue &Target,
+                        const MCFixup &Fixup) const override;
 };
 } // end anonymous namespace
 
@@ -27,10 +27,9 @@ SystemZGOFFObjectWriter::SystemZGOFFObjectWriter()
     : MCGOFFObjectTargetWriter() {}
 
 unsigned SystemZGOFFObjectWriter::getRelocType(const MCValue &Target,
-                                               const MCFixup &Fixup,
-                                               bool IsPCRel) const {
+                                               const MCFixup &Fixup) const {
   switch (Target.getSpecifier()) {
-  case SystemZ::S_PLT:  // TODO This doen't make sense.
+  case SystemZ::S_PLT: // TODO This doen't make sense.
     return Reloc_Type_RelImm;
   case SystemZ::S_RCon:
     return Reloc_Type_RCon;
@@ -39,7 +38,7 @@ unsigned SystemZGOFFObjectWriter::getRelocType(const MCValue 
&Target,
   case SystemZ::S_QCon:
     return Reloc_Type_QCon;
   case SystemZ::S_None:
-    if (IsPCRel)
+    if (Fixup.isPCRel())
       return Reloc_Type_RelImm;
     return Reloc_Type_ACon;
   }

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to