[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
Tue Apr 8 13:12:31 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/15] [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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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/15] 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
More information about the llvm-branch-commits
mailing list