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
