[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)

Kai Nacke via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu May 1 07:13:35 PDT 2025


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

>From 77c230f82a61769714bee98b2e848820850d9cb5 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 24 Mar 2025 16:26:19 -0400
Subject: [PATCH 01/35] [GOFF] Add writing of section symbols

The GOFF format uses symbol definitions to represent sections and
symbols. Introducing a section can require up to 3 symbol definitions.
However, most of these details are not needed by the AsmPrinter.
To mapped from a section (a MCSectionGOFF) to the symbol definitions,
a new class called MCGOFFSymbolMapper is used. The same information
can also be used by the assembly output, which justifies this
centralized approach. Writing the mapped symbols is then straight
forward.
---
 llvm/include/llvm/BinaryFormat/GOFF.h     |  85 +++++++
 llvm/include/llvm/MC/MCGOFFSymbolMapper.h | 148 +++++++++++
 llvm/lib/MC/CMakeLists.txt                |   1 +
 llvm/lib/MC/GOFFObjectWriter.cpp          | 290 +++++++++++++++++++---
 llvm/lib/MC/MCGOFFSymbolMapper.cpp        | 203 +++++++++++++++
 llvm/lib/MC/MCObjectFileInfo.cpp          |   2 +-
 llvm/test/CodeGen/SystemZ/zos-ppa2.ll     |   2 +-
 llvm/test/MC/GOFF/section.ll              |  73 ++++++
 8 files changed, 765 insertions(+), 39 deletions(-)
 create mode 100644 llvm/include/llvm/MC/MCGOFFSymbolMapper.h
 create mode 100644 llvm/lib/MC/MCGOFFSymbolMapper.cpp
 create mode 100644 llvm/test/MC/GOFF/section.ll

diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index 443bcfc9479a8..43d80e0c247e9 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -169,6 +169,91 @@ enum SubsectionKind : uint8_t {
   SK_PPA1 = 2,
   SK_PPA2 = 4,
 };
+
+// The standard System/390 convention is to name the high-order (leftmost) bit
+// in a byte as bit zero. The Flags type helps to set bits in byte according
+// to this numeration order.
+class Flags {
+  uint8_t Val;
+
+  constexpr static uint8_t bits(uint8_t BitIndex, uint8_t Length, uint8_t Value,
+                                uint8_t OldValue) {
+    uint8_t Pos = 8 - BitIndex - Length;
+    uint8_t Mask = ((1 << Length) - 1) << Pos;
+    Value = Value << Pos;
+    return (OldValue & ~Mask) | Value;
+  }
+
+public:
+  constexpr Flags() : Val(0) {}
+  constexpr Flags(uint8_t BitIndex, uint8_t Length, uint8_t Value)
+      : Val(bits(BitIndex, Length, Value, 0)) {}
+
+  template <typename T>
+  constexpr void set(uint8_t BitIndex, uint8_t Length, T NewValue) {
+    Val = bits(BitIndex, Length, static_cast<uint8_t>(NewValue), Val);
+  }
+
+  template <typename T>
+  constexpr T get(uint8_t BitIndex, uint8_t Length) const {
+    return static_cast<T>((Val >> (8 - BitIndex - Length)) &
+                          ((1 << Length) - 1));
+  }
+
+  constexpr operator uint8_t() const { return Val; }
+};
+
+// Structure for the flag field of a symbol. See
+// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record,
+// offset 41, for the definition.
+struct SymbolFlags {
+  Flags SymFlags;
+
+#define GOFF_SYMBOL_FLAG(NAME, TYPE, BITINDEX, LENGTH)                         \
+  void set##NAME(TYPE Val) { SymFlags.set<TYPE>(BITINDEX, LENGTH, Val); }      \
+  TYPE get##NAME() const { return SymFlags.get<TYPE>(BITINDEX, LENGTH); }
+
+  GOFF_SYMBOL_FLAG(FillBytePresence, bool, 0, 1)
+  GOFF_SYMBOL_FLAG(Mangled, bool, 1, 1)
+  GOFF_SYMBOL_FLAG(Renameable, bool, 2, 1)
+  GOFF_SYMBOL_FLAG(RemovableClass, bool, 3, 1)
+  GOFF_SYMBOL_FLAG(ReservedQwords, ESDReserveQwords, 5, 3)
+
+#undef GOFF_SYMBOL_FLAG
+
+constexpr operator uint8_t() const { return static_cast<uint8_t>(SymFlags); }
+};
+
+// Structure for the behavioral attributes. See
+// https://www.ibm.com/docs/en/zos/3.1.0?topic=record-external-symbol-definition-behavioral-attributes
+// for the definition.
+struct BehavioralAttributes {
+  Flags Attr[10];
+
+#define GOFF_BEHAVIORAL_ATTRIBUTE(NAME, TYPE, ATTRIDX, BITINDEX, LENGTH)       \
+  void set##NAME(TYPE Val) { Attr[ATTRIDX].set<TYPE>(BITINDEX, LENGTH, Val); } \
+  TYPE get##NAME() const { return Attr[ATTRIDX].get<TYPE>(BITINDEX, LENGTH); }
+
+  GOFF_BEHAVIORAL_ATTRIBUTE(Amode, GOFF::ESDAmode, 0, 0, 8)
+  GOFF_BEHAVIORAL_ATTRIBUTE(Rmode, GOFF::ESDRmode, 1, 0, 8)
+  GOFF_BEHAVIORAL_ATTRIBUTE(TextStyle, GOFF::ESDTextStyle, 2, 0, 4)
+  GOFF_BEHAVIORAL_ATTRIBUTE(BindingAlgorithm, GOFF::ESDBindingAlgorithm, 2, 4,
+                            4)
+  GOFF_BEHAVIORAL_ATTRIBUTE(TaskingBehavior, GOFF::ESDTaskingBehavior, 3, 0, 3)
+  GOFF_BEHAVIORAL_ATTRIBUTE(ReadOnly, bool, 3, 4, 1)
+  GOFF_BEHAVIORAL_ATTRIBUTE(Executable, GOFF::ESDExecutable, 3, 5, 3)
+  GOFF_BEHAVIORAL_ATTRIBUTE(DuplicateSymbolSeverity,
+                            GOFF::ESDDuplicateSymbolSeverity, 4, 2, 2)
+  GOFF_BEHAVIORAL_ATTRIBUTE(BindingStrength, GOFF::ESDBindingStrength, 4, 4, 4)
+  GOFF_BEHAVIORAL_ATTRIBUTE(LoadingBehavior, GOFF::ESDLoadingBehavior, 5, 0, 2)
+  GOFF_BEHAVIORAL_ATTRIBUTE(COMMON, bool, 5, 2, 1)
+  GOFF_BEHAVIORAL_ATTRIBUTE(IndirectReference, bool, 5, 3, 1)
+  GOFF_BEHAVIORAL_ATTRIBUTE(BindingScope, GOFF::ESDBindingScope, 5, 4, 4)
+  GOFF_BEHAVIORAL_ATTRIBUTE(LinkageType, GOFF::ESDLinkageType, 6, 2, 1)
+  GOFF_BEHAVIORAL_ATTRIBUTE(Alignment, GOFF::ESDAlignment, 6, 3, 5)
+
+#undef GOFF_BEHAVIORAL_ATTRIBUTE
+};
 } // end namespace GOFF
 
 } // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
new file mode 100644
index 0000000000000..dbdc1408dab2f
--- /dev/null
+++ b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
@@ -0,0 +1,148 @@
+//===- MCGOFFSymbolMapper.h - Maps MC section/symbol to GOFF symbols ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Maps a section or a symbol to the GOFF symbols it is composed of, and their
+// attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCGOFFSYMBOLMAPPER_H
+#define LLVM_MC_MCGOFFSYMBOLMAPPER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/Support/Alignment.h"
+#include <string>
+#include <utility>
+
+namespace llvm {
+class MCAssembler;
+class MCContext;
+class MCSectionGOFF;
+
+// An "External Symbol Definition" in the GOFF file has a type, and depending on
+// the type a different subset of the fields is used.
+//
+// Unlike other formats, a 2 dimensional structure is used to define the
+// location of data. For example, the equivalent of the ELF .text section is
+// made up of a Section Definition (SD) and a class (Element Definition; ED).
+// The name of the SD symbol depends on the application, while the class has the
+// predefined name C_CODE64.
+//
+// Data can be placed into this structure in 2 ways. First, the data (in a text
+// record) can be associated with an ED symbol. To refer to data, a Label
+// Definition (LD) is used to give an offset into the data a name. When binding,
+// the whole data is pulled into the resulting executable, and the addresses
+// given by the LD symbols are resolved.
+//
+// The alternative is to use a Part Defiition (PR). In this case, the data (in a
+// text record) is associated with the part. When binding, only the data of
+// referenced PRs is pulled into the resulting binary.
+//
+// Both approaches are used, which means that the equivalent of a section in ELF
+// results in 3 GOFF symbol, either SD/ED/LD or SD/ED/PR. Moreover, certain
+// sections are fine with just defining SD/ED symbols. The SymbolMapper takes
+// care of all those details.
+
+// Attributes for SD symbols.
+struct SDAttr {
+  GOFF::ESDTaskingBehavior TaskingBehavior = GOFF::ESD_TA_Unspecified;
+  GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
+};
+
+// Attributes for ED symbols.
+struct EDAttr {
+  bool IsReadOnly = false;
+  GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
+  GOFF::ESDAmode Amode;
+  GOFF::ESDRmode Rmode;
+  GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName;
+  GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented;
+  GOFF::ESDBindingAlgorithm BindAlgorithm = GOFF::ESD_BA_Concatenate;
+  GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial;
+  GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0;
+  GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword;
+};
+
+// Attributes for LD symbols.
+struct LDAttr {
+  bool IsRenamable = false;
+  GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
+  GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName;
+  GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
+  GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
+  GOFF::ESDAmode Amode;
+  GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
+};
+
+// Attributes for PR symbols.
+struct PRAttr {
+  bool IsRenamable = false;
+  bool IsReadOnly = false; // ???? Not documented.
+  GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
+  GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName;
+  GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
+  GOFF::ESDAmode Amode;
+  GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
+  GOFF::ESDDuplicateSymbolSeverity DuplicateSymbolSeverity =
+      GOFF::ESD_DSS_NoWarning;
+  GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Byte;
+  uint32_t SortKey = 0;
+};
+
+struct GOFFSectionData {
+  // Name and attributes of SD symbol.
+  StringRef SDName;
+  SDAttr SDAttributes;
+
+  // Name and attributes of ED symbol.
+  StringRef EDName;
+  EDAttr EDAttributes;
+
+  // Name and attributes of LD or PR symbol.
+  StringRef LDorPRName;
+  LDAttr LDAttributes;
+  PRAttr PRAttributes;
+
+  // Indicates if there is a LD or PR symbol.
+  enum { None, LD, PR } Tag;
+
+  // Indicates if the SD symbol is to root symbol (aka the Csect Code).
+  bool IsSDRootSD;
+};
+
+class GOFFSymbolMapper {
+  MCContext &Ctx;
+
+  std::string RootSDName;
+  SDAttr RootSDAttributes;
+
+  std::string ADALDName;
+
+  StringRef BaseName;
+
+  bool IsCsectCodeNameEmpty;
+  bool Is64Bit;
+  bool UsesXPLINK;
+
+public:
+  GOFFSymbolMapper(MCContext &Ctx);
+  GOFFSymbolMapper(MCAssembler &Asm);
+
+  // Required order: .text first, then .ada.
+  std::pair<GOFFSectionData, bool> getSection(const MCSectionGOFF &Section);
+
+  void setBaseName();
+  void determineRootSD(StringRef CSectCodeName);
+  llvm::StringRef getRootSDName() const;
+  const SDAttr &getRootSD() const;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index f49f14c848b90..967ec73a2be5b 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -26,6 +26,7 @@ add_llvm_component_library(LLVMMC
   MCExpr.cpp
   MCFragment.cpp
   MCGOFFStreamer.cpp
+  MCGOFFSymbolMapper.cpp
   MCInst.cpp
   MCInstPrinter.cpp
   MCInstrAnalysis.cpp
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index efaf5ff006ddc..92603c6fb1002 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -13,7 +13,11 @@
 #include "llvm/BinaryFormat/GOFF.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCGOFFObjectWriter.h"
+#include "llvm/MC/MCGOFFSymbolMapper.h"
+#include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ConvertEBCDIC.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/raw_ostream.h"
@@ -23,44 +27,13 @@ using namespace llvm;
 #define DEBUG_TYPE "goff-writer"
 
 namespace {
-
-// The standard System/390 convention is to name the high-order (leftmost) bit
-// in a byte as bit zero. The Flags type helps to set bits in a byte according
-// to this numeration order.
-class Flags {
-  uint8_t Val;
-
-  constexpr static uint8_t bits(uint8_t BitIndex, uint8_t Length, uint8_t Value,
-                                uint8_t OldValue) {
-    assert(BitIndex < 8 && "Bit index out of bounds!");
-    assert(Length + BitIndex <= 8 && "Bit length too long!");
-
-    uint8_t Mask = ((1 << Length) - 1) << (8 - BitIndex - Length);
-    Value = Value << (8 - BitIndex - Length);
-    assert((Value & Mask) == Value && "Bits set outside of range!");
-
-    return (OldValue & ~Mask) | Value;
-  }
-
-public:
-  constexpr Flags() : Val(0) {}
-  constexpr Flags(uint8_t BitIndex, uint8_t Length, uint8_t Value)
-      : Val(bits(BitIndex, Length, Value, 0)) {}
-
-  void set(uint8_t BitIndex, uint8_t Length, uint8_t Value) {
-    Val = bits(BitIndex, Length, Value, Val);
-  }
-
-  constexpr operator uint8_t() const { return Val; }
-};
-
 // Common flag values on records.
 
 // Flag: This record is continued.
-constexpr uint8_t RecContinued = Flags(7, 1, 1);
+constexpr uint8_t RecContinued = GOFF::Flags(7, 1, 1);
 
 // Flag: This record is a continuation.
-constexpr uint8_t RecContinuation = Flags(6, 1, 1);
+constexpr uint8_t RecContinuation = GOFF::Flags(6, 1, 1);
 
 // The GOFFOstream is responsible to write the data into the fixed physical
 // records of the format. A user of this class announces the begin of a new
@@ -223,13 +196,113 @@ void GOFFOstream::finalizeRecord() {
 }
 
 namespace {
+// A GOFFSymbol holds all the data required for writing an ESD record.
+class GOFFSymbol {
+public:
+  std::string Name;
+  uint32_t EsdId;
+  uint32_t ParentEsdId;
+  uint64_t Offset = 0; // Offset of the symbol into the section. LD only.
+                       // Offset is only 32 bit, the larger type is used to
+                       // enable error checking.
+  GOFF::ESDSymbolType SymbolType;
+  GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_ProgramManagementBinder;
+
+  GOFF::BehavioralAttributes BehavAttrs;
+  GOFF::SymbolFlags SymbolFlags;
+  uint32_t SortKey = 0;
+  uint32_t SectionLength = 0;
+  uint32_t ADAEsdId = 0;
+  uint32_t EASectionEDEsdId = 0;
+  uint32_t EASectionOffset = 0;
+  uint8_t FillByteValue = 0;
+
+  GOFFSymbol() : EsdId(0), ParentEsdId(0) {}
+
+  GOFFSymbol(StringRef Name, uint32_t EsdID, const SDAttr &Attr)
+      : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(0),
+        SymbolType(GOFF::ESD_ST_SectionDefinition) {
+    BehavAttrs.setTaskingBehavior(Attr.TaskingBehavior);
+    BehavAttrs.setBindingScope(Attr.BindingScope);
+  }
+
+  GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
+             const EDAttr &Attr)
+      : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
+        SymbolType(GOFF::ESD_ST_ElementDefinition) {
+    this->NameSpace = Attr.NameSpace;
+    // TODO Do we need/should set the "mangled" flag?
+    SymbolFlags.setFillBytePresence(1);
+    SymbolFlags.setReservedQwords(Attr.ReservedQwords);
+    BehavAttrs.setReadOnly(Attr.IsReadOnly);
+    BehavAttrs.setExecutable(Attr.Executable);
+    BehavAttrs.setAmode(Attr.Amode);
+    BehavAttrs.setRmode(Attr.Rmode);
+    BehavAttrs.setTextStyle(Attr.TextStyle);
+    BehavAttrs.setBindingAlgorithm(Attr.BindAlgorithm);
+    BehavAttrs.setLoadingBehavior(Attr.LoadBehavior);
+    BehavAttrs.setAlignment(Attr.Alignment);
+  }
+
+  GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
+             const LDAttr &Attr)
+      : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
+        SymbolType(GOFF::ESD_ST_LabelDefinition) {
+    this->NameSpace = Attr.NameSpace;
+    SymbolFlags.setRenameable(Attr.IsRenamable);
+    BehavAttrs.setExecutable(Attr.Executable);
+    BehavAttrs.setBindingStrength(Attr.BindingStrength);
+    BehavAttrs.setLinkageType(Attr.Linkage);
+    BehavAttrs.setAmode(Attr.Amode);
+    BehavAttrs.setBindingScope(Attr.BindingScope);
+  }
+
+  GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
+             const PRAttr &Attr)
+      : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
+        SymbolType(GOFF::ESD_ST_PartReference) {
+    this->NameSpace = Attr.NameSpace;
+    SymbolFlags.setRenameable(Attr.IsRenamable);
+    BehavAttrs.setExecutable(Attr.Executable);
+    BehavAttrs.setAlignment(Attr.Alignment);
+    BehavAttrs.setAmode(Attr.Amode);
+    BehavAttrs.setLinkageType(Attr.Linkage);
+    BehavAttrs.setBindingScope(Attr.BindingScope);
+    BehavAttrs.setDuplicateSymbolSeverity(Attr.DuplicateSymbolSeverity);
+    BehavAttrs.setReadOnly(Attr.IsReadOnly);
+  }
+};
+
 class GOFFWriter {
   GOFFOstream OS;
   [[maybe_unused]] MCAssembler &Asm;
 
+  /// Mapping from MCSectionGOFF/MCSymbolGOFF to GOFF symbols and attributes.
+  GOFFSymbolMapper SymbolMapper;
+
+  /// Counter for symbol id's.
+  uint32_t EsdIdCounter = 0;
+
+  /// Id's of some special symbols.
+  uint32_t RootSDEsdId = 0;
+  uint32_t ADAEsdId = 0;
+
   void writeHeader();
+  void writeSymbol(const GOFFSymbol &Symbol);
   void writeEnd();
 
+  GOFFSymbol createGOFFSymbol(StringRef Name, const SDAttr &Attr);
+  GOFFSymbol createGOFFSymbol(StringRef Name, const EDAttr &Attr,
+                              uint32_t ParentEsdId);
+  GOFFSymbol createGOFFSymbol(StringRef Name, const LDAttr &Attr,
+                              uint32_t ParentEsdId);
+  GOFFSymbol createGOFFSymbol(StringRef Name, const PRAttr &Attr,
+                              uint32_t ParentEsdId);
+
+  void defineRootSymbol(const MCSectionGOFF *Text);
+  void defineSectionSymbols(const MCSectionGOFF &Section);
+  void defineSymbols();
+
 public:
   GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm);
   uint64_t writeObject();
@@ -237,7 +310,108 @@ class GOFFWriter {
 } // namespace
 
 GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
-    : OS(OS), Asm(Asm) {}
+    : OS(OS), Asm(Asm), SymbolMapper(Asm) {}
+
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const SDAttr &Attr) {
+  return GOFFSymbol(Name, ++EsdIdCounter, Attr);
+}
+
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const EDAttr &Attr,
+                                        uint32_t ParentEsdId) {
+  return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
+}
+
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const LDAttr &Attr,
+                                        uint32_t ParentEsdId) {
+  return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
+}
+
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const PRAttr &Attr,
+                                        uint32_t ParentEsdId) {
+  return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
+}
+
+void GOFFWriter::defineRootSymbol(const MCSectionGOFF *Text) {
+  // There is always a text section except for DWARF unit tests.
+  SymbolMapper.determineRootSD("");
+  GOFFSymbol RootSD =
+      createGOFFSymbol(SymbolMapper.getRootSDName(), SymbolMapper.getRootSD());
+  writeSymbol(RootSD);
+  RootSDEsdId = RootSD.EsdId;
+}
+
+void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
+  auto [GOFFSectionData, Found] = SymbolMapper.getSection(Section);
+  if (Found) {
+    uint32_t SDEsdId = RootSDEsdId;
+    if (!GOFFSectionData.IsSDRootSD) {
+      GOFFSymbol SD = createGOFFSymbol(GOFFSectionData.SDName,
+                                       GOFFSectionData.SDAttributes);
+      SDEsdId = SD.EsdId;
+      writeSymbol(SD);
+    }
+
+    GOFFSymbol ED = createGOFFSymbol(GOFFSectionData.EDName,
+                                     GOFFSectionData.EDAttributes, SDEsdId);
+    if (GOFFSectionData.Tag == GOFFSectionData::None ||
+        GOFFSectionData.Tag == GOFFSectionData::LD) {
+      ED.SectionLength = Asm.getSectionAddressSize(Section);
+    }
+    writeSymbol(ED);
+
+    if (GOFFSectionData.Tag == GOFFSectionData::LD) {
+      GOFFSymbol LD = createGOFFSymbol(GOFFSectionData.LDorPRName,
+                                       GOFFSectionData.LDAttributes, ED.EsdId);
+      if (Section.isText())
+        LD.ADAEsdId = ADAEsdId;
+      writeSymbol(LD);
+    }
+
+    if (GOFFSectionData.Tag == GOFFSectionData::PR) {
+      GOFFSymbol PR = createGOFFSymbol(GOFFSectionData.LDorPRName,
+                                       GOFFSectionData.PRAttributes, ED.EsdId);
+      PR.SectionLength = Asm.getSectionAddressSize(Section);
+      if (Section.getName() == ".ada") {
+        // We cannot have a zero-length section for data.  If we do,
+        // artificially inflate it. Use 2 bytes to avoid odd alignments. Note:
+        // if this is ever changed, you will need to update the code in
+        // SystemZAsmPrinter::emitCEEMAIN and SystemZAsmPrinter::emitCELQMAIN to
+        // generate -1 if there is no ADA
+        if (!PR.SectionLength)
+          PR.SectionLength = 2;
+        ADAEsdId = PR.EsdId;
+      }
+      writeSymbol(PR);
+    }
+    return;
+  }
+  // TODO It is possible to get here. This will be handled later.
+}
+
+void GOFFWriter::defineSymbols() {
+  // Search for .text and .ada sections. These should be the first sections in
+  // the list, so the loop should be cheap.
+  MCSectionGOFF *Text = nullptr;
+  MCSectionGOFF *ADA = nullptr;
+  for (MCSection &S : Asm) {
+    if (S.getName() == ".text")
+      Text = &cast<MCSectionGOFF>(S);
+    if (S.getName() == ".ada")
+      ADA = &cast<MCSectionGOFF>(S);
+  }
+  defineRootSymbol(Text);
+  if (ADA)
+    defineSectionSymbols(*ADA);
+  if (Text)
+    defineSectionSymbols(*Text);
+
+  // Process the other sections.
+  for (MCSection &S : Asm) {
+    auto &Section = cast<MCSectionGOFF>(S);
+    if (Text != &Section && ADA != &Section)
+      defineSectionSymbols(Section);
+  }
+}
 
 void GOFFWriter::writeHeader() {
   OS.newRecord(GOFF::RT_HDR);
@@ -253,6 +427,45 @@ void GOFFWriter::writeHeader() {
   OS.write_zeros(6);       // Reserved
 }
 
+void GOFFWriter::writeSymbol(const GOFFSymbol &Symbol) {
+  if (Symbol.Offset >= (((uint64_t)1) << 31))
+    report_fatal_error("ESD offset outof range");
+
+  // All symbol names are in EBCDIC.
+  SmallString<256> Name;
+  ConverterEBCDIC::convertToEBCDIC(Symbol.Name, Name);
+
+  // Check length here since this number is technically signed but we need uint
+  // for writing to records.
+  if (Name.size() >= GOFF::MaxDataLength)
+    report_fatal_error("Symbol max name length exceeded");
+  uint16_t NameLength = Name.size();
+
+  OS.newRecord(GOFF::RT_ESD);
+  OS.writebe<uint8_t>(Symbol.SymbolType);   // Symbol Type
+  OS.writebe<uint32_t>(Symbol.EsdId);       // ESDID
+  OS.writebe<uint32_t>(Symbol.ParentEsdId); // Parent or Owning ESDID
+  OS.writebe<uint32_t>(0);                  // Reserved
+  OS.writebe<uint32_t>(
+      static_cast<uint32_t>(Symbol.Offset));     // Offset or Address
+  OS.writebe<uint32_t>(0);                       // Reserved
+  OS.writebe<uint32_t>(Symbol.SectionLength);    // Length
+  OS.writebe<uint32_t>(Symbol.EASectionEDEsdId); // Extended Attribute ESDID
+  OS.writebe<uint32_t>(Symbol.EASectionOffset);  // Extended Attribute Offset
+  OS.writebe<uint32_t>(0);                       // Reserved
+  OS.writebe<uint8_t>(Symbol.NameSpace);         // Name Space ID
+  OS.writebe<uint8_t>(Symbol.SymbolFlags);       // Flags
+  OS.writebe<uint8_t>(Symbol.FillByteValue);     // Fill-Byte Value
+  OS.writebe<uint8_t>(0);                        // Reserved
+  OS.writebe<uint32_t>(Symbol.ADAEsdId);         // ADA ESDID
+  OS.writebe<uint32_t>(Symbol.SortKey);          // Sort Priority
+  OS.writebe<uint64_t>(0);                       // Reserved
+  for (auto F : Symbol.BehavAttrs.Attr)
+    OS.writebe<uint8_t>(F);          // Behavioral Attributes
+  OS.writebe<uint16_t>(NameLength);  // Name Length
+  OS.write(Name.data(), NameLength); // Name
+}
+
 void GOFFWriter::writeEnd() {
   uint8_t F = GOFF::END_EPR_None;
   uint8_t AMODE = 0;
@@ -261,9 +474,9 @@ void GOFFWriter::writeEnd() {
   // TODO Set Flags/AMODE/ESDID for entry point.
 
   OS.newRecord(GOFF::RT_END);
-  OS.writebe<uint8_t>(Flags(6, 2, F)); // Indicator flags
-  OS.writebe<uint8_t>(AMODE);          // AMODE
-  OS.write_zeros(3);                   // Reserved
+  OS.writebe<uint8_t>(GOFF::Flags(6, 2, F)); // Indicator flags
+  OS.writebe<uint8_t>(AMODE);                // AMODE
+  OS.write_zeros(3);                         // Reserved
   // The record count is the number of logical records. In principle, this value
   // is available as OS.logicalRecords(). However, some tools rely on this field
   // being zero.
@@ -273,6 +486,9 @@ void GOFFWriter::writeEnd() {
 
 uint64_t GOFFWriter::writeObject() {
   writeHeader();
+
+  defineSymbols();
+
   writeEnd();
 
   // Make sure all records are written.
diff --git a/llvm/lib/MC/MCGOFFSymbolMapper.cpp b/llvm/lib/MC/MCGOFFSymbolMapper.cpp
new file mode 100644
index 0000000000000..57012c34a94f1
--- /dev/null
+++ b/llvm/lib/MC/MCGOFFSymbolMapper.cpp
@@ -0,0 +1,203 @@
+//===- MCGOFFSymbolMapper.cpp - Maps MC section/symbol to GOFF symbols ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Maps a section or a symbol to the GOFF symbols it is composed of, and their
+// attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCGOFFSymbolMapper.h"
+#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSectionGOFF.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Support/Path.h"
+
+using namespace llvm;
+
+namespace {
+const StringLiteral CODE[2]{"C_CODE", "C_CODE64"};
+const StringLiteral WSA[2]{"C_WSA", "C_WSA64"};
+const StringLiteral PPA2[2]{"C_@@PPA2", "C_@@QPPA2"};
+
+const GOFF::ESDAmode AMODE[2]{GOFF::ESD_AMODE_ANY, GOFF::ESD_AMODE_64};
+const GOFF::ESDRmode RMODE[2]{GOFF::ESD_RMODE_31, GOFF::ESD_RMODE_64};
+
+const GOFF::ESDLinkageType LINKAGE[2]{GOFF::ESD_LT_OS, GOFF::ESD_LT_XPLink};
+} // namespace
+
+GOFFSymbolMapper::GOFFSymbolMapper(MCContext &Ctx) : Ctx(Ctx) {
+  IsCsectCodeNameEmpty = true;
+  Is64Bit = true;
+  UsesXPLINK = true;
+}
+
+GOFFSymbolMapper::GOFFSymbolMapper(MCAssembler &Asm)
+    : GOFFSymbolMapper(Asm.getContext()) {
+  if (!Asm.getWriter().getFileNames().empty())
+    BaseName =
+        sys::path::stem((*(Asm.getWriter().getFileNames().begin())).first);
+}
+
+void GOFFSymbolMapper::determineRootSD(StringRef CSectCodeName) {
+  IsCsectCodeNameEmpty = CSectCodeName.empty();
+  if (IsCsectCodeNameEmpty) {
+    RootSDName = BaseName.str().append("#C");
+  } else {
+    RootSDName = CSectCodeName;
+  }
+  RootSDAttributes = {GOFF::ESD_TA_Rent, IsCsectCodeNameEmpty
+                                             ? GOFF::ESD_BSC_Section
+                                             : GOFF::ESD_BSC_Unspecified};
+}
+
+llvm::StringRef GOFFSymbolMapper::getRootSDName() const { return RootSDName; }
+
+const SDAttr &GOFFSymbolMapper::getRootSD() const { return RootSDAttributes; }
+
+std::pair<GOFFSectionData, bool>
+GOFFSymbolMapper::getSection(const MCSectionGOFF &Section) {
+  // Look up GOFFSection from name in MCSectionGOFF.
+  // Customize result, e.g. csect names, 32/64 bit, etc.
+  GOFFSectionData GOFFSec;
+  if (Section.getName() == ".text") {
+    GOFFSec.SDName = RootSDName;
+    GOFFSec.SDAttributes = RootSDAttributes;
+    GOFFSec.IsSDRootSD = true;
+    GOFFSec.EDName = CODE[Is64Bit];
+    // The GOFF alignment is encoded as log_2 value.
+    uint8_t Log = Log2(Section.getAlign());
+    assert(Log <= GOFF::ESD_ALIGN_4Kpage && "Alignment too large");
+    GOFFSec.EDAttributes = {true,
+                            GOFF::ESD_EXE_CODE,
+                            AMODE[Is64Bit],
+                            RMODE[Is64Bit],
+                            GOFF::ESD_NS_NormalName,
+                            GOFF::ESD_TS_ByteOriented,
+                            GOFF::ESD_BA_Concatenate,
+                            GOFF::ESD_LB_Initial,
+                            GOFF::ESD_RQ_0,
+                            static_cast<GOFF::ESDAlignment>(Log)};
+    GOFFSec.LDorPRName = GOFFSec.SDName;
+    GOFFSec.LDAttributes = {false,
+                            GOFF::ESD_EXE_CODE,
+                            GOFF::ESD_NS_NormalName,
+                            GOFF::ESD_BST_Strong,
+                            LINKAGE[UsesXPLINK],
+                            AMODE[Is64Bit],
+                            IsCsectCodeNameEmpty ? GOFF::ESD_BSC_Section
+                                                 : GOFF::ESD_BSC_Library};
+    GOFFSec.Tag = GOFFSectionData::LD;
+  } else if (Section.getName() == ".ada") {
+    assert(!RootSDName.empty() && "RootSD must be defined already");
+    GOFFSec.SDName = RootSDName;
+    GOFFSec.SDAttributes = RootSDAttributes;
+    GOFFSec.IsSDRootSD = true;
+    GOFFSec.EDName = WSA[Is64Bit];
+    GOFFSec.EDAttributes = {false,
+                            GOFF::ESD_EXE_DATA,
+                            AMODE[Is64Bit],
+                            RMODE[Is64Bit],
+                            GOFF::ESD_NS_Parts,
+                            GOFF::ESD_TS_ByteOriented,
+                            GOFF::ESD_BA_Merge,
+                            GOFF::ESD_LB_Deferred,
+                            GOFF::ESD_RQ_1,
+                            Is64Bit ? GOFF::ESD_ALIGN_Quadword
+                                    : GOFF::ESD_ALIGN_Doubleword};
+    ADALDName = BaseName.str().append("#S");
+    GOFFSec.LDorPRName = ADALDName;
+    GOFFSec.PRAttributes = {false,
+                            false,
+                            GOFF::ESD_EXE_DATA,
+                            GOFF::ESD_NS_Parts,
+                            GOFF::ESD_LT_XPLink,
+                            AMODE[Is64Bit],
+                            GOFF::ESD_BSC_Section,
+                            GOFF::ESD_DSS_NoWarning,
+                            Is64Bit ? GOFF::ESD_ALIGN_Quadword
+                                    : GOFF::ESD_ALIGN_Doubleword,
+                            0};
+    GOFFSec.Tag = GOFFSectionData::PR;
+  } else if (Section.getName().starts_with(".gcc_exception_table")) {
+    GOFFSec.SDName = RootSDName;
+    GOFFSec.SDAttributes = RootSDAttributes;
+    GOFFSec.IsSDRootSD = true;
+    GOFFSec.EDName = WSA[Is64Bit];
+    GOFFSec.EDAttributes = {false,
+                            GOFF::ESD_EXE_DATA,
+                            AMODE[Is64Bit],
+                            RMODE[Is64Bit],
+                            GOFF::ESD_NS_Parts,
+                            GOFF::ESD_TS_ByteOriented,
+                            GOFF::ESD_BA_Merge,
+                            UsesXPLINK ? GOFF::ESD_LB_Initial
+                                       : GOFF::ESD_LB_Deferred,
+                            GOFF::ESD_RQ_0,
+                            GOFF::ESD_ALIGN_Doubleword};
+    GOFFSec.LDorPRName = Section.getName();
+    GOFFSec.PRAttributes = {true,
+                            false,
+                            GOFF::ESD_EXE_Unspecified,
+                            GOFF::ESD_NS_Parts,
+                            LINKAGE[UsesXPLINK],
+                            AMODE[Is64Bit],
+                            GOFF::ESD_BSC_Section,
+                            GOFF::ESD_DSS_NoWarning,
+                            GOFF::ESD_ALIGN_Fullword,
+                            0};
+    GOFFSec.Tag = GOFFSectionData::PR;
+  } else if (Section.getName() == ".ppa2list") {
+    GOFFSec.SDName = RootSDName;
+    GOFFSec.SDAttributes = RootSDAttributes;
+    GOFFSec.IsSDRootSD = true;
+    GOFFSec.EDName = PPA2[Is64Bit];
+    GOFFSec.EDAttributes = {true,
+                            GOFF::ESD_EXE_DATA,
+                            AMODE[Is64Bit],
+                            RMODE[Is64Bit],
+                            GOFF::ESD_NS_Parts,
+                            GOFF::ESD_TS_ByteOriented,
+                            GOFF::ESD_BA_Merge,
+                            GOFF::ESD_LB_Initial,
+                            GOFF::ESD_RQ_0,
+                            GOFF::ESD_ALIGN_Doubleword};
+    GOFFSec.LDorPRName = ".&ppa2";
+    GOFFSec.PRAttributes = {true,
+                            false,
+                            GOFF::ESD_EXE_Unspecified,
+                            GOFF::ESD_NS_Parts,
+                            GOFF::ESD_LT_OS,
+                            AMODE[Is64Bit],
+                            GOFF::ESD_BSC_Section,
+                            GOFF::ESD_DSS_NoWarning,
+                            GOFF::ESD_ALIGN_Doubleword,
+                            0};
+    GOFFSec.Tag = GOFFSectionData::PR;
+  } else if (Section.getName() == ".idrl") {
+    GOFFSec.SDName = RootSDName;
+    GOFFSec.SDAttributes = RootSDAttributes;
+    GOFFSec.IsSDRootSD = true;
+    GOFFSec.EDName = "B_IDRL";
+    GOFFSec.EDAttributes = {true,
+                            GOFF::ESD_EXE_Unspecified,
+                            AMODE[Is64Bit],
+                            RMODE[Is64Bit],
+                            GOFF::ESD_NS_NormalName,
+                            GOFF::ESD_TS_Structured,
+                            GOFF::ESD_BA_Concatenate,
+                            GOFF::ESD_LB_NoLoad,
+                            GOFF::ESD_RQ_0,
+                            GOFF::ESD_ALIGN_Doubleword};
+    GOFFSec.Tag = GOFFSectionData::None;
+  } else
+    return std::pair(GOFFSec, false);
+  return std::pair(GOFFSec, true);
+}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index ab7552ca01061..a514a07ef7d3e 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -557,7 +557,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       Ctx->getGOFFSection(".ppa2list", SectionKind::getData(), nullptr);
 
   ADASection = Ctx->getGOFFSection(".ada", SectionKind::getData(), nullptr);
-  IDRLSection = Ctx->getGOFFSection("B_IDRL", SectionKind::getData(), nullptr);
+  IDRLSection = Ctx->getGOFFSection(".idrl", SectionKind::getData(), nullptr);
 }
 
 void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
diff --git a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
index 07025091fb240..82f416ddb8bf9 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
@@ -19,7 +19,7 @@
 ; CHECK:    .quad   L#PPA2-CELQSTRT                 * A(PPA2-CELQSTRT)
 ; CHECK: L#PPA1_void_test_0:
 ; CHECK:    .long   L#PPA2-L#PPA1_void_test_0       * Offset to PPA2
-; CHECK:    .section    "B_IDRL"
+; CHECK:    .section    ".idrl"
 ; CHECK:    .byte   0
 ; CHECK:    .byte   3
 ; CHECK:    .short  30
diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll
new file mode 100644
index 0000000000000..a0c64f0b83013
--- /dev/null
+++ b/llvm/test/MC/GOFF/section.ll
@@ -0,0 +1,73 @@
+; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj -o - | \
+; RUN:   od -Ax -tx1 -v | FileCheck --ignore-case %s
+; REQUIRES: systemz-registered-target
+
+source_filename = "test.ll"
+
+declare void @other(...)
+
+define void @me() {
+entry:
+  tail call void @other()
+  ret void
+}
+
+; Header record:
+;  03 is prefix byte
+;  f. is header type
+;  .0 is flag
+;  00 is version
+; The 1 at offset 0x33 is the architecture level.
+; CHECK: 000000 03 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000030 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+; ESD record, type SD.
+;  03 is prefix byte
+;  0. is header type
+;  .0 is flag
+;  00 is version
+;  00 is type = SD
+; The 01 at offset 0x57 is the id of the symbol.
+; The 60 at offset 0x89 is the tasking behavior.
+; The 01 at offset 0x91 is the binding scope.
+; The name begins at offset 0x97, and is test#C.
+; CHECK: 0000050 03 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00
+; CHECK: 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
+; CHECK: 0000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+
+; ESD record, type ED.
+; The name is C_WSA64.
+; CHECK: 00000a0 03 00 00 01 00 00 00 02 00 00 00 01 00 00 00 00
+; CHECK: 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00000c0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECK: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
+; CHECK: 00000e0 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
+; ESD record, type PR.
+; The name is test#S.
+; CHECK: 00000f0 03 00 00 03 00 00 00 03 00 00 00 02 00 00 00 00
+; CHECK: 0000100 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00
+; CHECK: 0000110 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK: 0000130 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
+
+; ESD record, type ED.
+; The name is C_CODE64.
+; CHECK: 0000140 03 00 00 01 00 00 00 04 00 00 00 01 00 00 00 00
+; CHECK: 0000150 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00
+; CHECK: 0000160 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK: 0000170 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a
+; CHECK: 0000180 00 00 04 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+
+; ESD record, type LD.
+; The name is test#C.
+; CHECK: 0000190 03 00 00 02 00 00 00 05 00 00 00 04 00 00 00 00
+; CHECK: 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00001b0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 03
+; CHECK: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK: 00001d0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00

>From bb71a074a822a18140f6d312dbdde259fe6c6a71 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 2 Apr 2025 11:25:15 -0400
Subject: [PATCH 02/35] Update llvm/include/llvm/MC/MCGOFFSymbolMapper.h

Co-authored-by: Neumann Hon <neumann.hon at ibm.com>
---
 llvm/include/llvm/MC/MCGOFFSymbolMapper.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
index dbdc1408dab2f..1402f8ad9713e 100644
--- a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
+++ b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
@@ -45,7 +45,7 @@ class MCSectionGOFF;
 // referenced PRs is pulled into the resulting binary.
 //
 // Both approaches are used, which means that the equivalent of a section in ELF
-// results in 3 GOFF symbol, either SD/ED/LD or SD/ED/PR. Moreover, certain
+// results in 3 GOFF symbols, either SD/ED/LD or SD/ED/PR. Moreover, certain
 // sections are fine with just defining SD/ED symbols. The SymbolMapper takes
 // care of all those details.
 

>From a0a2a1f52137923a78470c4d74822f0518b45082 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 2 Apr 2025 11:27:57 -0400
Subject: [PATCH 03/35] Update llvm/include/llvm/MC/MCGOFFSymbolMapper.h

Co-authored-by: Neumann Hon <neumann.hon at ibm.com>
---
 llvm/include/llvm/MC/MCGOFFSymbolMapper.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
index 1402f8ad9713e..252fc20454536 100644
--- a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
+++ b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
@@ -40,7 +40,7 @@ class MCSectionGOFF;
 // the whole data is pulled into the resulting executable, and the addresses
 // given by the LD symbols are resolved.
 //
-// The alternative is to use a Part Defiition (PR). In this case, the data (in a
+// The alternative is to use a Part Definition (PR). In this case, the data (in a
 // text record) is associated with the part. When binding, only the data of
 // referenced PRs is pulled into the resulting binary.
 //

>From 18cd9eb5e1a042800648dff3d5872552797c9108 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 2 Apr 2025 11:28:22 -0400
Subject: [PATCH 04/35] Update llvm/lib/MC/GOFFObjectWriter.cpp

Co-authored-by: Neumann Hon <neumann.hon at ibm.com>
---
 llvm/lib/MC/GOFFObjectWriter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 92603c6fb1002..062e62f31be40 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -429,7 +429,7 @@ void GOFFWriter::writeHeader() {
 
 void GOFFWriter::writeSymbol(const GOFFSymbol &Symbol) {
   if (Symbol.Offset >= (((uint64_t)1) << 31))
-    report_fatal_error("ESD offset outof range");
+    report_fatal_error("ESD offset out of range");
 
   // All symbol names are in EBCDIC.
   SmallString<256> Name;

>From f2be856fba17f7b9f8ba462b2cfbada00af5cd49 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 2 Apr 2025 11:46:30 -0400
Subject: [PATCH 05/35] More updates

---
 llvm/include/llvm/BinaryFormat/GOFF.h     | 8 ++++----
 llvm/include/llvm/MC/MCGOFFSymbolMapper.h | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index 43d80e0c247e9..bfa41d100a3b7 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -174,7 +174,7 @@ enum SubsectionKind : uint8_t {
 // in a byte as bit zero. The Flags type helps to set bits in byte according
 // to this numeration order.
 class Flags {
-  uint8_t Val;
+  uint8_t Val = 0;
 
   constexpr static uint8_t bits(uint8_t BitIndex, uint8_t Length, uint8_t Value,
                                 uint8_t OldValue) {
@@ -185,7 +185,7 @@ class Flags {
   }
 
 public:
-  constexpr Flags() : Val(0) {}
+  constexpr Flags() = default;
   constexpr Flags(uint8_t BitIndex, uint8_t Length, uint8_t Value)
       : Val(bits(BitIndex, Length, Value, 0)) {}
 
@@ -204,7 +204,7 @@ class Flags {
 };
 
 // Structure for the flag field of a symbol. See
-// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record,
+// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record ,
 // offset 41, for the definition.
 struct SymbolFlags {
   Flags SymFlags;
@@ -221,7 +221,7 @@ struct SymbolFlags {
 
 #undef GOFF_SYMBOL_FLAG
 
-constexpr operator uint8_t() const { return static_cast<uint8_t>(SymFlags); }
+  constexpr operator uint8_t() const { return static_cast<uint8_t>(SymFlags); }
 };
 
 // Structure for the behavioral attributes. See
diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
index 252fc20454536..c1aba6f1a413c 100644
--- a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
+++ b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
@@ -32,7 +32,7 @@ class MCSectionGOFF;
 // location of data. For example, the equivalent of the ELF .text section is
 // made up of a Section Definition (SD) and a class (Element Definition; ED).
 // The name of the SD symbol depends on the application, while the class has the
-// predefined name C_CODE64.
+// predefined name C_CODE/C_CODE64 in AMODE31 and AMODE64 respectively.
 //
 // Data can be placed into this structure in 2 ways. First, the data (in a text
 // record) can be associated with an ED symbol. To refer to data, a Label

>From 3cf7324ec5b335d75d1b887a49d0992abc31a6d2 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 2 Apr 2025 19:44:01 -0400
Subject: [PATCH 06/35] Remove the class GOFFSymbolMapper

---
 llvm/include/llvm/BinaryFormat/GOFF.h         |   4 +-
 .../CodeGen/TargetLoweringObjectFileImpl.h    |   2 +
 llvm/include/llvm/MC/MCContext.h              |  35 ++-
 ...CGOFFSymbolMapper.h => MCGOFFAttributes.h} |  89 +++-----
 llvm/include/llvm/MC/MCGOFFStreamer.h         |   5 +
 llvm/include/llvm/MC/MCObjectFileInfo.h       |   4 -
 llvm/include/llvm/MC/MCSectionGOFF.h          |  71 +++++-
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  |  59 ++++-
 llvm/lib/MC/CMakeLists.txt                    |   1 -
 llvm/lib/MC/GOFFObjectWriter.cpp              |  80 ++++---
 llvm/lib/MC/MCContext.cpp                     |  72 ++++++-
 llvm/lib/MC/MCGOFFStreamer.cpp                |  18 ++
 llvm/lib/MC/MCGOFFSymbolMapper.cpp            | 203 ------------------
 llvm/lib/MC/MCObjectFileInfo.cpp              |  58 +++--
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp |   7 +-
 llvm/test/MC/GOFF/section.ll                  |   1 -
 16 files changed, 362 insertions(+), 347 deletions(-)
 rename llvm/include/llvm/MC/{MCGOFFSymbolMapper.h => MCGOFFAttributes.h} (69%)
 delete mode 100644 llvm/lib/MC/MCGOFFSymbolMapper.cpp

diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index bfa41d100a3b7..49d2809cb6524 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -204,8 +204,8 @@ class Flags {
 };
 
 // Structure for the flag field of a symbol. See
-// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record ,
-// offset 41, for the definition.
+// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record
+// at offset 41 for the definition.
 struct SymbolFlags {
   Flags SymFlags;
 
diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 10f0594c267ae..b2ff064297809 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -320,6 +320,8 @@ class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile {
   TargetLoweringObjectFileGOFF();
   ~TargetLoweringObjectFileGOFF() override = default;
 
+  void getModuleMetadata(Module &M) override;
+
   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
                                     const TargetMachine &TM) const override;
   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index e97c890ce9135..a35df1bba4bc1 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -19,8 +19,10 @@
 #include "llvm/BinaryFormat/XCOFF.h"
 #include "llvm/MC/MCAsmMacro.h"
 #include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCGOFFAttributes.h"
 #include "llvm/MC/MCPseudoProbe.h"
 #include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCSymbolTableEntry.h"
 #include "llvm/MC/SectionKind.h"
 #include "llvm/Support/Allocator.h"
@@ -54,7 +56,6 @@ class MCSection;
 class MCSectionCOFF;
 class MCSectionDXContainer;
 class MCSectionELF;
-class MCSectionGOFF;
 class MCSectionMachO;
 class MCSectionSPIRV;
 class MCSectionWasm;
@@ -599,8 +600,36 @@ class MCContext {
                                                    unsigned Flags,
                                                    unsigned EntrySize);
 
-  MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind,
-                                MCSection *Parent, uint32_t Subsection = 0);
+private:
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName,
+                                GOFF::SDAttr SDAttributes, StringRef EDName,
+                                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
+                                GOFF::LDAttr LDAttributes,
+                                GOFF::PRAttr PRAttributes,
+                                MCSectionGOFF::SectionFlags Flags);
+
+public:
+  // Create a section with SD/ED/LD symbols.
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName,
+                                GOFF::SDAttr SDAttributes, StringRef EDName,
+                                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
+                                GOFF::LDAttr LDAttributes);
+  // Create a section with SD/ED/PR symbols.
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName,
+                                GOFF::SDAttr SDAttributes, StringRef EDName,
+                                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
+                                GOFF::PRAttr PRAttributes);
+  // Create a section with root-SD/ED/LD symbols, using the root-SD name for LD.
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
+                                GOFF::EDAttr EDAttributes,
+                                GOFF::LDAttr LDAttributes);
+  // Create a section with root-SD/ED/PR symbols.
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
+                                GOFF::EDAttr EDAttributes, StringRef PRName,
+                                GOFF::PRAttr PRAttributes);
+  // Create a section with root-SD/ED symbols.
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
+                                GOFF::EDAttr EDAttributes);
 
   MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
                                 StringRef COMDATSymName, int Selection,
diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
similarity index 69%
rename from llvm/include/llvm/MC/MCGOFFSymbolMapper.h
rename to llvm/include/llvm/MC/MCGOFFAttributes.h
index c1aba6f1a413c..6a27438b6e81a 100644
--- a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -1,4 +1,4 @@
-//===- MCGOFFSymbolMapper.h - Maps MC section/symbol to GOFF symbols ------===//
+//===- MCGOFFAttributes.h - Attributes of GOFF symbols --------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,25 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Maps a section or a symbol to the GOFF symbols it is composed of, and their
-// attributes.
+// Defines the various attribute collections defining GOFF symbols.
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_MC_MCGOFFSYMBOLMAPPER_H
-#define LLVM_MC_MCGOFFSYMBOLMAPPER_H
+#ifndef LLVM_MC_MCGOFFATTRIBUTES_H
+#define LLVM_MC_MCGOFFATTRIBUTES_H
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/GOFF.h"
-#include "llvm/Support/Alignment.h"
-#include <string>
-#include <utility>
 
 namespace llvm {
-class MCAssembler;
-class MCContext;
-class MCSectionGOFF;
-
+namespace GOFF {
 // An "External Symbol Definition" in the GOFF file has a type, and depending on
 // the type a different subset of the fields is used.
 //
@@ -40,8 +33,8 @@ class MCSectionGOFF;
 // the whole data is pulled into the resulting executable, and the addresses
 // given by the LD symbols are resolved.
 //
-// The alternative is to use a Part Definition (PR). In this case, the data (in a
-// text record) is associated with the part. When binding, only the data of
+// The alternative is to use a Part Definition (PR). In this case, the data (in
+// a text record) is associated with the part. When binding, only the data of
 // referenced PRs is pulled into the resulting binary.
 //
 // Both approaches are used, which means that the equivalent of a section in ELF
@@ -95,54 +88,40 @@ struct PRAttr {
   uint32_t SortKey = 0;
 };
 
-struct GOFFSectionData {
-  // Name and attributes of SD symbol.
-  StringRef SDName;
-  SDAttr SDAttributes;
-
-  // Name and attributes of ED symbol.
-  StringRef EDName;
-  EDAttr EDAttributes;
-
-  // Name and attributes of LD or PR symbol.
-  StringRef LDorPRName;
-  LDAttr LDAttributes;
-  PRAttr PRAttributes;
+// Class names and other values depending on AMODE64 or AMODE31, and other
+// environment properties.
+template <bool Is64Bit>
+constexpr StringLiteral CODE =
+    Is64Bit ? StringLiteral("C_CODE64") : StringLiteral("C_CODE");
 
-  // Indicates if there is a LD or PR symbol.
-  enum { None, LD, PR } Tag;
-
-  // Indicates if the SD symbol is to root symbol (aka the Csect Code).
-  bool IsSDRootSD;
-};
+template <bool Is64Bit>
+constexpr StringLiteral WSA =
+    Is64Bit ? StringLiteral("C_WSA64") : StringLiteral("C_WSA");
 
-class GOFFSymbolMapper {
-  MCContext &Ctx;
+template <bool Is64Bit>
+constexpr StringLiteral DATA =
+    Is64Bit ? StringLiteral("C_DATA64") : StringLiteral("C_DATA");
 
-  std::string RootSDName;
-  SDAttr RootSDAttributes;
+template <bool Is64Bit>
+constexpr StringLiteral PPA2 =
+    Is64Bit ? StringLiteral("C_@@QPPA2") : StringLiteral("C_@@PPA2");
 
-  std::string ADALDName;
+template <bool Is64Bit>
+constexpr GOFF::ESDAmode AMODE =
+    Is64Bit ? GOFF::ESD_AMODE_64 : GOFF::ESD_AMODE_ANY;
 
-  StringRef BaseName;
+template <bool Is64Bit>
+constexpr GOFF::ESDRmode RMODE =
+    Is64Bit ? GOFF::ESD_RMODE_64 : GOFF::ESD_RMODE_31;
 
-  bool IsCsectCodeNameEmpty;
-  bool Is64Bit;
-  bool UsesXPLINK;
-
-public:
-  GOFFSymbolMapper(MCContext &Ctx);
-  GOFFSymbolMapper(MCAssembler &Asm);
-
-  // Required order: .text first, then .ada.
-  std::pair<GOFFSectionData, bool> getSection(const MCSectionGOFF &Section);
-
-  void setBaseName();
-  void determineRootSD(StringRef CSectCodeName);
-  llvm::StringRef getRootSDName() const;
-  const SDAttr &getRootSD() const;
-};
+template <bool IsXPLINK>
+constexpr GOFF::ESDLinkageType LINKAGE =
+    IsXPLINK ? GOFF::ESD_LT_XPLink : GOFF::ESD_LT_OS;
 
+template <bool IsXPLINK>
+constexpr GOFF::ESDLoadingBehavior LOADBEHAVIOR =
+    IsXPLINK ? GOFF::ESD_LB_Initial : GOFF::ESD_LB_Deferred;
+} // namespace GOFF
 } // namespace llvm
 
 #endif
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 78c1f5b60434b..779d44a8930b3 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -16,6 +16,9 @@ namespace llvm {
 class GOFFObjectWriter;
 
 class MCGOFFStreamer : public MCObjectStreamer {
+  std::string RootSDName;
+  std::string ADAPRName;
+
 public:
   MCGOFFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
                  std::unique_ptr<MCObjectWriter> OW,
@@ -25,6 +28,8 @@ class MCGOFFStreamer : public MCObjectStreamer {
 
   ~MCGOFFStreamer() override;
 
+  void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
+
   GOFFObjectWriter &getWriter();
 
   bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index fb575fe721015..56697ee3ae962 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -230,8 +230,6 @@ class MCObjectFileInfo {
   MCSection *GLJMPSection = nullptr;
 
   // GOFF specific sections.
-  MCSection *PPA1Section = nullptr;
-  MCSection *PPA2Section = nullptr;
   MCSection *PPA2ListSection = nullptr;
   MCSection *ADASection = nullptr;
   MCSection *IDRLSection = nullptr;
@@ -438,8 +436,6 @@ class MCObjectFileInfo {
   MCSection *getGLJMPSection() const { return GLJMPSection; }
 
   // GOFF specific sections.
-  MCSection *getPPA1Section() const { return PPA1Section; }
-  MCSection *getPPA2Section() const { return PPA2Section; }
   MCSection *getPPA2ListSection() const { return PPA2ListSection; }
   MCSection *getADASection() const { return ADASection; }
   MCSection *getIDRLSection() const { return IDRLSection; }
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 11c0f95364037..0683c4690b0ba 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -15,7 +15,9 @@
 #ifndef LLVM_MC_MCSECTIONGOFF_H
 #define LLVM_MC_MCSECTIONGOFF_H
 
+#include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCGOFFAttributes.h"
 #include "llvm/MC/MCSection.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -25,13 +27,38 @@ class MCExpr;
 
 class MCSectionGOFF final : public MCSection {
 private:
-  MCSection *Parent;
-  uint32_t Subsection;
+  // The names of the GOFF symbols.
+  StringRef SDName;
+  StringRef EDName;
+  StringRef LDorPRName;
+
+  // The attributes of the GOFF symbols.
+  GOFF::SDAttr SDAttributes;
+  GOFF::EDAttr EDAttributes;
+  GOFF::LDAttr LDAttributes;
+  GOFF::PRAttr PRAttributes;
+
+public:
+  enum SectionFlags {
+    UsesRootSD = 1,     // Uses the common root SD.
+    HasLD = 2,          // Has a LD symbol.
+    HasPR = 4,          // Has a PR symbol.
+    LDorPRNameIsSD = 8, // The LD or PR name is the same as the SD name.
+    LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ 8)
+  };
+
+private:
+  SectionFlags Flags;
+  bool IsADA;
 
   friend class MCContext;
-  MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, uint32_t Sub)
-      : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
-        Parent(P), Subsection(Sub) {}
+  MCSectionGOFF(StringRef SynName, SectionKind K, SectionFlags Flags,
+                StringRef SDName, GOFF::SDAttr SDAttributes, StringRef EDName,
+                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
+                GOFF::LDAttr LDAttributes, GOFF::PRAttr PRAttributes)
+      : MCSection(SV_GOFF, SynName, K.isText(), /*IsVirtual=*/false, nullptr),
+        SDName(SDName), EDName(EDName), LDorPRName(LDorPRName),
+        SDAttributes(SDAttributes), EDAttributes(EDAttributes), Flags(Flags) {}
 
 public:
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
@@ -42,8 +69,38 @@ class MCSectionGOFF final : public MCSection {
 
   bool useCodeAlign() const override { return false; }
 
-  MCSection *getParent() const { return Parent; }
-  uint32_t getSubsection() const { return Subsection; }
+  // Accessors to the various symbol names.
+  StringRef getSDName() const { return SDName; };
+  StringRef getEDName() const { return EDName; };
+  StringRef getLDorPRName() const {
+    assert(Flags & (HasLD | HasPR) && "LD/PR name not available");
+    return (Flags & LDorPRNameIsSD) ? SDName : LDorPRName;
+  };
+
+  // Setters for the SD and LD/PR symbol names.
+  void setSDName(StringRef Name) { SDName = Name; }
+  void setLDorPRName(StringRef Name) { LDorPRName = Name; }
+
+  // Accessors to the various attributes.
+  GOFF::SDAttr getSDAttributes() const { return SDAttributes; }
+  GOFF::EDAttr getEDAttributes() const { return EDAttributes; }
+  GOFF::LDAttr getLDAttributes() const {
+    assert(Flags & HasLD && "LD not available");
+    return LDAttributes;
+  }
+  GOFF::PRAttr getPRAttributes() const {
+    assert(Flags & HasPR && "PR not available");
+    return PRAttributes;
+  }
+
+  // Query various flags.
+  bool usesRootSD() const { return Flags & UsesRootSD; }
+  bool hasLD() const { return Flags & HasLD; }
+  bool hasPR() const { return Flags & HasPR; }
+  bool isLDorPRNameTheSD() const { return Flags & LDorPRNameIsSD; }
+
+  bool isADA() const { return IsADA; }
+  void setADA() { IsADA = true; }
 
   static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; }
 };
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 00e4533559c28..529e86c0b893a 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -47,6 +47,7 @@
 #include "llvm/MC/MCAsmInfoDarwin.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCGOFFAttributes.h"
 #include "llvm/MC/MCSectionCOFF.h"
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCSectionGOFF.h"
@@ -2759,6 +2760,12 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA(
 //===----------------------------------------------------------------------===//
 TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default;
 
+void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
+  // Set the main file name if not set previously by the tool.
+  if (getContext().getMainFileName().empty())
+    getContext().setMainFileName(M.getSourceFileName());
+}
+
 MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
   return SelectSectionForGlobal(GO, Kind, TM);
@@ -2767,15 +2774,55 @@ MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
 MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
     const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
   std::string Name = ".gcc_exception_table." + F.getName().str();
-  return getContext().getGOFFSection(Name, SectionKind::getData(), nullptr, 0);
+  constexpr bool Is64Bit = true;
+  constexpr bool UsesXPLINK = true;
+  return getContext().getGOFFSection(
+      SectionKind::getData(), GOFF::WSA<true>,
+      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>,
+                   GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_Parts,
+                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
+                   GOFF::LOADBEHAVIOR<UsesXPLINK>, GOFF::ESD_RQ_0,
+                   GOFF::ESD_ALIGN_Doubleword},
+      Name,
+      GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
+                   GOFF::LINKAGE<UsesXPLINK>, GOFF::AMODE<Is64Bit>,
+                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
+                   GOFF::ESD_ALIGN_Fullword, 0});
 }
 
 MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
   auto *Symbol = TM.getSymbol(GO);
-  if (Kind.isBSS())
-    return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(),
-                                       nullptr, 0);
-
-  return getContext().getObjectFileInfo()->getTextSection();
+  constexpr bool Is64Bit = true;
+  constexpr bool UsesXPLINK = true;
+
+  if (Kind.isBSS() || Kind.isData()) {
+    GOFF::ESDBindingScope PRBindingScope =
+        GO->hasExternalLinkage()
+            ? (GO->hasDefaultVisibility() ? GOFF::ESD_BSC_ImportExport
+                                          : GOFF::ESD_BSC_Library)
+            : GOFF::ESD_BSC_Section;
+    GOFF::ESDBindingScope SDBindingScope =
+        PRBindingScope == GOFF::ESD_BSC_Section ? GOFF::ESD_BSC_Section
+                                                : GOFF::ESD_BSC_Unspecified;
+    return getContext().getGOFFSection(
+        Kind, Symbol->getName(),
+        GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope},
+        GOFF::WSA<Is64Bit>,
+        GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>,
+                     GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_Parts,
+                     GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
+                     GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0,
+                     static_cast<GOFF::ESDAlignment>(GO->getAlignment())
+
+        },
+        Symbol->getName(),
+        GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
+                     GOFF::LINKAGE<UsesXPLINK>, GOFF::AMODE<Is64Bit>,
+                     PRBindingScope, GOFF::ESD_DSS_NoWarning,
+                     static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0
+
+        });
+  }
+  return TextSection;
 }
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index 967ec73a2be5b..f49f14c848b90 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -26,7 +26,6 @@ add_llvm_component_library(LLVMMC
   MCExpr.cpp
   MCFragment.cpp
   MCGOFFStreamer.cpp
-  MCGOFFSymbolMapper.cpp
   MCInst.cpp
   MCInstPrinter.cpp
   MCInstrAnalysis.cpp
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 062e62f31be40..cb8820d82f65f 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -13,7 +13,7 @@
 #include "llvm/BinaryFormat/GOFF.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCGOFFObjectWriter.h"
-#include "llvm/MC/MCGOFFSymbolMapper.h"
+#include "llvm/MC/MCGOFFAttributes.h"
 #include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/Support/Casting.h"
@@ -219,7 +219,7 @@ class GOFFSymbol {
 
   GOFFSymbol() : EsdId(0), ParentEsdId(0) {}
 
-  GOFFSymbol(StringRef Name, uint32_t EsdID, const SDAttr &Attr)
+  GOFFSymbol(StringRef Name, uint32_t EsdID, const GOFF::SDAttr &Attr)
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(0),
         SymbolType(GOFF::ESD_ST_SectionDefinition) {
     BehavAttrs.setTaskingBehavior(Attr.TaskingBehavior);
@@ -227,7 +227,7 @@ class GOFFSymbol {
   }
 
   GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
-             const EDAttr &Attr)
+             const GOFF::EDAttr &Attr)
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
         SymbolType(GOFF::ESD_ST_ElementDefinition) {
     this->NameSpace = Attr.NameSpace;
@@ -245,7 +245,7 @@ class GOFFSymbol {
   }
 
   GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
-             const LDAttr &Attr)
+             const GOFF::LDAttr &Attr)
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
         SymbolType(GOFF::ESD_ST_LabelDefinition) {
     this->NameSpace = Attr.NameSpace;
@@ -258,7 +258,7 @@ class GOFFSymbol {
   }
 
   GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
-             const PRAttr &Attr)
+             const GOFF::PRAttr &Attr)
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
         SymbolType(GOFF::ESD_ST_PartReference) {
     this->NameSpace = Attr.NameSpace;
@@ -277,9 +277,6 @@ class GOFFWriter {
   GOFFOstream OS;
   [[maybe_unused]] MCAssembler &Asm;
 
-  /// Mapping from MCSectionGOFF/MCSymbolGOFF to GOFF symbols and attributes.
-  GOFFSymbolMapper SymbolMapper;
-
   /// Counter for symbol id's.
   uint32_t EsdIdCounter = 0;
 
@@ -291,12 +288,12 @@ class GOFFWriter {
   void writeSymbol(const GOFFSymbol &Symbol);
   void writeEnd();
 
-  GOFFSymbol createGOFFSymbol(StringRef Name, const SDAttr &Attr);
-  GOFFSymbol createGOFFSymbol(StringRef Name, const EDAttr &Attr,
+  GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::SDAttr &Attr);
+  GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::EDAttr &Attr,
                               uint32_t ParentEsdId);
-  GOFFSymbol createGOFFSymbol(StringRef Name, const LDAttr &Attr,
+  GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::LDAttr &Attr,
                               uint32_t ParentEsdId);
-  GOFFSymbol createGOFFSymbol(StringRef Name, const PRAttr &Attr,
+  GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::PRAttr &Attr,
                               uint32_t ParentEsdId);
 
   void defineRootSymbol(const MCSectionGOFF *Text);
@@ -310,66 +307,64 @@ class GOFFWriter {
 } // namespace
 
 GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
-    : OS(OS), Asm(Asm), SymbolMapper(Asm) {}
+    : OS(OS), Asm(Asm) {}
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const SDAttr &Attr) {
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::SDAttr &Attr) {
   return GOFFSymbol(Name, ++EsdIdCounter, Attr);
 }
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const EDAttr &Attr,
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::EDAttr &Attr,
                                         uint32_t ParentEsdId) {
   return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
 }
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const LDAttr &Attr,
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::LDAttr &Attr,
                                         uint32_t ParentEsdId) {
   return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
 }
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const PRAttr &Attr,
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::PRAttr &Attr,
                                         uint32_t ParentEsdId) {
   return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
 }
 
 void GOFFWriter::defineRootSymbol(const MCSectionGOFF *Text) {
-  // There is always a text section except for DWARF unit tests.
-  SymbolMapper.determineRootSD("");
+  // There is always a text section except for DWARF unit tests, so be lenient.
   GOFFSymbol RootSD =
-      createGOFFSymbol(SymbolMapper.getRootSDName(), SymbolMapper.getRootSD());
+      Text ? createGOFFSymbol(Text->getSDName(), Text->getSDAttributes())
+           : createGOFFSymbol("", GOFF::SDAttr{GOFF::ESD_TA_Unspecified,
+                                               GOFF::ESD_BSC_Unspecified});
   writeSymbol(RootSD);
   RootSDEsdId = RootSD.EsdId;
 }
 
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
-  auto [GOFFSectionData, Found] = SymbolMapper.getSection(Section);
-  if (Found) {
     uint32_t SDEsdId = RootSDEsdId;
-    if (!GOFFSectionData.IsSDRootSD) {
-      GOFFSymbol SD = createGOFFSymbol(GOFFSectionData.SDName,
-                                       GOFFSectionData.SDAttributes);
+    if (!Section.usesRootSD()) {
+      GOFFSymbol SD =
+          createGOFFSymbol(Section.getSDName(), Section.getSDAttributes());
       SDEsdId = SD.EsdId;
       writeSymbol(SD);
     }
 
-    GOFFSymbol ED = createGOFFSymbol(GOFFSectionData.EDName,
-                                     GOFFSectionData.EDAttributes, SDEsdId);
-    if (GOFFSectionData.Tag == GOFFSectionData::None ||
-        GOFFSectionData.Tag == GOFFSectionData::LD) {
+    GOFFSymbol ED = createGOFFSymbol(Section.getEDName(),
+                                     Section.getEDAttributes(), SDEsdId);
+    if ((!Section.hasLD() && !Section.hasPR()) || Section.hasLD()) {
       ED.SectionLength = Asm.getSectionAddressSize(Section);
     }
     writeSymbol(ED);
 
-    if (GOFFSectionData.Tag == GOFFSectionData::LD) {
-      GOFFSymbol LD = createGOFFSymbol(GOFFSectionData.LDorPRName,
-                                       GOFFSectionData.LDAttributes, ED.EsdId);
+    if (Section.hasLD()) {
+      GOFFSymbol LD = createGOFFSymbol(Section.getLDorPRName(),
+                                       Section.getLDAttributes(), ED.EsdId);
       if (Section.isText())
         LD.ADAEsdId = ADAEsdId;
       writeSymbol(LD);
     }
 
-    if (GOFFSectionData.Tag == GOFFSectionData::PR) {
-      GOFFSymbol PR = createGOFFSymbol(GOFFSectionData.LDorPRName,
-                                       GOFFSectionData.PRAttributes, ED.EsdId);
+    if (Section.hasPR()) {
+      GOFFSymbol PR = createGOFFSymbol(Section.getLDorPRName(),
+                                       Section.getPRAttributes(), ED.EsdId);
       PR.SectionLength = Asm.getSectionAddressSize(Section);
       if (Section.getName() == ".ada") {
         // We cannot have a zero-length section for data.  If we do,
@@ -383,21 +378,18 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
       }
       writeSymbol(PR);
     }
-    return;
-  }
-  // TODO It is possible to get here. This will be handled later.
 }
 
 void GOFFWriter::defineSymbols() {
-  // Search for .text and .ada sections. These should be the first sections in
-  // the list, so the loop should be cheap.
+  // Search for .text and .ada sections.
   MCSectionGOFF *Text = nullptr;
   MCSectionGOFF *ADA = nullptr;
   for (MCSection &S : Asm) {
-    if (S.getName() == ".text")
-      Text = &cast<MCSectionGOFF>(S);
-    if (S.getName() == ".ada")
-      ADA = &cast<MCSectionGOFF>(S);
+    auto &Section = cast<MCSectionGOFF>(S);
+    if (Section.isText())
+      Text = &Section;
+    if (Section.isADA())
+      ADA = &Section;
   }
   defineRootSymbol(Text);
   if (ADA)
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 09d4b518cc1c5..38b54ef50489d 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -671,24 +671,82 @@ MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
                                       : std::nullopt;
 }
 
-MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
-                                         MCSection *Parent,
-                                         uint32_t Subsection) {
+MCSectionGOFF *
+MCContext::getGOFFSection(SectionKind Kind, StringRef SDName,
+                          GOFF::SDAttr SDAttributes, StringRef EDName,
+                          GOFF::EDAttr EDAttributes, StringRef LDorPRName,
+                          GOFF::LDAttr LDAttributes, GOFF::PRAttr PRAttributes,
+                          MCSectionGOFF::SectionFlags Flags) {
+  std::string SynName = Twine(SDName)
+                            .concat("/")
+                            .concat(EDName)
+                            .concat("/")
+                            .concat(LDorPRName)
+                            .str();
   // Do the lookup. If we don't have a hit, return a new section.
-  auto IterBool =
-      GOFFUniquingMap.insert(std::make_pair(Section.str(), nullptr));
+  auto IterBool = GOFFUniquingMap.insert(std::make_pair(SynName, nullptr));
   auto Iter = IterBool.first;
   if (!IterBool.second)
     return Iter->second;
 
-  StringRef CachedName = Iter->first;
+  StringRef CachedSynName = Iter->first;
   MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate())
-      MCSectionGOFF(CachedName, Kind, Parent, Subsection);
+      MCSectionGOFF(CachedSynName, Kind, Flags, SDName, SDAttributes, EDName,
+                    EDAttributes, LDorPRName, LDAttributes, PRAttributes);
   Iter->second = GOFFSection;
   allocInitialFragment(*GOFFSection);
   return GOFFSection;
 }
 
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef SDName,
+                                         GOFF::SDAttr SDAttributes,
+                                         StringRef EDName,
+                                         GOFF::EDAttr EDAttributes,
+                                         StringRef LDorPRName,
+                                         GOFF::LDAttr LDAttributes) {
+  return getGOFFSection(Kind, SDName, SDAttributes, EDName, EDAttributes,
+                        LDorPRName, LDAttributes, GOFF::PRAttr{},
+                        MCSectionGOFF::HasLD);
+}
+
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef SDName,
+                                         GOFF::SDAttr SDAttributes,
+                                         StringRef EDName,
+                                         GOFF::EDAttr EDAttributes,
+                                         StringRef LDorPRName,
+                                         GOFF::PRAttr PRAttributes) {
+  return getGOFFSection(Kind, SDName, SDAttributes, EDName, EDAttributes,
+                        LDorPRName, GOFF::LDAttr{}, PRAttributes,
+                        MCSectionGOFF::HasPR);
+}
+
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
+                                         GOFF::EDAttr EDAttributes,
+                                         GOFF::LDAttr LDAttributes) {
+  return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes, "",
+                        LDAttributes, GOFF::PRAttr{},
+                        MCSectionGOFF::UsesRootSD |
+                            MCSectionGOFF::LDorPRNameIsSD |
+                            MCSectionGOFF::HasLD);
+}
+
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
+                                         GOFF::EDAttr EDAttributes,
+                                         StringRef LDorPRName,
+                                         GOFF::PRAttr PRAttributes) {
+  return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes,
+                        LDorPRName, GOFF::LDAttr{}, PRAttributes,
+                        MCSectionGOFF::UsesRootSD | MCSectionGOFF::HasPR);
+}
+
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
+                                         GOFF::EDAttr EDAttributes) {
+  return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes, "",
+                        GOFF::LDAttr{}, GOFF::PRAttr{},
+                        MCSectionGOFF::UsesRootSD |
+                            MCSectionGOFF::LDorPRNameIsSD);
+}
+
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
                                          unsigned Characteristics,
                                          StringRef COMDATSymName, int Selection,
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index c9e4c21c857ce..9b97c147ef5b3 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -26,6 +26,24 @@ GOFFObjectWriter &MCGOFFStreamer::getWriter() {
   return static_cast<GOFFObjectWriter &>(getAssembler().getWriter());
 }
 
+void MCGOFFStreamer::initSections(bool NoExecStack,
+                                  const MCSubtargetInfo &STI) {
+  MCContext &Ctx = getContext();
+
+  // Initialize the special names for the code and ada section.
+  StringRef FileName = Ctx.getMainFileName();
+  RootSDName = Twine(FileName).concat("#C").str();
+  ADAPRName = Twine(FileName).concat("#S").str();
+  MCSectionGOFF *TextSection = static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getTextSection());
+  MCSectionGOFF *ADASection = static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getADASection());
+  TextSection->setSDName(RootSDName);
+  ADASection->setLDorPRName(ADAPRName);
+  ADASection->setADA();
+
+  // Switch to the code section.
+  switchSection(TextSection);
+}
+
 MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
                                      std::unique_ptr<MCAsmBackend> &&MAB,
                                      std::unique_ptr<MCObjectWriter> &&OW,
diff --git a/llvm/lib/MC/MCGOFFSymbolMapper.cpp b/llvm/lib/MC/MCGOFFSymbolMapper.cpp
deleted file mode 100644
index 57012c34a94f1..0000000000000
--- a/llvm/lib/MC/MCGOFFSymbolMapper.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-//===- MCGOFFSymbolMapper.cpp - Maps MC section/symbol to GOFF symbols ----===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Maps a section or a symbol to the GOFF symbols it is composed of, and their
-// attributes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCGOFFSymbolMapper.h"
-#include "llvm/BinaryFormat/GOFF.h"
-#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCObjectWriter.h"
-#include "llvm/MC/MCSectionGOFF.h"
-#include "llvm/Support/Alignment.h"
-#include "llvm/Support/Path.h"
-
-using namespace llvm;
-
-namespace {
-const StringLiteral CODE[2]{"C_CODE", "C_CODE64"};
-const StringLiteral WSA[2]{"C_WSA", "C_WSA64"};
-const StringLiteral PPA2[2]{"C_@@PPA2", "C_@@QPPA2"};
-
-const GOFF::ESDAmode AMODE[2]{GOFF::ESD_AMODE_ANY, GOFF::ESD_AMODE_64};
-const GOFF::ESDRmode RMODE[2]{GOFF::ESD_RMODE_31, GOFF::ESD_RMODE_64};
-
-const GOFF::ESDLinkageType LINKAGE[2]{GOFF::ESD_LT_OS, GOFF::ESD_LT_XPLink};
-} // namespace
-
-GOFFSymbolMapper::GOFFSymbolMapper(MCContext &Ctx) : Ctx(Ctx) {
-  IsCsectCodeNameEmpty = true;
-  Is64Bit = true;
-  UsesXPLINK = true;
-}
-
-GOFFSymbolMapper::GOFFSymbolMapper(MCAssembler &Asm)
-    : GOFFSymbolMapper(Asm.getContext()) {
-  if (!Asm.getWriter().getFileNames().empty())
-    BaseName =
-        sys::path::stem((*(Asm.getWriter().getFileNames().begin())).first);
-}
-
-void GOFFSymbolMapper::determineRootSD(StringRef CSectCodeName) {
-  IsCsectCodeNameEmpty = CSectCodeName.empty();
-  if (IsCsectCodeNameEmpty) {
-    RootSDName = BaseName.str().append("#C");
-  } else {
-    RootSDName = CSectCodeName;
-  }
-  RootSDAttributes = {GOFF::ESD_TA_Rent, IsCsectCodeNameEmpty
-                                             ? GOFF::ESD_BSC_Section
-                                             : GOFF::ESD_BSC_Unspecified};
-}
-
-llvm::StringRef GOFFSymbolMapper::getRootSDName() const { return RootSDName; }
-
-const SDAttr &GOFFSymbolMapper::getRootSD() const { return RootSDAttributes; }
-
-std::pair<GOFFSectionData, bool>
-GOFFSymbolMapper::getSection(const MCSectionGOFF &Section) {
-  // Look up GOFFSection from name in MCSectionGOFF.
-  // Customize result, e.g. csect names, 32/64 bit, etc.
-  GOFFSectionData GOFFSec;
-  if (Section.getName() == ".text") {
-    GOFFSec.SDName = RootSDName;
-    GOFFSec.SDAttributes = RootSDAttributes;
-    GOFFSec.IsSDRootSD = true;
-    GOFFSec.EDName = CODE[Is64Bit];
-    // The GOFF alignment is encoded as log_2 value.
-    uint8_t Log = Log2(Section.getAlign());
-    assert(Log <= GOFF::ESD_ALIGN_4Kpage && "Alignment too large");
-    GOFFSec.EDAttributes = {true,
-                            GOFF::ESD_EXE_CODE,
-                            AMODE[Is64Bit],
-                            RMODE[Is64Bit],
-                            GOFF::ESD_NS_NormalName,
-                            GOFF::ESD_TS_ByteOriented,
-                            GOFF::ESD_BA_Concatenate,
-                            GOFF::ESD_LB_Initial,
-                            GOFF::ESD_RQ_0,
-                            static_cast<GOFF::ESDAlignment>(Log)};
-    GOFFSec.LDorPRName = GOFFSec.SDName;
-    GOFFSec.LDAttributes = {false,
-                            GOFF::ESD_EXE_CODE,
-                            GOFF::ESD_NS_NormalName,
-                            GOFF::ESD_BST_Strong,
-                            LINKAGE[UsesXPLINK],
-                            AMODE[Is64Bit],
-                            IsCsectCodeNameEmpty ? GOFF::ESD_BSC_Section
-                                                 : GOFF::ESD_BSC_Library};
-    GOFFSec.Tag = GOFFSectionData::LD;
-  } else if (Section.getName() == ".ada") {
-    assert(!RootSDName.empty() && "RootSD must be defined already");
-    GOFFSec.SDName = RootSDName;
-    GOFFSec.SDAttributes = RootSDAttributes;
-    GOFFSec.IsSDRootSD = true;
-    GOFFSec.EDName = WSA[Is64Bit];
-    GOFFSec.EDAttributes = {false,
-                            GOFF::ESD_EXE_DATA,
-                            AMODE[Is64Bit],
-                            RMODE[Is64Bit],
-                            GOFF::ESD_NS_Parts,
-                            GOFF::ESD_TS_ByteOriented,
-                            GOFF::ESD_BA_Merge,
-                            GOFF::ESD_LB_Deferred,
-                            GOFF::ESD_RQ_1,
-                            Is64Bit ? GOFF::ESD_ALIGN_Quadword
-                                    : GOFF::ESD_ALIGN_Doubleword};
-    ADALDName = BaseName.str().append("#S");
-    GOFFSec.LDorPRName = ADALDName;
-    GOFFSec.PRAttributes = {false,
-                            false,
-                            GOFF::ESD_EXE_DATA,
-                            GOFF::ESD_NS_Parts,
-                            GOFF::ESD_LT_XPLink,
-                            AMODE[Is64Bit],
-                            GOFF::ESD_BSC_Section,
-                            GOFF::ESD_DSS_NoWarning,
-                            Is64Bit ? GOFF::ESD_ALIGN_Quadword
-                                    : GOFF::ESD_ALIGN_Doubleword,
-                            0};
-    GOFFSec.Tag = GOFFSectionData::PR;
-  } else if (Section.getName().starts_with(".gcc_exception_table")) {
-    GOFFSec.SDName = RootSDName;
-    GOFFSec.SDAttributes = RootSDAttributes;
-    GOFFSec.IsSDRootSD = true;
-    GOFFSec.EDName = WSA[Is64Bit];
-    GOFFSec.EDAttributes = {false,
-                            GOFF::ESD_EXE_DATA,
-                            AMODE[Is64Bit],
-                            RMODE[Is64Bit],
-                            GOFF::ESD_NS_Parts,
-                            GOFF::ESD_TS_ByteOriented,
-                            GOFF::ESD_BA_Merge,
-                            UsesXPLINK ? GOFF::ESD_LB_Initial
-                                       : GOFF::ESD_LB_Deferred,
-                            GOFF::ESD_RQ_0,
-                            GOFF::ESD_ALIGN_Doubleword};
-    GOFFSec.LDorPRName = Section.getName();
-    GOFFSec.PRAttributes = {true,
-                            false,
-                            GOFF::ESD_EXE_Unspecified,
-                            GOFF::ESD_NS_Parts,
-                            LINKAGE[UsesXPLINK],
-                            AMODE[Is64Bit],
-                            GOFF::ESD_BSC_Section,
-                            GOFF::ESD_DSS_NoWarning,
-                            GOFF::ESD_ALIGN_Fullword,
-                            0};
-    GOFFSec.Tag = GOFFSectionData::PR;
-  } else if (Section.getName() == ".ppa2list") {
-    GOFFSec.SDName = RootSDName;
-    GOFFSec.SDAttributes = RootSDAttributes;
-    GOFFSec.IsSDRootSD = true;
-    GOFFSec.EDName = PPA2[Is64Bit];
-    GOFFSec.EDAttributes = {true,
-                            GOFF::ESD_EXE_DATA,
-                            AMODE[Is64Bit],
-                            RMODE[Is64Bit],
-                            GOFF::ESD_NS_Parts,
-                            GOFF::ESD_TS_ByteOriented,
-                            GOFF::ESD_BA_Merge,
-                            GOFF::ESD_LB_Initial,
-                            GOFF::ESD_RQ_0,
-                            GOFF::ESD_ALIGN_Doubleword};
-    GOFFSec.LDorPRName = ".&ppa2";
-    GOFFSec.PRAttributes = {true,
-                            false,
-                            GOFF::ESD_EXE_Unspecified,
-                            GOFF::ESD_NS_Parts,
-                            GOFF::ESD_LT_OS,
-                            AMODE[Is64Bit],
-                            GOFF::ESD_BSC_Section,
-                            GOFF::ESD_DSS_NoWarning,
-                            GOFF::ESD_ALIGN_Doubleword,
-                            0};
-    GOFFSec.Tag = GOFFSectionData::PR;
-  } else if (Section.getName() == ".idrl") {
-    GOFFSec.SDName = RootSDName;
-    GOFFSec.SDAttributes = RootSDAttributes;
-    GOFFSec.IsSDRootSD = true;
-    GOFFSec.EDName = "B_IDRL";
-    GOFFSec.EDAttributes = {true,
-                            GOFF::ESD_EXE_Unspecified,
-                            AMODE[Is64Bit],
-                            RMODE[Is64Bit],
-                            GOFF::ESD_NS_NormalName,
-                            GOFF::ESD_TS_Structured,
-                            GOFF::ESD_BA_Concatenate,
-                            GOFF::ESD_LB_NoLoad,
-                            GOFF::ESD_RQ_0,
-                            GOFF::ESD_ALIGN_Doubleword};
-    GOFFSec.Tag = GOFFSectionData::None;
-  } else
-    return std::pair(GOFFSec, false);
-  return std::pair(GOFFSec, true);
-}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index a514a07ef7d3e..8def94ad51038 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -13,6 +13,7 @@
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCGOFFAttributes.h"
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCSectionCOFF.h"
 #include "llvm/MC/MCSectionDXContainer.h"
@@ -546,18 +547,51 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
 }
 
 void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
-  TextSection = Ctx->getGOFFSection(".text", SectionKind::getText(), nullptr);
-  BSSSection = Ctx->getGOFFSection(".bss", SectionKind::getBSS(), nullptr);
-  PPA1Section = Ctx->getGOFFSection(".ppa1", SectionKind::getMetadata(),
-                                    TextSection, GOFF::SK_PPA1);
-  PPA2Section = Ctx->getGOFFSection(".ppa2", SectionKind::getMetadata(),
-                                    TextSection, GOFF::SK_PPA2);
-
-  PPA2ListSection =
-      Ctx->getGOFFSection(".ppa2list", SectionKind::getData(), nullptr);
-
-  ADASection = Ctx->getGOFFSection(".ada", SectionKind::getData(), nullptr);
-  IDRLSection = Ctx->getGOFFSection(".idrl", SectionKind::getData(), nullptr);
+  // Some values depend on AMODE31 or AMODE64, or other properties.
+  constexpr bool Is64Bit = true;
+  constexpr bool UsesXPLINK = true;
+
+  TextSection = Ctx->getGOFFSection(
+      SectionKind::getText(), GOFF::CODE<Is64Bit>,
+      GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::AMODE<Is64Bit>,
+                   GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_NormalName,
+                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate,
+                   GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
+                   GOFF::ESD_ALIGN_Doubleword},
+      GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, GOFF::ESD_NS_NormalName,
+                   GOFF::ESD_BST_Strong, GOFF::LINKAGE<UsesXPLINK>,
+                   GOFF::AMODE<Is64Bit>, GOFF::ESD_BSC_Section});
+
+  PPA2ListSection = Ctx->getGOFFSection(
+      SectionKind::getData(), GOFF::PPA2<Is64Bit>,
+      GOFF::EDAttr{
+          true, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>, GOFF::RMODE<Is64Bit>,
+          GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
+          GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
+      ".&ppa2",
+      GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
+                   GOFF::ESD_LT_OS, GOFF::AMODE<Is64Bit>, GOFF::ESD_BSC_Section,
+                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Doubleword, 0});
+
+  ADASection = Ctx->getGOFFSection(
+      SectionKind::getData(), GOFF::WSA<Is64Bit>,
+      GOFF::EDAttr{
+          false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>, GOFF::RMODE<Is64Bit>,
+          GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
+          GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1, GOFF::ESD_ALIGN_Quadword},
+      "",
+      GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
+                   GOFF::ESD_LT_XPLink, GOFF::AMODE<Is64Bit>,
+                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
+                   GOFF::ESD_ALIGN_Quadword, 0});
+
+  IDRLSection = Ctx->getGOFFSection(
+      SectionKind::getData(), "B_IDRL",
+      GOFF::EDAttr{true, GOFF::ESD_EXE_Unspecified, GOFF::AMODE<Is64Bit>,
+                   GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_NormalName,
+                   GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate,
+                   GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0,
+                   GOFF::ESD_ALIGN_Doubleword});
 }
 
 void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 448753fa43dc1..e18630b710e10 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -21,6 +21,7 @@
 #include "TargetInfo/SystemZTargetInfo.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/GOFF.h"
 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
 #include "llvm/IR/Mangler.h"
@@ -1229,7 +1230,8 @@ void SystemZAsmPrinter::emitFunctionBodyEnd() {
     OutStreamer->emitLabel(FnEndSym);
 
     OutStreamer->pushSection();
-    OutStreamer->switchSection(getObjFileLowering().getPPA1Section());
+    OutStreamer->switchSection(getObjFileLowering().getTextSection(),
+                               GOFF::SK_PPA1);
     emitPPA1(FnEndSym);
     OutStreamer->popSection();
 
@@ -1534,7 +1536,8 @@ void SystemZAsmPrinter::emitStartOfAsmFile(Module &M) {
 
 void SystemZAsmPrinter::emitPPA2(Module &M) {
   OutStreamer->pushSection();
-  OutStreamer->switchSection(getObjFileLowering().getPPA2Section());
+  OutStreamer->switchSection(getObjFileLowering().getTextSection(),
+                             GOFF::SK_PPA2);
   MCContext &OutContext = OutStreamer->getContext();
   // Make CELQSTRT symbol.
   const char *StartSymbolName = "CELQSTRT";
diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll
index a0c64f0b83013..16c3580fcf924 100644
--- a/llvm/test/MC/GOFF/section.ll
+++ b/llvm/test/MC/GOFF/section.ll
@@ -1,6 +1,5 @@
 ; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj -o - | \
 ; RUN:   od -Ax -tx1 -v | FileCheck --ignore-case %s
-; REQUIRES: systemz-registered-target
 
 source_filename = "test.ll"
 

>From 686b6284b3682b330f99839e3928ca46c5a44c6a Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 2 Apr 2025 19:48:21 -0400
Subject: [PATCH 07/35] Update formatting

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

diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 9b97c147ef5b3..b05cd46ef3fcf 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -34,8 +34,10 @@ void MCGOFFStreamer::initSections(bool NoExecStack,
   StringRef FileName = Ctx.getMainFileName();
   RootSDName = Twine(FileName).concat("#C").str();
   ADAPRName = Twine(FileName).concat("#S").str();
-  MCSectionGOFF *TextSection = static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getTextSection());
-  MCSectionGOFF *ADASection = static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getADASection());
+  MCSectionGOFF *TextSection =
+      static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getTextSection());
+  MCSectionGOFF *ADASection =
+      static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getADASection());
   TextSection->setSDName(RootSDName);
   ADASection->setLDorPRName(ADAPRName);
   ADASection->setADA();

>From c7fcda945d4f8382a96977798a5eb251110e6b2a Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Thu, 3 Apr 2025 16:02:12 -0400
Subject: [PATCH 08/35] More updates

---
 llvm/include/llvm/MC/MCContext.h              |  3 +-
 llvm/include/llvm/MC/MCGOFFAttributes.h       | 40 +++++--------
 llvm/include/llvm/MC/MCSectionGOFF.h          |  9 ++-
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  | 32 ++++-------
 llvm/lib/MC/GOFFObjectWriter.cpp              | 38 +++----------
 llvm/lib/MC/MCContext.cpp                     | 12 ++--
 llvm/lib/MC/MCGOFFStreamer.cpp                | 10 ++--
 llvm/lib/MC/MCObjectFileInfo.cpp              | 56 +++++++++----------
 8 files changed, 75 insertions(+), 125 deletions(-)

diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index a35df1bba4bc1..d143189e83904 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -619,9 +619,10 @@ class MCContext {
                                 GOFF::SDAttr SDAttributes, StringRef EDName,
                                 GOFF::EDAttr EDAttributes, StringRef LDorPRName,
                                 GOFF::PRAttr PRAttributes);
-  // Create a section with root-SD/ED/LD symbols, using the root-SD name for LD.
+  // Create a section with root-SD/ED/LD symbols.
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
                                 GOFF::EDAttr EDAttributes,
+                                StringRef LDorPRName,
                                 GOFF::LDAttr LDAttributes);
   // Create a section with root-SD/ED/PR symbols.
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index 6a27438b6e81a..02a336dc2a67a 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -89,38 +89,24 @@ struct PRAttr {
 };
 
 // Class names and other values depending on AMODE64 or AMODE31, and other
-// environment properties.
-template <bool Is64Bit>
-constexpr StringLiteral CODE =
-    Is64Bit ? StringLiteral("C_CODE64") : StringLiteral("C_CODE");
+// environment properties. For now, only the 64 bit XPLINK case is defined.
 
-template <bool Is64Bit>
-constexpr StringLiteral WSA =
-    Is64Bit ? StringLiteral("C_WSA64") : StringLiteral("C_WSA");
+// GOFF classes.
+constexpr StringLiteral CLASS_CODE = "C_CODE64";
+constexpr StringLiteral CLASS_WSA = "C_WSA64";
+constexpr StringLiteral CLASS_DATA = "C_DATA64";
+constexpr StringLiteral CLASS_PPA2 = "C_@@QPPA2";
 
-template <bool Is64Bit>
-constexpr StringLiteral DATA =
-    Is64Bit ? StringLiteral("C_DATA64") : StringLiteral("C_DATA");
+// Addres and residency mode.
+constexpr GOFF::ESDAmode AMODE = GOFF::ESD_AMODE_64;
+constexpr GOFF::ESDRmode RMODE = GOFF::ESD_RMODE_64;
 
-template <bool Is64Bit>
-constexpr StringLiteral PPA2 =
-    Is64Bit ? StringLiteral("C_@@QPPA2") : StringLiteral("C_@@PPA2");
+// Linkage.
+constexpr GOFF::ESDLinkageType LINKAGE = GOFF::ESD_LT_XPLink;
 
-template <bool Is64Bit>
-constexpr GOFF::ESDAmode AMODE =
-    Is64Bit ? GOFF::ESD_AMODE_64 : GOFF::ESD_AMODE_ANY;
+// Loadding behavior.
+constexpr GOFF::ESDLoadingBehavior LOADBEHAVIOR = GOFF::ESD_LB_Initial;
 
-template <bool Is64Bit>
-constexpr GOFF::ESDRmode RMODE =
-    Is64Bit ? GOFF::ESD_RMODE_64 : GOFF::ESD_RMODE_31;
-
-template <bool IsXPLINK>
-constexpr GOFF::ESDLinkageType LINKAGE =
-    IsXPLINK ? GOFF::ESD_LT_XPLink : GOFF::ESD_LT_OS;
-
-template <bool IsXPLINK>
-constexpr GOFF::ESDLoadingBehavior LOADBEHAVIOR =
-    IsXPLINK ? GOFF::ESD_LB_Initial : GOFF::ESD_LB_Deferred;
 } // namespace GOFF
 } // namespace llvm
 
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 0683c4690b0ba..be0210bdd623b 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -49,7 +49,6 @@ class MCSectionGOFF final : public MCSection {
 
 private:
   SectionFlags Flags;
-  bool IsADA;
 
   friend class MCContext;
   MCSectionGOFF(StringRef SynName, SectionKind K, SectionFlags Flags,
@@ -78,7 +77,10 @@ class MCSectionGOFF final : public MCSection {
   };
 
   // Setters for the SD and LD/PR symbol names.
-  void setSDName(StringRef Name) { SDName = Name; }
+  void setSDName(StringRef Name) {
+    assert(!(Flags & UsesRootSD) && "Uses root SD");
+    SDName = Name;
+  }
   void setLDorPRName(StringRef Name) { LDorPRName = Name; }
 
   // Accessors to the various attributes.
@@ -99,9 +101,6 @@ class MCSectionGOFF final : public MCSection {
   bool hasPR() const { return Flags & HasPR; }
   bool isLDorPRNameTheSD() const { return Flags & LDorPRNameIsSD; }
 
-  bool isADA() const { return IsADA; }
-  void setADA() { IsADA = true; }
-
   static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; }
 };
 } // end namespace llvm
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 529e86c0b893a..0bd996a2e1d10 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2774,27 +2774,21 @@ MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
 MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
     const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
   std::string Name = ".gcc_exception_table." + F.getName().str();
-  constexpr bool Is64Bit = true;
-  constexpr bool UsesXPLINK = true;
   return getContext().getGOFFSection(
-      SectionKind::getData(), GOFF::WSA<true>,
-      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>,
-                   GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_Parts,
-                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
-                   GOFF::LOADBEHAVIOR<UsesXPLINK>, GOFF::ESD_RQ_0,
+      SectionKind::getData(), GOFF::CLASS_WSA,
+      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
+                   GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
+                   GOFF::ESD_BA_Merge, GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword},
       Name,
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
-                   GOFF::LINKAGE<UsesXPLINK>, GOFF::AMODE<Is64Bit>,
-                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
-                   GOFF::ESD_ALIGN_Fullword, 0});
+                   GOFF::LINKAGE, GOFF::AMODE, GOFF::ESD_BSC_Section,
+                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Fullword, 0});
 }
 
 MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
   auto *Symbol = TM.getSymbol(GO);
-  constexpr bool Is64Bit = true;
-  constexpr bool UsesXPLINK = true;
 
   if (Kind.isBSS() || Kind.isData()) {
     GOFF::ESDBindingScope PRBindingScope =
@@ -2807,19 +2801,17 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
                                                 : GOFF::ESD_BSC_Unspecified;
     return getContext().getGOFFSection(
         Kind, Symbol->getName(),
-        GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope},
-        GOFF::WSA<Is64Bit>,
-        GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>,
-                     GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_Parts,
-                     GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
-                     GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0,
+        GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope}, GOFF::CLASS_WSA,
+        GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
+                     GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
+                     GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0,
                      static_cast<GOFF::ESDAlignment>(GO->getAlignment())
 
         },
         Symbol->getName(),
         GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
-                     GOFF::LINKAGE<UsesXPLINK>, GOFF::AMODE<Is64Bit>,
-                     PRBindingScope, GOFF::ESD_DSS_NoWarning,
+                     GOFF::LINKAGE, GOFF::AMODE, PRBindingScope,
+                     GOFF::ESD_DSS_NoWarning,
                      static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0
 
         });
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index cb8820d82f65f..891ee9d3fb907 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -284,6 +284,8 @@ class GOFFWriter {
   uint32_t RootSDEsdId = 0;
   uint32_t ADAEsdId = 0;
 
+  MCSectionGOFF *ADA = nullptr;
+
   void writeHeader();
   void writeSymbol(const GOFFSymbol &Symbol);
   void writeEnd();
@@ -296,7 +298,6 @@ class GOFFWriter {
   GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::PRAttr &Attr,
                               uint32_t ParentEsdId);
 
-  void defineRootSymbol(const MCSectionGOFF *Text);
   void defineSectionSymbols(const MCSectionGOFF &Section);
   void defineSymbols();
 
@@ -328,22 +329,14 @@ GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::PRAttr &Attr
   return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
 }
 
-void GOFFWriter::defineRootSymbol(const MCSectionGOFF *Text) {
-  // There is always a text section except for DWARF unit tests, so be lenient.
-  GOFFSymbol RootSD =
-      Text ? createGOFFSymbol(Text->getSDName(), Text->getSDAttributes())
-           : createGOFFSymbol("", GOFF::SDAttr{GOFF::ESD_TA_Unspecified,
-                                               GOFF::ESD_BSC_Unspecified});
-  writeSymbol(RootSD);
-  RootSDEsdId = RootSD.EsdId;
-}
-
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
     uint32_t SDEsdId = RootSDEsdId;
     if (!Section.usesRootSD()) {
       GOFFSymbol SD =
           createGOFFSymbol(Section.getSDName(), Section.getSDAttributes());
       SDEsdId = SD.EsdId;
+      if (RootSDEsdId == 0)
+        RootSDEsdId = SDEsdId;
       writeSymbol(SD);
     }
 
@@ -366,7 +359,7 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
       GOFFSymbol PR = createGOFFSymbol(Section.getLDorPRName(),
                                        Section.getPRAttributes(), ED.EsdId);
       PR.SectionLength = Asm.getSectionAddressSize(Section);
-      if (Section.getName() == ".ada") {
+      if (&Section == ADA) {
         // We cannot have a zero-length section for data.  If we do,
         // artificially inflate it. Use 2 bytes to avoid odd alignments. Note:
         // if this is ever changed, you will need to update the code in
@@ -381,27 +374,12 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
 }
 
 void GOFFWriter::defineSymbols() {
-  // Search for .text and .ada sections.
-  MCSectionGOFF *Text = nullptr;
-  MCSectionGOFF *ADA = nullptr;
+  // Process all sections.
   for (MCSection &S : Asm) {
     auto &Section = cast<MCSectionGOFF>(S);
-    if (Section.isText())
-      Text = &Section;
-    if (Section.isADA())
+    if (!ADA)
       ADA = &Section;
-  }
-  defineRootSymbol(Text);
-  if (ADA)
-    defineSectionSymbols(*ADA);
-  if (Text)
-    defineSectionSymbols(*Text);
-
-  // Process the other sections.
-  for (MCSection &S : Asm) {
-    auto &Section = cast<MCSectionGOFF>(S);
-    if (Text != &Section && ADA != &Section)
-      defineSectionSymbols(Section);
+    defineSectionSymbols(Section);
   }
 }
 
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 38b54ef50489d..56ca85d115792 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -722,12 +722,11 @@ MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef SDName,
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
                                          GOFF::EDAttr EDAttributes,
+                                         StringRef LDorPRName,
                                          GOFF::LDAttr LDAttributes) {
-  return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes, "",
-                        LDAttributes, GOFF::PRAttr{},
-                        MCSectionGOFF::UsesRootSD |
-                            MCSectionGOFF::LDorPRNameIsSD |
-                            MCSectionGOFF::HasLD);
+  return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes,
+                        LDorPRName, LDAttributes, GOFF::PRAttr{},
+                        MCSectionGOFF::UsesRootSD | MCSectionGOFF::HasLD);
 }
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
@@ -743,8 +742,7 @@ MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
                                          GOFF::EDAttr EDAttributes) {
   return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes, "",
                         GOFF::LDAttr{}, GOFF::PRAttr{},
-                        MCSectionGOFF::UsesRootSD |
-                            MCSectionGOFF::LDorPRNameIsSD);
+                        MCSectionGOFF::UsesRootSD);
 }
 
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index b05cd46ef3fcf..c67b4da6b3d74 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -17,6 +17,7 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCGOFFObjectWriter.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Path.h"
 
 using namespace llvm;
 
@@ -31,18 +32,19 @@ void MCGOFFStreamer::initSections(bool NoExecStack,
   MCContext &Ctx = getContext();
 
   // Initialize the special names for the code and ada section.
-  StringRef FileName = Ctx.getMainFileName();
+  StringRef FileName = sys::path::stem(Ctx.getMainFileName());
   RootSDName = Twine(FileName).concat("#C").str();
   ADAPRName = Twine(FileName).concat("#S").str();
   MCSectionGOFF *TextSection =
       static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getTextSection());
   MCSectionGOFF *ADASection =
       static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getADASection());
-  TextSection->setSDName(RootSDName);
+  ADASection->setSDName(RootSDName);
   ADASection->setLDorPRName(ADAPRName);
-  ADASection->setADA();
+  TextSection->setLDorPRName(RootSDName);
 
-  // Switch to the code section.
+  // Switch to the ADA section first, then code section.
+  switchSection(ADASection);
   switchSection(TextSection);
 }
 
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 8def94ad51038..2115641f74497 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -547,51 +547,45 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
 }
 
 void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
-  // Some values depend on AMODE31 or AMODE64, or other properties.
-  constexpr bool Is64Bit = true;
-  constexpr bool UsesXPLINK = true;
-
   TextSection = Ctx->getGOFFSection(
-      SectionKind::getText(), GOFF::CODE<Is64Bit>,
-      GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::AMODE<Is64Bit>,
-                   GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_NormalName,
-                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate,
-                   GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
-                   GOFF::ESD_ALIGN_Doubleword},
+      SectionKind::getText(), GOFF::CLASS_CODE,
+      GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::AMODE, GOFF::RMODE,
+                   GOFF::ESD_NS_NormalName, GOFF::ESD_TS_ByteOriented,
+                   GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_Initial,
+                   GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword}, "",
       GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, GOFF::ESD_NS_NormalName,
-                   GOFF::ESD_BST_Strong, GOFF::LINKAGE<UsesXPLINK>,
-                   GOFF::AMODE<Is64Bit>, GOFF::ESD_BSC_Section});
+                   GOFF::ESD_BST_Strong, GOFF::LINKAGE, GOFF::AMODE,
+                   GOFF::ESD_BSC_Section});
 
   PPA2ListSection = Ctx->getGOFFSection(
-      SectionKind::getData(), GOFF::PPA2<Is64Bit>,
-      GOFF::EDAttr{
-          true, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>, GOFF::RMODE<Is64Bit>,
-          GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
-          GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
+      SectionKind::getData(), GOFF::CLASS_PPA2,
+      GOFF::EDAttr{true, GOFF::ESD_EXE_DATA, GOFF::AMODE, 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},
       ".&ppa2",
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
-                   GOFF::ESD_LT_OS, GOFF::AMODE<Is64Bit>, GOFF::ESD_BSC_Section,
+                   GOFF::ESD_LT_OS, GOFF::AMODE, GOFF::ESD_BSC_Section,
                    GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Doubleword, 0});
 
   ADASection = Ctx->getGOFFSection(
-      SectionKind::getData(), GOFF::WSA<Is64Bit>,
-      GOFF::EDAttr{
-          false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>, GOFF::RMODE<Is64Bit>,
-          GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
-          GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1, GOFF::ESD_ALIGN_Quadword},
+      SectionKind::getData(), "",
+      GOFF::SDAttr{GOFF::ESD_TA_Rent, GOFF::ESD_BSC_Section}, GOFF::CLASS_WSA,
+      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
+                   GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
+                   GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
+                   GOFF::ESD_ALIGN_Quadword},
       "",
       GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
-                   GOFF::ESD_LT_XPLink, GOFF::AMODE<Is64Bit>,
-                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
-                   GOFF::ESD_ALIGN_Quadword, 0});
+                   GOFF::ESD_LT_XPLink, GOFF::AMODE, GOFF::ESD_BSC_Section,
+                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Quadword, 0});
 
   IDRLSection = Ctx->getGOFFSection(
       SectionKind::getData(), "B_IDRL",
-      GOFF::EDAttr{true, GOFF::ESD_EXE_Unspecified, GOFF::AMODE<Is64Bit>,
-                   GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_NormalName,
-                   GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate,
-                   GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0,
-                   GOFF::ESD_ALIGN_Doubleword});
+      GOFF::EDAttr{true, GOFF::ESD_EXE_Unspecified, GOFF::AMODE, GOFF::RMODE,
+                   GOFF::ESD_NS_NormalName, GOFF::ESD_TS_Structured,
+                   GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_NoLoad,
+                   GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword});
 }
 
 void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {

>From 1ca5fdc6356d1d6643e38e11ed82c7ce88551ff5 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 4 Apr 2025 17:04:34 -0400
Subject: [PATCH 09/35] Fix failing tests

Changes the `printSwitchToSection()` to be more HLASM-ish, and updates the test cases. That was necessary because the emitted name has changed.
However, zos-landingpad.ll is still failing due to a bug.
---
 llvm/include/llvm/MC/MCContext.h              |  3 +-
 llvm/include/llvm/MC/MCSectionGOFF.h          |  9 +-
 llvm/lib/MC/GOFFObjectWriter.cpp              | 90 ++++++++++---------
 llvm/lib/MC/MCObjectFileInfo.cpp              |  7 +-
 .../CodeGen/SystemZ/zos-ada-relocations.ll    |  4 +-
 llvm/test/CodeGen/SystemZ/zos-intrinsics.ll   |  4 +-
 llvm/test/CodeGen/SystemZ/zos-landingpad.ll   |  3 +-
 llvm/test/CodeGen/SystemZ/zos-ppa2.ll         |  4 +-
 llvm/test/CodeGen/SystemZ/zos-simple-test.ll  |  7 +-
 llvm/test/MC/GOFF/empty-goff.s                | 10 +--
 llvm/test/MC/GOFF/section.ll                  |  5 +-
 11 files changed, 82 insertions(+), 64 deletions(-)

diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index d143189e83904..30d4d6c197e69 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -621,8 +621,7 @@ class MCContext {
                                 GOFF::PRAttr PRAttributes);
   // Create a section with root-SD/ED/LD symbols.
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
-                                GOFF::EDAttr EDAttributes,
-                                StringRef LDorPRName,
+                                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
                                 GOFF::LDAttr LDAttributes);
   // Create a section with root-SD/ED/PR symbols.
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index be0210bdd623b..ac60a61b0a142 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -57,13 +57,18 @@ class MCSectionGOFF final : public MCSection {
                 GOFF::LDAttr LDAttributes, GOFF::PRAttr PRAttributes)
       : MCSection(SV_GOFF, SynName, K.isText(), /*IsVirtual=*/false, nullptr),
         SDName(SDName), EDName(EDName), LDorPRName(LDorPRName),
-        SDAttributes(SDAttributes), EDAttributes(EDAttributes), Flags(Flags) {}
+        SDAttributes(SDAttributes), EDAttributes(EDAttributes),
+        LDAttributes(LDAttributes), PRAttributes(PRAttributes), Flags(Flags) {}
 
 public:
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                             raw_ostream &OS,
                             uint32_t /*Subsection*/) const override {
-    OS << "\t.section\t\"" << getName() << "\"\n";
+    if (!usesRootSD())
+      OS << getSDName() << " CSECT\n";
+    OS << getEDName() << " CATTR\n";
+    if ((hasLD() || hasPR()) && !getLDorPRName().empty())
+      OS << getLDorPRName() << " XATTR\n";
   }
 
   bool useCodeAlign() const override { return false; }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 891ee9d3fb907..2aa3ffb0bf9a5 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -12,8 +12,8 @@
 
 #include "llvm/BinaryFormat/GOFF.h"
 #include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCGOFFObjectWriter.h"
 #include "llvm/MC/MCGOFFAttributes.h"
+#include "llvm/MC/MCGOFFObjectWriter.h"
 #include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/Support/Casting.h"
@@ -310,67 +310,71 @@ class GOFFWriter {
 GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
     : OS(OS), Asm(Asm) {}
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::SDAttr &Attr) {
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name,
+                                        const GOFF::SDAttr &Attr) {
   return GOFFSymbol(Name, ++EsdIdCounter, Attr);
 }
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::EDAttr &Attr,
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name,
+                                        const GOFF::EDAttr &Attr,
                                         uint32_t ParentEsdId) {
   return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
 }
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::LDAttr &Attr,
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name,
+                                        const GOFF::LDAttr &Attr,
                                         uint32_t ParentEsdId) {
   return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
 }
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::PRAttr &Attr,
+GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name,
+                                        const GOFF::PRAttr &Attr,
                                         uint32_t ParentEsdId) {
   return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
 }
 
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
-    uint32_t SDEsdId = RootSDEsdId;
-    if (!Section.usesRootSD()) {
-      GOFFSymbol SD =
-          createGOFFSymbol(Section.getSDName(), Section.getSDAttributes());
-      SDEsdId = SD.EsdId;
-      if (RootSDEsdId == 0)
-        RootSDEsdId = SDEsdId;
-      writeSymbol(SD);
-    }
+  uint32_t SDEsdId = RootSDEsdId;
+  if (!Section.usesRootSD()) {
+    GOFFSymbol SD =
+        createGOFFSymbol(Section.getSDName(), Section.getSDAttributes());
+    SDEsdId = SD.EsdId;
+    if (RootSDEsdId == 0)
+      RootSDEsdId = SDEsdId;
+    writeSymbol(SD);
+  }
 
-    GOFFSymbol ED = createGOFFSymbol(Section.getEDName(),
-                                     Section.getEDAttributes(), SDEsdId);
-    if ((!Section.hasLD() && !Section.hasPR()) || Section.hasLD()) {
-      ED.SectionLength = Asm.getSectionAddressSize(Section);
-    }
-    writeSymbol(ED);
-
-    if (Section.hasLD()) {
-      GOFFSymbol LD = createGOFFSymbol(Section.getLDorPRName(),
-                                       Section.getLDAttributes(), ED.EsdId);
-      if (Section.isText())
-        LD.ADAEsdId = ADAEsdId;
-      writeSymbol(LD);
-    }
+  GOFFSymbol ED =
+      createGOFFSymbol(Section.getEDName(), Section.getEDAttributes(), SDEsdId);
+  if ((!Section.hasLD() && !Section.hasPR()) || Section.hasLD()) {
+    ED.SectionLength = Asm.getSectionAddressSize(Section);
+  }
+  writeSymbol(ED);
+
+  if (Section.hasLD()) {
+    GOFFSymbol LD = createGOFFSymbol(Section.getLDorPRName(),
+                                     Section.getLDAttributes(), ED.EsdId);
+    if (Section.isText())
+      LD.ADAEsdId = ADAEsdId;
+    writeSymbol(LD);
+  }
 
-    if (Section.hasPR()) {
-      GOFFSymbol PR = createGOFFSymbol(Section.getLDorPRName(),
-                                       Section.getPRAttributes(), ED.EsdId);
-      PR.SectionLength = Asm.getSectionAddressSize(Section);
-      if (&Section == ADA) {
-        // We cannot have a zero-length section for data.  If we do,
-        // artificially inflate it. Use 2 bytes to avoid odd alignments. Note:
-        // if this is ever changed, you will need to update the code in
-        // SystemZAsmPrinter::emitCEEMAIN and SystemZAsmPrinter::emitCELQMAIN to
-        // generate -1 if there is no ADA
-        if (!PR.SectionLength)
-          PR.SectionLength = 2;
-        ADAEsdId = PR.EsdId;
-      }
-      writeSymbol(PR);
+  if (Section.hasPR()) {
+    GOFFSymbol PR = createGOFFSymbol(Section.getLDorPRName(),
+                                     Section.getPRAttributes(), ED.EsdId);
+    PR.SectionLength = Asm.getSectionAddressSize(Section);
+    if (&Section == ADA) {
+      // We cannot have a zero-length section for data.  If we do,
+      // artificially inflate it. Use 2 bytes to avoid odd alignments. Note:
+      // if this is ever changed, you will need to update the code in
+      // SystemZAsmPrinter::emitCEEMAIN and SystemZAsmPrinter::emitCELQMAIN to
+      // generate -1 if there is no ADA
+      if (!PR.SectionLength)
+        PR.SectionLength = 2;
+      ADAEsdId = PR.EsdId;
     }
+    writeSymbol(PR);
+  }
 }
 
 void GOFFWriter::defineSymbols() {
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 2115641f74497..ada59a0de86e6 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -552,7 +552,8 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::AMODE, GOFF::RMODE,
                    GOFF::ESD_NS_NormalName, GOFF::ESD_TS_ByteOriented,
                    GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_Initial,
-                   GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword}, "",
+                   GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
+      "#C",
       GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, GOFF::ESD_NS_NormalName,
                    GOFF::ESD_BST_Strong, GOFF::LINKAGE, GOFF::AMODE,
                    GOFF::ESD_BSC_Section});
@@ -569,13 +570,13 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Doubleword, 0});
 
   ADASection = Ctx->getGOFFSection(
-      SectionKind::getData(), "",
+      SectionKind::getData(), "#C",
       GOFF::SDAttr{GOFF::ESD_TA_Rent, GOFF::ESD_BSC_Section}, GOFF::CLASS_WSA,
       GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
                    GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
                    GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
                    GOFF::ESD_ALIGN_Quadword},
-      "",
+      "#S",
       GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
                    GOFF::ESD_LT_XPLink, GOFF::AMODE, GOFF::ESD_BSC_Section,
                    GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Quadword, 0});
diff --git a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
index 068b56d8cef8b..59ad4ff93c5e9 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
@@ -55,7 +55,9 @@ entry:
 
 declare signext i32 @callout(i32 signext)
 
-; CHECK:     .section    ".ada"
+; CHECK: #C CSECT
+; CHECK: C_WSA64 CATTR
+; CHECK: #S XATTR
 ; CHECK:  .set L#DoFunc at indirect0, DoFunc
 ; CHECK:      .indirect_symbol   L#DoFunc at indirect0
 ; CHECK:  .quad V(L#DoFunc at indirect0)          * Offset 0 pointer to function descriptor DoFunc
diff --git a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
index b1f0c9e5b8e54..b9aedf6517d4b 100644
--- a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
@@ -30,7 +30,9 @@ declare double @llvm.sin.f64(double)
 declare fp128 @llvm.exp2.f128(fp128)
 
 ; Check the calls in the ADA.
-; CHECK: .section ".ada"
+; CHECK: #C CSECT
+; CHECK: C_WSA64 CATTR
+; CHECK: #S XATTR
 
 ; Check that there is no call to sqrt.
 ; CHECK-NOT:  .quad   R(@@WSQT at B)
diff --git a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
index 63c332eb423e3..f447731c849e1 100644
--- a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
@@ -37,5 +37,6 @@ lpad:
 ; CHECK: Personality routine
 ; CHECK: LSDA location
 ; Check that the exception table is emitted into .lsda section.
-; CHECK: .section ".gcc_exception_table.test1"
+; CHECK: C_WSA64 CATTR
+; CHECK: GCC_except_table0 XATTR
 ; CHECK: GCC_except_table0:
diff --git a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
index 82f416ddb8bf9..8f3847da32e31 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -mtriple s390x-ibm-zos -mcpu=z15 -asm-verbose=true < %s | FileCheck %s
 
-; CHECK:    .section    ".ppa2"
+; CHECK: C_CODE64 CATTR
 ; CHECK: L#PPA2:
 ; CHECK:    .byte   3
 ; CHECK:    .byte   231
@@ -19,7 +19,7 @@
 ; CHECK:    .quad   L#PPA2-CELQSTRT                 * A(PPA2-CELQSTRT)
 ; CHECK: L#PPA1_void_test_0:
 ; CHECK:    .long   L#PPA2-L#PPA1_void_test_0       * Offset to PPA2
-; CHECK:    .section    ".idrl"
+; CHECK: B_IDRL CATTR
 ; CHECK:    .byte   0
 ; CHECK:    .byte   3
 ; CHECK:    .short  30
diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
index a46079818b130..40a4b91b9f1da 100644
--- a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -5,9 +5,12 @@
 @a = global i32 0, align 4
 
 define signext i32 @main() {
-; CHECK: .section ".text"
+; CHECK: C_CODE64 CATTR
+; CHECK: #C XATTR
 ; CHECK: main:
-; CHECK: .section "a"
+; CHECK: a CSECT
+; CHECK: C_WSA64 CATTR
+; CHECK: a XATTR
 entry:
   ret i32 0
 }
diff --git a/llvm/test/MC/GOFF/empty-goff.s b/llvm/test/MC/GOFF/empty-goff.s
index f6d402863d71c..ba1b0e0a49077 100644
--- a/llvm/test/MC/GOFF/empty-goff.s
+++ b/llvm/test/MC/GOFF/empty-goff.s
@@ -17,8 +17,8 @@
 *  03 is prefix byte
 *  4. is header type
 *  .0 is version
-* CHECK: 000050 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-* CHECK: 000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-* CHECK: 000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-* CHECK: 000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-* CHECK: 000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: {{([[:xdigit:]]{6})}} 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: {{([[:xdigit:]]{6})}} 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: {{([[:xdigit:]]{6})}} 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: {{([[:xdigit:]]{6})}} 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: {{([[:xdigit:]]{6})}} 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll
index 16c3580fcf924..9e943a71cbf4a 100644
--- a/llvm/test/MC/GOFF/section.ll
+++ b/llvm/test/MC/GOFF/section.ll
@@ -57,11 +57,12 @@ entry:
 
 ; ESD record, type ED.
 ; The name is C_CODE64.
+; The regular expression matches the low byte of the length.
 ; CHECK: 0000140 03 00 00 01 00 00 00 04 00 00 00 01 00 00 00 00
-; CHECK: 0000150 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00
+; CHECK: 0000150 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
 ; CHECK: 0000160 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
 ; CHECK: 0000170 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a
-; CHECK: 0000180 00 00 04 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+; CHECK: 0000180 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
 
 ; ESD record, type LD.
 ; The name is test#C.

>From 682f07b525d9b24d1d6256cf812522eed6376524 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 4 Apr 2025 20:17:43 -0400
Subject: [PATCH 10/35] Rework based on reviewer comment.

---
 .../CodeGen/TargetLoweringObjectFileImpl.h    |   2 +
 llvm/include/llvm/MC/MCContext.h              |  58 ++++-----
 llvm/include/llvm/MC/MCGOFFStreamer.h         |   1 +
 llvm/include/llvm/MC/MCObjectFileInfo.h       |  14 ++-
 llvm/include/llvm/MC/MCSectionGOFF.h          | 112 +++++++++---------
 llvm/include/llvm/MC/MCSymbolGOFF.h           |  23 ++++
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  |  52 +++++---
 llvm/lib/MC/GOFFObjectWriter.cpp              |  96 +++++----------
 llvm/lib/MC/MCContext.cpp                     |  77 ++++--------
 llvm/lib/MC/MCGOFFStreamer.cpp                |  34 +++---
 llvm/lib/MC/MCObjectFileInfo.cpp              |  49 ++++----
 11 files changed, 258 insertions(+), 260 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index b2ff064297809..dd4339824c49e 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -316,6 +316,8 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
 };
 
 class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile {
+  std::string DefaultRootSDName;
+  std::string DefaultADAPRName;
 public:
   TargetLoweringObjectFileGOFF();
   ~TargetLoweringObjectFileGOFF() override = default;
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 30d4d6c197e69..67d7d5e2642be 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -270,6 +270,21 @@ class MCContext {
     }
   };
 
+  struct GOFFSectionKey {
+    std::string SectionName;
+    GOFF::ESDSymbolType SymbolType;
+
+    GOFFSectionKey(StringRef SectionName, GOFF::ESDSymbolType SymbolType)
+        : SectionName(SectionName), SymbolType(SymbolType) {}
+
+    bool operator<(const GOFFSectionKey &Other) const {
+      if (SymbolType == Other.SymbolType) {
+        return SectionName < Other.SectionName;
+      }
+      return SymbolType < Other.SymbolType;
+    }
+  };
+
   struct WasmSectionKey {
     std::string SectionName;
     StringRef GroupName;
@@ -323,7 +338,7 @@ class MCContext {
   StringMap<MCSectionMachO *> MachOUniquingMap;
   std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
   StringMap<MCSectionELF *> ELFUniquingMap;
-  std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
+  std::map<GOFFSectionKey, MCSectionGOFF *> GOFFUniquingMap;
   std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
   std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
   StringMap<MCSectionDXContainer *> DXCUniquingMap;
@@ -601,35 +616,22 @@ class MCContext {
                                                    unsigned EntrySize);
 
 private:
-  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName,
-                                GOFF::SDAttr SDAttributes, StringRef EDName,
-                                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
-                                GOFF::LDAttr LDAttributes,
-                                GOFF::PRAttr PRAttributes,
-                                MCSectionGOFF::SectionFlags Flags);
+  MCSectionGOFF *getGOFFSection(SectionKind Kind,
+                                GOFF::ESDSymbolType SymbolType, StringRef Name,
+                                GOFF::SDAttr SDAttributes,
+                                GOFF::EDAttr EDAttributes,
+                                GOFF::PRAttr PRAttributes, MCSection *Parent);
 
 public:
-  // Create a section with SD/ED/LD symbols.
-  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName,
-                                GOFF::SDAttr SDAttributes, StringRef EDName,
-                                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
-                                GOFF::LDAttr LDAttributes);
-  // Create a section with SD/ED/PR symbols.
-  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName,
-                                GOFF::SDAttr SDAttributes, StringRef EDName,
-                                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
-                                GOFF::PRAttr PRAttributes);
-  // Create a section with root-SD/ED/LD symbols.
-  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
-                                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
-                                GOFF::LDAttr LDAttributes);
-  // Create a section with root-SD/ED/PR symbols.
-  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
-                                GOFF::EDAttr EDAttributes, StringRef PRName,
-                                GOFF::PRAttr PRAttributes);
-  // Create a section with root-SD/ED symbols.
-  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName,
-                                GOFF::EDAttr EDAttributes);
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
+                                GOFF::SDAttr SDAttributes,
+                                MCSection *Parent = nullptr);
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
+                                GOFF::EDAttr EDAttributes,
+                                MCSection *Parent = nullptr);
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
+                                GOFF::PRAttr PRAttributes,
+                                MCSection *Parent = nullptr);
 
   MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
                                 StringRef COMDATSymName, int Selection,
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 779d44a8930b3..771d77b50209a 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -29,6 +29,7 @@ class MCGOFFStreamer : public MCObjectStreamer {
   ~MCGOFFStreamer() override;
 
   void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
+  void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
 
   GOFFObjectWriter &getWriter();
 
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index 56697ee3ae962..b5ec42fdd352e 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -230,8 +230,11 @@ class MCObjectFileInfo {
   MCSection *GLJMPSection = nullptr;
 
   // GOFF specific sections.
-  MCSection *PPA2ListSection = nullptr;
-  MCSection *ADASection = nullptr;
+  MCSection *RootSDSection = nullptr;
+  MCSection *PPA2ListEDSection = nullptr;
+  MCSection *PPA2ListPRSection = nullptr;
+  MCSection *ADAEDSection = nullptr;
+  MCSection *ADAPRSection = nullptr;
   MCSection *IDRLSection = nullptr;
 
   // XCOFF specific sections
@@ -436,8 +439,11 @@ class MCObjectFileInfo {
   MCSection *getGLJMPSection() const { return GLJMPSection; }
 
   // GOFF specific sections.
-  MCSection *getPPA2ListSection() const { return PPA2ListSection; }
-  MCSection *getADASection() const { return ADASection; }
+  MCSection *getRootSDSection() const { return RootSDSection; }
+  MCSection *getPPA2ListEDSection() const { return PPA2ListEDSection; }
+  MCSection *getPPA2ListSection() const { return PPA2ListPRSection; }
+  MCSection *getADAEDSection() const { return ADAEDSection; }
+  MCSection *getADASection() const { return ADAPRSection; }
   MCSection *getIDRLSection() const { return IDRLSection; }
 
   // XCOFF specific sections
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index ac60a61b0a142..e922101187905 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -15,10 +15,10 @@
 #ifndef LLVM_MC_MCSECTIONGOFF_H
 #define LLVM_MC_MCSECTIONGOFF_H
 
-#include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/BinaryFormat/GOFF.h"
 #include "llvm/MC/MCGOFFAttributes.h"
 #include "llvm/MC/MCSection.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace llvm {
@@ -26,85 +26,85 @@ namespace llvm {
 class MCExpr;
 
 class MCSectionGOFF final : public MCSection {
-private:
-  // The names of the GOFF symbols.
-  StringRef SDName;
-  StringRef EDName;
-  StringRef LDorPRName;
+  // Parent of this section. Implies that the parent is emitted first.
+  MCSectionGOFF *Parent;
 
   // The attributes of the GOFF symbols.
   GOFF::SDAttr SDAttributes;
   GOFF::EDAttr EDAttributes;
-  GOFF::LDAttr LDAttributes;
   GOFF::PRAttr PRAttributes;
 
-public:
-  enum SectionFlags {
-    UsesRootSD = 1,     // Uses the common root SD.
-    HasLD = 2,          // Has a LD symbol.
-    HasPR = 4,          // Has a PR symbol.
-    LDorPRNameIsSD = 8, // The LD or PR name is the same as the SD name.
-    LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ 8)
-  };
+  // The type of this section.
+  GOFF::ESDSymbolType SymbolType;
+
+  // Indicates that the ED symbol needs to set the length of the section.
+  unsigned RequiresLength : 1;
 
-private:
-  SectionFlags Flags;
+  // Indicates that the PR symbol needs to set the length of the section to a
+  // non-zero value.
+  unsigned RequiresNonZeroLength : 1;
 
   friend class MCContext;
-  MCSectionGOFF(StringRef SynName, SectionKind K, SectionFlags Flags,
-                StringRef SDName, GOFF::SDAttr SDAttributes, StringRef EDName,
-                GOFF::EDAttr EDAttributes, StringRef LDorPRName,
-                GOFF::LDAttr LDAttributes, GOFF::PRAttr PRAttributes)
-      : MCSection(SV_GOFF, SynName, K.isText(), /*IsVirtual=*/false, nullptr),
-        SDName(SDName), EDName(EDName), LDorPRName(LDorPRName),
-        SDAttributes(SDAttributes), EDAttributes(EDAttributes),
-        LDAttributes(LDAttributes), PRAttributes(PRAttributes), Flags(Flags) {}
+  MCSectionGOFF(StringRef Name, SectionKind K, GOFF::ESDSymbolType SymbolType,
+                GOFF::SDAttr SDAttributes, GOFF::EDAttr EDAttributes,
+                GOFF::PRAttr PRAttributes, MCSectionGOFF *Parent = nullptr)
+      : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
+        Parent(Parent), SDAttributes(SDAttributes), EDAttributes(EDAttributes),
+        PRAttributes(PRAttributes), SymbolType(SymbolType) {}
 
 public:
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                             raw_ostream &OS,
                             uint32_t /*Subsection*/) const override {
-    if (!usesRootSD())
-      OS << getSDName() << " CSECT\n";
-    OS << getEDName() << " CATTR\n";
-    if ((hasLD() || hasPR()) && !getLDorPRName().empty())
-      OS << getLDorPRName() << " XATTR\n";
+    ;
+    switch (SymbolType) {
+    case GOFF::ESD_ST_SectionDefinition:
+      OS << Name << " CSECT\n";
+      break;
+    case GOFF::ESD_ST_ElementDefinition:
+      OS << Name << " CATTR\n";
+      break;
+    case GOFF::ESD_ST_PartReference:
+      OS << Name << " XATTR\n";
+      break;
+    default:
+      llvm_unreachable("Wrong section type");
+    }
   }
 
   bool useCodeAlign() const override { return false; }
 
-  // Accessors to the various symbol names.
-  StringRef getSDName() const { return SDName; };
-  StringRef getEDName() const { return EDName; };
-  StringRef getLDorPRName() const {
-    assert(Flags & (HasLD | HasPR) && "LD/PR name not available");
-    return (Flags & LDorPRNameIsSD) ? SDName : LDorPRName;
-  };
-
-  // Setters for the SD and LD/PR symbol names.
-  void setSDName(StringRef Name) {
-    assert(!(Flags & UsesRootSD) && "Uses root SD");
-    SDName = Name;
+  // Return the id of the section. It is the 1-based ordinal number.
+  unsigned getId() const { return getOrdinal() + 1; }
+
+  // Return the parent section.
+  MCSectionGOFF *getParent() const { return Parent; }
+
+  // Returns the type of this section.
+  GOFF::ESDSymbolType getSymbolType() const { return SymbolType; }
+
+  bool isSD() const { return SymbolType == GOFF::ESD_ST_SectionDefinition; }
+  bool isED() const { return SymbolType == GOFF::ESD_ST_ElementDefinition; }
+  bool isPR() const { return SymbolType == GOFF::ESD_ST_PartReference; }
+
+  // Accessors to the attributes.
+  GOFF::SDAttr getSDAttributes() const {
+    assert(SymbolType == GOFF::ESD_ST_SectionDefinition && "Not PR symbol");
+    return SDAttributes;
   }
-  void setLDorPRName(StringRef Name) { LDorPRName = Name; }
-
-  // Accessors to the various attributes.
-  GOFF::SDAttr getSDAttributes() const { return SDAttributes; }
-  GOFF::EDAttr getEDAttributes() const { return EDAttributes; }
-  GOFF::LDAttr getLDAttributes() const {
-    assert(Flags & HasLD && "LD not available");
-    return LDAttributes;
+  GOFF::EDAttr getEDAttributes() const {
+    assert(SymbolType == GOFF::ESD_ST_ElementDefinition && "Not PR symbol");
+    return EDAttributes;
   }
   GOFF::PRAttr getPRAttributes() const {
-    assert(Flags & HasPR && "PR not available");
+    assert(SymbolType == GOFF::ESD_ST_PartReference && "Not PR symbol");
     return PRAttributes;
   }
 
-  // Query various flags.
-  bool usesRootSD() const { return Flags & UsesRootSD; }
-  bool hasLD() const { return Flags & HasLD; }
-  bool hasPR() const { return Flags & HasPR; }
-  bool isLDorPRNameTheSD() const { return Flags & LDorPRNameIsSD; }
+  bool requiresLength() const { return RequiresLength; }
+  bool requiresNonZeroLength() const { return RequiresNonZeroLength; }
+
+  void setName(StringRef SectionName) { Name = SectionName; }
 
   static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; }
 };
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 9ca53a5653108..c46f5bd4234b5 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -13,15 +13,38 @@
 #ifndef LLVM_MC_MCSYMBOLGOFF_H
 #define LLVM_MC_MCSYMBOLGOFF_H
 
+#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCGOFFAttributes.h"
+#include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCSymbolTableEntry.h"
 
 namespace llvm {
 
 class MCSymbolGOFF : public MCSymbol {
+  // Associated data area of the section. Needs to be emitted first.
+  MCSectionGOFF *ADA;
+
+  GOFF::LDAttr LDAttributes;
+
+  enum SymbolFlags : uint16_t {
+    SF_LD = 0x01, // LD attributes are set.
+  };
+
 public:
   MCSymbolGOFF(const MCSymbolTableEntry *Name, bool IsTemporary)
       : MCSymbol(SymbolKindGOFF, Name, IsTemporary) {}
+
+  void setLDAttributes(GOFF::LDAttr Attr) {
+    modifyFlags(SF_LD, SF_LD);
+    LDAttributes = Attr;
+  }
+  GOFF::LDAttr getLDAttributes() const { return LDAttributes; }
+  bool hasLDAttributes() const { return getFlags() & SF_LD; }
+
+  void setADA(MCSectionGOFF *AssociatedDataArea) { ADA = AssociatedDataArea; }
+  MCSectionGOFF *getADA() const { return ADA; }
+
   static bool classof(const MCSymbol *S) { return S->isGOFF(); }
 };
 } // end namespace llvm
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 0bd996a2e1d10..a64a22ebcf67d 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -57,6 +57,7 @@
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCSymbolELF.h"
+#include "llvm/MC/MCSymbolGOFF.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/MC/SectionKind.h"
 #include "llvm/ProfileData/InstrProf.h"
@@ -2761,9 +2762,21 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA(
 TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default;
 
 void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
-  // Set the main file name if not set previously by the tool.
-  if (getContext().getMainFileName().empty())
-    getContext().setMainFileName(M.getSourceFileName());
+  // Construct the default names for the root SD and the ADA PR symbol.
+  DefaultRootSDName = Twine(M.getSourceFileName()).concat("#C").str();
+  DefaultADAPRName = Twine(M.getSourceFileName()).concat("#S").str();
+  MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(RootSDSection);
+  MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADAPRSection);
+  RootSD->setName(DefaultRootSDName);
+  ADAPR->setName(DefaultADAPRName);
+  // Initialize the label for the text section.
+  MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>(
+      getContext().getOrCreateSymbol(RootSD->getName()));
+  TextLD->setLDAttributes(GOFF::LDAttr{
+      false, GOFF::ESD_EXE_CODE, GOFF::ESD_NS_NormalName, GOFF::ESD_BST_Strong,
+      GOFF::LINKAGE, GOFF::AMODE, GOFF::ESD_BSC_Section});
+  TextLD->setADA(ADAPR);
+  TextSection->setBeginSymbol(TextLD);
 }
 
 MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
@@ -2774,16 +2787,20 @@ MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
 MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
     const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
   std::string Name = ".gcc_exception_table." + F.getName().str();
-  return getContext().getGOFFSection(
-      SectionKind::getData(), GOFF::CLASS_WSA,
+
+  MCSectionGOFF *WSA = getContext().getGOFFSection(
+      SectionKind::getMetadata(), GOFF::CLASS_WSA,
       GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
                    GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
                    GOFF::ESD_BA_Merge, GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword},
-      Name,
+      RootSDSection);
+  return getContext().getGOFFSection(
+      SectionKind::getData(), Name,
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
                    GOFF::LINKAGE, GOFF::AMODE, GOFF::ESD_BSC_Section,
-                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Fullword, 0});
+                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Fullword, 0},
+      WSA);
 }
 
 MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
@@ -2799,22 +2816,23 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
     GOFF::ESDBindingScope SDBindingScope =
         PRBindingScope == GOFF::ESD_BSC_Section ? GOFF::ESD_BSC_Section
                                                 : GOFF::ESD_BSC_Unspecified;
-    return getContext().getGOFFSection(
-        Kind, Symbol->getName(),
-        GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope}, GOFF::CLASS_WSA,
+    MCSectionGOFF *SD = getContext().getGOFFSection(
+        SectionKind::getMetadata(), Symbol->getName(),
+        GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope});
+    MCSectionGOFF *ED = getContext().getGOFFSection(
+        SectionKind::getMetadata(), GOFF::CLASS_WSA,
         GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
                      GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
                      GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0,
-                     static_cast<GOFF::ESDAlignment>(GO->getAlignment())
-
-        },
-        Symbol->getName(),
+                     static_cast<GOFF::ESDAlignment>(GO->getAlignment())},
+        SD);
+    return getContext().getGOFFSection(
+        Kind, Symbol->getName(),
         GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
                      GOFF::LINKAGE, GOFF::AMODE, PRBindingScope,
                      GOFF::ESD_DSS_NoWarning,
-                     static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0
-
-        });
+                     static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0},
+        ED);
   }
   return TextSection;
 }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 2aa3ffb0bf9a5..b70fab6185a03 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -15,6 +15,7 @@
 #include "llvm/MC/MCGOFFAttributes.h"
 #include "llvm/MC/MCGOFFObjectWriter.h"
 #include "llvm/MC/MCSectionGOFF.h"
+#include "llvm/MC/MCSymbolGOFF.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ConvertEBCDIC.h"
@@ -280,25 +281,12 @@ class GOFFWriter {
   /// Counter for symbol id's.
   uint32_t EsdIdCounter = 0;
 
-  /// Id's of some special symbols.
-  uint32_t RootSDEsdId = 0;
-  uint32_t ADAEsdId = 0;
-
-  MCSectionGOFF *ADA = nullptr;
-
   void writeHeader();
   void writeSymbol(const GOFFSymbol &Symbol);
   void writeEnd();
 
-  GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::SDAttr &Attr);
-  GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::EDAttr &Attr,
-                              uint32_t ParentEsdId);
-  GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::LDAttr &Attr,
-                              uint32_t ParentEsdId);
-  GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::PRAttr &Attr,
-                              uint32_t ParentEsdId);
-
   void defineSectionSymbols(const MCSectionGOFF &Section);
+  void defineLabel(const MCSymbolGOFF &Symbol);
   void defineSymbols();
 
 public:
@@ -310,60 +298,26 @@ class GOFFWriter {
 GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
     : OS(OS), Asm(Asm) {}
 
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name,
-                                        const GOFF::SDAttr &Attr) {
-  return GOFFSymbol(Name, ++EsdIdCounter, Attr);
-}
-
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name,
-                                        const GOFF::EDAttr &Attr,
-                                        uint32_t ParentEsdId) {
-  return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
-}
-
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name,
-                                        const GOFF::LDAttr &Attr,
-                                        uint32_t ParentEsdId) {
-  return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
-}
-
-GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name,
-                                        const GOFF::PRAttr &Attr,
-                                        uint32_t ParentEsdId) {
-  return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr);
-}
-
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
-  uint32_t SDEsdId = RootSDEsdId;
-  if (!Section.usesRootSD()) {
-    GOFFSymbol SD =
-        createGOFFSymbol(Section.getSDName(), Section.getSDAttributes());
-    SDEsdId = SD.EsdId;
-    if (RootSDEsdId == 0)
-      RootSDEsdId = SDEsdId;
+  if (Section.isSD()) {
+    GOFFSymbol SD(Section.getName(), Section.getId(),
+                  Section.getSDAttributes());
     writeSymbol(SD);
   }
 
-  GOFFSymbol ED =
-      createGOFFSymbol(Section.getEDName(), Section.getEDAttributes(), SDEsdId);
-  if ((!Section.hasLD() && !Section.hasPR()) || Section.hasLD()) {
-    ED.SectionLength = Asm.getSectionAddressSize(Section);
-  }
-  writeSymbol(ED);
-
-  if (Section.hasLD()) {
-    GOFFSymbol LD = createGOFFSymbol(Section.getLDorPRName(),
-                                     Section.getLDAttributes(), ED.EsdId);
-    if (Section.isText())
-      LD.ADAEsdId = ADAEsdId;
-    writeSymbol(LD);
+  if (Section.isED()) {
+    GOFFSymbol ED(Section.getName(), Section.getId(),
+                  Section.getParent()->getId(), Section.getEDAttributes());
+    if (Section.requiresLength())
+      ED.SectionLength = Asm.getSectionAddressSize(Section);
+    writeSymbol(ED);
   }
 
-  if (Section.hasPR()) {
-    GOFFSymbol PR = createGOFFSymbol(Section.getLDorPRName(),
-                                     Section.getPRAttributes(), ED.EsdId);
+  if (Section.isPR()) {
+    GOFFSymbol PR(Section.getName(), Section.getId(),
+                  Section.getParent()->getId(), Section.getPRAttributes());
     PR.SectionLength = Asm.getSectionAddressSize(Section);
-    if (&Section == ADA) {
+    if (Section.requiresNonZeroLength()) {
       // We cannot have a zero-length section for data.  If we do,
       // artificially inflate it. Use 2 bytes to avoid odd alignments. Note:
       // if this is ever changed, you will need to update the code in
@@ -371,19 +325,33 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
       // generate -1 if there is no ADA
       if (!PR.SectionLength)
         PR.SectionLength = 2;
-      ADAEsdId = PR.EsdId;
     }
     writeSymbol(PR);
   }
 }
 
+void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
+  GOFFSymbol LD(Symbol.getName(), ++EsdIdCounter, 0, Symbol.getLDAttributes());
+  if (Symbol.getADA())
+    LD.ADAEsdId = Symbol.getADA()->getId();
+  writeSymbol(LD);
+}
+
 void GOFFWriter::defineSymbols() {
   // Process all sections.
   for (MCSection &S : Asm) {
     auto &Section = cast<MCSectionGOFF>(S);
-    if (!ADA)
-      ADA = &Section;
     defineSectionSymbols(Section);
+    EsdIdCounter = std::max(EsdIdCounter, Section.getId());
+  }
+
+  // Process all symbols
+  for (const MCSymbol &Sym : Asm.symbols()) {
+    if (Sym.isTemporary())
+      continue;
+    auto &Symbol = cast<MCSymbolGOFF>(Sym);
+    if (Symbol.hasLDAttributes()) {
+    }
   }
 }
 
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 56ca85d115792..fa4c090d0fe24 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -14,6 +14,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/BinaryFormat/COFF.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/GOFF.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/BinaryFormat/XCOFF.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -672,77 +673,45 @@ MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
 }
 
 MCSectionGOFF *
-MCContext::getGOFFSection(SectionKind Kind, StringRef SDName,
-                          GOFF::SDAttr SDAttributes, StringRef EDName,
-                          GOFF::EDAttr EDAttributes, StringRef LDorPRName,
-                          GOFF::LDAttr LDAttributes, GOFF::PRAttr PRAttributes,
-                          MCSectionGOFF::SectionFlags Flags) {
-  std::string SynName = Twine(SDName)
-                            .concat("/")
-                            .concat(EDName)
-                            .concat("/")
-                            .concat(LDorPRName)
-                            .str();
+MCContext::getGOFFSection(SectionKind Kind, GOFF::ESDSymbolType SymbolType,
+                          StringRef Name, GOFF::SDAttr SDAttributes,
+                          GOFF::EDAttr EDAttributes, GOFF::PRAttr PRAttributes,
+                          MCSection *Parent) {
+  GOFFSectionKey T{Name, SymbolType};
   // Do the lookup. If we don't have a hit, return a new section.
-  auto IterBool = GOFFUniquingMap.insert(std::make_pair(SynName, nullptr));
+  auto IterBool = GOFFUniquingMap.insert(std::make_pair(T, nullptr));
   auto Iter = IterBool.first;
   if (!IterBool.second)
     return Iter->second;
 
-  StringRef CachedSynName = Iter->first;
+  StringRef CachedName = Iter->first.SectionName;
   MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate())
-      MCSectionGOFF(CachedSynName, Kind, Flags, SDName, SDAttributes, EDName,
-                    EDAttributes, LDorPRName, LDAttributes, PRAttributes);
+      MCSectionGOFF(CachedName, Kind, SymbolType, SDAttributes, EDAttributes,
+                    PRAttributes, static_cast<MCSectionGOFF *>(Parent));
   Iter->second = GOFFSection;
   allocInitialFragment(*GOFFSection);
   return GOFFSection;
 }
 
-MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef SDName,
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::SDAttr SDAttributes,
-                                         StringRef EDName,
-                                         GOFF::EDAttr EDAttributes,
-                                         StringRef LDorPRName,
-                                         GOFF::LDAttr LDAttributes) {
-  return getGOFFSection(Kind, SDName, SDAttributes, EDName, EDAttributes,
-                        LDorPRName, LDAttributes, GOFF::PRAttr{},
-                        MCSectionGOFF::HasLD);
+                                         MCSection *Parent) {
+  return getGOFFSection(Kind, GOFF::ESD_ST_SectionDefinition, Name,
+                        SDAttributes, GOFF::EDAttr{}, GOFF::PRAttr{}, Parent);
 }
 
-MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef SDName,
-                                         GOFF::SDAttr SDAttributes,
-                                         StringRef EDName,
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::EDAttr EDAttributes,
-                                         StringRef LDorPRName,
-                                         GOFF::PRAttr PRAttributes) {
-  return getGOFFSection(Kind, SDName, SDAttributes, EDName, EDAttributes,
-                        LDorPRName, GOFF::LDAttr{}, PRAttributes,
-                        MCSectionGOFF::HasPR);
+                                         MCSection *Parent) {
+  return getGOFFSection(Kind, GOFF::ESD_ST_ElementDefinition, Name,
+                        GOFF::SDAttr{}, EDAttributes, GOFF::PRAttr{}, Parent);
 }
 
-MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
-                                         GOFF::EDAttr EDAttributes,
-                                         StringRef LDorPRName,
-                                         GOFF::LDAttr LDAttributes) {
-  return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes,
-                        LDorPRName, LDAttributes, GOFF::PRAttr{},
-                        MCSectionGOFF::UsesRootSD | MCSectionGOFF::HasLD);
-}
-
-MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
-                                         GOFF::EDAttr EDAttributes,
-                                         StringRef LDorPRName,
-                                         GOFF::PRAttr PRAttributes) {
-  return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes,
-                        LDorPRName, GOFF::LDAttr{}, PRAttributes,
-                        MCSectionGOFF::UsesRootSD | MCSectionGOFF::HasPR);
-}
-
-MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName,
-                                         GOFF::EDAttr EDAttributes) {
-  return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes, "",
-                        GOFF::LDAttr{}, GOFF::PRAttr{},
-                        MCSectionGOFF::UsesRootSD);
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
+                                         GOFF::PRAttr PRAttributes,
+                                         MCSection *Parent) {
+  return getGOFFSection(Kind, GOFF::ESD_ST_SectionDefinition, Name,
+                        GOFF::SDAttr{}, GOFF::EDAttr{}, PRAttributes, Parent);
 }
 
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index c67b4da6b3d74..114e48ed57751 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -27,25 +27,27 @@ GOFFObjectWriter &MCGOFFStreamer::getWriter() {
   return static_cast<GOFFObjectWriter &>(getAssembler().getWriter());
 }
 
-void MCGOFFStreamer::initSections(bool NoExecStack,
+void MCGOFFStreamer::initSections(bool /*NoExecStack*/,
                                   const MCSubtargetInfo &STI) {
   MCContext &Ctx = getContext();
+  // Emit the text section.
+  switchSection(Ctx.getObjectFileInfo()->getTextSection());
+}
+
+namespace {
+// Make sure that all section are registered in the correct order.
+void registerSectionHierarchy(MCAssembler &Asm, MCSectionGOFF *Section) {
+  if (Section->isRegistered())
+    return;
+  if (Section->getParent())
+    registerSectionHierarchy(Asm, Section->getParent());
+  registerSectionHierarchy(Asm, Section);
+}
+} // namespace
 
-  // Initialize the special names for the code and ada section.
-  StringRef FileName = sys::path::stem(Ctx.getMainFileName());
-  RootSDName = Twine(FileName).concat("#C").str();
-  ADAPRName = Twine(FileName).concat("#S").str();
-  MCSectionGOFF *TextSection =
-      static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getTextSection());
-  MCSectionGOFF *ADASection =
-      static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getADASection());
-  ADASection->setSDName(RootSDName);
-  ADASection->setLDorPRName(ADAPRName);
-  TextSection->setLDorPRName(RootSDName);
-
-  // Switch to the ADA section first, then code section.
-  switchSection(ADASection);
-  switchSection(TextSection);
+void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
+  registerSectionHierarchy(getAssembler(), static_cast<MCSectionGOFF *>(Section));
+  MCObjectStreamer::changeSection(Section, Subsection);
 }
 
 MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index ada59a0de86e6..9daa197288cb8 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -547,46 +547,53 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
 }
 
 void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
+  RootSDSection = Ctx->getGOFFSection(
+      SectionKind::getMetadata(), "#C",
+      GOFF::SDAttr{GOFF::ESD_TA_Rent, GOFF::ESD_BSC_Section});
+
+  ADAEDSection = Ctx->getGOFFSection(
+      SectionKind::getMetadata(), GOFF::CLASS_WSA,
+      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
+                   GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
+                   GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
+                   GOFF::ESD_ALIGN_Quadword},
+      RootSDSection);
+  ADAPRSection = Ctx->getGOFFSection(
+      SectionKind::getData(), "#S",
+      GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
+                   GOFF::ESD_LT_XPLink, GOFF::AMODE, GOFF::ESD_BSC_Section,
+                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Quadword, 0},
+      ADAEDSection);
+
   TextSection = Ctx->getGOFFSection(
       SectionKind::getText(), GOFF::CLASS_CODE,
       GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::AMODE, GOFF::RMODE,
                    GOFF::ESD_NS_NormalName, GOFF::ESD_TS_ByteOriented,
                    GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_Initial,
                    GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
-      "#C",
-      GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, GOFF::ESD_NS_NormalName,
-                   GOFF::ESD_BST_Strong, GOFF::LINKAGE, GOFF::AMODE,
-                   GOFF::ESD_BSC_Section});
+      RootSDSection);
 
-  PPA2ListSection = Ctx->getGOFFSection(
-      SectionKind::getData(), GOFF::CLASS_PPA2,
+  PPA2ListEDSection = Ctx->getGOFFSection(
+      SectionKind::getMetadata(), GOFF::CLASS_PPA2,
       GOFF::EDAttr{true, GOFF::ESD_EXE_DATA, GOFF::AMODE, 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},
-      ".&ppa2",
+      RootSDSection);
+  PPA2ListPRSection = Ctx->getGOFFSection(
+      SectionKind::getData(), ".&ppa2",
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
                    GOFF::ESD_LT_OS, GOFF::AMODE, GOFF::ESD_BSC_Section,
-                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Doubleword, 0});
-
-  ADASection = Ctx->getGOFFSection(
-      SectionKind::getData(), "#C",
-      GOFF::SDAttr{GOFF::ESD_TA_Rent, GOFF::ESD_BSC_Section}, GOFF::CLASS_WSA,
-      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
-                   GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
-                   GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
-                   GOFF::ESD_ALIGN_Quadword},
-      "#S",
-      GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
-                   GOFF::ESD_LT_XPLink, GOFF::AMODE, GOFF::ESD_BSC_Section,
-                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Quadword, 0});
+                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Doubleword, 0},
+      PPA2ListEDSection);
 
   IDRLSection = Ctx->getGOFFSection(
       SectionKind::getData(), "B_IDRL",
       GOFF::EDAttr{true, GOFF::ESD_EXE_Unspecified, GOFF::AMODE, GOFF::RMODE,
                    GOFF::ESD_NS_NormalName, GOFF::ESD_TS_Structured,
                    GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_NoLoad,
-                   GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword});
+                   GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
+      RootSDSection);
 }
 
 void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {

>From 5d522fddfbd5edf87b7565702cd96fb5aaae47fc Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 7 Apr 2025 16:14:11 -0400
Subject: [PATCH 11/35] More work on reviewer comments

Most comments are resolved except:
- I kept the RootSDSection variable
- The attributes are not yet in a union
- I still need to extend the unique section key for hashmap
---
 llvm/include/llvm/MC/MCContext.h                  |  9 +++------
 llvm/include/llvm/MC/MCGOFFStreamer.h             |  2 --
 llvm/include/llvm/MC/MCObjectFileInfo.h           | 13 ++++---------
 llvm/include/llvm/MC/MCSectionGOFF.h              | 13 ++++++-------
 llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 10 +++++++---
 llvm/lib/MC/GOFFObjectWriter.cpp                  |  8 +++++---
 llvm/lib/MC/MCContext.cpp                         |  9 ++++-----
 llvm/lib/MC/MCGOFFStreamer.cpp                    |  3 ++-
 llvm/lib/MC/MCObjectFileInfo.cpp                  |  8 ++++----
 llvm/test/CodeGen/SystemZ/zos-landingpad.ll       |  5 +++--
 llvm/test/CodeGen/SystemZ/zos-simple-test.ll      |  4 ++--
 llvm/test/MC/GOFF/ppa1.ll                         |  3 ++-
 llvm/test/MC/GOFF/section.ll                      | 10 +++++-----
 13 files changed, 47 insertions(+), 50 deletions(-)

diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 67d7d5e2642be..99f3d75cd8f78 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -624,14 +624,11 @@ class MCContext {
 
 public:
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
-                                GOFF::SDAttr SDAttributes,
-                                MCSection *Parent = nullptr);
+                                GOFF::SDAttr SDAttributes);
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
-                                GOFF::EDAttr EDAttributes,
-                                MCSection *Parent = nullptr);
+                                GOFF::EDAttr EDAttributes, MCSection *Parent);
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
-                                GOFF::PRAttr PRAttributes,
-                                MCSection *Parent = nullptr);
+                                GOFF::PRAttr PRAttributes, MCSection *Parent);
 
   MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
                                 StringRef COMDATSymName, int Selection,
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 771d77b50209a..68af26ef17c70 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -16,8 +16,6 @@ namespace llvm {
 class GOFFObjectWriter;
 
 class MCGOFFStreamer : public MCObjectStreamer {
-  std::string RootSDName;
-  std::string ADAPRName;
 
 public:
   MCGOFFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index b5ec42fdd352e..55c979b127f59 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -231,10 +231,8 @@ class MCObjectFileInfo {
 
   // GOFF specific sections.
   MCSection *RootSDSection = nullptr;
-  MCSection *PPA2ListEDSection = nullptr;
-  MCSection *PPA2ListPRSection = nullptr;
-  MCSection *ADAEDSection = nullptr;
-  MCSection *ADAPRSection = nullptr;
+  MCSection *PPA2ListSection = nullptr;
+  MCSection *ADASection = nullptr;
   MCSection *IDRLSection = nullptr;
 
   // XCOFF specific sections
@@ -439,11 +437,8 @@ class MCObjectFileInfo {
   MCSection *getGLJMPSection() const { return GLJMPSection; }
 
   // GOFF specific sections.
-  MCSection *getRootSDSection() const { return RootSDSection; }
-  MCSection *getPPA2ListEDSection() const { return PPA2ListEDSection; }
-  MCSection *getPPA2ListSection() const { return PPA2ListPRSection; }
-  MCSection *getADAEDSection() const { return ADAEDSection; }
-  MCSection *getADASection() const { return ADAPRSection; }
+  MCSection *getPPA2ListSection() const { return PPA2ListSection; }
+  MCSection *getADASection() const { return ADASection; }
   MCSection *getIDRLSection() const { return IDRLSection; }
 
   // XCOFF specific sections
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index e922101187905..a09fe0980dd76 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -37,11 +37,9 @@ class MCSectionGOFF final : public MCSection {
   // The type of this section.
   GOFF::ESDSymbolType SymbolType;
 
-  // Indicates that the ED symbol needs to set the length of the section.
-  unsigned RequiresLength : 1;
-
   // Indicates that the PR symbol needs to set the length of the section to a
-  // non-zero value.
+  // non-zero value. This is only a problem with the ADA PR - the binder will
+  // generate an error in this case.
   unsigned RequiresNonZeroLength : 1;
 
   friend class MCContext;
@@ -55,16 +53,17 @@ class MCSectionGOFF final : public MCSection {
 public:
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                             raw_ostream &OS,
-                            uint32_t /*Subsection*/) const override {
-    ;
+                            uint32_t Subsection) const override {
     switch (SymbolType) {
     case GOFF::ESD_ST_SectionDefinition:
       OS << Name << " CSECT\n";
       break;
     case GOFF::ESD_ST_ElementDefinition:
+      getParent()->printSwitchToSection(MAI, T, OS, Subsection);
       OS << Name << " CATTR\n";
       break;
     case GOFF::ESD_ST_PartReference:
+      getParent()->printSwitchToSection(MAI, T, OS, Subsection);
       OS << Name << " XATTR\n";
       break;
     default:
@@ -101,7 +100,7 @@ class MCSectionGOFF final : public MCSection {
     return PRAttributes;
   }
 
-  bool requiresLength() const { return RequiresLength; }
+  void setRequiresNonZeroLength() { RequiresNonZeroLength = true; }
   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 a64a22ebcf67d..9ca89bf272418 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -66,6 +66,7 @@
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/TargetParser/Triple.h"
@@ -2763,12 +2764,15 @@ TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default;
 
 void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
   // Construct the default names for the root SD and the ADA PR symbol.
-  DefaultRootSDName = Twine(M.getSourceFileName()).concat("#C").str();
-  DefaultADAPRName = Twine(M.getSourceFileName()).concat("#S").str();
+  StringRef FileName = sys::path::stem(M.getSourceFileName());
+  DefaultRootSDName = Twine(FileName).concat("#C").str();
+  DefaultADAPRName = Twine(FileName).concat("#S").str();
   MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(RootSDSection);
-  MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADAPRSection);
+  MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADASection);
   RootSD->setName(DefaultRootSDName);
   ADAPR->setName(DefaultADAPRName);
+  // The length of the ADA needs to be adjusted in case it is 0.
+  ADAPR->setRequiresNonZeroLength();
   // Initialize the label for the text section.
   MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>(
       getContext().getOrCreateSymbol(RootSD->getName()));
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index b70fab6185a03..fd5f52d2b7523 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -308,8 +308,7 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
   if (Section.isED()) {
     GOFFSymbol ED(Section.getName(), Section.getId(),
                   Section.getParent()->getId(), Section.getEDAttributes());
-    if (Section.requiresLength())
-      ED.SectionLength = Asm.getSectionAddressSize(Section);
+    ED.SectionLength = Asm.getSectionAddressSize(Section);
     writeSymbol(ED);
   }
 
@@ -331,7 +330,9 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
 }
 
 void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
-  GOFFSymbol LD(Symbol.getName(), ++EsdIdCounter, 0, Symbol.getLDAttributes());
+  GOFFSymbol LD(Symbol.getName(), ++EsdIdCounter,
+                static_cast<MCSectionGOFF &>(Symbol.getSection()).getId(),
+                Symbol.getLDAttributes());
   if (Symbol.getADA())
     LD.ADAEsdId = Symbol.getADA()->getId();
   writeSymbol(LD);
@@ -351,6 +352,7 @@ void GOFFWriter::defineSymbols() {
       continue;
     auto &Symbol = cast<MCSymbolGOFF>(Sym);
     if (Symbol.hasLDAttributes()) {
+      defineLabel(Symbol);
     }
   }
 }
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index fa4c090d0fe24..11ac998c80512 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -694,10 +694,9 @@ MCContext::getGOFFSection(SectionKind Kind, GOFF::ESDSymbolType SymbolType,
 }
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
-                                         GOFF::SDAttr SDAttributes,
-                                         MCSection *Parent) {
+                                         GOFF::SDAttr SDAttributes) {
   return getGOFFSection(Kind, GOFF::ESD_ST_SectionDefinition, Name,
-                        SDAttributes, GOFF::EDAttr{}, GOFF::PRAttr{}, Parent);
+                        SDAttributes, GOFF::EDAttr{}, GOFF::PRAttr{}, nullptr);
 }
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
@@ -710,8 +709,8 @@ MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::PRAttr PRAttributes,
                                          MCSection *Parent) {
-  return getGOFFSection(Kind, GOFF::ESD_ST_SectionDefinition, Name,
-                        GOFF::SDAttr{}, GOFF::EDAttr{}, PRAttributes, Parent);
+  return getGOFFSection(Kind, GOFF::ESD_ST_PartReference, Name, GOFF::SDAttr{},
+                        GOFF::EDAttr{}, PRAttributes, Parent);
 }
 
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 114e48ed57751..cf0adae68189c 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -31,6 +31,7 @@ void MCGOFFStreamer::initSections(bool /*NoExecStack*/,
                                   const MCSubtargetInfo &STI) {
   MCContext &Ctx = getContext();
   // Emit the text section.
+  switchSection(Ctx.getObjectFileInfo()->getADASection());
   switchSection(Ctx.getObjectFileInfo()->getTextSection());
 }
 
@@ -41,7 +42,7 @@ void registerSectionHierarchy(MCAssembler &Asm, MCSectionGOFF *Section) {
     return;
   if (Section->getParent())
     registerSectionHierarchy(Asm, Section->getParent());
-  registerSectionHierarchy(Asm, Section);
+  Asm.registerSection(*Section);
 }
 } // namespace
 
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 9daa197288cb8..a1ed984639406 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -551,14 +551,14 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       SectionKind::getMetadata(), "#C",
       GOFF::SDAttr{GOFF::ESD_TA_Rent, GOFF::ESD_BSC_Section});
 
-  ADAEDSection = Ctx->getGOFFSection(
+  MCSectionGOFF *ADAEDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_WSA,
       GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
                    GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
                    GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
                    GOFF::ESD_ALIGN_Quadword},
       RootSDSection);
-  ADAPRSection = Ctx->getGOFFSection(
+  ADASection = Ctx->getGOFFSection(
       SectionKind::getData(), "#S",
       GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
                    GOFF::ESD_LT_XPLink, GOFF::AMODE, GOFF::ESD_BSC_Section,
@@ -573,14 +573,14 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
       RootSDSection);
 
-  PPA2ListEDSection = Ctx->getGOFFSection(
+  MCSectionGOFF *PPA2ListEDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_PPA2,
       GOFF::EDAttr{true, GOFF::ESD_EXE_DATA, GOFF::AMODE, 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},
       RootSDSection);
-  PPA2ListPRSection = Ctx->getGOFFSection(
+  PPA2ListSection = Ctx->getGOFFSection(
       SectionKind::getData(), ".&ppa2",
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
                    GOFF::ESD_LT_OS, GOFF::AMODE, GOFF::ESD_BSC_Section,
diff --git a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
index f447731c849e1..6a76c2fe50878 100644
--- a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
@@ -37,6 +37,7 @@ lpad:
 ; CHECK: Personality routine
 ; CHECK: LSDA location
 ; Check that the exception table is emitted into .lsda section.
-; CHECK: C_WSA64 CATTR
-; CHECK: GCC_except_table0 XATTR
+; CHECK:  <stdin>#C CSECT
+; CHECK:  C_WSA64 CATTR
+; CHECK:  .gcc_exception_table.test1 XATTR
 ; CHECK: GCC_except_table0:
diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
index 40a4b91b9f1da..d1c83060410e5 100644
--- a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -5,10 +5,10 @@
 @a = global i32 0, align 4
 
 define signext i32 @main() {
+; CHECK: <stdin>#C CSECT
 ; CHECK: C_CODE64 CATTR
-; CHECK: #C XATTR
 ; CHECK: main:
-; CHECK: a CSECT
+; CHECK: <stdin>#C CSECT
 ; CHECK: C_WSA64 CATTR
 ; CHECK: a XATTR
 entry:
diff --git a/llvm/test/MC/GOFF/ppa1.ll b/llvm/test/MC/GOFF/ppa1.ll
index fe2dc77bba2f5..95e036dedecd2 100644
--- a/llvm/test/MC/GOFF/ppa1.ll
+++ b/llvm/test/MC/GOFF/ppa1.ll
@@ -12,7 +12,8 @@
 ; CHECK: *   Bit 1: 1 = Leaf function
 ; CHECK: *   Bit 2: 0 = Does not use alloca
 ; CHECK: L#func_end0:
-; CHECK: .section        ".ppa1"
+; CHECK: <stdin>#C CSECT
+; CHECK: C_CODE64 CATTR
 ; CHECK: L#PPA1_void_test_0:                     * PPA1
 ; CHECK:        .byte   2                               * Version
 ; CHECK:        .byte   206                             * LE Signature X'CE'
diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll
index 9e943a71cbf4a..004c5540f0709 100644
--- a/llvm/test/MC/GOFF/section.ll
+++ b/llvm/test/MC/GOFF/section.ll
@@ -66,8 +66,8 @@ entry:
 
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK: 0000190 03 00 00 02 00 00 00 05 00 00 00 04 00 00 00 00
-; CHECK: 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 00001b0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 03
-; CHECK: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK: 00001d0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK: 00002d0 03 00 00 02 00 00 00 08 00 00 00 04 00 00 00 00
+; CHECK: 00002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00002f0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 03
+; CHECK: 0000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK: 0000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00

>From 74e804c18789ff961d0639249c9ce814c98099ba Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 7 Apr 2025 18:47:40 -0400
Subject: [PATCH 12/35] Emit CSECT/CATTR

This adds the logic to emit the CSECT and CATTR assembler instructions.
---
 llvm/include/llvm/MC/MCSectionGOFF.h          |  26 +---
 llvm/include/llvm/MC/MCSymbolGOFF.h           |   5 +-
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  |   5 +-
 llvm/lib/MC/CMakeLists.txt                    |   1 +
 llvm/lib/MC/MCSectionGOFF.cpp                 | 145 ++++++++++++++++++
 .../CodeGen/SystemZ/zos-ada-relocations.ll    |   5 +-
 llvm/test/CodeGen/SystemZ/zos-intrinsics.ll   |   5 +-
 llvm/test/CodeGen/SystemZ/zos-landingpad.ll   |   5 +-
 llvm/test/CodeGen/SystemZ/zos-simple-test.ll  |  12 +-
 llvm/test/MC/GOFF/ppa1.ll                     |   4 +-
 10 files changed, 175 insertions(+), 38 deletions(-)
 create mode 100644 llvm/lib/MC/MCSectionGOFF.cpp

diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index a09fe0980dd76..36d27dab3d4e3 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -42,34 +42,23 @@ class MCSectionGOFF final : public MCSection {
   // generate an error in this case.
   unsigned RequiresNonZeroLength : 1;
 
+  // Set to true if the section definition was already emitted.
+  mutable unsigned Emitted : 1;
+
   friend class MCContext;
+  friend class MCSymbolGOFF;
   MCSectionGOFF(StringRef Name, SectionKind K, GOFF::ESDSymbolType SymbolType,
                 GOFF::SDAttr SDAttributes, GOFF::EDAttr EDAttributes,
                 GOFF::PRAttr PRAttributes, MCSectionGOFF *Parent = nullptr)
       : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
         Parent(Parent), SDAttributes(SDAttributes), EDAttributes(EDAttributes),
-        PRAttributes(PRAttributes), SymbolType(SymbolType) {}
+        PRAttributes(PRAttributes), SymbolType(SymbolType),
+        RequiresNonZeroLength(0), Emitted(0) {}
 
 public:
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                             raw_ostream &OS,
-                            uint32_t Subsection) const override {
-    switch (SymbolType) {
-    case GOFF::ESD_ST_SectionDefinition:
-      OS << Name << " CSECT\n";
-      break;
-    case GOFF::ESD_ST_ElementDefinition:
-      getParent()->printSwitchToSection(MAI, T, OS, Subsection);
-      OS << Name << " CATTR\n";
-      break;
-    case GOFF::ESD_ST_PartReference:
-      getParent()->printSwitchToSection(MAI, T, OS, Subsection);
-      OS << Name << " XATTR\n";
-      break;
-    default:
-      llvm_unreachable("Wrong section type");
-    }
-  }
+                            uint32_t Subsection) const override;
 
   bool useCodeAlign() const override { return false; }
 
@@ -100,7 +89,6 @@ class MCSectionGOFF final : public MCSection {
     return PRAttributes;
   }
 
-  void setRequiresNonZeroLength() { RequiresNonZeroLength = true; }
   bool requiresNonZeroLength() const { return RequiresNonZeroLength; }
 
   void setName(StringRef SectionName) { Name = SectionName; }
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index c46f5bd4234b5..d8c570d2de240 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -42,7 +42,10 @@ class MCSymbolGOFF : public MCSymbol {
   GOFF::LDAttr getLDAttributes() const { return LDAttributes; }
   bool hasLDAttributes() const { return getFlags() & SF_LD; }
 
-  void setADA(MCSectionGOFF *AssociatedDataArea) { ADA = AssociatedDataArea; }
+  void setADA(MCSectionGOFF *AssociatedDataArea) {
+    ADA = AssociatedDataArea;
+    AssociatedDataArea->RequiresNonZeroLength = true;
+  }
   MCSectionGOFF *getADA() const { return ADA; }
 
   static bool classof(const MCSymbol *S) { return S->isGOFF(); }
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 9ca89bf272418..265d5b18e78a3 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2765,14 +2765,15 @@ TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default;
 void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
   // Construct the default names for the root SD and the ADA PR symbol.
   StringRef FileName = sys::path::stem(M.getSourceFileName());
+  if (FileName.size() > 1 && FileName.starts_with('<') &&
+      FileName.ends_with('>'))
+    FileName = FileName.substr(1, FileName.size() - 2);
   DefaultRootSDName = Twine(FileName).concat("#C").str();
   DefaultADAPRName = Twine(FileName).concat("#S").str();
   MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(RootSDSection);
   MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADASection);
   RootSD->setName(DefaultRootSDName);
   ADAPR->setName(DefaultADAPRName);
-  // The length of the ADA needs to be adjusted in case it is 0.
-  ADAPR->setRequiresNonZeroLength();
   // Initialize the label for the text section.
   MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>(
       getContext().getOrCreateSymbol(RootSD->getName()));
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index f49f14c848b90..d662c42c522fc 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -46,6 +46,7 @@ add_llvm_component_library(LLVMMC
   MCSectionCOFF.cpp
   MCSectionDXContainer.cpp
   MCSectionELF.cpp
+  MCSectionGOFF.cpp
   MCSectionMachO.cpp
   MCSectionWasm.cpp
   MCSectionXCOFF.cpp
diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
new file mode 100644
index 0000000000000..3ff2a239ff51d
--- /dev/null
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -0,0 +1,145 @@
+//===- MCSectionGOFF.cpp - GOFF Code Section Representation ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCSectionGOFF.h"
+#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+void emitRMode(raw_ostream &OS, GOFF::ESDRmode Rmode, bool UseParenthesis) {
+  if (Rmode != GOFF::ESD_RMODE_None) {
+    OS << "RMODE" << (UseParenthesis ? '(' : ' ');
+    switch (Rmode) {
+    case GOFF::ESD_RMODE_24:
+      OS << "24";
+      break;
+    case GOFF::ESD_RMODE_31:
+      OS << "31";
+      break;
+    case GOFF::ESD_RMODE_64:
+      OS << "64";
+      break;
+    case GOFF::ESD_RMODE_None:
+      break;
+    }
+    if (UseParenthesis)
+      OS << ')';
+  }
+}
+
+void emitCATTR(raw_ostream &OS, StringRef Name, StringRef ParentName,
+               bool EmitAmodeAndRmode, GOFF::ESDAmode Amode,
+               GOFF::ESDRmode Rmode, GOFF::ESDAlignment Alignment,
+               GOFF::ESDLoadingBehavior LoadBehavior,
+               GOFF::ESDExecutable Executable, bool IsReadOnly,
+               StringRef PartName) {
+  if (EmitAmodeAndRmode && Amode != GOFF::ESD_AMODE_None) {
+    OS << ParentName << " AMODE ";
+    switch (Amode) {
+    case GOFF::ESD_AMODE_24:
+      OS << "24";
+      break;
+    case GOFF::ESD_AMODE_31:
+      OS << "31";
+      break;
+    case GOFF::ESD_AMODE_ANY:
+      OS << "ANY";
+      break;
+    case GOFF::ESD_AMODE_64:
+      OS << "64";
+      break;
+    case GOFF::ESD_AMODE_MIN:
+      OS << "ANY64";
+      break;
+    case GOFF::ESD_AMODE_None:
+      break;
+    }
+    OS << "\n";
+  }
+  if (EmitAmodeAndRmode && Rmode != GOFF::ESD_RMODE_None) {
+    OS << ParentName << ' ';
+    emitRMode(OS, Rmode, /*UseParenthesis=*/false);
+    OS << "\n";
+  }
+  OS << Name << " CATTR ";
+  OS << "ALIGN(" << static_cast<unsigned>(Alignment) << ")";
+  switch (LoadBehavior) {
+  case GOFF::ESD_LB_Deferred:
+    OS << ",DEFLOAD";
+    break;
+  case GOFF::ESD_LB_NoLoad:
+    OS << ",NOLOAD";
+    break;
+  default:
+    break;
+  }
+  switch (Executable) {
+  case GOFF::ESD_EXE_CODE:
+    OS << ",EXECUTABLE";
+    break;
+  case GOFF::ESD_EXE_DATA:
+    OS << ",NOTEXECUTABLE";
+    break;
+  default:
+    break;
+  }
+  if (IsReadOnly)
+    OS << ",READONLY";
+  if (Rmode != GOFF::ESD_RMODE_None) {
+    OS << ',';
+    emitRMode(OS, Rmode, /*UseParenthesis=*/true);
+  }
+  if (!PartName.empty())
+    OS << ",PART(" << PartName << ")";
+  OS << '\n';
+}
+} // namespace
+
+void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+                                         raw_ostream &OS,
+                                         uint32_t Subsection) const {
+  switch (SymbolType) {
+  case GOFF::ESD_ST_SectionDefinition: {
+    OS << Name << " CSECT\n";
+    Emitted = true;
+    break;
+  }
+  case GOFF::ESD_ST_ElementDefinition: {
+    bool ParentEmitted = getParent()->Emitted;
+    getParent()->printSwitchToSection(MAI, T, OS, Subsection);
+    if (!Emitted) {
+      emitCATTR(OS, Name, getParent()->getName(), !ParentEmitted,
+                EDAttributes.Amode, EDAttributes.Rmode, EDAttributes.Alignment,
+                EDAttributes.LoadBehavior, EDAttributes.Executable,
+                EDAttributes.IsReadOnly, StringRef());
+      Emitted = true;
+    } else
+      OS << Name << " CATTR ,\n";
+    break;
+  }
+  case GOFF::ESD_ST_PartReference: {
+    MCSectionGOFF *ED = getParent();
+    bool SDEmitted = ED->getParent()->Emitted;
+    ED->getParent()->printSwitchToSection(MAI, T, OS, Subsection);
+    if (!Emitted) {
+      emitCATTR(OS, ED->getName(), ED->getParent()->getName(), !SDEmitted,
+                PRAttributes.Amode, getParent()->EDAttributes.Rmode,
+                PRAttributes.Alignment, getParent()->EDAttributes.LoadBehavior,
+                PRAttributes.Executable, PRAttributes.IsReadOnly, Name);
+      ED->Emitted = true;
+      Emitted = true;
+    } else
+      OS << ED->getName() << " CATTR ,\n";
+    break;
+  }
+  default:
+    llvm_unreachable("Wrong section type");
+  }
+}
\ No newline at end of file
diff --git a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
index 59ad4ff93c5e9..8a31dab9c7686 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
@@ -55,9 +55,8 @@ entry:
 
 declare signext i32 @callout(i32 signext)
 
-; CHECK: #C CSECT
-; CHECK: C_WSA64 CATTR
-; CHECK: #S XATTR
+; CHECK: stdin#C CSECT
+; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
 ; CHECK:  .set L#DoFunc at indirect0, DoFunc
 ; CHECK:      .indirect_symbol   L#DoFunc at indirect0
 ; CHECK:  .quad V(L#DoFunc at indirect0)          * Offset 0 pointer to function descriptor DoFunc
diff --git a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
index b9aedf6517d4b..f413fc5ce7671 100644
--- a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
@@ -30,9 +30,8 @@ declare double @llvm.sin.f64(double)
 declare fp128 @llvm.exp2.f128(fp128)
 
 ; Check the calls in the ADA.
-; CHECK: #C CSECT
-; CHECK: C_WSA64 CATTR
-; CHECK: #S XATTR
+; CHECK: stdin#C CSECT
+; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
 
 ; Check that there is no call to sqrt.
 ; CHECK-NOT:  .quad   R(@@WSQT at B)
diff --git a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
index 6a76c2fe50878..d216f292396a8 100644
--- a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
@@ -37,7 +37,6 @@ lpad:
 ; CHECK: Personality routine
 ; CHECK: LSDA location
 ; Check that the exception table is emitted into .lsda section.
-; CHECK:  <stdin>#C CSECT
-; CHECK:  C_WSA64 CATTR
-; CHECK:  .gcc_exception_table.test1 XATTR
+; CHECK:  stdin#C CSECT
+; CHECK:  C_WSA64 CATTR ALIGN(2),DEFLOAD,RMODE(64),PART(.gcc_exception_table.test1)
 ; CHECK: GCC_except_table0:
diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
index d1c83060410e5..35ef34f2313f3 100644
--- a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -5,12 +5,14 @@
 @a = global i32 0, align 4
 
 define signext i32 @main() {
-; CHECK: <stdin>#C CSECT
-; CHECK: C_CODE64 CATTR
+; CHECK: stdin#C CSECT
+; CHECK: stdin#C AMODE 64
+; CHECK: stdin#C RMODE 64
+; CHECK: C_CODE64 CATTR ALIGN(3),EXECUTABLE,READONLY,RMODE(64)
 ; CHECK: main:
-; CHECK: <stdin>#C CSECT
-; CHECK: C_WSA64 CATTR
-; CHECK: a XATTR
+; CHECK: stdin#C CSECT
+; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)
+; CHECK: a:
 entry:
   ret i32 0
 }
diff --git a/llvm/test/MC/GOFF/ppa1.ll b/llvm/test/MC/GOFF/ppa1.ll
index 95e036dedecd2..222e4c448a668 100644
--- a/llvm/test/MC/GOFF/ppa1.ll
+++ b/llvm/test/MC/GOFF/ppa1.ll
@@ -12,8 +12,8 @@
 ; CHECK: *   Bit 1: 1 = Leaf function
 ; CHECK: *   Bit 2: 0 = Does not use alloca
 ; CHECK: L#func_end0:
-; CHECK: <stdin>#C CSECT
-; CHECK: C_CODE64 CATTR
+; CHECK: stdin#C CSECT
+; CHECK: C_CODE64 CATTR ,
 ; CHECK: L#PPA1_void_test_0:                     * PPA1
 ; CHECK:        .byte   2                               * Version
 ; CHECK:        .byte   206                             * LE Signature X'CE'

>From c541729ef3f846825110956e8e591e6424699d7c Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 8 Apr 2025 13:44:40 -0400
Subject: [PATCH 13/35] Fix key for hashmap and introduce union

---
 llvm/include/llvm/MC/MCContext.h            | 25 +++------------
 llvm/include/llvm/MC/MCSectionGOFF.h        | 34 +++++++++++++++------
 llvm/lib/MC/MCContext.cpp                   | 33 ++++++++++----------
 llvm/test/CodeGen/SystemZ/zos-landingpad.ll |  2 +-
 4 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 99f3d75cd8f78..ff4ed76aa6ee4 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -270,21 +270,6 @@ class MCContext {
     }
   };
 
-  struct GOFFSectionKey {
-    std::string SectionName;
-    GOFF::ESDSymbolType SymbolType;
-
-    GOFFSectionKey(StringRef SectionName, GOFF::ESDSymbolType SymbolType)
-        : SectionName(SectionName), SymbolType(SymbolType) {}
-
-    bool operator<(const GOFFSectionKey &Other) const {
-      if (SymbolType == Other.SymbolType) {
-        return SectionName < Other.SectionName;
-      }
-      return SymbolType < Other.SymbolType;
-    }
-  };
-
   struct WasmSectionKey {
     std::string SectionName;
     StringRef GroupName;
@@ -338,7 +323,7 @@ class MCContext {
   StringMap<MCSectionMachO *> MachOUniquingMap;
   std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
   StringMap<MCSectionELF *> ELFUniquingMap;
-  std::map<GOFFSectionKey, MCSectionGOFF *> GOFFUniquingMap;
+  std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
   std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
   std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
   StringMap<MCSectionDXContainer *> DXCUniquingMap;
@@ -616,11 +601,9 @@ class MCContext {
                                                    unsigned EntrySize);
 
 private:
-  MCSectionGOFF *getGOFFSection(SectionKind Kind,
-                                GOFF::ESDSymbolType SymbolType, StringRef Name,
-                                GOFF::SDAttr SDAttributes,
-                                GOFF::EDAttr EDAttributes,
-                                GOFF::PRAttr PRAttributes, MCSection *Parent);
+  template <typename TAttr>
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
+                                TAttr SDAttributes, MCSection *Parent);
 
 public:
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 36d27dab3d4e3..c239a8ad3ee15 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -30,9 +30,11 @@ class MCSectionGOFF final : public MCSection {
   MCSectionGOFF *Parent;
 
   // The attributes of the GOFF symbols.
-  GOFF::SDAttr SDAttributes;
-  GOFF::EDAttr EDAttributes;
-  GOFF::PRAttr PRAttributes;
+  union {
+    GOFF::SDAttr SDAttributes;
+    GOFF::EDAttr EDAttributes;
+    GOFF::PRAttr PRAttributes;
+  };
 
   // The type of this section.
   GOFF::ESDSymbolType SymbolType;
@@ -47,13 +49,27 @@ class MCSectionGOFF final : public MCSection {
 
   friend class MCContext;
   friend class MCSymbolGOFF;
-  MCSectionGOFF(StringRef Name, SectionKind K, GOFF::ESDSymbolType SymbolType,
-                GOFF::SDAttr SDAttributes, GOFF::EDAttr EDAttributes,
-                GOFF::PRAttr PRAttributes, MCSectionGOFF *Parent = nullptr)
+
+  MCSectionGOFF(StringRef Name, SectionKind K, GOFF::SDAttr SDAttributes,
+                MCSectionGOFF *Parent)
+      : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
+        Parent(Parent), SDAttributes(SDAttributes),
+        SymbolType(GOFF::ESD_ST_SectionDefinition), RequiresNonZeroLength(0),
+        Emitted(0) {}
+
+  MCSectionGOFF(StringRef Name, SectionKind K, GOFF::EDAttr EDAttributes,
+                MCSectionGOFF *Parent)
+      : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
+        Parent(Parent), EDAttributes(EDAttributes),
+        SymbolType(GOFF::ESD_ST_ElementDefinition), RequiresNonZeroLength(0),
+        Emitted(0) {}
+
+  MCSectionGOFF(StringRef Name, SectionKind K, GOFF::PRAttr PRAttributes,
+                MCSectionGOFF *Parent)
       : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
-        Parent(Parent), SDAttributes(SDAttributes), EDAttributes(EDAttributes),
-        PRAttributes(PRAttributes), SymbolType(SymbolType),
-        RequiresNonZeroLength(0), Emitted(0) {}
+        Parent(Parent), PRAttributes(PRAttributes),
+        SymbolType(GOFF::ESD_ST_PartReference), RequiresNonZeroLength(0),
+        Emitted(0) {}
 
 public:
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 11ac998c80512..c00a870051c49 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -672,22 +672,24 @@ MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
                                       : std::nullopt;
 }
 
-MCSectionGOFF *
-MCContext::getGOFFSection(SectionKind Kind, GOFF::ESDSymbolType SymbolType,
-                          StringRef Name, GOFF::SDAttr SDAttributes,
-                          GOFF::EDAttr EDAttributes, GOFF::PRAttr PRAttributes,
-                          MCSection *Parent) {
-  GOFFSectionKey T{Name, SymbolType};
+template <typename TAttr>
+MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
+                                         TAttr Attributes, MCSection *Parent) {
+  std::string UniqueName(Name);
+  if (Parent) {
+    UniqueName.append("/").append(Parent->getName());
+    if (auto *P = static_cast<MCSectionGOFF *>(Parent)->getParent())
+      UniqueName.append("/").append(P->getName());
+  }
   // Do the lookup. If we don't have a hit, return a new section.
-  auto IterBool = GOFFUniquingMap.insert(std::make_pair(T, nullptr));
+  auto IterBool = GOFFUniquingMap.insert(std::make_pair(UniqueName, nullptr));
   auto Iter = IterBool.first;
   if (!IterBool.second)
     return Iter->second;
 
-  StringRef CachedName = Iter->first.SectionName;
-  MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate())
-      MCSectionGOFF(CachedName, Kind, SymbolType, SDAttributes, EDAttributes,
-                    PRAttributes, static_cast<MCSectionGOFF *>(Parent));
+  StringRef CachedName = StringRef(Iter->first.c_str(), Name.size());
+  MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate()) MCSectionGOFF(
+      CachedName, Kind, Attributes, static_cast<MCSectionGOFF *>(Parent));
   Iter->second = GOFFSection;
   allocInitialFragment(*GOFFSection);
   return GOFFSection;
@@ -695,22 +697,19 @@ MCContext::getGOFFSection(SectionKind Kind, GOFF::ESDSymbolType SymbolType,
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::SDAttr SDAttributes) {
-  return getGOFFSection(Kind, GOFF::ESD_ST_SectionDefinition, Name,
-                        SDAttributes, GOFF::EDAttr{}, GOFF::PRAttr{}, nullptr);
+  return getGOFFSection<GOFF::SDAttr>(Kind, Name, SDAttributes, nullptr);
 }
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::EDAttr EDAttributes,
                                          MCSection *Parent) {
-  return getGOFFSection(Kind, GOFF::ESD_ST_ElementDefinition, Name,
-                        GOFF::SDAttr{}, EDAttributes, GOFF::PRAttr{}, Parent);
+  return getGOFFSection<GOFF::EDAttr>(Kind, Name, EDAttributes, Parent);
 }
 
 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
                                          GOFF::PRAttr PRAttributes,
                                          MCSection *Parent) {
-  return getGOFFSection(Kind, GOFF::ESD_ST_PartReference, Name, GOFF::SDAttr{},
-                        GOFF::EDAttr{}, PRAttributes, Parent);
+  return getGOFFSection<GOFF::PRAttr>(Kind, Name, PRAttributes, Parent);
 }
 
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
diff --git a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
index d216f292396a8..fd58656e549d1 100644
--- a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
@@ -38,5 +38,5 @@ lpad:
 ; CHECK: LSDA location
 ; Check that the exception table is emitted into .lsda section.
 ; CHECK:  stdin#C CSECT
-; CHECK:  C_WSA64 CATTR ALIGN(2),DEFLOAD,RMODE(64),PART(.gcc_exception_table.test1)
+; CHECK:  C_WSA64 CATTR ALIGN(2),RMODE(64),PART(.gcc_exception_table.test1)
 ; CHECK: GCC_except_table0:

>From 469206d463cf9941c7f20291a3a521f3ea2c2408 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 8 Apr 2025 15:33:37 -0400
Subject: [PATCH 14/35] Use getOrdinal/getIndex as the GOFF symbol id.

---
 llvm/include/llvm/MC/MCSectionGOFF.h |  3 ---
 llvm/lib/MC/GOFFObjectWriter.cpp     | 23 +++++++++++------------
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index c239a8ad3ee15..1bb8a7a0b7155 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -78,9 +78,6 @@ class MCSectionGOFF final : public MCSection {
 
   bool useCodeAlign() const override { return false; }
 
-  // Return the id of the section. It is the 1-based ordinal number.
-  unsigned getId() const { return getOrdinal() + 1; }
-
   // Return the parent section.
   MCSectionGOFF *getParent() const { return Parent; }
 
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index fd5f52d2b7523..a0fe350585376 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -278,9 +278,6 @@ class GOFFWriter {
   GOFFOstream OS;
   [[maybe_unused]] MCAssembler &Asm;
 
-  /// Counter for symbol id's.
-  uint32_t EsdIdCounter = 0;
-
   void writeHeader();
   void writeSymbol(const GOFFSymbol &Symbol);
   void writeEnd();
@@ -300,21 +297,21 @@ GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
 
 void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
   if (Section.isSD()) {
-    GOFFSymbol SD(Section.getName(), Section.getId(),
+    GOFFSymbol SD(Section.getName(), Section.getOrdinal(),
                   Section.getSDAttributes());
     writeSymbol(SD);
   }
 
   if (Section.isED()) {
-    GOFFSymbol ED(Section.getName(), Section.getId(),
-                  Section.getParent()->getId(), Section.getEDAttributes());
+    GOFFSymbol ED(Section.getName(), Section.getOrdinal(),
+                  Section.getParent()->getOrdinal(), Section.getEDAttributes());
     ED.SectionLength = Asm.getSectionAddressSize(Section);
     writeSymbol(ED);
   }
 
   if (Section.isPR()) {
-    GOFFSymbol PR(Section.getName(), Section.getId(),
-                  Section.getParent()->getId(), Section.getPRAttributes());
+    GOFFSymbol PR(Section.getName(), Section.getOrdinal(),
+                  Section.getParent()->getOrdinal(), Section.getPRAttributes());
     PR.SectionLength = Asm.getSectionAddressSize(Section);
     if (Section.requiresNonZeroLength()) {
       // We cannot have a zero-length section for data.  If we do,
@@ -330,20 +327,21 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
 }
 
 void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
-  GOFFSymbol LD(Symbol.getName(), ++EsdIdCounter,
-                static_cast<MCSectionGOFF &>(Symbol.getSection()).getId(),
+  GOFFSymbol LD(Symbol.getName(), Symbol.getIndex(),
+                static_cast<MCSectionGOFF &>(Symbol.getSection()).getOrdinal(),
                 Symbol.getLDAttributes());
   if (Symbol.getADA())
-    LD.ADAEsdId = Symbol.getADA()->getId();
+    LD.ADAEsdId = Symbol.getADA()->getOrdinal();
   writeSymbol(LD);
 }
 
 void GOFFWriter::defineSymbols() {
+  unsigned Ordinal = 0;
   // Process all sections.
   for (MCSection &S : Asm) {
     auto &Section = cast<MCSectionGOFF>(S);
+    Section.setOrdinal(++Ordinal);
     defineSectionSymbols(Section);
-    EsdIdCounter = std::max(EsdIdCounter, Section.getId());
   }
 
   // Process all symbols
@@ -352,6 +350,7 @@ void GOFFWriter::defineSymbols() {
       continue;
     auto &Symbol = cast<MCSymbolGOFF>(Sym);
     if (Symbol.hasLDAttributes()) {
+      Symbol.setIndex(++Ordinal);
       defineLabel(Symbol);
     }
   }

>From f859b78c9bf4ac47ac4e97b6259cd991e67da986 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 8 Apr 2025 16:12:10 -0400
Subject: [PATCH 15/35] Remove initSections()

Also updates the test to match ideas, to make it easier to move those blocks around.
---
 llvm/include/llvm/MC/MCGOFFStreamer.h |  1 -
 llvm/lib/MC/MCGOFFStreamer.cpp        |  8 -----
 llvm/test/MC/GOFF/section.ll          | 44 +++++++++++++--------------
 3 files changed, 22 insertions(+), 31 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 68af26ef17c70..366d7dc08c679 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -26,7 +26,6 @@ class MCGOFFStreamer : public MCObjectStreamer {
 
   ~MCGOFFStreamer() override;
 
-  void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
   void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
 
   GOFFObjectWriter &getWriter();
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index cf0adae68189c..2686a6f96e98b 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -27,14 +27,6 @@ GOFFObjectWriter &MCGOFFStreamer::getWriter() {
   return static_cast<GOFFObjectWriter &>(getAssembler().getWriter());
 }
 
-void MCGOFFStreamer::initSections(bool /*NoExecStack*/,
-                                  const MCSubtargetInfo &STI) {
-  MCContext &Ctx = getContext();
-  // Emit the text section.
-  switchSection(Ctx.getObjectFileInfo()->getADASection());
-  switchSection(Ctx.getObjectFileInfo()->getTextSection());
-}
-
 namespace {
 // Make sure that all section are registered in the correct order.
 void registerSectionHierarchy(MCAssembler &Asm, MCSectionGOFF *Section) {
diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll
index 004c5540f0709..73bc9ae42c3b5 100644
--- a/llvm/test/MC/GOFF/section.ll
+++ b/llvm/test/MC/GOFF/section.ll
@@ -33,41 +33,41 @@ entry:
 ; The 60 at offset 0x89 is the tasking behavior.
 ; The 01 at offset 0x91 is the binding scope.
 ; The name begins at offset 0x97, and is test#C.
-; CHECK: 0000050 03 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00
+; CHECK: 0000050 03 00 00 00 [[ROOTSD:00 00 00 01]] 00 00 00 00 00 00 00 00
 ; CHECK: 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK: 0000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK: 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
 ; CHECK: 0000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
+; ESD record, type ED.
+; The name is C_CODE64.
+; The regular expression matches the low byte of the length.
+; CHECK: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
+; CHECK: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a
+; CHECK: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+
 ; ESD record, type ED.
 ; The name is C_WSA64.
-; CHECK: 00000a0 03 00 00 01 00 00 00 02 00 00 00 01 00 00 00 00
-; CHECK: 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 00000c0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
-; CHECK: 00000e0 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+; CHECK: 00001e0 03 00 00 01 [[C_WSA64:00 00 00 05]] [[ROOTSD]] 00 00 00 00
+; CHECK: 00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0000200 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECK: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
+; CHECK: 0000220 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
 ; The name is test#S.
-; CHECK: 00000f0 03 00 00 03 00 00 00 03 00 00 00 02 00 00 00 00
-; CHECK: 0000100 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00
-; CHECK: 0000110 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
-; CHECK: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
-; CHECK: 0000130 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
-
-; ESD record, type ED.
-; The name is C_CODE64.
-; The regular expression matches the low byte of the length.
-; CHECK: 0000140 03 00 00 01 00 00 00 04 00 00 00 01 00 00 00 00
-; CHECK: 0000150 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
-; CHECK: 0000160 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK: 0000170 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a
-; CHECK: 0000180 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+; CHECK: 0000230 03 00 00 03 [[TESTS:00 00 00 06]] [[C_WSA64]] 00 00 00 00
+; CHECK: 0000240 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00
+; CHECK: 0000250 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK: 0000270 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
 
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK: 00002d0 03 00 00 02 00 00 00 08 00 00 00 04 00 00 00 00
+; CHECK: 00002d0 03 00 00 02 [[TESTC:00 00 00 08]] [[C_CODE64]] 00 00 00 00
 ; CHECK: 00002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 00002f0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 03
+; CHECK: 00002f0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
 ; CHECK: 0000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
 ; CHECK: 0000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00

>From 7be8fa30644f37f86e4a3cf27eb29879342d9a92 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 8 Apr 2025 16:35:55 -0400
Subject: [PATCH 16/35] Remove RootSDSection

---
 llvm/include/llvm/MC/MCObjectFileInfo.h           | 1 -
 llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 4 ++--
 llvm/lib/MC/MCObjectFileInfo.cpp                  | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index 55c979b127f59..56697ee3ae962 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -230,7 +230,6 @@ class MCObjectFileInfo {
   MCSection *GLJMPSection = nullptr;
 
   // GOFF specific sections.
-  MCSection *RootSDSection = nullptr;
   MCSection *PPA2ListSection = nullptr;
   MCSection *ADASection = nullptr;
   MCSection *IDRLSection = nullptr;
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 265d5b18e78a3..b301004d44e5c 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2770,7 +2770,7 @@ void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
     FileName = FileName.substr(1, FileName.size() - 2);
   DefaultRootSDName = Twine(FileName).concat("#C").str();
   DefaultADAPRName = Twine(FileName).concat("#S").str();
-  MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(RootSDSection);
+  MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(TextSection)->getParent();
   MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADASection);
   RootSD->setName(DefaultRootSDName);
   ADAPR->setName(DefaultADAPRName);
@@ -2799,7 +2799,7 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
                    GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
                    GOFF::ESD_BA_Merge, GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword},
-      RootSDSection);
+      static_cast<MCSectionGOFF *>(TextSection)->getParent());
   return getContext().getGOFFSection(
       SectionKind::getData(), Name,
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index a1ed984639406..1c9e2bf528ab1 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -547,7 +547,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
 }
 
 void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
-  RootSDSection = Ctx->getGOFFSection(
+  MCSectionGOFF *RootSDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), "#C",
       GOFF::SDAttr{GOFF::ESD_TA_Rent, GOFF::ESD_BSC_Section});
 

>From f358e40b56fe41217d6b914a30522b6fcaa5fe1c Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 9 Apr 2025 15:12:59 -0400
Subject: [PATCH 17/35] Fix formatting and assertions

---
 llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h | 1 +
 llvm/include/llvm/MC/MCSectionGOFF.h                     | 6 +++---
 llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp        | 3 ++-
 llvm/lib/MC/MCGOFFStreamer.cpp                           | 3 ++-
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index dd4339824c49e..c819abf76cd3a 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -318,6 +318,7 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
 class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile {
   std::string DefaultRootSDName;
   std::string DefaultADAPRName;
+
 public:
   TargetLoweringObjectFileGOFF();
   ~TargetLoweringObjectFileGOFF() override = default;
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 1bb8a7a0b7155..b8b8cf112a34d 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -90,15 +90,15 @@ class MCSectionGOFF final : public MCSection {
 
   // Accessors to the attributes.
   GOFF::SDAttr getSDAttributes() const {
-    assert(SymbolType == GOFF::ESD_ST_SectionDefinition && "Not PR symbol");
+    assert(isSD() && "Not a SD section");
     return SDAttributes;
   }
   GOFF::EDAttr getEDAttributes() const {
-    assert(SymbolType == GOFF::ESD_ST_ElementDefinition && "Not PR symbol");
+    assert(isED() && "Not a ED section");
     return EDAttributes;
   }
   GOFF::PRAttr getPRAttributes() const {
-    assert(SymbolType == GOFF::ESD_ST_PartReference && "Not PR symbol");
+    assert(isPR() && "Not a PR section");
     return PRAttributes;
   }
 
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index b301004d44e5c..090f58c76f620 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2770,7 +2770,8 @@ void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
     FileName = FileName.substr(1, FileName.size() - 2);
   DefaultRootSDName = Twine(FileName).concat("#C").str();
   DefaultADAPRName = Twine(FileName).concat("#S").str();
-  MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(TextSection)->getParent();
+  MCSectionGOFF *RootSD =
+      static_cast<MCSectionGOFF *>(TextSection)->getParent();
   MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADASection);
   RootSD->setName(DefaultRootSDName);
   ADAPR->setName(DefaultADAPRName);
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 2686a6f96e98b..23bdcf75f945d 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -39,7 +39,8 @@ void registerSectionHierarchy(MCAssembler &Asm, MCSectionGOFF *Section) {
 } // namespace
 
 void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
-  registerSectionHierarchy(getAssembler(), static_cast<MCSectionGOFF *>(Section));
+  registerSectionHierarchy(getAssembler(),
+                           static_cast<MCSectionGOFF *>(Section));
   MCObjectStreamer::changeSection(Section, Subsection);
 }
 

>From 83440e1a726372ea6db08b4d87aa7f7085cc0936 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 9 Apr 2025 16:15:52 -0400
Subject: [PATCH 18/35] Update the test case to cover all records in the file.

---
 llvm/test/MC/GOFF/section.ll | 99 +++++++++++++++++++++++++-----------
 1 file changed, 69 insertions(+), 30 deletions(-)

diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll
index 73bc9ae42c3b5..f926686945c19 100644
--- a/llvm/test/MC/GOFF/section.ll
+++ b/llvm/test/MC/GOFF/section.ll
@@ -17,11 +17,11 @@ entry:
 ;  .0 is flag
 ;  00 is version
 ; The 1 at offset 0x33 is the architecture level.
-; CHECK: 000000 03 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 000030 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK:      000000 03 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000030 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
 ; ESD record, type SD.
 ;  03 is prefix byte
@@ -33,41 +33,80 @@ entry:
 ; The 60 at offset 0x89 is the tasking behavior.
 ; The 01 at offset 0x91 is the binding scope.
 ; The name begins at offset 0x97, and is test#C.
-; CHECK: 0000050 03 00 00 00 [[ROOTSD:00 00 00 01]] 00 00 00 00 00 00 00 00
-; CHECK: 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 0000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
-; CHECK: 0000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 0000050 03 00 00 00 [[ROOTSD:00 00 00 01]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
+; CHECK-NEXT: 0000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
 ; ESD record, type ED.
 ; The name is C_CODE64.
 ; The regular expression matches the low byte of the length.
-; CHECK: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
-; CHECK: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
-; CHECK: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a
-; CHECK: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+; CHECK-NEXT: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a
+; CHECK-NEXT: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+
+; ESD record, type ED.
+; The name is C_@@QPPA2.
+; This record has a continuation, therefore the falg at offset 0xf1 is set.
+; CHECK-NEXT: 00000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 09
+; CHECK-NEXT: 0000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
+;
+; Continuation:
+; CHECK-NEXT: 0000140 03 02 00 f2 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+; ESD record, type PR.
+; The name is .&ppa2.
+; CHECK-NEXT: 0000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
+; CHECK-NEXT: 00001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
+; CHECK-NEXT: 00001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
+; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
+; CHECK-NEXT: 00001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
 
 ; ESD record, type ED.
 ; The name is C_WSA64.
-; CHECK: 00001e0 03 00 00 01 [[C_WSA64:00 00 00 05]] [[ROOTSD]] 00 00 00 00
-; CHECK: 00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 0000200 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
-; CHECK: 0000220 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+; CHECK-NEXT: 00001e0 03 00 00 01 [[C_WSA64:00 00 00 05]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000200 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECK-NEXT: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
+; CHECK-NEXT: 0000220 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
 ; The name is test#S.
-; CHECK: 0000230 03 00 00 03 [[TESTS:00 00 00 06]] [[C_WSA64]] 00 00 00 00
-; CHECK: 0000240 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00
-; CHECK: 0000250 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
-; CHECK: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
-; CHECK: 0000270 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
+; CHECK-NEXT: 0000230 03 00 00 03 [[TESTS:00 00 00 06]] [[C_WSA64]] 00 00 00 00
+; CHECK-NEXT: 0000240 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 0000250 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK-NEXT: 0000270 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
+
+; ESD record, type ED.
+; The name is B_IDRL.
+; CHECK-NEXT: 0000280 03 00 00 01 [[BIDRL:00 00 00 07]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0000290 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 00002a0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK-NEXT: 00002b0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 10 08
+; CHECK-NEXT: 00002c0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
 
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK: 00002d0 03 00 00 02 [[TESTC:00 00 00 08]] [[C_CODE64]] 00 00 00 00
-; CHECK: 00002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK: 00002f0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK: 0000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK: 0000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 00002d0 03 00 00 02 [[TESTC:00 00 00 08]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 00002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00002f0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; CHECK-NEXT: 0000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 0000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+
+; End record.
+; CHECK-NEXT: 0000320 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

>From b6b261aafc890ff3bf8574584be4dbd82752b248 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 11 Apr 2025 10:38:18 -0400
Subject: [PATCH 19/35] Reuse NameSpace from ED in PR/LD

---
 llvm/include/llvm/MC/MCGOFFAttributes.h       |  2 --
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  | 17 +++++++-------
 llvm/lib/MC/GOFFObjectWriter.cpp              | 22 +++++++++----------
 llvm/lib/MC/MCObjectFileInfo.cpp              | 12 +++++-----
 4 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index 02a336dc2a67a..d827f9b19bf60 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -66,7 +66,6 @@ struct EDAttr {
 struct LDAttr {
   bool IsRenamable = false;
   GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
-  GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName;
   GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
   GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
   GOFF::ESDAmode Amode;
@@ -78,7 +77,6 @@ struct PRAttr {
   bool IsRenamable = false;
   bool IsReadOnly = false; // ???? Not documented.
   GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
-  GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName;
   GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
   GOFF::ESDAmode Amode;
   GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 090f58c76f620..51f200bcbbdf0 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2778,9 +2778,9 @@ void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
   // Initialize the label for the text section.
   MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>(
       getContext().getOrCreateSymbol(RootSD->getName()));
-  TextLD->setLDAttributes(GOFF::LDAttr{
-      false, GOFF::ESD_EXE_CODE, GOFF::ESD_NS_NormalName, GOFF::ESD_BST_Strong,
-      GOFF::LINKAGE, GOFF::AMODE, GOFF::ESD_BSC_Section});
+  TextLD->setLDAttributes(GOFF::LDAttr{false, GOFF::ESD_EXE_CODE,
+                                       GOFF::ESD_BST_Strong, GOFF::LINKAGE,
+                                       GOFF::AMODE, GOFF::ESD_BSC_Section});
   TextLD->setADA(ADAPR);
   TextSection->setBeginSymbol(TextLD);
 }
@@ -2803,9 +2803,9 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
       static_cast<MCSectionGOFF *>(TextSection)->getParent());
   return getContext().getGOFFSection(
       SectionKind::getData(), Name,
-      GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
-                   GOFF::LINKAGE, GOFF::AMODE, GOFF::ESD_BSC_Section,
-                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Fullword, 0},
+      GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::LINKAGE,
+                   GOFF::AMODE, GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
+                   GOFF::ESD_ALIGN_Fullword, 0},
       WSA);
 }
 
@@ -2834,9 +2834,8 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
         SD);
     return getContext().getGOFFSection(
         Kind, Symbol->getName(),
-        GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
-                     GOFF::LINKAGE, GOFF::AMODE, PRBindingScope,
-                     GOFF::ESD_DSS_NoWarning,
+        GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
+                     GOFF::AMODE, PRBindingScope, GOFF::ESD_DSS_NoWarning,
                      static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0},
         ED);
   }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index a0fe350585376..dbac76be4b7be 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -246,10 +246,9 @@ class GOFFSymbol {
   }
 
   GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
-             const GOFF::LDAttr &Attr)
+             GOFF::ESDNameSpaceId NameSpace, const GOFF::LDAttr &Attr)
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
-        SymbolType(GOFF::ESD_ST_LabelDefinition) {
-    this->NameSpace = Attr.NameSpace;
+        SymbolType(GOFF::ESD_ST_LabelDefinition), NameSpace(NameSpace) {
     SymbolFlags.setRenameable(Attr.IsRenamable);
     BehavAttrs.setExecutable(Attr.Executable);
     BehavAttrs.setBindingStrength(Attr.BindingStrength);
@@ -259,10 +258,9 @@ class GOFFSymbol {
   }
 
   GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
-             const GOFF::PRAttr &Attr)
+             GOFF::ESDNameSpaceId NameSpace, const GOFF::PRAttr &Attr)
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
-        SymbolType(GOFF::ESD_ST_PartReference) {
-    this->NameSpace = Attr.NameSpace;
+        SymbolType(GOFF::ESD_ST_PartReference), NameSpace(NameSpace) {
     SymbolFlags.setRenameable(Attr.IsRenamable);
     BehavAttrs.setExecutable(Attr.Executable);
     BehavAttrs.setAlignment(Attr.Alignment);
@@ -310,8 +308,10 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
   }
 
   if (Section.isPR()) {
-    GOFFSymbol PR(Section.getName(), Section.getOrdinal(),
-                  Section.getParent()->getOrdinal(), Section.getPRAttributes());
+    MCSectionGOFF *Parent = Section.getParent();
+    GOFFSymbol PR(Section.getName(), Section.getOrdinal(), Parent->getOrdinal(),
+                  Parent->getEDAttributes().NameSpace,
+                  Section.getPRAttributes());
     PR.SectionLength = Asm.getSectionAddressSize(Section);
     if (Section.requiresNonZeroLength()) {
       // We cannot have a zero-length section for data.  If we do,
@@ -327,9 +327,9 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
 }
 
 void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
-  GOFFSymbol LD(Symbol.getName(), Symbol.getIndex(),
-                static_cast<MCSectionGOFF &>(Symbol.getSection()).getOrdinal(),
-                Symbol.getLDAttributes());
+  MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(Symbol.getSection());
+  GOFFSymbol LD(Symbol.getName(), Symbol.getIndex(), Section.getOrdinal(),
+                Section.getEDAttributes().NameSpace, Symbol.getLDAttributes());
   if (Symbol.getADA())
     LD.ADAEsdId = Symbol.getADA()->getOrdinal();
   writeSymbol(LD);
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 1c9e2bf528ab1..702be71692aed 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -560,9 +560,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       RootSDSection);
   ADASection = Ctx->getGOFFSection(
       SectionKind::getData(), "#S",
-      GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts,
-                   GOFF::ESD_LT_XPLink, GOFF::AMODE, GOFF::ESD_BSC_Section,
-                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Quadword, 0},
+      GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink,
+                   GOFF::AMODE, GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
+                   GOFF::ESD_ALIGN_Quadword, 0},
       ADAEDSection);
 
   TextSection = Ctx->getGOFFSection(
@@ -582,9 +582,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       RootSDSection);
   PPA2ListSection = Ctx->getGOFFSection(
       SectionKind::getData(), ".&ppa2",
-      GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts,
-                   GOFF::ESD_LT_OS, GOFF::AMODE, GOFF::ESD_BSC_Section,
-                   GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Doubleword, 0},
+      GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_LT_OS,
+                   GOFF::AMODE, GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
+                   GOFF::ESD_ALIGN_Doubleword, 0},
       PPA2ListEDSection);
 
   IDRLSection = Ctx->getGOFFSection(

>From 01549d43fdde2c8090878449da263abbbb852d79 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 11 Apr 2025 11:44:42 -0400
Subject: [PATCH 20/35] Also set FillByteValue.

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

diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index dbac76be4b7be..084ce26174e9b 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -232,9 +232,11 @@ class GOFFSymbol {
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
         SymbolType(GOFF::ESD_ST_ElementDefinition) {
     this->NameSpace = Attr.NameSpace;
-    // TODO Do we need/should set the "mangled" flag?
+    // We default to 0 as fill byte value.
+    this->FillByteValue = 0;
     SymbolFlags.setFillBytePresence(1);
     SymbolFlags.setReservedQwords(Attr.ReservedQwords);
+    // TODO Do we need/should set the "mangled" flag?
     BehavAttrs.setReadOnly(Attr.IsReadOnly);
     BehavAttrs.setExecutable(Attr.Executable);
     BehavAttrs.setAmode(Attr.Amode);

>From 4d7e8c598bec94d09911d6cf7efe240a640fda9b Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 14 Apr 2025 16:17:11 -0400
Subject: [PATCH 21/35] - Amode only for LD - Add sorting key - Change
 generation of Rmode/Amode

---
 llvm/include/llvm/MC/MCGOFFAttributes.h       |  2 -
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  | 16 ++--
 llvm/lib/MC/GOFFObjectWriter.cpp              |  2 -
 llvm/lib/MC/MCObjectFileInfo.cpp              | 20 ++---
 llvm/lib/MC/MCSectionGOFF.cpp                 | 89 ++++++-------------
 llvm/test/CodeGen/SystemZ/zos-simple-test.ll  |  2 -
 llvm/test/MC/GOFF/section.ll                  | 12 +--
 7 files changed, 50 insertions(+), 93 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index d827f9b19bf60..027bdadbec1f1 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -52,7 +52,6 @@ struct SDAttr {
 struct EDAttr {
   bool IsReadOnly = false;
   GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
-  GOFF::ESDAmode Amode;
   GOFF::ESDRmode Rmode;
   GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName;
   GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented;
@@ -78,7 +77,6 @@ struct PRAttr {
   bool IsReadOnly = false; // ???? Not documented.
   GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
   GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
-  GOFF::ESDAmode Amode;
   GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
   GOFF::ESDDuplicateSymbolSeverity DuplicateSymbolSeverity =
       GOFF::ESD_DSS_NoWarning;
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 51f200bcbbdf0..0bac1abfb489d 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2796,15 +2796,15 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
 
   MCSectionGOFF *WSA = getContext().getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_WSA,
-      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
-                   GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
-                   GOFF::ESD_BA_Merge, GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0,
+      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::RMODE, GOFF::ESD_NS_Parts,
+                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
+                   GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword},
       static_cast<MCSectionGOFF *>(TextSection)->getParent());
   return getContext().getGOFFSection(
       SectionKind::getData(), Name,
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::LINKAGE,
-                   GOFF::AMODE, GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
+                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
                    GOFF::ESD_ALIGN_Fullword, 0},
       WSA);
 }
@@ -2827,15 +2827,15 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
         GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope});
     MCSectionGOFF *ED = getContext().getGOFFSection(
         SectionKind::getMetadata(), GOFF::CLASS_WSA,
-        GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
-                     GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
-                     GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0,
+        GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::RMODE, GOFF::ESD_NS_Parts,
+                     GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
+                     GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0,
                      static_cast<GOFF::ESDAlignment>(GO->getAlignment())},
         SD);
     return getContext().getGOFFSection(
         Kind, Symbol->getName(),
         GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
-                     GOFF::AMODE, PRBindingScope, GOFF::ESD_DSS_NoWarning,
+                     PRBindingScope, GOFF::ESD_DSS_NoWarning,
                      static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0},
         ED);
   }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 084ce26174e9b..713a5a5996854 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -239,7 +239,6 @@ class GOFFSymbol {
     // TODO Do we need/should set the "mangled" flag?
     BehavAttrs.setReadOnly(Attr.IsReadOnly);
     BehavAttrs.setExecutable(Attr.Executable);
-    BehavAttrs.setAmode(Attr.Amode);
     BehavAttrs.setRmode(Attr.Rmode);
     BehavAttrs.setTextStyle(Attr.TextStyle);
     BehavAttrs.setBindingAlgorithm(Attr.BindAlgorithm);
@@ -266,7 +265,6 @@ class GOFFSymbol {
     SymbolFlags.setRenameable(Attr.IsRenamable);
     BehavAttrs.setExecutable(Attr.Executable);
     BehavAttrs.setAlignment(Attr.Alignment);
-    BehavAttrs.setAmode(Attr.Amode);
     BehavAttrs.setLinkageType(Attr.Linkage);
     BehavAttrs.setBindingScope(Attr.BindingScope);
     BehavAttrs.setDuplicateSymbolSeverity(Attr.DuplicateSymbolSeverity);
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 702be71692aed..731572b0ad25e 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -553,21 +553,21 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
 
   MCSectionGOFF *ADAEDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_WSA,
-      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
-                   GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
-                   GOFF::ESD_BA_Merge, GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
+      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::RMODE, GOFF::ESD_NS_Parts,
+                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
+                   GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
                    GOFF::ESD_ALIGN_Quadword},
       RootSDSection);
   ADASection = Ctx->getGOFFSection(
       SectionKind::getData(), "#S",
       GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink,
-                   GOFF::AMODE, GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
+                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
                    GOFF::ESD_ALIGN_Quadword, 0},
       ADAEDSection);
 
   TextSection = Ctx->getGOFFSection(
       SectionKind::getText(), GOFF::CLASS_CODE,
-      GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::AMODE, GOFF::RMODE,
+      GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::RMODE,
                    GOFF::ESD_NS_NormalName, GOFF::ESD_TS_ByteOriented,
                    GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_Initial,
                    GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
@@ -575,21 +575,21 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
 
   MCSectionGOFF *PPA2ListEDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_PPA2,
-      GOFF::EDAttr{true, GOFF::ESD_EXE_DATA, GOFF::AMODE, GOFF::RMODE,
-                   GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented,
-                   GOFF::ESD_BA_Merge, GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
+      GOFF::EDAttr{true, GOFF::ESD_EXE_DATA, 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},
       RootSDSection);
   PPA2ListSection = Ctx->getGOFFSection(
       SectionKind::getData(), ".&ppa2",
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_LT_OS,
-                   GOFF::AMODE, GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
+                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
                    GOFF::ESD_ALIGN_Doubleword, 0},
       PPA2ListEDSection);
 
   IDRLSection = Ctx->getGOFFSection(
       SectionKind::getData(), "B_IDRL",
-      GOFF::EDAttr{true, GOFF::ESD_EXE_Unspecified, GOFF::AMODE, GOFF::RMODE,
+      GOFF::EDAttr{true, GOFF::ESD_EXE_Unspecified, GOFF::RMODE,
                    GOFF::ESD_NS_NormalName, GOFF::ESD_TS_Structured,
                    GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_NoLoad,
                    GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
index 3ff2a239ff51d..f9b0c776f4311 100644
--- a/llvm/lib/MC/MCSectionGOFF.cpp
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -13,61 +13,11 @@
 using namespace llvm;
 
 namespace {
-void emitRMode(raw_ostream &OS, GOFF::ESDRmode Rmode, bool UseParenthesis) {
-  if (Rmode != GOFF::ESD_RMODE_None) {
-    OS << "RMODE" << (UseParenthesis ? '(' : ' ');
-    switch (Rmode) {
-    case GOFF::ESD_RMODE_24:
-      OS << "24";
-      break;
-    case GOFF::ESD_RMODE_31:
-      OS << "31";
-      break;
-    case GOFF::ESD_RMODE_64:
-      OS << "64";
-      break;
-    case GOFF::ESD_RMODE_None:
-      break;
-    }
-    if (UseParenthesis)
-      OS << ')';
-  }
-}
-
-void emitCATTR(raw_ostream &OS, StringRef Name, StringRef ParentName,
-               bool EmitAmodeAndRmode, GOFF::ESDAmode Amode,
-               GOFF::ESDRmode Rmode, GOFF::ESDAlignment Alignment,
+void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
+               GOFF::ESDAlignment Alignment,
                GOFF::ESDLoadingBehavior LoadBehavior,
                GOFF::ESDExecutable Executable, bool IsReadOnly,
-               StringRef PartName) {
-  if (EmitAmodeAndRmode && Amode != GOFF::ESD_AMODE_None) {
-    OS << ParentName << " AMODE ";
-    switch (Amode) {
-    case GOFF::ESD_AMODE_24:
-      OS << "24";
-      break;
-    case GOFF::ESD_AMODE_31:
-      OS << "31";
-      break;
-    case GOFF::ESD_AMODE_ANY:
-      OS << "ANY";
-      break;
-    case GOFF::ESD_AMODE_64:
-      OS << "64";
-      break;
-    case GOFF::ESD_AMODE_MIN:
-      OS << "ANY64";
-      break;
-    case GOFF::ESD_AMODE_None:
-      break;
-    }
-    OS << "\n";
-  }
-  if (EmitAmodeAndRmode && Rmode != GOFF::ESD_RMODE_None) {
-    OS << ParentName << ' ';
-    emitRMode(OS, Rmode, /*UseParenthesis=*/false);
-    OS << "\n";
-  }
+               uint32_t SortKey, StringRef PartName) {
   OS << Name << " CATTR ";
   OS << "ALIGN(" << static_cast<unsigned>(Alignment) << ")";
   switch (LoadBehavior) {
@@ -94,8 +44,24 @@ void emitCATTR(raw_ostream &OS, StringRef Name, StringRef ParentName,
     OS << ",READONLY";
   if (Rmode != GOFF::ESD_RMODE_None) {
     OS << ',';
-    emitRMode(OS, Rmode, /*UseParenthesis=*/true);
+    OS << "RMODE(";
+    switch (Rmode) {
+    case GOFF::ESD_RMODE_24:
+      OS << "24";
+      break;
+    case GOFF::ESD_RMODE_31:
+      OS << "31";
+      break;
+    case GOFF::ESD_RMODE_64:
+      OS << "64";
+      break;
+    case GOFF::ESD_RMODE_None:
+      break;
+    }
+    OS << ')';
   }
+  if (SortKey)
+    OS << ",PRIORITY(" << SortKey << ")";
   if (!PartName.empty())
     OS << ",PART(" << PartName << ")";
   OS << '\n';
@@ -112,13 +78,11 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
     break;
   }
   case GOFF::ESD_ST_ElementDefinition: {
-    bool ParentEmitted = getParent()->Emitted;
     getParent()->printSwitchToSection(MAI, T, OS, Subsection);
     if (!Emitted) {
-      emitCATTR(OS, Name, getParent()->getName(), !ParentEmitted,
-                EDAttributes.Amode, EDAttributes.Rmode, EDAttributes.Alignment,
+      emitCATTR(OS, Name, EDAttributes.Rmode, EDAttributes.Alignment,
                 EDAttributes.LoadBehavior, EDAttributes.Executable,
-                EDAttributes.IsReadOnly, StringRef());
+                EDAttributes.IsReadOnly, 0, StringRef());
       Emitted = true;
     } else
       OS << Name << " CATTR ,\n";
@@ -126,13 +90,12 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
   }
   case GOFF::ESD_ST_PartReference: {
     MCSectionGOFF *ED = getParent();
-    bool SDEmitted = ED->getParent()->Emitted;
     ED->getParent()->printSwitchToSection(MAI, T, OS, Subsection);
     if (!Emitted) {
-      emitCATTR(OS, ED->getName(), ED->getParent()->getName(), !SDEmitted,
-                PRAttributes.Amode, getParent()->EDAttributes.Rmode,
-                PRAttributes.Alignment, getParent()->EDAttributes.LoadBehavior,
-                PRAttributes.Executable, PRAttributes.IsReadOnly, Name);
+      emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode,
+                PRAttributes.Alignment, ED->EDAttributes.LoadBehavior,
+                PRAttributes.Executable, PRAttributes.IsReadOnly,
+                PRAttributes.SortKey, Name);
       ED->Emitted = true;
       Emitted = true;
     } else
diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
index 35ef34f2313f3..dd256e481c42a 100644
--- a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -6,8 +6,6 @@
 
 define signext i32 @main() {
 ; CHECK: stdin#C CSECT
-; CHECK: stdin#C AMODE 64
-; CHECK: stdin#C RMODE 64
 ; CHECK: C_CODE64 CATTR ALIGN(3),EXECUTABLE,READONLY,RMODE(64)
 ; CHECK: main:
 ; CHECK: stdin#C CSECT
diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll
index f926686945c19..8f41ab61f6f9a 100644
--- a/llvm/test/MC/GOFF/section.ll
+++ b/llvm/test/MC/GOFF/section.ll
@@ -45,7 +45,7 @@ entry:
 ; CHECK-NEXT: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
 ; CHECK-NEXT: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a
+; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 0a
 ; CHECK-NEXT: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
 
 ; ESD record, type ED.
@@ -54,7 +54,7 @@ entry:
 ; CHECK-NEXT: 00000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 0000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 0000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 09
+; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 09
 ; CHECK-NEXT: 0000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
 ;
 ; Continuation:
@@ -69,7 +69,7 @@ entry:
 ; CHECK-NEXT: 0000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
 ; CHECK-NEXT: 00001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
 ; CHECK-NEXT: 00001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
-; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00
+; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 00001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
 
 ; ESD record, type ED.
@@ -77,7 +77,7 @@ entry:
 ; CHECK-NEXT: 00001e0 03 00 00 01 [[C_WSA64:00 00 00 05]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 0000200 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK-NEXT: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
+; CHECK-NEXT: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 01
 ; CHECK-NEXT: 0000220 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
@@ -85,7 +85,7 @@ entry:
 ; CHECK-NEXT: 0000230 03 00 00 03 [[TESTS:00 00 00 06]] [[C_WSA64]] 00 00 00 00
 ; CHECK-NEXT: 0000240 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
 ; CHECK-NEXT: 0000250 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK-NEXT: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
 ; CHECK-NEXT: 0000270 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
 
 ; ESD record, type ED.
@@ -93,7 +93,7 @@ entry:
 ; CHECK-NEXT: 0000280 03 00 00 01 [[BIDRL:00 00 00 07]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 0000290 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
 ; CHECK-NEXT: 00002a0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK-NEXT: 00002b0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 10 08
+; CHECK-NEXT: 00002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
 ; CHECK-NEXT: 00002c0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
 
 ; ESD record, type LD.

>From 1926203acd87273a882109a8b51a4877127ab791 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 14 Apr 2025 17:41:51 -0400
Subject: [PATCH 22/35] Emit XATTR

---
 llvm/lib/MC/MCSectionGOFF.cpp                 | 33 +++++++++++++++++++
 .../CodeGen/SystemZ/zos-ada-relocations.ll    |  1 +
 llvm/test/CodeGen/SystemZ/zos-intrinsics.ll   |  1 +
 llvm/test/CodeGen/SystemZ/zos-landingpad.ll   |  1 +
 llvm/test/CodeGen/SystemZ/zos-simple-test.ll  |  1 +
 5 files changed, 37 insertions(+)

diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
index f9b0c776f4311..f0a5b04de746a 100644
--- a/llvm/lib/MC/MCSectionGOFF.cpp
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -66,6 +66,37 @@ void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
     OS << ",PART(" << PartName << ")";
   OS << '\n';
 }
+
+void emitXATTR(raw_ostream &OS, StringRef Name, GOFF::ESDLinkageType Linkage,
+               GOFF::ESDExecutable Executable,
+               GOFF::ESDBindingScope BindingScope) {
+  OS << Name << " XATTR ";
+  OS << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK") << "),";
+  if (Executable != GOFF::ESD_EXE_Unspecified)
+    OS << "REFERENCE(" << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA")
+       << "),";
+  if (BindingScope != GOFF::ESD_BSC_Unspecified) {
+    OS << "SCOPE(";
+    switch (BindingScope) {
+    case GOFF::ESD_BSC_Section:
+      OS << "SECTION";
+      break;
+    case GOFF::ESD_BSC_Module:
+      OS << "MODULE";
+      break;
+    case GOFF::ESD_BSC_Library:
+      OS << "LIBRARY";
+      break;
+    case GOFF::ESD_BSC_ImportExport:
+      OS << "EXPORT";
+      break;
+    default:
+      break;
+    }
+    OS << ')';
+  }
+  OS << '\n';
+}
 } // namespace
 
 void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
@@ -96,6 +127,8 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                 PRAttributes.Alignment, ED->EDAttributes.LoadBehavior,
                 PRAttributes.Executable, PRAttributes.IsReadOnly,
                 PRAttributes.SortKey, Name);
+      emitXATTR(OS, Name, PRAttributes.Linkage, PRAttributes.Executable,
+                PRAttributes.BindingScope);
       ED->Emitted = true;
       Emitted = true;
     } else
diff --git a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
index 8a31dab9c7686..b2eb2836fc361 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
@@ -57,6 +57,7 @@ declare signext i32 @callout(i32 signext)
 
 ; CHECK: stdin#C CSECT
 ; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
+; CHECK: stdin#S XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
 ; CHECK:  .set L#DoFunc at indirect0, DoFunc
 ; CHECK:      .indirect_symbol   L#DoFunc at indirect0
 ; CHECK:  .quad V(L#DoFunc at indirect0)          * Offset 0 pointer to function descriptor DoFunc
diff --git a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
index f413fc5ce7671..4a8fc1cd03980 100644
--- a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
@@ -32,6 +32,7 @@ declare fp128 @llvm.exp2.f128(fp128)
 ; Check the calls in the ADA.
 ; CHECK: stdin#C CSECT
 ; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
+; CHECK: stdin#S XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
 
 ; Check that there is no call to sqrt.
 ; CHECK-NOT:  .quad   R(@@WSQT at B)
diff --git a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
index fd58656e549d1..a296b7fd006e8 100644
--- a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
@@ -39,4 +39,5 @@ lpad:
 ; Check that the exception table is emitted into .lsda section.
 ; CHECK:  stdin#C CSECT
 ; CHECK:  C_WSA64 CATTR ALIGN(2),RMODE(64),PART(.gcc_exception_table.test1)
+; CHECK:  .gcc_exception_table.test1 XATTR LINKAGE(XPLINK),SCOPE(SECTION)
 ; CHECK: GCC_except_table0:
diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
index dd256e481c42a..e0b7f65326de5 100644
--- a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -10,6 +10,7 @@ define signext i32 @main() {
 ; CHECK: main:
 ; CHECK: stdin#C CSECT
 ; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)
+; CHECK: a XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(EXPORT)
 ; CHECK: a:
 entry:
   ret i32 0

>From adef64a8a6f54609d9b0975b51575270669b8f86 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 15 Apr 2025 10:53:31 -0400
Subject: [PATCH 23/35] Remove comma and add part name.

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

diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
index f0a5b04de746a..d3ef76411731f 100644
--- a/llvm/lib/MC/MCSectionGOFF.cpp
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -116,7 +116,7 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                 EDAttributes.IsReadOnly, 0, StringRef());
       Emitted = true;
     } else
-      OS << Name << " CATTR ,\n";
+      OS << Name << " CATTR\n";
     break;
   }
   case GOFF::ESD_ST_PartReference: {
@@ -132,7 +132,7 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
       ED->Emitted = true;
       Emitted = true;
     } else
-      OS << ED->getName() << " CATTR ,\n";
+      OS << ED->getName() << " CATTR PART(" << Name << ")\n";
     break;
   }
   default:

>From a4b425fe8a66b66c19f1df3f3607214fec707a95 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 15 Apr 2025 11:47:04 -0400
Subject: [PATCH 24/35] Fix test case due to removed comma

---
 llvm/test/MC/GOFF/ppa1.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/MC/GOFF/ppa1.ll b/llvm/test/MC/GOFF/ppa1.ll
index 222e4c448a668..fc51e9c5eccc5 100644
--- a/llvm/test/MC/GOFF/ppa1.ll
+++ b/llvm/test/MC/GOFF/ppa1.ll
@@ -13,7 +13,7 @@
 ; CHECK: *   Bit 2: 0 = Does not use alloca
 ; CHECK: L#func_end0:
 ; CHECK: stdin#C CSECT
-; CHECK: C_CODE64 CATTR ,
+; CHECK: C_CODE64 CATTR
 ; CHECK: L#PPA1_void_test_0:                     * PPA1
 ; CHECK:        .byte   2                               * Version
 ; CHECK:        .byte   206                             * LE Signature X'CE'

>From 0b549679aed1ae86bc31d05566734b0d919bff2c Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 15 Apr 2025 11:47:35 -0400
Subject: [PATCH 25/35] Remove DuplicateSymbolSeverity since it is not
 required.

---
 llvm/include/llvm/MC/MCGOFFAttributes.h           | 2 --
 llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 5 ++---
 llvm/lib/MC/GOFFObjectWriter.cpp                  | 1 -
 llvm/lib/MC/MCObjectFileInfo.cpp                  | 6 ++----
 4 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index 027bdadbec1f1..e28b9bea2862d 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -78,8 +78,6 @@ struct PRAttr {
   GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
   GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
   GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
-  GOFF::ESDDuplicateSymbolSeverity DuplicateSymbolSeverity =
-      GOFF::ESD_DSS_NoWarning;
   GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Byte;
   uint32_t SortKey = 0;
 };
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 0bac1abfb489d..addece0591f7e 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2804,8 +2804,7 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
   return getContext().getGOFFSection(
       SectionKind::getData(), Name,
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::LINKAGE,
-                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
-                   GOFF::ESD_ALIGN_Fullword, 0},
+                   GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Fullword, 0},
       WSA);
 }
 
@@ -2835,7 +2834,7 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
     return getContext().getGOFFSection(
         Kind, Symbol->getName(),
         GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
-                     PRBindingScope, GOFF::ESD_DSS_NoWarning,
+                     PRBindingScope,
                      static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0},
         ED);
   }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 713a5a5996854..294297b869719 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -267,7 +267,6 @@ class GOFFSymbol {
     BehavAttrs.setAlignment(Attr.Alignment);
     BehavAttrs.setLinkageType(Attr.Linkage);
     BehavAttrs.setBindingScope(Attr.BindingScope);
-    BehavAttrs.setDuplicateSymbolSeverity(Attr.DuplicateSymbolSeverity);
     BehavAttrs.setReadOnly(Attr.IsReadOnly);
   }
 };
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 731572b0ad25e..4bc4dc370c588 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -561,8 +561,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
   ADASection = Ctx->getGOFFSection(
       SectionKind::getData(), "#S",
       GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink,
-                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
-                   GOFF::ESD_ALIGN_Quadword, 0},
+                   GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Quadword, 0},
       ADAEDSection);
 
   TextSection = Ctx->getGOFFSection(
@@ -583,8 +582,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
   PPA2ListSection = Ctx->getGOFFSection(
       SectionKind::getData(), ".&ppa2",
       GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_LT_OS,
-                   GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning,
-                   GOFF::ESD_ALIGN_Doubleword, 0},
+                   GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Doubleword, 0},
       PPA2ListEDSection);
 
   IDRLSection = Ctx->getGOFFSection(

>From 7576e130834bf99e4d2918c0334b7a94c5f44c4c Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 15 Apr 2025 13:38:47 -0400
Subject: [PATCH 26/35] Change code as recommended by MaskRay

---
 llvm/include/llvm/MC/MCContext.h | 10 ++++------
 llvm/lib/MC/MCGOFFStreamer.cpp   |  4 +---
 llvm/lib/MC/MCSectionGOFF.cpp    | 19 +++++++++----------
 3 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index ff4ed76aa6ee4..8eb904966f4de 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -364,6 +364,10 @@ class MCContext {
   MCSymbolXCOFF *createXCOFFSymbolImpl(const MCSymbolTableEntry *Name,
                                        bool IsTemporary);
 
+  template <typename TAttr>
+  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
+                                TAttr SDAttributes, MCSection *Parent);
+
   /// Map of currently defined macros.
   StringMap<MCAsmMacro> MacroMap;
 
@@ -600,12 +604,6 @@ class MCContext {
                                                    unsigned Flags,
                                                    unsigned EntrySize);
 
-private:
-  template <typename TAttr>
-  MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
-                                TAttr SDAttributes, MCSection *Parent);
-
-public:
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
                                 GOFF::SDAttr SDAttributes);
   MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef Name,
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 23bdcf75f945d..70db8d4696027 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -27,16 +27,14 @@ GOFFObjectWriter &MCGOFFStreamer::getWriter() {
   return static_cast<GOFFObjectWriter &>(getAssembler().getWriter());
 }
 
-namespace {
 // Make sure that all section are registered in the correct order.
-void registerSectionHierarchy(MCAssembler &Asm, MCSectionGOFF *Section) {
+static void registerSectionHierarchy(MCAssembler &Asm, MCSectionGOFF *Section) {
   if (Section->isRegistered())
     return;
   if (Section->getParent())
     registerSectionHierarchy(Asm, Section->getParent());
   Asm.registerSection(*Section);
 }
-} // namespace
 
 void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
   registerSectionHierarchy(getAssembler(),
diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
index d3ef76411731f..d8757fa75b9af 100644
--- a/llvm/lib/MC/MCSectionGOFF.cpp
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -12,12 +12,11 @@
 
 using namespace llvm;
 
-namespace {
-void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
-               GOFF::ESDAlignment Alignment,
-               GOFF::ESDLoadingBehavior LoadBehavior,
-               GOFF::ESDExecutable Executable, bool IsReadOnly,
-               uint32_t SortKey, StringRef PartName) {
+static void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
+                      GOFF::ESDAlignment Alignment,
+                      GOFF::ESDLoadingBehavior LoadBehavior,
+                      GOFF::ESDExecutable Executable, bool IsReadOnly,
+                      uint32_t SortKey, StringRef PartName) {
   OS << Name << " CATTR ";
   OS << "ALIGN(" << static_cast<unsigned>(Alignment) << ")";
   switch (LoadBehavior) {
@@ -67,9 +66,10 @@ void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
   OS << '\n';
 }
 
-void emitXATTR(raw_ostream &OS, StringRef Name, GOFF::ESDLinkageType Linkage,
-               GOFF::ESDExecutable Executable,
-               GOFF::ESDBindingScope BindingScope) {
+static void emitXATTR(raw_ostream &OS, StringRef Name,
+                      GOFF::ESDLinkageType Linkage,
+                      GOFF::ESDExecutable Executable,
+                      GOFF::ESDBindingScope BindingScope) {
   OS << Name << " XATTR ";
   OS << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK") << "),";
   if (Executable != GOFF::ESD_EXE_Unspecified)
@@ -97,7 +97,6 @@ void emitXATTR(raw_ostream &OS, StringRef Name, GOFF::ESDLinkageType Linkage,
   }
   OS << '\n';
 }
-} // namespace
 
 void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                                          raw_ostream &OS,

>From 7803d02d9baf37aca541a19550c53b92f4db5579 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 15 Apr 2025 13:58:20 -0400
Subject: [PATCH 27/35] Move .ll test cases

---
 llvm/test/{MC/GOFF/ppa1.ll => CodeGen/SystemZ/zos-ppa1.ll}        | 0
 .../test/{MC/GOFF/section.ll => CodeGen/SystemZ/zos-section-1.ll} | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename llvm/test/{MC/GOFF/ppa1.ll => CodeGen/SystemZ/zos-ppa1.ll} (100%)
 rename llvm/test/{MC/GOFF/section.ll => CodeGen/SystemZ/zos-section-1.ll} (100%)

diff --git a/llvm/test/MC/GOFF/ppa1.ll b/llvm/test/CodeGen/SystemZ/zos-ppa1.ll
similarity index 100%
rename from llvm/test/MC/GOFF/ppa1.ll
rename to llvm/test/CodeGen/SystemZ/zos-ppa1.ll
diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
similarity index 100%
rename from llvm/test/MC/GOFF/section.ll
rename to llvm/test/CodeGen/SystemZ/zos-section-1.ll

>From 5810c44cf3d6030b3a8d77709929917fddafdede Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 15 Apr 2025 14:56:20 -0400
Subject: [PATCH 28/35] Add another test case, and remove -o - in the run line
 Also fixes the alignment for data.

---
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  |  10 +-
 llvm/test/CodeGen/SystemZ/zos-section-1.ll    |   2 +-
 llvm/test/CodeGen/SystemZ/zos-section-2.ll    | 155 ++++++++++++++++++
 llvm/test/CodeGen/SystemZ/zos-simple-test.ll  |   2 +-
 4 files changed, 163 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/CodeGen/SystemZ/zos-section-2.ll

diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index addece0591f7e..4654cc009eaf0 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -19,6 +19,7 @@
 #include "llvm/BinaryFormat/COFF.h"
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/GOFF.h"
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/BinaryFormat/Wasm.h"
 #include "llvm/CodeGen/BasicBlockSectionUtils.h"
@@ -2821,6 +2822,9 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
     GOFF::ESDBindingScope SDBindingScope =
         PRBindingScope == GOFF::ESD_BSC_Section ? GOFF::ESD_BSC_Section
                                                 : GOFF::ESD_BSC_Unspecified;
+    GOFF::ESDAlignment Align =
+        GO->getAlign() ? static_cast<GOFF::ESDAlignment>(Log2(*GO->getAlign()))
+                       : GOFF::ESD_ALIGN_Doubleword;
     MCSectionGOFF *SD = getContext().getGOFFSection(
         SectionKind::getMetadata(), Symbol->getName(),
         GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope});
@@ -2828,14 +2832,12 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
         SectionKind::getMetadata(), GOFF::CLASS_WSA,
         GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::RMODE, GOFF::ESD_NS_Parts,
                      GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
-                     GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0,
-                     static_cast<GOFF::ESDAlignment>(GO->getAlignment())},
+                     GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align},
         SD);
     return getContext().getGOFFSection(
         Kind, Symbol->getName(),
         GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
-                     PRBindingScope,
-                     static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0},
+                     PRBindingScope, Align, 0},
         ED);
   }
   return TextSection;
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 8f41ab61f6f9a..7b59e71a5a9aa 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -1,4 +1,4 @@
-; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj -o - | \
+; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj | \
 ; RUN:   od -Ax -tx1 -v | FileCheck --ignore-case %s
 
 source_filename = "test.ll"
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
new file mode 100644
index 0000000000000..d7766d72ff528
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -0,0 +1,155 @@
+; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj | \
+; RUN:   od -Ax -tx1 -v | FileCheck --ignore-case %s
+
+source_filename = "test.ll"
+
+ at data = hidden global i32 42, align 4
+ at bss = hidden global i64 0, align 8
+
+; Header record:
+;  03 is prefix byte
+;  f. is header type
+;  .0 is flag
+;  00 is version
+; The 1 at offset 0x33 is the architecture level.
+; CHECK:      000000 03 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000030 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+; ESD record, type SD.
+;  03 is prefix byte
+;  0. is header type
+;  .0 is flag
+;  00 is version
+;  00 is type = SD
+; The 01 at offset 0x57 is the id of the symbol.
+; The 60 at offset 0x89 is the tasking behavior.
+; The 01 at offset 0x91 is the binding scope.
+; The name begins at offset 0x97, and is test#C.
+; CHECK-NEXT: 0000050 03 00 00 00 [[ROOTSD:00 00 00 01]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
+; CHECK-NEXT: 0000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+
+; ESD record, type ED.
+; The name is C_CODE64.
+; The regular expression matches the low byte of the length.
+; CHECK-NEXT: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 0a
+; CHECK-NEXT: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+
+; ESD record, type ED.
+; The name is C_@@QPPA2.
+; This record has a continuation, therefore the falg at offset 0xf1 is set.
+; CHECK-NEXT: 00000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 09
+; CHECK-NEXT: 0000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
+;
+; Continuation:
+; CHECK-NEXT: 0000140 03 02 00 f2 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+; ESD record, type PR.
+; The name is .&ppa2.
+; CHECK-NEXT: 0000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
+; CHECK-NEXT: 00001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
+; CHECK-NEXT: 00001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
+; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
+
+; ESD record, type SD.
+; The name is data.
+; CHECK-NEXT: 00001e0 03 00 00 00 [[DATA:00 00 00 05]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000220 00 00 00 00 00 00 00 04 84 81 a3 81 00 00 00 00
+
+; ESD record, type ED.
+; The name is C_WSA64.
+; CHECK-NEXT: 0000230 03 00 00 01 [[DATA_WSA:00 00 00 06]] [[DATA]] 00 00 00 00
+; CHECK-NEXT: 0000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000250 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK-NEXT: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 01
+; CHECK-NEXT: 0000270 00 40 02 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
+; ESD record, type PR.
+; The name is data.
+; CHECK-NEXT: 0000280 03 00 00 03 [[DATA_PR:00 00 00 07]] [[DATA_WSA]] 00 00 00 00
+; CHECK-NEXT: 0000290 00 00 00 00 00 00 00 00 [[DATA_LEN:00 00 00 04]] 00 00 00 00
+; CHECK-NEXT: 00002a0 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK-NEXT: 00002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 00002c0 00 03 22 00 00 00 00 04 84 81 a3 81 00 00 00 00
+
+; ESD record, type SD.
+; The name is bss.
+; CHECK-NEXT: 00002d0 03 00 00 00 [[BSS:00 00 00 08]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00002f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000310 00 00 00 00 00 00 00 03 82 a2 a2 00 00 00 00 00
+
+; ESD record, type ED.
+; The name is C_WSA64.
+; CHECK-NEXT: 0000320 03 00 00 01 [[BSS_WSA:00 00 00 09]] [[BSS]] 00 00 00 00
+; CHECK-NEXT: 0000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000340 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK-NEXT: 0000350 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 01
+; CHECK-NEXT: 0000360 00 40 03 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
+; ESD record, type PR.
+; The name is bss.
+; CHECK-NEXT: 0000370 03 00 00 03 [[BSS_PR:00 00 00 0a]] [[BSS_WSA]] 00 00 00 00
+; CHECK-NEXT: 0000380 00 00 00 00 00 00 00 00 [[BSS_LEN:00 00 00 08]] 00 00 00 00
+; CHECK-NEXT: 0000390 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK-NEXT: 00003a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 00003b0 00 03 23 00 00 00 00 03 82 a2 a2 00 00 00 00 00
+
+; ESD record, type ED.
+; The name is C_WSA64.
+; CHECK-NEXT: 00003c0 03 00 00 01 [[C_WSA64:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 00003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00003e0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECK-NEXT: 00003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 01
+; CHECK-NEXT: 0000400 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
+; ESD record, type PR.
+; The name is test#S.
+; CHECK-NEXT: 0000410 03 00 00 03 [[TESTS:00 00 00 0c]] [[C_WSA64]] 00 00 00 00
+; CHECK-NEXT: 0000420 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 0000430 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 0000450 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
+
+; ESD record, type ED.
+; The name is B_IDRL.
+; CHECK-NEXT: 0000460 03 00 00 01 [[BIDRL:00 00 00 0d]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0000470 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 0000480 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK-NEXT: 0000490 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
+; CHECK-NEXT: 00004a0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
+
+; ESD record, type LD.
+; The name is test#C.
+; CHECK-NEXT: 00004b0 03 00 00 02 [[TESTC:00 00 00 0e]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 00004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00004d0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; CHECK-NEXT: 00004e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 00004f0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+
+; End record.
+; CHECK-NEXT: 0000500 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
index e0b7f65326de5..90e1e0c589ea4 100644
--- a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -9,7 +9,7 @@ define signext i32 @main() {
 ; CHECK: C_CODE64 CATTR ALIGN(3),EXECUTABLE,READONLY,RMODE(64)
 ; CHECK: main:
 ; CHECK: stdin#C CSECT
-; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)
+; CHECK: C_WSA64 CATTR ALIGN(2),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)
 ; CHECK: a XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(EXPORT)
 ; CHECK: a:
 entry:

>From ba1223ae5a08197d30d3fb285a725a5278549e74 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 23 Apr 2025 10:28:58 -0400
Subject: [PATCH 29/35] Remove Executable from the ED element

The value would serve as default if not specified on LD or PR. However, we can make sure that it is always specified on LD and PR, s not need to have it on ED.
---
 llvm/include/llvm/MC/MCGOFFAttributes.h       |  1 -
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  |  6 ++---
 llvm/lib/MC/GOFFObjectWriter.cpp              |  1 -
 llvm/lib/MC/MCObjectFileInfo.cpp              | 22 +++++++++----------
 llvm/lib/MC/MCSectionGOFF.cpp                 |  2 +-
 llvm/test/CodeGen/SystemZ/zos-landingpad.ll   |  4 ++--
 llvm/test/CodeGen/SystemZ/zos-section-1.ll    |  8 +++----
 llvm/test/CodeGen/SystemZ/zos-section-2.ll    | 12 +++++-----
 llvm/test/CodeGen/SystemZ/zos-simple-test.ll  |  2 +-
 9 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index e28b9bea2862d..95163fed898a0 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -51,7 +51,6 @@ struct SDAttr {
 // Attributes for ED symbols.
 struct EDAttr {
   bool IsReadOnly = false;
-  GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
   GOFF::ESDRmode Rmode;
   GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName;
   GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented;
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 4654cc009eaf0..5460c84beffc1 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2797,14 +2797,14 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
 
   MCSectionGOFF *WSA = getContext().getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_WSA,
-      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::RMODE, GOFF::ESD_NS_Parts,
+      GOFF::EDAttr{false, GOFF::RMODE, GOFF::ESD_NS_Parts,
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword},
       static_cast<MCSectionGOFF *>(TextSection)->getParent());
   return getContext().getGOFFSection(
       SectionKind::getData(), Name,
-      GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::LINKAGE,
+      GOFF::PRAttr{true, false, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
                    GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Fullword, 0},
       WSA);
 }
@@ -2830,7 +2830,7 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
         GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope});
     MCSectionGOFF *ED = getContext().getGOFFSection(
         SectionKind::getMetadata(), GOFF::CLASS_WSA,
-        GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::RMODE, GOFF::ESD_NS_Parts,
+        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},
         SD);
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 294297b869719..8bedc08c3066f 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -238,7 +238,6 @@ class GOFFSymbol {
     SymbolFlags.setReservedQwords(Attr.ReservedQwords);
     // TODO Do we need/should set the "mangled" flag?
     BehavAttrs.setReadOnly(Attr.IsReadOnly);
-    BehavAttrs.setExecutable(Attr.Executable);
     BehavAttrs.setRmode(Attr.Rmode);
     BehavAttrs.setTextStyle(Attr.TextStyle);
     BehavAttrs.setBindingAlgorithm(Attr.BindAlgorithm);
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 4bc4dc370c588..e90797f05073d 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -553,7 +553,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
 
   MCSectionGOFF *ADAEDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_WSA,
-      GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::RMODE, GOFF::ESD_NS_Parts,
+      GOFF::EDAttr{false, GOFF::RMODE, GOFF::ESD_NS_Parts,
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
                    GOFF::ESD_ALIGN_Quadword},
@@ -566,31 +566,31 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
 
   TextSection = Ctx->getGOFFSection(
       SectionKind::getText(), GOFF::CLASS_CODE,
-      GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::RMODE,
-                   GOFF::ESD_NS_NormalName, GOFF::ESD_TS_ByteOriented,
-                   GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_Initial,
-                   GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
+      GOFF::EDAttr{true, GOFF::RMODE, GOFF::ESD_NS_NormalName,
+                   GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate,
+                   GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
+                   GOFF::ESD_ALIGN_Doubleword},
       RootSDSection);
 
   MCSectionGOFF *PPA2ListEDSection = Ctx->getGOFFSection(
       SectionKind::getMetadata(), GOFF::CLASS_PPA2,
-      GOFF::EDAttr{true, GOFF::ESD_EXE_DATA, GOFF::RMODE, GOFF::ESD_NS_Parts,
+      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},
       RootSDSection);
   PPA2ListSection = Ctx->getGOFFSection(
       SectionKind::getData(), ".&ppa2",
-      GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_LT_OS,
+      GOFF::PRAttr{true, false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_OS,
                    GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Doubleword, 0},
       PPA2ListEDSection);
 
   IDRLSection = Ctx->getGOFFSection(
       SectionKind::getData(), "B_IDRL",
-      GOFF::EDAttr{true, GOFF::ESD_EXE_Unspecified, GOFF::RMODE,
-                   GOFF::ESD_NS_NormalName, GOFF::ESD_TS_Structured,
-                   GOFF::ESD_BA_Concatenate, GOFF::ESD_LB_NoLoad,
-                   GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword},
+      GOFF::EDAttr{true, GOFF::RMODE, GOFF::ESD_NS_NormalName,
+                   GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate,
+                   GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0,
+                   GOFF::ESD_ALIGN_Doubleword},
       RootSDSection);
 }
 
diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
index d8757fa75b9af..e93a53be104e1 100644
--- a/llvm/lib/MC/MCSectionGOFF.cpp
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -111,7 +111,7 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
     getParent()->printSwitchToSection(MAI, T, OS, Subsection);
     if (!Emitted) {
       emitCATTR(OS, Name, EDAttributes.Rmode, EDAttributes.Alignment,
-                EDAttributes.LoadBehavior, EDAttributes.Executable,
+                EDAttributes.LoadBehavior, GOFF::ESD_EXE_Unspecified,
                 EDAttributes.IsReadOnly, 0, StringRef());
       Emitted = true;
     } else
diff --git a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
index a296b7fd006e8..04963a06a93e8 100644
--- a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
@@ -38,6 +38,6 @@ lpad:
 ; CHECK: LSDA location
 ; Check that the exception table is emitted into .lsda section.
 ; CHECK:  stdin#C CSECT
-; CHECK:  C_WSA64 CATTR ALIGN(2),RMODE(64),PART(.gcc_exception_table.test1)
-; CHECK:  .gcc_exception_table.test1 XATTR LINKAGE(XPLINK),SCOPE(SECTION)
+; CHECK:  C_WSA64 CATTR ALIGN(2),NOTEXECUTABLE,RMODE(64),PART(.gcc_exception_table.test1)
+; CHECK:  .gcc_exception_table.test1 XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
 ; CHECK: GCC_except_table0:
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 7b59e71a5a9aa..74f4e272005f8 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -45,7 +45,7 @@ entry:
 ; CHECK-NEXT: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
 ; CHECK-NEXT: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 0a
+; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 08
 ; CHECK-NEXT: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
 
 ; ESD record, type ED.
@@ -54,7 +54,7 @@ entry:
 ; CHECK-NEXT: 00000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 0000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 0000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 09
+; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 08
 ; CHECK-NEXT: 0000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
 ;
 ; Continuation:
@@ -69,7 +69,7 @@ entry:
 ; CHECK-NEXT: 0000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
 ; CHECK-NEXT: 00001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
 ; CHECK-NEXT: 00001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
-; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
 ; CHECK-NEXT: 00001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
 
 ; ESD record, type ED.
@@ -77,7 +77,7 @@ entry:
 ; CHECK-NEXT: 00001e0 03 00 00 01 [[C_WSA64:00 00 00 05]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 0000200 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK-NEXT: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 01
+; CHECK-NEXT: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
 ; CHECK-NEXT: 0000220 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index d7766d72ff528..25803c3bbfb0c 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -40,7 +40,7 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
 ; CHECK-NEXT: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 0a
+; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 08
 ; CHECK-NEXT: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
 
 ; ESD record, type ED.
@@ -49,7 +49,7 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 00000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 0000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 0000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 09
+; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 08
 ; CHECK-NEXT: 0000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
 ;
 ; Continuation:
@@ -64,7 +64,7 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 0000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
 ; CHECK-NEXT: 00001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
 ; CHECK-NEXT: 00001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
-; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
 ; CHECK-NEXT: 00001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
 
 ; ESD record, type SD.
@@ -80,7 +80,7 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 0000230 03 00 00 01 [[DATA_WSA:00 00 00 06]] [[DATA]] 00 00 00 00
 ; CHECK-NEXT: 0000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 0000250 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 01
+; CHECK-NEXT: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
 ; CHECK-NEXT: 0000270 00 40 02 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
@@ -104,7 +104,7 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 0000320 03 00 00 01 [[BSS_WSA:00 00 00 09]] [[BSS]] 00 00 00 00
 ; CHECK-NEXT: 0000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 0000340 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000350 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 01
+; CHECK-NEXT: 0000350 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
 ; CHECK-NEXT: 0000360 00 40 03 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
@@ -120,7 +120,7 @@ source_filename = "test.ll"
 ; CHECK-NEXT: 00003c0 03 00 00 01 [[C_WSA64:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
 ; CHECK-NEXT: 00003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ; CHECK-NEXT: 00003e0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK-NEXT: 00003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 01
+; CHECK-NEXT: 00003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
 ; CHECK-NEXT: 0000400 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
index 90e1e0c589ea4..dd894a810d95a 100644
--- a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -6,7 +6,7 @@
 
 define signext i32 @main() {
 ; CHECK: stdin#C CSECT
-; CHECK: C_CODE64 CATTR ALIGN(3),EXECUTABLE,READONLY,RMODE(64)
+; CHECK: C_CODE64 CATTR ALIGN(3),READONLY,RMODE(64)
 ; CHECK: main:
 ; CHECK: stdin#C CSECT
 ; CHECK: C_WSA64 CATTR ALIGN(2),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)

>From 2f6babe736af559e3f281cf79502edd78e514572 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Thu, 24 Apr 2025 16:42:09 -0400
Subject: [PATCH 30/35] Remove unused header file

---
 llvm/lib/MC/MCGOFFStreamer.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 70db8d4696027..b7021915e7b70 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -17,7 +17,6 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCGOFFObjectWriter.h"
 #include "llvm/MC/TargetRegistry.h"
-#include "llvm/Support/Path.h"
 
 using namespace llvm;
 

>From 005bd751f7958c989327fc20bce2f9cde79fecb8 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 29 Apr 2025 11:51:11 -0400
Subject: [PATCH 31/35] Remove ReadOnly attribute for PR elements

---
 llvm/include/llvm/MC/MCGOFFAttributes.h           |  1 -
 llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 12 ++++++------
 llvm/lib/MC/GOFFObjectWriter.cpp                  |  1 -
 llvm/lib/MC/MCObjectFileInfo.cpp                  |  4 ++--
 llvm/lib/MC/MCSectionGOFF.cpp                     |  2 +-
 5 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index 95163fed898a0..90bc89a87838d 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -73,7 +73,6 @@ struct LDAttr {
 // Attributes for PR symbols.
 struct PRAttr {
   bool IsRenamable = false;
-  bool IsReadOnly = false; // ???? Not documented.
   GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
   GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
   GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 5460c84beffc1..073bb24bd2a87 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2804,7 +2804,7 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
       static_cast<MCSectionGOFF *>(TextSection)->getParent());
   return getContext().getGOFFSection(
       SectionKind::getData(), Name,
-      GOFF::PRAttr{true, false, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
+      GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
                    GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Fullword, 0},
       WSA);
 }
@@ -2834,11 +2834,11 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
                      GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                      GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align},
         SD);
-    return getContext().getGOFFSection(
-        Kind, Symbol->getName(),
-        GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
-                     PRBindingScope, Align, 0},
-        ED);
+    return getContext().getGOFFSection(Kind, Symbol->getName(),
+                                       GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
+                                                    GOFF::LINKAGE,
+                                                    PRBindingScope, Align, 0},
+                                       ED);
   }
   return TextSection;
 }
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 8bedc08c3066f..ef902468b2a65 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -266,7 +266,6 @@ class GOFFSymbol {
     BehavAttrs.setAlignment(Attr.Alignment);
     BehavAttrs.setLinkageType(Attr.Linkage);
     BehavAttrs.setBindingScope(Attr.BindingScope);
-    BehavAttrs.setReadOnly(Attr.IsReadOnly);
   }
 };
 
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index e90797f05073d..3a59a8b449796 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -560,7 +560,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       RootSDSection);
   ADASection = Ctx->getGOFFSection(
       SectionKind::getData(), "#S",
-      GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink,
+      GOFF::PRAttr{false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink,
                    GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Quadword, 0},
       ADAEDSection);
 
@@ -581,7 +581,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       RootSDSection);
   PPA2ListSection = Ctx->getGOFFSection(
       SectionKind::getData(), ".&ppa2",
-      GOFF::PRAttr{true, false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_OS,
+      GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_OS,
                    GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Doubleword, 0},
       PPA2ListEDSection);
 
diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
index e93a53be104e1..550ff4b1790f2 100644
--- a/llvm/lib/MC/MCSectionGOFF.cpp
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -124,7 +124,7 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
     if (!Emitted) {
       emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode,
                 PRAttributes.Alignment, ED->EDAttributes.LoadBehavior,
-                PRAttributes.Executable, PRAttributes.IsReadOnly,
+                PRAttributes.Executable, ED->EDAttributes.IsReadOnly,
                 PRAttributes.SortKey, Name);
       emitXATTR(OS, Name, PRAttributes.Linkage, PRAttributes.Executable,
                 PRAttributes.BindingScope);

>From 7ba4c75d8621145726906e0af0e40285898fd252 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 29 Apr 2025 13:20:26 -0400
Subject: [PATCH 32/35] Make alignment of PR always the same as ED

---
 llvm/include/llvm/MC/MCGOFFAttributes.h       |  1 -
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  | 14 ++++++-------
 llvm/lib/MC/GOFFObjectWriter.cpp              |  9 ++++-----
 llvm/lib/MC/MCObjectFileInfo.cpp              | 20 +++++++++----------
 llvm/lib/MC/MCSectionGOFF.cpp                 |  2 +-
 5 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index 90bc89a87838d..bf4b545b0dff0 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -76,7 +76,6 @@ struct PRAttr {
   GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
   GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
   GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
-  GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Byte;
   uint32_t SortKey = 0;
 };
 
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 073bb24bd2a87..ea1431491eeab 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2800,13 +2800,13 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
       GOFF::EDAttr{false, GOFF::RMODE, GOFF::ESD_NS_Parts,
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0,
-                   GOFF::ESD_ALIGN_Doubleword},
+                   GOFF::ESD_ALIGN_Fullword},
       static_cast<MCSectionGOFF *>(TextSection)->getParent());
-  return getContext().getGOFFSection(
-      SectionKind::getData(), Name,
-      GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::LINKAGE,
-                   GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Fullword, 0},
-      WSA);
+  return getContext().getGOFFSection(SectionKind::getData(), Name,
+                                     GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,
+                                                  GOFF::LINKAGE,
+                                                  GOFF::ESD_BSC_Section, 0},
+                                     WSA);
 }
 
 MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
@@ -2837,7 +2837,7 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
     return getContext().getGOFFSection(Kind, Symbol->getName(),
                                        GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
                                                     GOFF::LINKAGE,
-                                                    PRBindingScope, Align, 0},
+                                                    PRBindingScope, 0},
                                        ED);
   }
   return TextSection;
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index ef902468b2a65..339e9da29ef03 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -258,14 +258,14 @@ class GOFFSymbol {
   }
 
   GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
-             GOFF::ESDNameSpaceId NameSpace, const GOFF::PRAttr &Attr)
+    const GOFF::EDAttr &EDAttr, const GOFF::PRAttr &Attr)
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
-        SymbolType(GOFF::ESD_ST_PartReference), NameSpace(NameSpace) {
+        SymbolType(GOFF::ESD_ST_PartReference), NameSpace(EDAttr.NameSpace) {
     SymbolFlags.setRenameable(Attr.IsRenamable);
     BehavAttrs.setExecutable(Attr.Executable);
-    BehavAttrs.setAlignment(Attr.Alignment);
     BehavAttrs.setLinkageType(Attr.Linkage);
     BehavAttrs.setBindingScope(Attr.BindingScope);
+    BehavAttrs.setAlignment(EDAttr.Alignment);
   }
 };
 
@@ -307,8 +307,7 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) {
   if (Section.isPR()) {
     MCSectionGOFF *Parent = Section.getParent();
     GOFFSymbol PR(Section.getName(), Section.getOrdinal(), Parent->getOrdinal(),
-                  Parent->getEDAttributes().NameSpace,
-                  Section.getPRAttributes());
+                  Parent->getEDAttributes(), Section.getPRAttributes());
     PR.SectionLength = Asm.getSectionAddressSize(Section);
     if (Section.requiresNonZeroLength()) {
       // We cannot have a zero-length section for data.  If we do,
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 3a59a8b449796..edbc69c17219e 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -558,11 +558,11 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
                    GOFF::ESD_ALIGN_Quadword},
       RootSDSection);
-  ADASection = Ctx->getGOFFSection(
-      SectionKind::getData(), "#S",
-      GOFF::PRAttr{false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink,
-                   GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Quadword, 0},
-      ADAEDSection);
+  ADASection = Ctx->getGOFFSection(SectionKind::getData(), "#S",
+                                   GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
+                                                GOFF::ESD_LT_XPLink,
+                                                GOFF::ESD_BSC_Section, 0},
+                                   ADAEDSection);
 
   TextSection = Ctx->getGOFFSection(
       SectionKind::getText(), GOFF::CLASS_CODE,
@@ -579,11 +579,11 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
                    GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
                    GOFF::ESD_ALIGN_Doubleword},
       RootSDSection);
-  PPA2ListSection = Ctx->getGOFFSection(
-      SectionKind::getData(), ".&ppa2",
-      GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_OS,
-                   GOFF::ESD_BSC_Section, GOFF::ESD_ALIGN_Doubleword, 0},
-      PPA2ListEDSection);
+  PPA2ListSection = Ctx->getGOFFSection(SectionKind::getData(), ".&ppa2",
+                                        GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,
+                                                     GOFF::ESD_LT_OS,
+                                                     GOFF::ESD_BSC_Section, 0},
+                                        PPA2ListEDSection);
 
   IDRLSection = Ctx->getGOFFSection(
       SectionKind::getData(), "B_IDRL",
diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
index 550ff4b1790f2..5dc5ba53e69dd 100644
--- a/llvm/lib/MC/MCSectionGOFF.cpp
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -123,7 +123,7 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
     ED->getParent()->printSwitchToSection(MAI, T, OS, Subsection);
     if (!Emitted) {
       emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode,
-                PRAttributes.Alignment, ED->EDAttributes.LoadBehavior,
+                ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior,
                 PRAttributes.Executable, ED->EDAttributes.IsReadOnly,
                 PRAttributes.SortKey, Name);
       emitXATTR(OS, Name, PRAttributes.Linkage, PRAttributes.Executable,

>From 9f0aa1267d1959094df8cf93a90b6e30130d503e Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 29 Apr 2025 13:35:47 -0400
Subject: [PATCH 33/35] Fix test cases

There were too many zeroes in the address.
---
 llvm/test/CodeGen/SystemZ/zos-section-1.ll | 100 ++++++-------
 llvm/test/CodeGen/SystemZ/zos-section-2.ll | 160 ++++++++++-----------
 2 files changed, 130 insertions(+), 130 deletions(-)

diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 74f4e272005f8..ea9bc4ce95174 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -33,80 +33,80 @@ entry:
 ; The 60 at offset 0x89 is the tasking behavior.
 ; The 01 at offset 0x91 is the binding scope.
 ; The name begins at offset 0x97, and is test#C.
-; CHECK-NEXT: 0000050 03 00 00 00 [[ROOTSD:00 00 00 01]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
-; CHECK-NEXT: 0000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 000050 03 00 00 00 [[ROOTSD:00 00 00 01]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
+; CHECK-NEXT: 000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
 ; ESD record, type ED.
 ; The name is C_CODE64.
 ; The regular expression matches the low byte of the length.
-; CHECK-NEXT: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
-; CHECK-NEXT: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 08
-; CHECK-NEXT: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+; CHECK-NEXT: 0000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 0000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK-NEXT: 0000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 08
+; CHECK-NEXT: 0000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
 
 ; ESD record, type ED.
 ; The name is C_@@QPPA2.
 ; This record has a continuation, therefore the falg at offset 0xf1 is set.
-; CHECK-NEXT: 00000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 0000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 08
-; CHECK-NEXT: 0000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
+; CHECK-NEXT: 0000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK-NEXT: 000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 08
+; CHECK-NEXT: 000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
 ;
 ; Continuation:
-; CHECK-NEXT: 0000140 03 02 00 f2 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000140 03 02 00 f2 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
 ; ESD record, type PR.
 ; The name is .&ppa2.
-; CHECK-NEXT: 0000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
-; CHECK-NEXT: 00001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
-; CHECK-NEXT: 00001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
-; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
-; CHECK-NEXT: 00001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
+; CHECK-NEXT: 000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
+; CHECK-NEXT: 0001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
+; CHECK-NEXT: 0001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
+; CHECK-NEXT: 0001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 0001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
 
 ; ESD record, type ED.
 ; The name is C_WSA64.
-; CHECK-NEXT: 00001e0 03 00 00 01 [[C_WSA64:00 00 00 05]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000200 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK-NEXT: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
-; CHECK-NEXT: 0000220 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+; CHECK-NEXT: 0001e0 03 00 00 01 [[C_WSA64:00 00 00 05]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000200 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECK-NEXT: 000210 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
+; CHECK-NEXT: 000220 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
 ; The name is test#S.
-; CHECK-NEXT: 0000230 03 00 00 03 [[TESTS:00 00 00 06]] [[C_WSA64]] 00 00 00 00
-; CHECK-NEXT: 0000240 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
-; CHECK-NEXT: 0000250 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
-; CHECK-NEXT: 0000270 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
+; CHECK-NEXT: 000230 03 00 00 03 [[TESTS:00 00 00 06]] [[C_WSA64]] 00 00 00 00
+; CHECK-NEXT: 000240 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 000250 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK-NEXT: 000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 000270 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
 
 ; ESD record, type ED.
 ; The name is B_IDRL.
-; CHECK-NEXT: 0000280 03 00 00 01 [[BIDRL:00 00 00 07]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 0000290 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
-; CHECK-NEXT: 00002a0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK-NEXT: 00002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
-; CHECK-NEXT: 00002c0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
+; CHECK-NEXT: 000280 03 00 00 01 [[BIDRL:00 00 00 07]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000290 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 0002a0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK-NEXT: 0002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
+; CHECK-NEXT: 0002c0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
 
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK-NEXT: 00002d0 03 00 00 02 [[TESTC:00 00 00 08]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 00002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 00002f0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK-NEXT: 0000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 0000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 0002d0 03 00 00 02 [[TESTC:00 00 00 08]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 0002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0002f0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
+; 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
 
 ; End record.
-; CHECK-NEXT: 0000320 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; 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
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index 25803c3bbfb0c..472517acc4a45 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -28,128 +28,128 @@ source_filename = "test.ll"
 ; The 60 at offset 0x89 is the tasking behavior.
 ; The 01 at offset 0x91 is the binding scope.
 ; The name begins at offset 0x97, and is test#C.
-; CHECK-NEXT: 0000050 03 00 00 00 [[ROOTSD:00 00 00 01]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
-; CHECK-NEXT: 0000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 000050 03 00 00 00 [[ROOTSD:00 00 00 01]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60
+; CHECK-NEXT: 000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
 
 ; ESD record, type ED.
 ; The name is C_CODE64.
 ; The regular expression matches the low byte of the length.
-; CHECK-NEXT: 00000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 00000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
-; CHECK-NEXT: 00000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK-NEXT: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 08
-; CHECK-NEXT: 00000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+; CHECK-NEXT: 0000a0 03 00 00 01 [[C_CODE64:00 00 00 02]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 0000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK-NEXT: 0000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 08
+; CHECK-NEXT: 0000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
 
 ; ESD record, type ED.
 ; The name is C_@@QPPA2.
 ; This record has a continuation, therefore the falg at offset 0xf1 is set.
-; CHECK-NEXT: 00000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 0000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 08
-; CHECK-NEXT: 0000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
+; CHECK-NEXT: 0000f0 03 01 00 01 [[C_QPPA2:00 00 00 03]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK-NEXT: 000120 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 08
+; CHECK-NEXT: 000130 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
 ;
 ; Continuation:
-; CHECK-NEXT: 0000140 03 02 00 f2 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000140 03 02 00 f2 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
 ; ESD record, type PR.
 ; The name is .&ppa2.
-; CHECK-NEXT: 0000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
-; CHECK-NEXT: 00001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
-; CHECK-NEXT: 00001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
-; CHECK-NEXT: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
-; CHECK-NEXT: 00001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
+; CHECK-NEXT: 000190 03 00 00 03 [[PPA2:00 00 00 04]] [[C_QPPA2]] 00 00 00 00
+; CHECK-NEXT: 0001a0 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
+; CHECK-NEXT: 0001b0 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
+; CHECK-NEXT: 0001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 0001d0 00 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
 
 ; ESD record, type SD.
 ; The name is data.
-; CHECK-NEXT: 00001e0 03 00 00 00 [[DATA:00 00 00 05]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 00001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000220 00 00 00 00 00 00 00 04 84 81 a3 81 00 00 00 00
+; CHECK-NEXT: 0001e0 03 00 00 00 [[DATA:00 00 00 05]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000220 00 00 00 00 00 00 00 04 84 81 a3 81 00 00 00 00
 
 ; ESD record, type ED.
 ; The name is C_WSA64.
-; CHECK-NEXT: 0000230 03 00 00 01 [[DATA_WSA:00 00 00 06]] [[DATA]] 00 00 00 00
-; CHECK-NEXT: 0000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000250 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000260 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
-; CHECK-NEXT: 0000270 00 40 02 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+; CHECK-NEXT: 000230 03 00 00 01 [[DATA_WSA:00 00 00 06]] [[DATA]] 00 00 00 00
+; CHECK-NEXT: 000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000250 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK-NEXT: 000260 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
+; CHECK-NEXT: 000270 00 40 02 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
 ; The name is data.
-; CHECK-NEXT: 0000280 03 00 00 03 [[DATA_PR:00 00 00 07]] [[DATA_WSA]] 00 00 00 00
-; CHECK-NEXT: 0000290 00 00 00 00 00 00 00 00 [[DATA_LEN:00 00 00 04]] 00 00 00 00
-; CHECK-NEXT: 00002a0 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
-; CHECK-NEXT: 00002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
-; CHECK-NEXT: 00002c0 00 03 22 00 00 00 00 04 84 81 a3 81 00 00 00 00
+; CHECK-NEXT: 000280 03 00 00 03 [[DATA_PR:00 00 00 07]] [[DATA_WSA]] 00 00 00 00
+; CHECK-NEXT: 000290 00 00 00 00 00 00 00 00 [[DATA_LEN:00 00 00 04]] 00 00 00 00
+; CHECK-NEXT: 0002a0 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK-NEXT: 0002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 0002c0 00 03 22 00 00 00 00 04 84 81 a3 81 00 00 00 00
 
 ; ESD record, type SD.
 ; The name is bss.
-; CHECK-NEXT: 00002d0 03 00 00 00 [[BSS:00 00 00 08]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 00002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 00002f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000310 00 00 00 00 00 00 00 03 82 a2 a2 00 00 00 00 00
+; CHECK-NEXT: 0002d0 03 00 00 00 [[BSS:00 00 00 08]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0002f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000310 00 00 00 00 00 00 00 03 82 a2 a2 00 00 00 00 00
 
 ; ESD record, type ED.
 ; The name is C_WSA64.
-; CHECK-NEXT: 0000320 03 00 00 01 [[BSS_WSA:00 00 00 09]] [[BSS]] 00 00 00 00
-; CHECK-NEXT: 0000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000340 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000350 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
-; CHECK-NEXT: 0000360 00 40 03 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+; CHECK-NEXT: 000320 03 00 00 01 [[BSS_WSA:00 00 00 09]] [[BSS]] 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 03 80 00 00 00 00 00 00
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
+; CHECK-NEXT: 000360 00 40 03 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
 ; The name is bss.
-; CHECK-NEXT: 0000370 03 00 00 03 [[BSS_PR:00 00 00 0a]] [[BSS_WSA]] 00 00 00 00
-; CHECK-NEXT: 0000380 00 00 00 00 00 00 00 00 [[BSS_LEN:00 00 00 08]] 00 00 00 00
-; CHECK-NEXT: 0000390 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
-; CHECK-NEXT: 00003a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
-; CHECK-NEXT: 00003b0 00 03 23 00 00 00 00 03 82 a2 a2 00 00 00 00 00
+; CHECK-NEXT: 000370 03 00 00 03 [[BSS_PR:00 00 00 0a]] [[BSS_WSA]] 00 00 00 00
+; CHECK-NEXT: 000380 00 00 00 00 00 00 00 00 [[BSS_LEN:00 00 00 08]] 00 00 00 00
+; CHECK-NEXT: 000390 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 0003b0 00 03 23 00 00 00 00 03 82 a2 a2 00 00 00 00 00
 
 ; ESD record, type ED.
 ; The name is C_WSA64.
-; CHECK-NEXT: 00003c0 03 00 00 01 [[C_WSA64:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 00003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 00003e0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
-; CHECK-NEXT: 00003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
-; CHECK-NEXT: 0000400 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+; CHECK-NEXT: 0003c0 03 00 00 01 [[C_WSA64:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00
+; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 00
+; CHECK-NEXT: 000400 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
 
 ; ESD record, type PR.
 ; The name is test#S.
-; CHECK-NEXT: 0000410 03 00 00 03 [[TESTS:00 00 00 0c]] [[C_WSA64]] 00 00 00 00
-; CHECK-NEXT: 0000420 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
-; CHECK-NEXT: 0000430 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
-; CHECK-NEXT: 0000450 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
+; CHECK-NEXT: 000410 03 00 00 03 [[TESTS:00 00 00 0c]] [[C_WSA64]] 00 00 00 00
+; CHECK-NEXT: 000420 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 000430 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK-NEXT: 000440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
+; CHECK-NEXT: 000450 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00
 
 ; ESD record, type ED.
 ; The name is B_IDRL.
-; CHECK-NEXT: 0000460 03 00 00 01 [[BIDRL:00 00 00 0d]] [[ROOTSD]] 00 00 00 00
-; CHECK-NEXT: 0000470 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
-; CHECK-NEXT: 0000480 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
-; CHECK-NEXT: 0000490 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
-; CHECK-NEXT: 00004a0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
+; CHECK-NEXT: 000460 03 00 00 01 [[BIDRL:00 00 00 0d]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000470 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00
+; CHECK-NEXT: 000480 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK-NEXT: 000490 00 00 00 00 00 00 00 00 00 00 00 00 00 04 10 08
+; CHECK-NEXT: 0004a0 00 80 03 00 00 00 00 06 c2 6d c9 c4 d9 d3 00 00
 
 ; ESD record, type LD.
 ; The name is test#C.
-; CHECK-NEXT: 00004b0 03 00 00 02 [[TESTC:00 00 00 0e]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 00004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 00004d0 00 00 00 00 00 00 00 00 01 00 00 00 [[TESTS]]
-; CHECK-NEXT: 00004e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 00004f0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; CHECK-NEXT: 0004b0 03 00 00 02 [[TESTC:00 00 00 0e]] [[C_CODE64]] 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 01 00 00 00 [[TESTS]]
+; 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
 
 ; End record.
-; CHECK-NEXT: 0000500 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; 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

>From 4883fc367a2714e14e7be8fefcbd423ce75a0b4f Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Tue, 29 Apr 2025 15:52:36 -0400
Subject: [PATCH 34/35] Lift fill byte value to higher layer.

---
 llvm/include/llvm/MC/MCGOFFAttributes.h           |  2 ++
 llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp |  6 +++---
 llvm/lib/MC/GOFFObjectWriter.cpp                  |  4 ++--
 llvm/lib/MC/MCObjectFileInfo.cpp                  |  8 ++++----
 llvm/lib/MC/MCSectionGOFF.cpp                     | 11 +++++++----
 llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll  |  2 +-
 llvm/test/CodeGen/SystemZ/zos-intrinsics.ll       |  2 +-
 llvm/test/CodeGen/SystemZ/zos-landingpad.ll       |  2 +-
 llvm/test/CodeGen/SystemZ/zos-simple-test.ll      |  4 ++--
 9 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index bf4b545b0dff0..23451912e03bb 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -15,6 +15,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/GOFF.h"
+#include <cstdint>
 
 namespace llvm {
 namespace GOFF {
@@ -58,6 +59,7 @@ struct EDAttr {
   GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial;
   GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0;
   GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword;
+  uint8_t FillByteValue = 0;
 };
 
 // Attributes for LD symbols.
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index ea1431491eeab..cd4f1dd93077e 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2799,8 +2799,8 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
       SectionKind::getMetadata(), GOFF::CLASS_WSA,
       GOFF::EDAttr{false, GOFF::RMODE, GOFF::ESD_NS_Parts,
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
-                   GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0,
-                   GOFF::ESD_ALIGN_Fullword},
+                   GOFF::LOADBEHAVIOR, GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Fullword,
+                   0},
       static_cast<MCSectionGOFF *>(TextSection)->getParent());
   return getContext().getGOFFSection(SectionKind::getData(), Name,
                                      GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,
@@ -2832,7 +2832,7 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
         SectionKind::getMetadata(), GOFF::CLASS_WSA,
         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},
+                     GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align, 0},
         SD);
     return getContext().getGOFFSection(Kind, Symbol->getName(),
                                        GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 339e9da29ef03..c4bd836e4976a 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -232,8 +232,8 @@ class GOFFSymbol {
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
         SymbolType(GOFF::ESD_ST_ElementDefinition) {
     this->NameSpace = Attr.NameSpace;
-    // We default to 0 as fill byte value.
-    this->FillByteValue = 0;
+    // We always set a fill byte value.
+    this->FillByteValue = Attr.FillByteValue;
     SymbolFlags.setFillBytePresence(1);
     SymbolFlags.setReservedQwords(Attr.ReservedQwords);
     // TODO Do we need/should set the "mangled" flag?
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index edbc69c17219e..9d969b2db91a7 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -556,7 +556,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       GOFF::EDAttr{false, GOFF::RMODE, GOFF::ESD_NS_Parts,
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge,
                    GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1,
-                   GOFF::ESD_ALIGN_Quadword},
+                   GOFF::ESD_ALIGN_Quadword, 0},
       RootSDSection);
   ADASection = Ctx->getGOFFSection(SectionKind::getData(), "#S",
                                    GOFF::PRAttr{false, GOFF::ESD_EXE_DATA,
@@ -569,7 +569,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       GOFF::EDAttr{true, GOFF::RMODE, GOFF::ESD_NS_NormalName,
                    GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate,
                    GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0,
-                   GOFF::ESD_ALIGN_Doubleword},
+                   GOFF::ESD_ALIGN_Doubleword, 0},
       RootSDSection);
 
   MCSectionGOFF *PPA2ListEDSection = Ctx->getGOFFSection(
@@ -577,7 +577,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       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},
+                   GOFF::ESD_ALIGN_Doubleword, 0},
       RootSDSection);
   PPA2ListSection = Ctx->getGOFFSection(SectionKind::getData(), ".&ppa2",
                                         GOFF::PRAttr{true, GOFF::ESD_EXE_DATA,
@@ -590,7 +590,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
       GOFF::EDAttr{true, GOFF::RMODE, GOFF::ESD_NS_NormalName,
                    GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate,
                    GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0,
-                   GOFF::ESD_ALIGN_Doubleword},
+                   GOFF::ESD_ALIGN_Doubleword, 0},
       RootSDSection);
 }
 
diff --git a/llvm/lib/MC/MCSectionGOFF.cpp b/llvm/lib/MC/MCSectionGOFF.cpp
index 5dc5ba53e69dd..8163e5bbd632b 100644
--- a/llvm/lib/MC/MCSectionGOFF.cpp
+++ b/llvm/lib/MC/MCSectionGOFF.cpp
@@ -16,9 +16,11 @@ static void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
                       GOFF::ESDAlignment Alignment,
                       GOFF::ESDLoadingBehavior LoadBehavior,
                       GOFF::ESDExecutable Executable, bool IsReadOnly,
-                      uint32_t SortKey, StringRef PartName) {
+                      uint32_t SortKey, uint8_t FillByteValue,
+                      StringRef PartName) {
   OS << Name << " CATTR ";
-  OS << "ALIGN(" << static_cast<unsigned>(Alignment) << ")";
+  OS << "ALIGN(" << static_cast<unsigned>(Alignment) << "),"
+     << "FILL(" << static_cast<unsigned>(FillByteValue) << ")";
   switch (LoadBehavior) {
   case GOFF::ESD_LB_Deferred:
     OS << ",DEFLOAD";
@@ -112,7 +114,8 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
     if (!Emitted) {
       emitCATTR(OS, Name, EDAttributes.Rmode, EDAttributes.Alignment,
                 EDAttributes.LoadBehavior, GOFF::ESD_EXE_Unspecified,
-                EDAttributes.IsReadOnly, 0, StringRef());
+                EDAttributes.IsReadOnly, 0, EDAttributes.FillByteValue,
+                StringRef());
       Emitted = true;
     } else
       OS << Name << " CATTR\n";
@@ -125,7 +128,7 @@ void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
       emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode,
                 ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior,
                 PRAttributes.Executable, ED->EDAttributes.IsReadOnly,
-                PRAttributes.SortKey, Name);
+                PRAttributes.SortKey, ED->EDAttributes.FillByteValue, Name);
       emitXATTR(OS, Name, PRAttributes.Linkage, PRAttributes.Executable,
                 PRAttributes.BindingScope);
       ED->Emitted = true;
diff --git a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
index b2eb2836fc361..d6aa99b5634d7 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
@@ -56,7 +56,7 @@ entry:
 declare signext i32 @callout(i32 signext)
 
 ; CHECK: stdin#C CSECT
-; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
+; CHECK: C_WSA64 CATTR ALIGN(4),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
 ; CHECK: stdin#S XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
 ; CHECK:  .set L#DoFunc at indirect0, DoFunc
 ; CHECK:      .indirect_symbol   L#DoFunc at indirect0
diff --git a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
index 4a8fc1cd03980..c963d85d60f1c 100644
--- a/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-intrinsics.ll
@@ -31,7 +31,7 @@ declare fp128 @llvm.exp2.f128(fp128)
 
 ; Check the calls in the ADA.
 ; CHECK: stdin#C CSECT
-; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
+; CHECK: C_WSA64 CATTR ALIGN(4),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
 ; CHECK: stdin#S XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
 
 ; Check that there is no call to sqrt.
diff --git a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
index 04963a06a93e8..307f280617619 100644
--- a/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-landingpad.ll
@@ -38,6 +38,6 @@ lpad:
 ; CHECK: LSDA location
 ; Check that the exception table is emitted into .lsda section.
 ; CHECK:  stdin#C CSECT
-; CHECK:  C_WSA64 CATTR ALIGN(2),NOTEXECUTABLE,RMODE(64),PART(.gcc_exception_table.test1)
+; CHECK:  C_WSA64 CATTR ALIGN(2),FILL(0),NOTEXECUTABLE,RMODE(64),PART(.gcc_exception_table.test1)
 ; CHECK:  .gcc_exception_table.test1 XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(SECTION)
 ; CHECK: GCC_except_table0:
diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
index dd894a810d95a..f1f7cee8268f7 100644
--- a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -6,10 +6,10 @@
 
 define signext i32 @main() {
 ; CHECK: stdin#C CSECT
-; CHECK: C_CODE64 CATTR ALIGN(3),READONLY,RMODE(64)
+; CHECK: C_CODE64 CATTR ALIGN(3),FILL(0),READONLY,RMODE(64)
 ; CHECK: main:
 ; CHECK: stdin#C CSECT
-; CHECK: C_WSA64 CATTR ALIGN(2),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)
+; CHECK: C_WSA64 CATTR ALIGN(2),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)
 ; CHECK: a XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(EXPORT)
 ; CHECK: a:
 entry:

>From 1e4c70025ae0dd0eff664aa909842bb9feb00b29 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 30 Apr 2025 10:36:06 -0400
Subject: [PATCH 35/35] Fix formatting.

---
 llvm/lib/MC/GOFFObjectWriter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index c4bd836e4976a..c2bc3885030aa 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -258,7 +258,7 @@ class GOFFSymbol {
   }
 
   GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
-    const GOFF::EDAttr &EDAttr, const GOFF::PRAttr &Attr)
+             const GOFF::EDAttr &EDAttr, const GOFF::PRAttr &Attr)
       : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
         SymbolType(GOFF::ESD_ST_PartReference), NameSpace(EDAttr.NameSpace) {
     SymbolFlags.setRenameable(Attr.IsRenamable);



More information about the llvm-branch-commits mailing list