[llvm-branch-commits] [llvm] [GOFF] Add writing of text records (PR #137235)

Kai Nacke via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue May 6 12:06:58 PDT 2025


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

>From c9b5b19f6f6cb74f0aaf5eac950158342d3a3ada Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 9 Apr 2025 15:08:52 -0400
Subject: [PATCH 1/4] [GOFF] Add writing of text records

Sections which are not allowed to carry data are marked as virtual.
Only complication when writing out the text is that it must be
written in chunks of 32k-1 bytes, which is done by having a wrapper
stream writing those records.
Data of BSS sections is not written, since the contents is known to
be zero. Instead, the fill byte value is used.
---
 llvm/include/llvm/MC/MCContext.h              |  6 +-
 llvm/include/llvm/MC/MCSectionGOFF.h          | 47 +++++++----
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  |  5 +-
 llvm/lib/MC/GOFFObjectWriter.cpp              | 78 +++++++++++++++++++
 llvm/lib/MC/MCContext.cpp                     | 19 +++--
 llvm/lib/MC/MCObjectFileInfo.cpp              |  9 +--
 llvm/test/CodeGen/SystemZ/zos-section-1.ll    | 27 +++++--
 llvm/test/CodeGen/SystemZ/zos-section-2.ll    | 30 +++++--
 8 files changed, 180 insertions(+), 41 deletions(-)

diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 8eb904966f4de..2cdba64be116d 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -366,7 +366,8 @@ class MCContext {
 
   template <typename TAttr>
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
-                                TAttr SDAttributes, MCSection *Parent);
+                                TAttr SDAttributes, MCSection *Parent,
+                                bool IsVirtual);
 
   /// Map of currently defined macros.
   StringMap<MCAsmMacro> MacroMap;
@@ -607,7 +608,8 @@ class MCContext {
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
                                 GOFF::SDAttr SDAttributes);
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
-                                GOFF::EDAttr EDAttributes, MCSection *Parent);
+                                GOFF::EDAttr EDAttributes, MCSection *Parent,
+                                bool IsVirtual);
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
                                 GOFF::PRAttr PRAttributes, MCSection *Parent);
 
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index b8b8cf112a34d..b2ca74c3ba78a 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -39,6 +39,9 @@ class MCSectionGOFF final : public MCSection {
   // The type of this section.
   GOFF::ESDSymbolType SymbolType;
 
+  // This section is a BSS section.
+  unsigned IsBSS : 1;
+
   // Indicates that the PR symbol needs to set the length of the section to a
   // non-zero value. This is only a problem with the ADA PR - the binder will
   // generate an error in this case.
@@ -50,26 +53,26 @@ class MCSectionGOFF final : public MCSection {
   friend class MCContext;
   friend class MCSymbolGOFF;
 
-  MCSectionGOFF(StringRef Name, SectionKind K, GOFF::SDAttr SDAttributes,
-                MCSectionGOFF *Parent)
-      : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
+  MCSectionGOFF(StringRef Name, SectionKind K, bool IsVirtual,
+                GOFF::SDAttr SDAttributes, MCSectionGOFF *Parent)
+      : MCSection(SV_GOFF, Name, K.isText(), IsVirtual, nullptr),
         Parent(Parent), SDAttributes(SDAttributes),
-        SymbolType(GOFF::ESD_ST_SectionDefinition), RequiresNonZeroLength(0),
-        Emitted(0) {}
+        SymbolType(GOFF::ESD_ST_SectionDefinition), IsBSS(K.isBSS()),
+        RequiresNonZeroLength(0), Emitted(0) {}
 
-  MCSectionGOFF(StringRef Name, SectionKind K, GOFF::EDAttr EDAttributes,
-                MCSectionGOFF *Parent)
-      : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
+  MCSectionGOFF(StringRef Name, SectionKind K, bool IsVirtual,
+                GOFF::EDAttr EDAttributes, MCSectionGOFF *Parent)
+      : MCSection(SV_GOFF, Name, K.isText(), IsVirtual, nullptr),
         Parent(Parent), EDAttributes(EDAttributes),
-        SymbolType(GOFF::ESD_ST_ElementDefinition), RequiresNonZeroLength(0),
-        Emitted(0) {}
+        SymbolType(GOFF::ESD_ST_ElementDefinition), IsBSS(K.isBSS()),
+        RequiresNonZeroLength(0), Emitted(0) {}
 
-  MCSectionGOFF(StringRef Name, SectionKind K, GOFF::PRAttr PRAttributes,
-                MCSectionGOFF *Parent)
-      : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
+  MCSectionGOFF(StringRef Name, SectionKind K, bool IsVirtual,
+                GOFF::PRAttr PRAttributes, MCSectionGOFF *Parent)
+      : MCSection(SV_GOFF, Name, K.isText(), IsVirtual, nullptr),
         Parent(Parent), PRAttributes(PRAttributes),
-        SymbolType(GOFF::ESD_ST_PartReference), RequiresNonZeroLength(0),
-        Emitted(0) {}
+        SymbolType(GOFF::ESD_ST_PartReference), IsBSS(K.isBSS()),
+        RequiresNonZeroLength(0), Emitted(0) {}
 
 public:
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
@@ -81,6 +84,9 @@ class MCSectionGOFF final : public MCSection {
   // Return the parent section.
   MCSectionGOFF *getParent() const { return Parent; }
 
+  // Returns true if this is a BSS section.
+  bool isBSS() const { return IsBSS; }
+
   // Returns the type of this section.
   GOFF::ESDSymbolType getSymbolType() const { return SymbolType; }
 
@@ -102,6 +108,17 @@ class MCSectionGOFF final : public MCSection {
     return PRAttributes;
   }
 
+  // Returns the text style for a section. Only defined for ED and PR sections.
+  GOFF::ESDTextStyle getTextStyle() const {
+    assert(isED() || isPR() || isVirtualSection() && "Expect ED or PR section");
+    if (isED())
+      return EDAttributes.TextStyle;
+    if (isPR())
+      return getParent()->getEDAttributes().TextStyle;
+    // Virtual sections have no data, so byte orientation is fine.
+    return GOFF::ESD_TS_ByteOriented;
+  }
+
   bool requiresNonZeroLength() const { return RequiresNonZeroLength; }
 
   void setName(StringRef SectionName) { Name = SectionName; }
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index cd4f1dd93077e..888039aad274c 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2801,7 +2801,8 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Fullword,
                    0},
-      static_cast<MCSectionGOFF *>(TextSection)->getParent());
+      static_cast<MCSectionGOFF *>(TextSection)->getParent(),
+      /*IsVirtual=*/true);
   return getContext().getGOFFSection(SectionKind::getData(), Name,
                                      GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,
                                                   GOFF::LINKAGE,
@@ -2833,7 +2834,7 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
         GOFF::EDAttr{false, GOFF::RMODE, GOFF::ESD_NS_Parts,
                      GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                      GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align, 0},
-        SD);
+        SD, /*IsVirtual=*/true);
     return getContext().getGOFFSection(Kind, Symbol->getName(),
                                        GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
                                                     GOFF::LINKAGE,
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index c4bd836e4976a..b1a36a1c4dbf1 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -275,6 +275,7 @@ class GOFFWriter {
 
   void writeHeader();
   void writeSymbol(const GOFFSymbol &Symbol);
+  void writeText(const MCSectionGOFF *MC);
   void writeEnd();
 
   void defineSectionSymbols(const MCSectionGOFF &Section);
@@ -405,6 +406,80 @@ void GOFFWriter::writeSymbol(const GOFFSymbol &Symbol) {
   OS.write(Name.data(), NameLength); // Name
 }
 
+namespace {
+/// Adapter stream to write a text section.
+class TextStream : public raw_ostream {
+  /// The underlying GOFFOstream.
+  GOFFOstream &OS;
+
+  /// The buffer size is the maximum number of bytes in a TXT section.
+  static constexpr size_t BufferSize = GOFF::MaxDataLength;
+
+  /// Static allocated buffer for the stream, used by the raw_ostream class. The
+  /// buffer is sized to hold the payload of a logical TXT record.
+  char Buffer[BufferSize];
+
+  /// The offset for the next TXT record. This is equal to the number of bytes
+  /// written.
+  size_t Offset;
+
+  /// The Esdid of the GOFF section.
+  const uint32_t EsdId;
+
+  /// The record style.
+  const GOFF::ESDTextStyle RecordStyle;
+
+  /// See raw_ostream::write_impl.
+  void write_impl(const char *Ptr, size_t Size) override;
+
+  uint64_t current_pos() const override { return Offset; }
+
+public:
+  explicit TextStream(GOFFOstream &OS, uint32_t EsdId,
+                      GOFF::ESDTextStyle RecordStyle)
+      : OS(OS), Offset(0), EsdId(EsdId), RecordStyle(RecordStyle) {
+    SetBuffer(Buffer, sizeof(Buffer));
+  }
+
+  ~TextStream() { flush(); }
+};
+
+void TextStream::write_impl(const char *Ptr, size_t Size) {
+  size_t WrittenLength = 0;
+
+  // We only have signed 32bits of offset.
+  if (Offset + Size > std::numeric_limits<int32_t>::max())
+    report_fatal_error("TXT section too large");
+
+  while (WrittenLength < Size) {
+    size_t ToWriteLength =
+        std::min(Size - WrittenLength, size_t(GOFF::MaxDataLength));
+
+    OS.newRecord(GOFF::RT_TXT);
+    OS.writebe<uint8_t>(GOFF::Flags(4, 4, RecordStyle)); // Text Record Style
+    OS.writebe<uint32_t>(EsdId);                         // Element ESDID
+    OS.writebe<uint32_t>(0);                             // Reserved
+    OS.writebe<uint32_t>(static_cast<uint32_t>(Offset)); // Offset
+    OS.writebe<uint32_t>(0);                      // Text Field True Length
+    OS.writebe<uint16_t>(0);                      // Text Encoding
+    OS.writebe<uint16_t>(ToWriteLength);          // Data Length
+    OS.write(Ptr + WrittenLength, ToWriteLength); // Data
+
+    WrittenLength += ToWriteLength;
+    Offset += ToWriteLength;
+  }
+}
+} // namespace
+
+void GOFFWriter::writeText(const MCSectionGOFF *Section) {
+  // A BSS section contains only zeros, no need to write this.
+  if (Section->isBSS())
+    return;
+
+  TextStream S(OS, Section->getOrdinal(), Section->getTextStyle());
+  Asm.writeSectionData(S, Section);
+}
+
 void GOFFWriter::writeEnd() {
   uint8_t F = GOFF::END_EPR_None;
   uint8_t AMODE = 0;
@@ -428,6 +503,9 @@ uint64_t GOFFWriter::writeObject() {
 
   defineSymbols();
 
+  for (const MCSection &Section : Asm)
+    writeText(static_cast<const MCSectionGOFF*>(&Section));
+
   writeEnd();
 
   // Make sure all records are written.
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index c00a870051c49..e431a2e8a1a54 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -674,7 +674,8 @@ MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
 
 template <typename TAttr>
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
-                                         TAttr Attributes, MCSection *Parent) {
+                                         TAttr Attributes, MCSection *Parent,
+                                         bool IsVirtual) {
   std::string UniqueName(Name);
   if (Parent) {
     UniqueName.append("/").append(Parent->getName());
@@ -688,8 +689,9 @@ MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
     return Iter->second;
 
   StringRef CachedName = StringRef(Iter->first.c_str(), Name.size());
-  MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate()) MCSectionGOFF(
-      CachedName, Kind, Attributes, static_cast<MCSectionGOFF *>(Parent));
+  MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate())
+      MCSectionGOFF(CachedName, Kind, IsVirtual, Attributes,
+                    static_cast<MCSectionGOFF *>(Parent));
   Iter->second = GOFFSection;
   allocInitialFragment(*GOFFSection);
   return GOFFSection;
@@ -697,19 +699,22 @@ MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::SDAttr SDAttributes) {
-  return getGOFFSection<GOFF::SDAttr>(Kind, Name, SDAttributes, nullptr);
+  return getGOFFSection<GOFF::SDAttr>(Kind, Name, SDAttributes, nullptr,
+                                      /*IsVirtual=*/true);
 }
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::EDAttr EDAttributes,
-                                         MCSection *Parent) {
-  return getGOFFSection<GOFF::EDAttr>(Kind, Name, EDAttributes, Parent);
+                                         MCSection *Parent, bool IsVirtual) {
+  return getGOFFSection<GOFF::EDAttr>(Kind, Name, EDAttributes, Parent,
+                                      IsVirtual);
 }
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::PRAttr PRAttributes,
                                          MCSection *Parent) {
-  return getGOFFSection<GOFF::PRAttr>(Kind, Name, PRAttributes, Parent);
+  return getGOFFSection<GOFF::PRAttr>(Kind, Name, PRAttributes, Parent,
+                                      /*IsVirtual=*/false);
 }
 
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 9d969b2db91a7..0fd40700e37ce 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -557,7 +557,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
                    GOFF::ESD_ALIGN_Quadword, 0},
-      RootSDSection);
+      RootSDSection, /*IsVirtual=*/true);
   ADASection = Ctx->getGOFFSection(SectionKind::getData(), "#S",
                                    GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
                                                 GOFF::ESD_LT_XPLink,
@@ -570,15 +570,14 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate,
                    GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword, 0},
-      RootSDSection);
-
+      RootSDSection, /*IsVirtual=*/false);
   MCSectionGOFF *PPA2ListEDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_PPA2,
       GOFF::EDAttr{true, GOFF::RMODE, GOFF::ESD_NS_Parts,
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword, 0},
-      RootSDSection);
+      RootSDSection, /*IsVirtual=*/true);
   PPA2ListSection = Ctx->getGOFFSection(SectionKind::getData(), ".&ppa2",
                                         GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,
                                                      GOFF::ESD_LT_OS,
@@ -591,7 +590,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate,
                    GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword, 0},
-      RootSDSection);
+      RootSDSection, /*IsVirtual=*/false);
 }
 
 void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index ea9bc4ce95174..e88ec34441130 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -104,9 +104,26 @@ entry:
 ; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
 ; CHECK-NEXT: 000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
+; Text record for the code section C_CODE64.
+; The regular expression matches the lower byte of the length.
+; CHECK-NEXT: 0000320 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000330 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
+
+; Text record for the section .&ppa2.
+; CHECK:      00003c0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00003d0 00 00 00 00 00 00 00 {{..}} {{.*}}
+
+; Text record for the ADA section test#S.
+; CHECK:      0000410 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000420 00 00 00 00 00 00 00 {{..}} {{.*}}
+
+; Text record for the section B_IDRL.
+; CHECK:      0000460 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000470 00 00 00 00 00 00 00 {{..}} {{.*}}
+
 ; End record.
-; CHECK-NEXT: 000320 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK:      0004b0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004f0 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 472517acc4a45..68258eeed2c5c 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -147,9 +147,29 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
 ; CHECK-NEXT: 0004f0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
+; Text record for the code section C_CODE64.
+; The regular expression matches the lower byte of the length.
+; CHECK-NEXT: 0000500 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000510 00 00 00 00 00 00 00 {{..}} {{.*}}
+
+; Text record for the section .&ppa2.
+; CHECK:      0000550 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000560 00 00 00 00 00 00 00 {{..}} {{.*}}
+
+; Text record for the section data.
+; Length is 4, and the content is 0x2a = 42.
+; CHECK:      00005a0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00005b0 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
+
+; There is no text record for section bss!
+
+; Text record for the section B_IDRL.
+; CHECK:      00005f0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000600 00 00 00 00 00 00 00 {{..}} {{.*}}
+
 ; End record.
-; CHECK-NEXT: 000500 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000540 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

>From 37f7a1e49dbc56d73f70f1853f87b436f11a9cc7 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Thu, 24 Apr 2025 16:06:33 -0400
Subject: [PATCH 2/4] Fix formatting & move method out of anonymous namespace

---
 llvm/lib/MC/GOFFObjectWriter.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index b1a36a1c4dbf1..214533b99688e 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -443,6 +443,7 @@ class TextStream : public raw_ostream {
 
   ~TextStream() { flush(); }
 };
+} // namespace
 
 void TextStream::write_impl(const char *Ptr, size_t Size) {
   size_t WrittenLength = 0;
@@ -469,7 +470,6 @@ void TextStream::write_impl(const char *Ptr, size_t Size) {
     Offset += ToWriteLength;
   }
 }
-} // namespace
 
 void GOFFWriter::writeText(const MCSectionGOFF *Section) {
   // A BSS section contains only zeros, no need to write this.
@@ -504,7 +504,7 @@ uint64_t GOFFWriter::writeObject() {
   defineSymbols();
 
   for (const MCSection &Section : Asm)
-    writeText(static_cast<const MCSectionGOFF*>(&Section));
+    writeText(static_cast<const MCSectionGOFF *>(&Section));
 
   writeEnd();
 

>From a5e31c165725d3bc90e8b5934a02ecf100ea0a98 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 30 Apr 2025 10:28:48 -0400
Subject: [PATCH 3/4] Fix test cases

---
 llvm/test/CodeGen/SystemZ/zos-section-1.ll | 12 ++++++------
 llvm/test/CodeGen/SystemZ/zos-section-2.ll | 16 ++++++++--------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index e88ec34441130..05c0a0eb6bd50 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -110,16 +110,16 @@ entry:
 ; CHECK-NEXT: 0000330 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
 
 ; Text record for the section .&ppa2.
-; CHECK:      00003c0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 00003d0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      0003c0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the ADA section test#S.
-; CHECK:      0000410 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000420 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000410 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section B_IDRL.
-; CHECK:      0000460 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000470 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000460 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; End record.
 ; CHECK:      0004b0 03 40 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 68258eeed2c5c..0f608c1206b96 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -149,23 +149,23 @@ source_filename = "test.ll"
 
 ; Text record for the code section C_CODE64.
 ; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 0000500 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000510 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK-NEXT: 000500 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section .&ppa2.
-; CHECK:      0000550 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000560 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      000550 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; Text record for the section data.
 ; Length is 4, and the content is 0x2a = 42.
-; CHECK:      00005a0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 00005b0 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
+; CHECK:      0005a0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
 
 ; There is no text record for section bss!
 
 ; Text record for the section B_IDRL.
-; CHECK:      00005f0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000600 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK:      0005f0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000600 00 00 00 00 00 00 00 {{..}} {{.*}}
 
 ; End record.
 ; CHECK:      000640 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00

>From 94f7af1992c1f02e7998e604e6096ed967fed79f Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 6 May 2025 15:05:58 -0400
Subject: [PATCH 4/4] Derive IsVirtual from the given attributes

---
 llvm/include/llvm/MC/MCContext.h                  | 3 +--
 llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 5 ++---
 llvm/lib/MC/MCContext.cpp                         | 7 ++++---
 llvm/lib/MC/MCObjectFileInfo.cpp                  | 8 ++++----
 4 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 2cdba64be116d..790598dc54e61 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -608,8 +608,7 @@ class MCContext {
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
                                 GOFF::SDAttr SDAttributes);
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
-                                GOFF::EDAttr EDAttributes, MCSection *Parent,
-                                bool IsVirtual);
+                                GOFF::EDAttr EDAttributes, MCSection *Parent);
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
                                 GOFF::PRAttr PRAttributes, MCSection *Parent);
 
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 888039aad274c..cd4f1dd93077e 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2801,8 +2801,7 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Fullword,
                    0},
-      static_cast<MCSectionGOFF *>(TextSection)->getParent(),
-      /*IsVirtual=*/true);
+      static_cast<MCSectionGOFF *>(TextSection)->getParent());
   return getContext().getGOFFSection(SectionKind::getData(), Name,
                                      GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,
                                                   GOFF::LINKAGE,
@@ -2834,7 +2833,7 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
         GOFF::EDAttr{false, GOFF::RMODE, GOFF::ESD_NS_Parts,
                      GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                      GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align, 0},
-        SD, /*IsVirtual=*/true);
+        SD);
     return getContext().getGOFFSection(Kind, Symbol->getName(),
                                        GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
                                                     GOFF::LINKAGE,
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index e431a2e8a1a54..cfe69b299062f 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -705,9 +705,10 @@ MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::EDAttr EDAttributes,
-                                         MCSection *Parent, bool IsVirtual) {
-  return getGOFFSection<GOFF::EDAttr>(Kind, Name, EDAttributes, Parent,
-                                      IsVirtual);
+                                         MCSection *Parent) {
+  return getGOFFSection<GOFF::EDAttr>(
+      Kind, Name, EDAttributes, Parent,
+      /*IsVirtual=*/EDAttributes.BindAlgorithm == GOFF::ESD_BA_Merge);
 }
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 0fd40700e37ce..584857b095572 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -557,7 +557,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
                    GOFF::ESD_ALIGN_Quadword, 0},
-      RootSDSection, /*IsVirtual=*/true);
+      RootSDSection);
   ADASection = Ctx->getGOFFSection(SectionKind::getData(), "#S",
                                    GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
                                                 GOFF::ESD_LT_XPLink,
@@ -570,14 +570,14 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate,
                    GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword, 0},
-      RootSDSection, /*IsVirtual=*/false);
+      RootSDSection);
   MCSectionGOFF *PPA2ListEDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_PPA2,
       GOFF::EDAttr{true, GOFF::RMODE, GOFF::ESD_NS_Parts,
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword, 0},
-      RootSDSection, /*IsVirtual=*/true);
+      RootSDSection);
   PPA2ListSection = Ctx->getGOFFSection(SectionKind::getData(), ".&ppa2",
                                         GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,
                                                      GOFF::ESD_LT_OS,
@@ -590,7 +590,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate,
                    GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword, 0},
-      RootSDSection, /*IsVirtual=*/false);
+      RootSDSection);
 }
 
 void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {



More information about the llvm-branch-commits mailing list