[llvm] [z/OS][GOFF] Implement support for writing ESD + TXT records by the GOFFObjectWriter (PR #85851)
Neumann Hon via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 1 14:02:57 PDT 2024
https://github.com/Everybody0523 updated https://github.com/llvm/llvm-project/pull/85851
>From adf262bb65cfc5a2adfabc9ec10eab79533d1371 Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Tue, 19 Mar 2024 12:03:05 -0400
Subject: [PATCH 01/12] new attempt for implementing ESD+TXT
---
llvm/include/llvm/BinaryFormat/GOFF.h | 16 +-
llvm/include/llvm/CodeGen/AsmPrinter.h | 5 +-
llvm/include/llvm/MC/MCAssembler.h | 7 +
llvm/include/llvm/MC/MCContext.h | 3 +-
llvm/include/llvm/MC/MCGOFFStreamer.h | 11 +-
llvm/include/llvm/MC/MCSymbolGOFF.h | 55 +-
.../CodeGen/TargetLoweringObjectFileImpl.cpp | 8 +-
llvm/lib/MC/GOFFObjectWriter.cpp | 807 +++++++++++++++++-
llvm/lib/MC/MCGOFFStreamer.cpp | 76 ++
llvm/lib/MC/MCObjectFileInfo.cpp | 3 +
.../SystemZ/MCTargetDesc/SystemZMCExpr.cpp | 4 +
.../SystemZ/MCTargetDesc/SystemZMCExpr.h | 2 +
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 99 ++-
llvm/lib/Target/SystemZ/SystemZAsmPrinter.h | 4 +
llvm/test/MC/GOFF/basic-goff-64.ll | 252 ++++++
llvm/test/MC/GOFF/empty-goff.s | 39 +-
16 files changed, 1351 insertions(+), 40 deletions(-)
create mode 100644 llvm/test/MC/GOFF/basic-goff-64.ll
diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index 443bcfc9479a8b..b0cd2484536ea2 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -29,6 +29,8 @@ constexpr uint8_t RecordLength = 80;
constexpr uint8_t RecordPrefixLength = 3;
constexpr uint8_t PayloadLength = 77;
constexpr uint8_t RecordContentLength = RecordLength - RecordPrefixLength;
+constexpr uint8_t ESDMetadataLength = 69;
+constexpr uint8_t TXTMetadataLength = 21;
/// \brief Maximum data length before starting a new card for RLD and TXT data.
///
@@ -65,12 +67,7 @@ enum ESDNameSpaceId : uint8_t {
ESD_NS_Parts = 3
};
-enum ESDReserveQwords : uint8_t {
- ESD_RQ_0 = 0,
- ESD_RQ_1 = 1,
- ESD_RQ_2 = 2,
- ESD_RQ_3 = 3
-};
+enum ESDReserveQwords : uint8_t { ESD_RQ_0 = 0, ESD_RQ_1 = 1 };
enum ESDAmode : uint8_t {
ESD_AMODE_None = 0,
@@ -157,6 +154,12 @@ enum ESDAlignment : uint8_t {
ESD_ALIGN_4Kpage = 12,
};
+enum TXTRecordStyle : uint8_t {
+ TXT_RS_Byte = 0,
+ TXT_RS_Structured = 1,
+ TXT_RS_Unstructured = 2,
+};
+
enum ENDEntryPointRequest : uint8_t {
END_EPR_None = 0,
END_EPR_EsdidOffset = 1,
@@ -166,6 +169,7 @@ enum ENDEntryPointRequest : uint8_t {
// \brief Subsections of the primary C_CODE section in the object file.
enum SubsectionKind : uint8_t {
+ SK_ReadOnly = 1,
SK_PPA1 = 2,
SK_PPA2 = 4,
};
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index a7fbf4aeb74494..0fb696bbb68b13 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -897,10 +897,13 @@ class AsmPrinter : public MachineFunctionPass {
virtual void emitModuleCommandLines(Module &M);
GCMetadataPrinter *getOrCreateGCPrinter(GCStrategy &S);
+
+protected:
virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA);
- void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);
private:
+ void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);
+
/// This method decides whether the specified basic block requires a label.
bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const;
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 3fa5f2fe655e86..7c1b6bdb3ffb60 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -136,6 +136,9 @@ class MCAssembler {
// Optional compiler version.
std::string CompilerVersion;
+ /// GOFF Csect names.
+ std::pair<std::string, std::string> CsectNames;
+
MCDwarfLineTableParams LTParams;
/// The set of function symbols for which a .thumb_func directive has
@@ -488,6 +491,10 @@ class MCAssembler {
FileNames.emplace_back(std::string(FileName), Symbols.size());
}
+ std::pair<std::string, std::string> const &getCsectNames() {
+ return CsectNames;
+ }
+
void setCompilerVersion(std::string CompilerVers) {
if (CompilerVersion.empty())
CompilerVersion = std::move(CompilerVers);
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 3f585d4d2efaf5..e9c7c96298d683 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -623,7 +623,8 @@ class MCContext {
unsigned EntrySize);
MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind,
- MCSection *Parent, const MCExpr *SubsectionId);
+ MCSection *Parent = nullptr,
+ const MCExpr *SubsectionId = nullptr);
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName,
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 2345509b161da5..52cde0632483a0 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -24,12 +24,15 @@ class MCGOFFStreamer : public MCObjectStreamer {
~MCGOFFStreamer() override;
- bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
- return false;
- }
+ // state management
+ void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
+
+ void switchSection(MCSection *Section,
+ const MCExpr *Subsection = nullptr) override;
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
- void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override {}
+ void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, Align ByteAlignment = Align(1),
SMLoc Loc = SMLoc()) override {}
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index cc4e2bbe246e2d..bb3c3b07947aa3 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -18,10 +18,63 @@
namespace llvm {
class MCSymbolGOFF : public MCSymbol {
+ Align Alignment;
+
+ mutable StringRef AliasName; // ADA indirect
+
+ enum SymbolFlags : uint16_t {
+ SF_NoRent = 0x01, // Symbol is no-reentrant.
+ SF_Alias = 0x02, // Symbol is alias.
+ SF_Hidden = 0x04, // Symbol is hidden, aka not exported.
+ SF_Weak = 0x08, // Symbol is weak.
+ SF_OSLinkage = 0x10, // Symbol uses OS linkage.
+ };
+
+ // Shift value for GOFF::ESDExecutable. 3 possible values. 2 bits.
+ static constexpr uint8_t GOFF_Executable_Shift = 6;
+ static constexpr uint8_t GOFF_Executable_Bitmask = 0x03;
+
public:
MCSymbolGOFF(const StringMapEntry<bool> *Name, bool IsTemporary)
- : MCSymbol(SymbolKindGOFF, Name, IsTemporary) {}
+ : MCSymbol(SymbolKindGOFF, Name, IsTemporary), AliasName() {}
static bool classof(const MCSymbol *S) { return S->isGOFF(); }
+
+ bool hasAliasName() const { return !AliasName.empty(); }
+ void setAliasName(StringRef Name) { AliasName = Name; }
+ StringRef getAliasName() const { return AliasName; }
+
+ void setTemporary(bool Value) { IsTemporary = Value; }
+
+ void setOSLinkage(bool Value = true) const {
+ modifyFlags(Value ? SF_OSLinkage : 0, SF_OSLinkage);
+ }
+ bool isOSLinkage() const { return getFlags() & SF_OSLinkage; }
+
+ void setAlignment(Align Value) { Alignment = Value; }
+ Align getAlignment() const { return Alignment; }
+
+ void setExecutable(GOFF::ESDExecutable Value) const {
+ modifyFlags(Value << GOFF_Executable_Shift,
+ GOFF_Executable_Bitmask << GOFF_Executable_Shift);
+ }
+ GOFF::ESDExecutable getExecutable() const {
+ return static_cast<GOFF::ESDExecutable>(
+ (getFlags() >> GOFF_Executable_Shift) & GOFF_Executable_Bitmask);
+ }
+
+ void setHidden(bool Value = true) {
+ modifyFlags(Value ? SF_Hidden : 0, SF_Hidden);
+ }
+ bool isHidden() const { return getFlags() & SF_Hidden; }
+ bool isExported() const { return !isHidden(); }
+
+ void setWeak(bool Value = true) { modifyFlags(Value ? SF_Weak : 0, SF_Weak); }
+ bool isWeak() const { return getFlags() & SF_Weak; }
+
+ void setAlias(bool Value = true) {
+ modifyFlags(Value ? SF_Alias : 0, SF_Alias);
+ }
+ bool isAlias() const { return getFlags() & SF_Alias; }
};
} // end namespace llvm
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 15b59421a0f44a..3b4f7faa99d590 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2744,9 +2744,13 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA(
MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
auto *Symbol = TM.getSymbol(GO);
+ if (Kind.isData())
+ return getContext().getGOFFSection(Symbol->getName(),
+ SectionKind::getData());
+
if (Kind.isBSS())
- return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(),
- nullptr, nullptr);
+ return getContext().getGOFFSection(Symbol->getName(),
+ SectionKind::getBSS());
return getContext().getObjectFileInfo()->getTextSection();
}
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index addeb6db959693..60ab410e9765e2 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -13,8 +13,13 @@
#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.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"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Path.h"
@@ -217,13 +222,112 @@ void GOFFOstream::write_impl(const char *Ptr, size_t Size) {
}
}
+/// \brief Wrapper class for symbols used exclusively for the symbol table in a
+/// GOFF file.
+class GOFFSymbol {
+public:
+ std::string Name;
+ uint32_t EsdId;
+ uint32_t ParentEsdId;
+ const MCSymbolGOFF *MCSym;
+ GOFF::ESDSymbolType SymbolType;
+
+ GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName;
+ GOFF::ESDAmode Amode = GOFF::ESD_AMODE_64;
+ GOFF::ESDRmode Rmode = GOFF::ESD_RMODE_64;
+ GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
+ GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
+ GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Byte;
+ GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented;
+ GOFF::ESDBindingAlgorithm BindAlgorithm = GOFF::ESD_BA_Concatenate;
+ GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial;
+ GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
+ GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
+ GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0;
+
+ uint32_t SortKey = 0;
+ uint32_t SectionLength = 0;
+ uint32_t ADAEsdId = 0;
+ bool Indirect = false;
+ bool ForceRent = false;
+ bool Renamable = false;
+ bool ReadOnly = false;
+ uint32_t EASectionEsdId = 0;
+ uint32_t EASectionOffset = 0;
+
+ GOFFSymbol(StringRef Name, GOFF::ESDSymbolType Type, uint32_t EsdID,
+ uint32_t ParentEsdID)
+ : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
+ MCSym(nullptr), SymbolType(Type) {}
+ GOFFSymbol() {}
+
+ bool isForceRent() const { return ForceRent; }
+ bool isReadOnly() const { return ReadOnly; }
+ bool isRemovable() const { return false; }
+ bool isExecutable() const { return Executable == GOFF::ESD_EXE_CODE; }
+ bool isExecUnspecified() const {
+ return Executable == GOFF::ESD_EXE_Unspecified;
+ }
+ bool isWeakRef() const { return BindingStrength == GOFF::ESD_BST_Weak; }
+ bool isExternal() const {
+ return (BindingScope == GOFF::ESD_BSC_Library) ||
+ (BindingScope == GOFF::ESD_BSC_ImportExport);
+ }
+
+ void setAlignment(Align A) {
+ // The GOFF alignment is encoded as log_2 value.
+ uint8_t Log = Log2(A);
+ if (Log <= GOFF::ESD_ALIGN_4Kpage)
+ Alignment = static_cast<GOFF::ESDAlignment>(Log);
+ else
+ llvm_unreachable("Unsupported alignment");
+ }
+};
+
+/// \brief Wrapper class for sections used exclusively for representing sections
+/// of the GOFF output that have actual bytes. This could be a ED or a PR.
+/// Relocations will always have a P-pointer to the ESDID of one of these.
+struct GOFFSection {
+ uint32_t PEsdId;
+ uint32_t REsdId;
+ uint32_t SDEsdId;
+ const MCSectionGOFF *MC;
+
+ GOFFSection(uint32_t PEsdId, uint32_t REsdId, uint32_t SDEsdId)
+ : PEsdId(PEsdId), REsdId(REsdId), SDEsdId(SDEsdId), MC(nullptr) {}
+ GOFFSection(uint32_t PEsdId, uint32_t REsdId, uint32_t SDEsdId,
+ const MCSectionGOFF *MC)
+ : PEsdId(PEsdId), REsdId(REsdId), SDEsdId(SDEsdId), MC(MC) {}
+};
+
+// An MCSymbol may map to up to two GOFF Symbols. The first is the
+// "true" underlying symbol, the second one represents any indirect
+// references to that symbol.
class GOFFObjectWriter : public MCObjectWriter {
+ typedef DenseMap<MCSymbol const *, uint32_t> SymbolMapType;
+ typedef DenseMap<MCSection const *, GOFFSection> SectionMapType;
+
// The target specific GOFF writer instance.
std::unique_ptr<MCGOFFObjectTargetWriter> TargetObjectWriter;
+ /// Lookup table for MCSymbols to GOFFSymbols. Needed to determine EsdIds
+ /// of symbols in Relocations.
+ SymbolMapType SymbolMap;
+
+ /// Lookup table for MCSections to GOFFSections. Needed to determine
+ /// SymbolType on GOFFSymbols that reside in GOFFSections.
+ SectionMapType SectionMap;
+
// The stream used to write the GOFF records.
GOFFOstream OS;
+ uint32_t EsdCounter = 1;
+
+ // The "root" SD node. This should have ESDID = 1
+ GOFFSymbol RootSD;
+ uint32_t EntryEDEsdId;
+ uint32_t CodeLDEsdId;
+
public:
GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
raw_pwrite_stream &OS)
@@ -231,20 +335,290 @@ class GOFFObjectWriter : public MCObjectWriter {
~GOFFObjectWriter() override {}
+private:
// Write GOFF records.
void writeHeader();
+
+ void writeSymbol(const GOFFSymbol &Symbol, const MCAsmLayout &Layout);
+
+ void writeADAandCodeSectionSymbols(MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+ // Write out all ESD Symbols that own a section. GOFF doesn't have
+ // "sections" in the way other object file formats like ELF do; instead
+ // a GOFF section is defined as a triple of ESD Symbols (SD, ED, PR/LD).
+ // The PR/LD symbol should own a TXT record that contains the actual
+ // data of the section.
+ void writeSectionSymbols(MCAssembler &Asm, const MCAsmLayout &Layout);
+
+ void writeText(const MCSectionGOFF *MCSec, uint32_t EsdId, bool IsStructured,
+ MCAssembler &Asm, const MCAsmLayout &Layout);
+
void writeEnd();
+public:
// Implementation of the MCObjectWriter interface.
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, uint64_t &FixedValue) override {}
void executePostLayoutBinding(MCAssembler &Asm,
- const MCAsmLayout &Layout) override {}
+ const MCAsmLayout &Layout) override;
uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+
+private:
+ GOFFSection *createGOFFSection(GOFFSymbol *Pptr, GOFFSymbol *Rptr,
+ GOFFSymbol *SD, const MCSectionGOFF *MC);
+ GOFFSymbol createGOFFSymbol(StringRef Name, GOFF::ESDSymbolType Type,
+ uint32_t ParentEsdId);
+ GOFFSymbol createSDSymbol(StringRef Name);
+ GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId);
+ GOFFSymbol createLDSymbol(StringRef Name, uint32_t ParentEsdId);
+ GOFFSymbol createERSymbol(StringRef Name, uint32_t ParentEsdId,
+ const MCSymbolGOFF *Source = nullptr);
+ GOFFSymbol createPRSymbol(StringRef Name, uint32_t ParentEsdId);
+
+ GOFFSymbol createWSASymbol(uint32_t ParentEsdId, bool ReserveQWords = false);
+
+ // Define the root SD node as well as the symbols that make up the
+ // ADA section.
+ void defineRootSD(MCAssembler &Asm, const MCAsmLayout &Layout);
+
+ void defineSectionSymbols(const MCAssembler &Asm,
+ const MCSectionGOFF &Section,
+ const MCAsmLayout &Layout);
+ void writeSymbolDefinedInModule(const MCSymbolGOFF &Symbol, MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+ void writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol, MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+
+ // In XPLINK, the ESD Record owning the ADA is always the 4th record, behind
+ // the HDR record, the Root SD, and the ED symbol for the ADA, meaning it
+ // always has EsdId = 3.
+ static constexpr uint32_t ADAEsdId = 3u;
};
} // end anonymous namespace
+GOFFSymbol GOFFObjectWriter::createGOFFSymbol(StringRef Name,
+ GOFF::ESDSymbolType Type,
+ uint32_t ParentEsdId) {
+ return GOFFSymbol(Name, Type, EsdCounter++, ParentEsdId);
+}
+
+GOFFSymbol GOFFObjectWriter::createSDSymbol(StringRef Name) {
+ return createGOFFSymbol(Name, GOFF::ESD_ST_SectionDefinition, 0);
+}
+
+GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name,
+ uint32_t ParentEsdId) {
+ GOFFSymbol ED =
+ createGOFFSymbol(Name, GOFF::ESD_ST_ElementDefinition, ParentEsdId);
+
+ ED.Alignment = GOFF::ESD_ALIGN_Doubleword;
+ return ED;
+}
+
+GOFFSymbol GOFFObjectWriter::createLDSymbol(StringRef Name,
+ uint32_t ParentEsdId) {
+ return createGOFFSymbol(Name, GOFF::ESD_ST_LabelDefinition, ParentEsdId);
+}
+
+GOFFSymbol GOFFObjectWriter::createERSymbol(StringRef Name,
+ uint32_t ParentEsdId,
+ const MCSymbolGOFF *Source) {
+ GOFFSymbol ER =
+ createGOFFSymbol(Name, GOFF::ESD_ST_ExternalReference, ParentEsdId);
+
+ if (Source) {
+ ER.Linkage = Source->isOSLinkage() ? GOFF::ESDLinkageType::ESD_LT_OS
+ : GOFF::ESDLinkageType::ESD_LT_XPLink;
+ ER.Executable = Source->getExecutable();
+ ER.BindingScope = Source->isExternal()
+ ? GOFF::ESDBindingScope::ESD_BSC_Library
+ : GOFF::ESDBindingScope::ESD_BSC_Section;
+ ER.BindingStrength = Source->isWeak()
+ ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong;
+ }
+
+ return ER;
+}
+
+GOFFSymbol GOFFObjectWriter::createPRSymbol(StringRef Name,
+ uint32_t ParentEsdId) {
+ return createGOFFSymbol(Name, GOFF::ESD_ST_PartReference, ParentEsdId);
+}
+
+GOFFSymbol GOFFObjectWriter::createWSASymbol(uint32_t ParentEsdId,
+ bool ReserveQwords) {
+ const char *WSAClassName = "C_WSA64";
+ GOFFSymbol WSA = createEDSymbol(WSAClassName, ParentEsdId);
+
+ WSA.Executable = GOFF::ESD_EXE_DATA;
+ WSA.TextStyle = GOFF::ESD_TS_ByteOriented;
+ WSA.BindAlgorithm = GOFF::ESD_BA_Merge;
+ WSA.Alignment = GOFF::ESD_ALIGN_Quadword;
+ WSA.LoadBehavior = GOFF::ESD_LB_Deferred;
+ WSA.NameSpace = GOFF::ESD_NS_Parts;
+ WSA.SectionLength = 0;
+ WSA.ReservedQwords = ReserveQwords ? GOFF::ESD_RQ_1 : GOFF::ESD_RQ_0;
+
+ return WSA;
+}
+
+static uint32_t getADASectionLength(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ for (MCSection &S : Asm)
+ if (S.getName().equals(".ada"))
+ return Layout.getSectionAddressSize(&S);
+ return 0;
+}
+
+void GOFFObjectWriter::defineRootSD(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ StringRef FileName = "";
+ if (!Asm.getFileNames().empty())
+ FileName = sys::path::stem((*(Asm.getFileNames().begin())).first);
+ std::pair<std::string, std::string> CsectNames = Asm.getCsectNames();
+ if (CsectNames.first.empty()) {
+ RootSD = createSDSymbol(FileName.str().append("#C"));
+ RootSD.BindingScope = GOFF::ESD_BSC_Section;
+ } else {
+ RootSD = createSDSymbol(CsectNames.first);
+ }
+ RootSD.Executable = GOFF::ESD_EXE_CODE;
+}
+
+void GOFFObjectWriter::writeSymbolDefinedInModule(const MCSymbolGOFF &Symbol,
+ MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ MCSection &Section = Symbol.getSection();
+ SectionKind Kind = Section.getKind();
+ auto &Sec = cast<MCSectionGOFF>(Section);
+
+ StringRef SymbolName = Symbol.getName();
+ // If it's a text section, then create a label for it.
+ if (Kind.isText()) {
+ auto &GSection = SectionMap.at(&Sec);
+ GOFFSymbol LD = createLDSymbol(SymbolName, GSection.PEsdId);
+ LD.BindingStrength = Symbol.isWeak()
+ ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong;
+
+ // If we don't know if it is code or data, assume it is code.
+ LD.Executable = Symbol.getExecutable();
+ if (LD.isExecUnspecified())
+ LD.Executable = GOFF::ESD_EXE_CODE;
+
+ // Determine the binding scope. Please note that the combination
+ // !isExternal && isExported makes no sense.
+ LD.BindingScope =
+ Symbol.isExternal()
+ ? (Symbol.isExported() ? GOFF::ESD_BSC_ImportExport
+ : (LD.isExecutable() ? GOFF::ESD_BSC_Library
+ : GOFF::ESD_BSC_Module))
+ : GOFF::ESD_BSC_Section;
+
+ LD.ADAEsdId = GOFFObjectWriter::ADAEsdId;
+
+ if (Symbol.getName().equals("main")) {
+ LD.BindingScope = GOFF::ESD_BSC_Library;
+ LD.Renamable = true;
+ }
+
+ LD.MCSym = &Symbol;
+ SymbolMap.insert(std::make_pair(&Symbol, LD.EsdId));
+ writeSymbol(LD, Layout);
+ } else if ((Kind.isBSS() || Kind.isData()) && Symbol.isAlias()) {
+ // Alias to variable at the object file level.
+ // Not supported in RENT mode.
+ llvm_unreachable("Alias to rent variable is unsupported");
+ } else if (Kind.isBSS() || Kind.isData()) {
+ std::string SectionName = Section.getName().str();
+ GOFFSymbol SD = createSDSymbol(SectionName);
+ auto BindingScope = Symbol.isExternal()
+ ? (Symbol.isExported() ? GOFF::ESD_BSC_ImportExport
+ : GOFF::ESD_BSC_Library)
+ : GOFF::ESD_BSC_Section;
+ if (!Symbol.isExternal())
+ SD.BindingScope = GOFF::ESD_BSC_Section;
+
+ GOFFSymbol ED = createWSASymbol(SD.EsdId);
+ GOFFSymbol PR = createPRSymbol(SectionName, ED.EsdId);
+ ED.Alignment =
+ std::max(static_cast<GOFF::ESDAlignment>(Log2(Section.getAlign())),
+ GOFF::ESD_ALIGN_Quadword);
+
+ PR.Executable = GOFF::ESD_EXE_DATA;
+ PR.NameSpace = GOFF::ESD_NS_Parts;
+ PR.BindingScope = BindingScope;
+ PR.setAlignment(Symbol.getAlignment());
+ PR.SectionLength = Layout.getSectionAddressSize(&Section);
+
+ // As above, avoid zero-length sections for data.
+ if (!PR.SectionLength)
+ PR.SectionLength = 2;
+
+ writeSymbol(SD, Layout);
+ writeSymbol(ED, Layout);
+ writeSymbol(PR, Layout);
+
+ SymbolMap.insert(std::make_pair(&Symbol, PR.EsdId));
+ GOFFSection GoffSec = GOFFSection(PR.EsdId, PR.EsdId, SD.EsdId);
+ SectionMap.insert(std::make_pair(&Section, GoffSec));
+ } else
+ llvm_unreachable("Unhandled section kind for Symbol");
+}
+
+void GOFFObjectWriter::writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol,
+ MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ GOFFSymbol SD = RootSD;
+
+ GOFF::ESDExecutable Exec = Symbol.getExecutable();
+
+ GOFFSymbol GSym;
+ uint32_t GSymEsdId = 0;
+ switch (Exec) {
+ case GOFF::ESD_EXE_CODE:
+ case GOFF::ESD_EXE_Unspecified: {
+ bool IsIndirectSymbol = Symbol.hasAliasName();
+ GOFFSymbol ER = createERSymbol(IsIndirectSymbol ? Symbol.getAliasName()
+ : Symbol.getName(),
+ SD.EsdId, &Symbol);
+ ER.BindingScope = GOFF::ESD_BSC_ImportExport;
+ GSym.Indirect = IsIndirectSymbol;
+ GSym = ER;
+ GSymEsdId = ER.EsdId;
+ break;
+ }
+ case GOFF::ESD_EXE_DATA: {
+ GOFFSymbol ED = createWSASymbol(SD.EsdId);
+ ED.setAlignment(Symbol.getAlignment());
+ writeSymbol(ED, Layout);
+ GOFFSymbol PR = createPRSymbol(Symbol.getName(), ED.EsdId);
+ PR.BindingScope = GOFF::ESD_BSC_ImportExport;
+ PR.setAlignment(Symbol.getAlignment());
+ PR.NameSpace = GOFF::ESD_NS_Parts;
+ PR.SectionLength = 0;
+ GSym = PR;
+ GSymEsdId = PR.EsdId;
+ break;
+ }
+ }
+
+ GSym.BindingScope =
+ Symbol.isExported() ? GOFF::ESD_BSC_ImportExport : GOFF::ESD_BSC_Library;
+
+ SymbolMap.insert(std::make_pair(&Symbol, GSymEsdId));
+ writeSymbol(GSym, Layout);
+}
+
+void GOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ LLVM_DEBUG(dbgs() << "Entering " << __FUNCTION__ << "\n");
+
+ defineRootSD(Asm, Layout);
+}
+
void GOFFObjectWriter::writeHeader() {
OS.newRecord(GOFF::RT_HDR, /*Size=*/57);
OS.write_zeros(1); // Reserved
@@ -259,6 +633,411 @@ void GOFFObjectWriter::writeHeader() {
OS.write_zeros(6); // Reserved
}
+void GOFFObjectWriter::writeSymbol(const GOFFSymbol &Symbol,
+ const MCAsmLayout &Layout) {
+ uint32_t Offset = 0;
+ uint32_t Length = 0;
+ GOFF::ESDNameSpaceId NameSpaceId = GOFF::ESD_NS_ProgramManagementBinder;
+ Flags SymbolFlags;
+ uint8_t FillByteValue = 0;
+
+ Flags BehavAttrs[10] = {};
+ auto setAmode = [&BehavAttrs](GOFF::ESDAmode Amode) {
+ BehavAttrs[0].set(0, 8, Amode);
+ };
+ auto setRmode = [&BehavAttrs](GOFF::ESDRmode Rmode) {
+ BehavAttrs[1].set(0, 8, Rmode);
+ };
+ auto setTextStyle = [&BehavAttrs](GOFF::ESDTextStyle Style) {
+ BehavAttrs[2].set(0, 4, Style);
+ };
+ auto setBindingAlgorithm =
+ [&BehavAttrs](GOFF::ESDBindingAlgorithm Algorithm) {
+ BehavAttrs[2].set(4, 4, Algorithm);
+ };
+ auto setTaskingBehavior =
+ [&BehavAttrs](GOFF::ESDTaskingBehavior TaskingBehavior) {
+ BehavAttrs[3].set(0, 3, TaskingBehavior);
+ };
+ auto setReadOnly = [&BehavAttrs](bool ReadOnly) {
+ BehavAttrs[3].set(4, 1, ReadOnly);
+ };
+ auto setExecutable = [&BehavAttrs](GOFF::ESDExecutable Executable) {
+ BehavAttrs[3].set(5, 3, Executable);
+ };
+ auto setDuplicateSeverity =
+ [&BehavAttrs](GOFF::ESDDuplicateSymbolSeverity DSS) {
+ BehavAttrs[4].set(2, 2, DSS);
+ };
+ auto setBindingStrength = [&BehavAttrs](GOFF::ESDBindingStrength Strength) {
+ BehavAttrs[4].set(4, 4, Strength);
+ };
+ auto setLoadingBehavior = [&BehavAttrs](GOFF::ESDLoadingBehavior Behavior) {
+ BehavAttrs[5].set(0, 2, Behavior);
+ };
+ auto setIndirectReference = [&BehavAttrs](bool Indirect) {
+ uint8_t Value = Indirect ? 1 : 0;
+ BehavAttrs[5].set(3, 1, Value);
+ };
+ auto setBindingScope = [&BehavAttrs](GOFF::ESDBindingScope Scope) {
+ BehavAttrs[5].set(4, 4, Scope);
+ };
+ auto setLinkageType = [&BehavAttrs](GOFF::ESDLinkageType Type) {
+ BehavAttrs[6].set(2, 1, Type);
+ };
+ auto setAlignment = [&BehavAttrs](GOFF::ESDAlignment Alignment) {
+ BehavAttrs[6].set(3, 5, Alignment);
+ };
+
+ uint32_t AdaEsdId = 0;
+ uint32_t SortPriority = 0;
+
+ switch (Symbol.SymbolType) {
+ case GOFF::ESD_ST_SectionDefinition: {
+ if (Symbol.isExecutable()) // Unspecified otherwise
+ setTaskingBehavior(GOFF::ESD_TA_Rent);
+ if (Symbol.BindingScope == GOFF::ESD_BSC_Section)
+ setBindingScope(Symbol.BindingScope);
+ } break;
+ case GOFF::ESD_ST_ElementDefinition: {
+ SymbolFlags.set(3, 1, Symbol.isRemovable()); // Removable
+ if (Symbol.isExecutable()) {
+ setExecutable(GOFF::ESD_EXE_CODE);
+ setReadOnly(true);
+ } else {
+ if (Symbol.isExecUnspecified())
+ setExecutable(GOFF::ESD_EXE_Unspecified);
+ else
+ setExecutable(GOFF::ESD_EXE_DATA);
+
+ if (Symbol.isForceRent() || Symbol.isReadOnly()) // TODO
+ setReadOnly(true);
+ }
+ Offset = 0; // TODO ED and SD are 1-1 for now
+ setAlignment(Symbol.Alignment);
+ SymbolFlags.set(0, 1, 1); // Fill-Byte Value Presence Flag
+ FillByteValue = 0;
+ SymbolFlags.set(1, 1, 0); // Mangled Flag TODO ?
+ setAmode(Symbol.Amode);
+ setRmode(Symbol.Rmode);
+ setTextStyle(Symbol.TextStyle);
+ setBindingAlgorithm(Symbol.BindAlgorithm);
+ setLoadingBehavior(Symbol.LoadBehavior);
+ SymbolFlags.set(5, 3, GOFF::ESD_RQ_0); // Reserved Qwords
+ if (Symbol.isForceRent())
+ setReadOnly(true);
+ NameSpaceId = Symbol.NameSpace;
+ Length = Symbol.SectionLength;
+ break;
+ }
+ case GOFF::ESD_ST_LabelDefinition: {
+ if (Symbol.isExecutable())
+ setExecutable(GOFF::ESD_EXE_CODE);
+ else
+ setExecutable(GOFF::ESD_EXE_DATA);
+ setBindingStrength(Symbol.BindingStrength);
+ setLinkageType(Symbol.Linkage);
+ SymbolFlags.set(2, 1, Symbol.Renamable); // Renamable;
+ setAmode(Symbol.Amode);
+ NameSpaceId = Symbol.NameSpace;
+ setBindingScope(Symbol.BindingScope);
+ AdaEsdId = Symbol.ADAEsdId;
+
+ // Only symbol that doesn't have an MC is the SectionLabelSymbol which
+ // implicitly has 0 offset into the parent SD!
+ if (auto *MCSym = Symbol.MCSym) {
+ uint64_t Ofs = Layout.getSymbolOffset(*MCSym);
+ // We only have signed 32bits of offset!
+ assert(Ofs < (((uint64_t)1) << 31) && "ESD offset out of range.");
+ Offset = static_cast<uint32_t>(Ofs);
+ }
+ break;
+ }
+ case GOFF::ESD_ST_ExternalReference: {
+ setExecutable(Symbol.isExecutable() ? GOFF::ESD_EXE_CODE
+ : GOFF::ESD_EXE_DATA);
+ setBindingStrength(Symbol.BindingStrength);
+ setLinkageType(Symbol.Linkage);
+ SymbolFlags.set(2, 1, Symbol.Renamable); // Renamable;
+ setIndirectReference(Symbol.Indirect);
+ Offset = 0; // ERs don't do offsets
+ NameSpaceId = Symbol.NameSpace;
+ setBindingScope(Symbol.BindingScope);
+ setAmode(Symbol.Amode);
+ break;
+ }
+ case GOFF::ESD_ST_PartReference: {
+ setExecutable(Symbol.isExecutable() ? GOFF::ESD_EXE_CODE
+ : GOFF::ESD_EXE_DATA);
+ NameSpaceId = Symbol.NameSpace;
+ setAlignment(Symbol.Alignment);
+ setAmode(Symbol.Amode);
+ setLinkageType(Symbol.Linkage);
+ setBindingScope(Symbol.BindingScope);
+ SymbolFlags.set(2, 1, Symbol.Renamable); // Renamable;
+ setDuplicateSeverity(Symbol.isWeakRef() ? GOFF::ESD_DSS_NoWarning
+ : GOFF::ESD_DSS_Warning);
+ setIndirectReference(Symbol.Indirect);
+ setReadOnly(Symbol.ReadOnly);
+ SortPriority = Symbol.SortKey;
+
+ Length = Symbol.SectionLength;
+ break;
+ }
+ } // End switch
+
+ SmallString<256> Res;
+ ConverterEBCDIC::convertToEBCDIC(Symbol.Name, Res);
+ StringRef Name = Res.str();
+
+ // Assert here since this number is technically signed but we need uint for
+ // writing to records.
+ assert(Name.size() < GOFF::MaxDataLength &&
+ "Symbol max name length exceeded");
+ uint16_t NameLength = Name.size();
+
+ OS.newRecord(GOFF::RT_ESD, GOFF::ESDMetadataLength + NameLength);
+ 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>(Offset); // Offset or Address
+ OS.writebe<uint32_t>(0); // Reserved
+ OS.writebe<uint32_t>(Length); // Length
+ OS.writebe<uint32_t>(Symbol.EASectionEsdId); // Extended Attribute ESDID
+ OS.writebe<uint32_t>(Symbol.EASectionOffset); // Extended Attribute Offset
+ OS.writebe<uint32_t>(0); // Reserved
+ OS.writebe<uint8_t>(NameSpaceId); // Name Space ID
+ OS.writebe<uint8_t>(SymbolFlags); // Flags
+ OS.writebe<uint8_t>(FillByteValue); // Fill-Byte Value
+ OS.writebe<uint8_t>(0); // Reserved
+ OS.writebe<uint32_t>(AdaEsdId); // ADA ESDID
+ OS.writebe<uint32_t>(SortPriority); // Sort Priority
+ OS.writebe<uint64_t>(0); // Reserved
+ for (auto F : BehavAttrs)
+ OS.writebe<uint8_t>(F); // Behavioral Attributes
+ OS.writebe<uint16_t>(NameLength); // Name Length
+ OS.write(Name.data(), NameLength); // Name
+}
+
+void GOFFObjectWriter::writeADAandCodeSectionSymbols(
+ MCAssembler &Asm, const MCAsmLayout &Layout) {
+ // Write ESD Records for ADA Section
+ GOFFSymbol ADAED = createWSASymbol(RootSD.EsdId, true);
+ StringRef FileName = "";
+ if (!Asm.getFileNames().empty())
+ FileName = sys::path::stem((*(Asm.getFileNames().begin())).first);
+ std::pair<std::string, std::string> CsectNames = Asm.getCsectNames();
+
+ GOFFSymbol ADA;
+ if (CsectNames.second.empty()) {
+ ADA = createPRSymbol(FileName.str().append("#S"), ADAED.EsdId);
+ ADA.BindingScope = GOFF::ESD_BSC_Section;
+ } else {
+ ADA = createPRSymbol(CsectNames.second, ADAED.EsdId);
+ ADA.BindingScope = GOFF::ESD_BSC_Library;
+ }
+ ADA.Executable = GOFF::ESD_EXE_DATA;
+ ADA.NameSpace = GOFF::ESD_NS_Parts;
+ ADA.Alignment = GOFF::ESD_ALIGN_Quadword;
+
+ ADA.SectionLength = std::max(getADASectionLength(Asm, Layout), 2u);
+ writeSymbol(ADAED, Layout);
+ writeSymbol(ADA, Layout);
+
+ // Write ESD Records for Code Section
+ GOFFSymbol ED = createEDSymbol("C_CODE64", RootSD.EsdId);
+ ED.SectionLength = 0;
+ ED.Executable = GOFF::ESD_EXE_CODE;
+ ED.ForceRent = true;
+
+ for (const MCSection &MCSec : Asm) {
+ SectionKind Kind = MCSec.getKind();
+ if (Kind.isText()) {
+ if (!ED.SectionLength)
+ ED.SectionLength = Layout.getSectionAddressSize(&MCSec);
+ }
+ }
+
+ GOFFSymbol LD = createLDSymbol(RootSD.Name, ED.EsdId);
+ LD.Executable = GOFF::ESD_EXE_CODE;
+ if (RootSD.BindingScope == GOFF::ESD_BSC_Section)
+ LD.BindingScope = GOFF::ESD_BSC_Section;
+ else
+ LD.BindingScope = GOFF::ESD_BSC_Library;
+
+ LD.ADAEsdId = GOFFObjectWriter::ADAEsdId;
+
+ EntryEDEsdId = ED.EsdId;
+ CodeLDEsdId = LD.EsdId;
+ writeSymbol(ED, Layout);
+ writeSymbol(LD, Layout);
+}
+
+void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ bool IsOSLinkageType = false;
+ for (MCSection &S : Asm) {
+ auto &Section = cast<MCSectionGOFF>(S);
+ SectionKind Kind = Section.getKind();
+
+ if (Kind.isText()) {
+ // The only text section is the code section and the relevant ESD Records
+ // are already created. All we need to do is populate the SectionMap.
+ uint32_t RootSDEsdId = RootSD.EsdId;
+
+ GOFFSection GoffSec = GOFFSection(EntryEDEsdId, CodeLDEsdId, RootSDEsdId);
+ SectionMap.insert(std::make_pair(&Section, GoffSec));
+ } else if (Section.getName().starts_with(".lsda")) {
+ GOFFSymbol SD = RootSD;
+
+ const char *WSAClassName = "C_WSA64";
+ GOFFSymbol ED = createEDSymbol(WSAClassName, SD.EsdId);
+ if (IsOSLinkageType)
+ ED.LoadBehavior = GOFF::ESDLoadingBehavior::ESD_LB_Deferred;
+ ED.BindAlgorithm = GOFF::ESD_BA_Merge;
+ ED.Executable = GOFF::ESD_EXE_DATA;
+ ED.NameSpace = GOFF::ESD_NS_Parts;
+
+ GOFFSymbol PR = createPRSymbol(Section.getName(), ED.EsdId);
+ PR.Alignment = GOFF::ESD_ALIGN_Fullword;
+ PR.SectionLength = Layout.getSectionAddressSize(&Section);
+ PR.LoadBehavior = GOFF::ESD_LB_Deferred;
+ PR.NameSpace = GOFF::ESD_NS_Parts;
+ PR.BindingScope = GOFF::ESD_BSC_Section;
+
+ writeSymbol(ED, Layout);
+ writeSymbol(PR, Layout);
+
+ GOFFSection GoffSec = GOFFSection(PR.EsdId, PR.EsdId, SD.EsdId);
+ SectionMap.insert(std::make_pair(&Section, GoffSec));
+ } else if (Section.getName().equals(".ppa2list")) {
+ StringRef EDSectionName = "C_@@QPPA2";
+ StringRef PRSectionName = ".&ppa2";
+ GOFFSymbol SD = RootSD;
+ GOFFSymbol ED = createEDSymbol(EDSectionName, SD.EsdId);
+ GOFFSymbol PR = createPRSymbol(PRSectionName, ED.EsdId);
+
+ // Set namespace
+ ED.NameSpace = GOFF::ESD_NS_Parts;
+ ED.BindAlgorithm = GOFF::ESD_BA_Merge;
+ ED.Executable = GOFF::ESD_EXE_DATA;
+ ED.ReadOnly = true;
+
+ PR.SectionLength = Layout.getSectionAddressSize(&Section);
+ PR.NameSpace = GOFF::ESD_NS_Parts;
+ PR.BindingScope = GOFF::ESD_BSC_Section;
+ PR.Alignment = GOFF::ESD_ALIGN_Doubleword;
+ PR.Renamable = true;
+ PR.Linkage = GOFF::ESD_LT_OS;
+
+ writeSymbol(ED, Layout);
+ writeSymbol(PR, Layout);
+
+ GOFFSection GoffSec = GOFFSection(PR.EsdId, PR.EsdId, SD.EsdId);
+ SectionMap.insert(std::make_pair(&Section, GoffSec));
+ } else if (Section.getName().equals("B_IDRL")) {
+ GOFFSymbol SD = RootSD;
+ GOFFSymbol ED = createEDSymbol("B_IDRL", SD.EsdId);
+ ED.Executable = GOFF::ESD_EXE_Unspecified;
+ ED.BindingScope = GOFF::ESD_BSC_Module;
+ ED.NameSpace = GOFF::ESD_NS_NormalName;
+ ED.BindAlgorithm = GOFF::ESD_BA_Concatenate;
+ ED.ReadOnly = true;
+ ED.SectionLength = Layout.getSectionAddressSize(&Section);
+ ED.TextStyle = GOFF::ESD_TS_Structured;
+ ED.LoadBehavior = GOFF::ESD_LB_NoLoad;
+
+ writeSymbol(ED, Layout);
+
+ GOFFSection GoffSec = GOFFSection(ED.EsdId, 0, 0);
+ SectionMap.insert(std::make_pair(&Section, GoffSec));
+ } else if (Section.getName().equals(".ada")) {
+ GOFFSection GoffSec = GOFFSection(
+ GOFFObjectWriter::ADAEsdId, GOFFObjectWriter::ADAEsdId, RootSD.EsdId);
+ SectionMap.insert(std::make_pair(&Section, GoffSec));
+ } else if (Kind.isBSS() || Kind.isData() || Kind.isThreadData()) {
+ // We handle this with the symbol definition, so there is no need to do
+ // anything here.
+ } else {
+ llvm_unreachable("Unhandled section kind");
+ }
+ }
+}
+
+namespace {
+/// Adapter stream to write a text section.
+class TextStream : public raw_ostream {
+ /// The underlying GOFFOstream.
+ GOFFOstream &OS;
+
+ /// The buffer size is the maximum number of bytes in a TXT section.
+ static constexpr size_t BufferSize = GOFF::MaxDataLength;
+
+ /// Static allocated buffer for the stream, used by the raw_ostream class. The
+ /// buffer is sized to hold the payload of a logical TXT record.
+ char Buffer[BufferSize];
+
+ /// The offset for the next TXT record. This is equal to the number of bytes
+ /// written.
+ size_t Offset;
+
+ /// The Esdid of the GOFF section.
+ const uint32_t EsdId;
+
+ /// The record style.
+ const GOFF::TXTRecordStyle RecordStyle;
+
+ /// See raw_ostream::write_impl.
+ void write_impl(const char *Ptr, size_t Size) override;
+
+ uint64_t current_pos() const override { return Offset; }
+
+public:
+ explicit TextStream(GOFFOstream &OS, uint32_t EsdId,
+ GOFF::TXTRecordStyle RecordStyle)
+ : OS(OS), Offset(0), EsdId(EsdId), RecordStyle(RecordStyle) {
+ SetBuffer(Buffer, sizeof(Buffer));
+ }
+
+ ~TextStream() { flush(); }
+};
+
+void TextStream::write_impl(const char *Ptr, size_t Size) {
+ size_t WrittenLength = 0;
+
+ // We only have signed 32bits of offset.
+ if (Offset + Size > std::numeric_limits<int32_t>::max())
+ report_fatal_error("TXT section too large");
+
+ while (WrittenLength < Size) {
+ size_t ToWriteLength =
+ std::min(Size - WrittenLength, size_t(GOFF::MaxDataLength));
+
+ OS.newRecord(GOFF::RT_TXT, GOFF::TXTMetadataLength + ToWriteLength);
+ OS.writebe<uint8_t>(Flags(4, 4, RecordStyle)); // Text Record Style
+ OS.writebe<uint32_t>(EsdId); // Element ESDID
+ OS.writebe<uint32_t>(0); // Reserved
+ OS.writebe<uint32_t>(static_cast<uint32_t>(Offset)); // Offset
+ OS.writebe<uint32_t>(0); // Text Field True Length
+ OS.writebe<uint16_t>(0); // Text Encoding
+ OS.writebe<uint16_t>(ToWriteLength); // Data Length
+ OS.write(Ptr + WrittenLength, ToWriteLength); // Data
+
+ WrittenLength += ToWriteLength;
+ Offset += ToWriteLength;
+ }
+}
+} // namespace
+
+void GOFFObjectWriter::writeText(const MCSectionGOFF *MCSec, uint32_t EsdId,
+ bool IsStructured, MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ TextStream S(OS, EsdId,
+ IsStructured ? GOFF::TXT_RS_Structured : GOFF::TXT_RS_Byte);
+ Asm.writeSectionData(S, MCSec, Layout);
+}
+
void GOFFObjectWriter::writeEnd() {
uint8_t F = GOFF::END_EPR_None;
uint8_t AMODE = 0;
@@ -283,6 +1062,32 @@ uint64_t GOFFObjectWriter::writeObject(MCAssembler &Asm,
uint64_t StartOffset = OS.tell();
writeHeader();
+ writeSymbol(RootSD, Layout);
+
+ writeADAandCodeSectionSymbols(Asm, Layout);
+ writeSectionSymbols(Asm, Layout);
+
+ // Process all MCSymbols and generate the ESD Record(s) for them.
+ // Symbols that are aliases of other symbols need to be processed
+ // at the end, after the symbols they alias are processed.
+ for (const MCSymbol &MCSym : Asm.symbols()) {
+ if (!MCSym.isTemporary()) {
+ auto &Symbol = cast<MCSymbolGOFF>(MCSym);
+ if (Symbol.isDefined())
+ writeSymbolDefinedInModule(Symbol, Asm, Layout);
+ else
+ writeSymbolDeclaredInModule(Symbol, Asm, Layout);
+ }
+ }
+
+ for (auto GSecIter = SectionMap.begin(); GSecIter != SectionMap.end();
+ GSecIter++) {
+ auto &MCGOFFSec = cast<MCSectionGOFF>(*(GSecIter->first));
+ GOFFSection &CurrGSec = GSecIter->second;
+ bool IsStructured = MCGOFFSec.getName().equals("B_IDRL");
+ writeText(&MCGOFFSec, CurrGSec.PEsdId, IsStructured, Asm, Layout);
+ }
+
writeEnd();
LLVM_DEBUG(dbgs() << "Wrote " << OS.logicalRecords() << " logical records.");
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 58d13c9f378853..bc9a30c52c15f8 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -12,10 +12,18 @@
#include "llvm/MC/MCGOFFStreamer.h"
#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionGOFF.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Casting.h"
+
+#define DEBUG_TYPE "goff-streamer"
using namespace llvm;
@@ -32,3 +40,71 @@ MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
S->getAssembler().setRelaxAll(true);
return S;
}
+
+void MCGOFFStreamer::initSections(bool NoExecStack,
+ const MCSubtargetInfo &STI) {
+ MCContext &Ctx = getContext();
+ if (NoExecStack)
+ switchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
+ else
+ switchSection(Ctx.getObjectFileInfo()->getTextSection());
+}
+
+void MCGOFFStreamer::switchSection(MCSection *S, const MCExpr *Subsection) {
+ auto Section = cast<MCSectionGOFF>(S);
+ MCSection *Parent = Section->getParent();
+
+ if (Parent) {
+ const MCExpr *Subsection = Section->getSubsectionId();
+ assert(Subsection && "No subsection associated with child section");
+ this->MCObjectStreamer::switchSection(Parent, Subsection);
+ return;
+ }
+
+ this->MCObjectStreamer::switchSection(Section, Subsection);
+}
+
+bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
+ auto *Symbol = cast<MCSymbolGOFF>(S);
+
+ getAssembler().registerSymbol(*Symbol);
+
+ switch (Attribute) {
+ case MCSA_Global:
+ Symbol->setExternal(true);
+ break;
+ case MCSA_Local:
+ Symbol->setExternal(false);
+ break;
+ case MCSA_Hidden:
+ Symbol->setHidden(true);
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+void MCGOFFStreamer::emitInstToData(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ LLVM_DEBUG(dbgs() << "Entering " << __PRETTY_FUNCTION__ << "\n");
+ LLVM_DEBUG(dbgs() << "Inst: " << Inst << "\n");
+
+ MCAssembler &Assembler = getAssembler();
+ SmallVector<MCFixup, 4> Fixups;
+ SmallString<256> Code;
+ Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
+
+ // Bundling is not currently supported.
+ assert(!Assembler.isBundlingEnabled() && "Do not handle bundling yet");
+
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ // Add the fixups and data.
+ for (unsigned I = 0, E = Fixups.size(); I != E; ++I) {
+ Fixups[I].setOffset(Fixups[I].getOffset() + DF->getContents().size());
+ DF->getFixups().push_back(Fixups[I]);
+ }
+ DF->setHasInstructions(STI);
+ DF->getContents().append(Code.begin(), Code.end());
+}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 1f8f8ec5572759..b203f1a1945921 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -548,6 +548,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
Ctx->getGOFFSection(".text", SectionKind::getText(), nullptr, nullptr);
BSSSection =
Ctx->getGOFFSection(".bss", SectionKind::getBSS(), nullptr, nullptr);
+ ReadOnlySection =
+ Ctx->getGOFFSection(".rodata", SectionKind::getReadOnly(), TextSection,
+ MCConstantExpr::create(GOFF::SK_ReadOnly, *Ctx));
PPA1Section =
Ctx->getGOFFSection(".ppa1", SectionKind::getMetadata(), TextSection,
MCConstantExpr::create(GOFF::SK_PPA1, *Ctx));
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCExpr.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCExpr.cpp
index 647cf765c6a3ea..89a69d8140b8f3 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCExpr.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCExpr.cpp
@@ -17,6 +17,10 @@ const SystemZMCExpr *SystemZMCExpr::create(VariantKind Kind, const MCExpr *Expr,
return new (Ctx) SystemZMCExpr(Kind, Expr);
}
+const SystemZMCExpr *SystemZMCExpr::create(const MCExpr *Expr, MCContext &Ctx) {
+ return create(VK_SystemZ_None, Expr, Ctx);
+}
+
StringRef SystemZMCExpr::getVariantKindName() const {
switch (static_cast<uint32_t>(getKind())) {
case VK_SystemZ_None:
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCExpr.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCExpr.h
index 62e61091a14c64..b1372cafdd6f02 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCExpr.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCExpr.h
@@ -36,6 +36,8 @@ class SystemZMCExpr : public MCTargetExpr {
static const SystemZMCExpr *create(VariantKind Kind, const MCExpr *Expr,
MCContext &Ctx);
+ static const SystemZMCExpr *create(const MCExpr *Expr, MCContext &Ctx);
+
/// getOpcode - Get the kind of this expression.
VariantKind getKind() const { return Kind; }
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 5696ae117d69f0..46f126e061e15f 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -19,6 +19,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"
@@ -26,6 +27,7 @@
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/ConvertEBCDIC.h"
@@ -985,12 +987,12 @@ void SystemZAsmPrinter::emitADASection() {
const unsigned PointerSize = getDataLayout().getPointerSize();
OutStreamer->switchSection(getObjFileLowering().getADASection());
-
+ OutStreamer->emitLabel(ADASym);
unsigned EmittedBytes = 0;
for (auto &Entry : ADATable.getTable()) {
- const MCSymbol *Sym;
- unsigned SlotKind;
- std::tie(Sym, SlotKind) = Entry.first;
+ MCSymbolGOFF *Sym =
+ static_cast<MCSymbolGOFF *>(const_cast<MCSymbol *>(Entry.first.first));
+ unsigned SlotKind = Entry.first.second;
unsigned Offset = Entry.second;
assert(Offset == EmittedBytes && "Offset not as expected");
(void)EmittedBytes;
@@ -1014,6 +1016,8 @@ void SystemZAsmPrinter::emitADASection() {
MCSymbolRefExpr::create(Sym, OutContext),
OutContext),
PointerSize);
+ Sym->setExecutable(GOFF::ESD_EXE_CODE);
+ Sym->setTemporary(false);
EmittedBytes += PointerSize * 2;
break;
case SystemZII::MO_ADA_DATA_SYMBOL_ADDR:
@@ -1023,6 +1027,7 @@ void SystemZAsmPrinter::emitADASection() {
MCSymbolRefExpr::create(Sym, OutContext),
OutContext),
PointerSize);
+ Sym->setExecutable(GOFF::ESD_EXE_DATA);
EmittedBytes += PointerSize;
break;
case SystemZII::MO_ADA_INDIRECT_FUNC_DESC: {
@@ -1420,9 +1425,89 @@ void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) {
4);
}
+void SystemZAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
+ if (TM.getTargetTriple().isOSzOS()) {
+ auto *Sym = cast<MCSymbolGOFF>(getSymbol(GV));
+ Sym->setExecutable(GOFF::ESD_EXE_DATA);
+ }
+
+ return AsmPrinter::emitGlobalVariable(GV);
+}
+
+void SystemZAsmPrinter::emitGlobalAlias(const Module &M,
+ const GlobalAlias &GA) {
+ if (!TM.getTargetTriple().isOSzOS()) {
+ AsmPrinter::emitGlobalAlias(M, GA);
+ return;
+ }
+
+ MCSymbol *Name = getSymbol(&GA);
+ bool IsFunc = isa<Function>(GA.getAliasee()->stripPointerCasts());
+
+ if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective())
+ OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
+ else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage())
+ OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
+ else
+ assert(GA.hasLocalLinkage() && "Invalid alias linkage");
+
+ emitVisibility(Name, GA.getVisibility());
+
+ const MCExpr *Expr;
+
+ // For XPLINK, create a VCON relocation in case of a function, and
+ // a direct reference else.
+ MCSymbol *Sym = getSymbol(GA.getAliaseeObject());
+ if (IsFunc)
+ Expr = SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
+ MCSymbolRefExpr::create(Sym, OutContext),
+ OutContext);
+
+ else
+ Expr = MCSymbolRefExpr::create(Sym, OutContext);
+
+ OutStreamer->emitAssignment(Name, Expr);
+}
+
+const MCExpr *SystemZAsmPrinter::lowerConstant(const Constant *CV) {
+ const Triple &TargetTriple = TM.getTargetTriple();
+ if (TargetTriple.isOSzOS()) {
+ const GlobalAlias *GA = dyn_cast<GlobalAlias>(CV);
+ const Function *FV = dyn_cast<Function>(CV);
+ bool IsFunc = FV || (GA && isa<Function>(GA->getAliaseeObject()));
+ MCSymbolGOFF *Sym = nullptr;
+
+ if (auto GValue = dyn_cast<GlobalValue>(CV))
+ Sym = cast<MCSymbolGOFF>(getSymbol(GValue));
+ // TODO: Is it necessary to assert if CV is of type GlobalIFunc?
+
+ if (IsFunc) {
+ Sym->setExecutable(GOFF::ESD_EXE_CODE);
+ if (Sym->isExternal())
+ return SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
+ MCSymbolRefExpr::create(Sym, OutContext),
+ OutContext);
+ // Trigger creation of function descriptor in ADA for internal
+ // functions.
+ unsigned Disp = ADATable.insert(Sym, SystemZII::MO_ADA_DIRECT_FUNC_DESC);
+ return MCBinaryExpr::createAdd(
+ SystemZMCExpr::create(MCSymbolRefExpr::create(ADASym, OutContext),
+ OutContext),
+ MCConstantExpr::create(Disp, OutContext), OutContext);
+ } else if (Sym) {
+ Sym->setExecutable(GOFF::ESD_EXE_DATA);
+ return MCSymbolRefExpr::create(Sym, OutContext);
+ }
+ }
+
+ return AsmPrinter::lowerConstant(CV);
+}
+
void SystemZAsmPrinter::emitStartOfAsmFile(Module &M) {
- if (TM.getTargetTriple().isOSzOS())
+ if (TM.getTargetTriple().isOSzOS()) {
+ ADASym = OutContext.createTempSymbol("ada_sec_start");
emitPPA2(M);
+ }
AsmPrinter::emitStartOfAsmFile(M);
}
@@ -1433,6 +1518,10 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
// Make CELQSTRT symbol.
const char *StartSymbolName = "CELQSTRT";
MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
+ auto *GStartSym = static_cast<MCSymbolGOFF *>(CELQSTRT);
+ GStartSym->setExecutable(GOFF::ESD_EXE_CODE);
+ GStartSym->setOSLinkage();
+ GStartSym->setExternal(true);
// Create symbol and assign to class field for use in PPA1.
PPA2Sym = OutContext.createTempSymbol("PPA2", false);
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
index 303cce1a1b6581..5da1307571cc76 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
@@ -28,6 +28,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
MCSymbol *CurrentFnPPA1Sym; // PPA1 Symbol.
MCSymbol *CurrentFnEPMarkerSym; // Entry Point Marker.
MCSymbol *PPA2Sym;
+ MCSymbol *ADASym;
SystemZTargetStreamer *getTargetStreamer() {
MCTargetStreamer *TS = OutStreamer->getTargetStreamer();
@@ -117,6 +118,9 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
}
void emitFunctionEntryLabel() override;
void emitFunctionBodyEnd() override;
+ void emitGlobalVariable(const GlobalVariable *GV) override;
+ void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override;
+ const MCExpr *lowerConstant(const Constant *CV) override;
void emitStartOfAsmFile(Module &M) override;
private:
diff --git a/llvm/test/MC/GOFF/basic-goff-64.ll b/llvm/test/MC/GOFF/basic-goff-64.ll
new file mode 100644
index 00000000000000..555c3952e984f8
--- /dev/null
+++ b/llvm/test/MC/GOFF/basic-goff-64.ll
@@ -0,0 +1,252 @@
+; RUN: llc %s -mtriple s390x-ibm-zos -filetype=obj -o - | od -v -Ax -tx1 | FileCheck --ignore-case %s
+; REQUIRES: systemz-registered-target
+
+ at x = global i32 0, align 4
+ at y = internal global i32 1, align 4
+ at z = external global i32, align 4
+
+; Function Attrs: noinline nounwind optnone
+define hidden void @foo() {
+entry:
+ store i32 8200, ptr @x, align 4
+ %0 = load i32, ptr @x, align 4
+ store i32 2, ptr @y, align 4
+ store i32 100, ptr @z, align 4
+ call void @bar(i32 noundef signext %0)
+ ret void
+}
+
+declare void @bar(i32 noundef signext)
+
+; Records for basic-goff-64#C
+; Requires a continuation record due to the name's length. ESD items
+; with names of length greater than 8 require continuation records.
+; Byte 1 of the first record for this ESD entry is 0x01 to indicate
+; that this record is continued, and byte 2 of the second record
+; to indicate that this is the final continuation record.
+; Byte 3 of first record for this ESD entry is 0x00 to indicate
+; SD (Section Definition).
+; This is the "root" SD Node.
+; CHECK: 000050 03 01 00 00 00 00 00 01 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 60
+; CHECK: 000090 00 01 00 00 00 00 00 0f 82 81 a2 89 83 60 87 96
+; CHECK: 0000a0 03 02 00 86 86 60 f6 f4 7b c3 00 00 00 00 00 00
+; CHECK: 0000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+; The next two logical records represent the ADA.
+; Record for C_WSA64.
+; Byte 3 is 0x01 to indicate ED (Element Definition).
+; This represents the writable static area.
+; CHECK: 0000f0 03 00 00 01 00 00 00 02 00 00 00 01 00 00 00 00
+; CHECK: 000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000110 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK: 000120 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
+; CHECK: 000130 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
+; Records for basic-goff-64#S
+; Requires a continuation record.
+; Byte 3 is 0x03 to indicate PR (Part Reference).
+; This represents the ADA (associated data area).
+; CHECK: 000140 03 01 00 03 00 00 00 03 00 00 00 02 00 00 00 00
+; CHECK: 000150 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 00
+; CHECK: 000160 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK: 000170 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK: 000180 10 01 24 00 00 00 00 0f 82 81 a2 89 83 60 87 96
+; CHECK: 000190 03 02 00 86 86 60 f6 f4 7b e2 00 00 00 00 00 00
+; CHECK: 0001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0001c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+; The next two logical records represent the code section. Source
+; code and affiliated metadata (such as the PPA1 and PPA2 sections)
+; reside here.
+; Record for C_CODE64.
+; Byte 3 is 0x01 to indicate ED (Element Definition).
+; CHECK: 0001e0 03 00 00 01 00 00 00 04 00 00 00 01 00 00 00 00
+; CHECK: 0001f0 00 00 00 00 00 00 00 00 00 00 00 ac 00 00 00 00
+; CHECK: 000200 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00
+; CHECK: 000210 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a
+; CHECK: 000220 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4
+
+; Records for basic-goff-64#C. Note that names for ESD entries
+; need not be unique.
+; Byte 3 is 0x02 to indicate LD (Label Definition).
+; CHECK: 000230 03 01 00 02 00 00 00 05 00 00 00 04 00 00 00 00
+; CHECK: 000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000250 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 03
+; CHECK: 000260 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK: 000270 00 01 20 00 00 00 00 0f 82 81 a2 89 83 60 87 96
+; CHECK: 000280 03 02 00 86 86 60 f6 f4 7b c3 00 00 00 00 00 00
+; CHECK: 000290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0002a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0002b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0002c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+; Records for the C_@@QPPA2 section, which contains the offset
+; to the PPA2.
+; CHECK: 0002d0 03 01 00 01 00 00 00 06 00 00 00 01 00 00 00 00
+; CHECK: 0002e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0002f0 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK: 000300 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 09
+; CHECK: 000310 00 00 03 00 00 00 00 09 c3 6d 7c 7c d8 d7 d7 c1
+; CHECK: 000320 03 02 00 f2 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000370 03 00 00 03 00 00 00 07 00 00 00 06 00 00 00 00
+; CHECK: 000380 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00
+; CHECK: 000390 00 00 00 00 00 00 00 00 03 20 00 00 00 00 00 00
+; CHECK: 0003a0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK: 0003b0 10 01 03 00 00 00 00 06 4b 50 97 97 81 f2 00 00
+
+
+; Record for function foo().
+; Byte 3 is 0x02 to indicate LD.
+; This record is owned by ESD entry with ID 4, which is
+; C_CODE64. That is in turn owned by ESD entry with ID 1,
+; which is C_WSA64, which is owned by Section Definition
+; basic-goff-64#C. All functions in GOFF defined in the
+; compilation unit are defined in this manner.
+; Byte 63 is 0x02 = 0b00000010. Bits 5-7 indicate that
+; this record is executable, since it contains code. Note
+; that Bits 5-7 should be 001 if it is not executable and
+; 000 if executability is not specified.
+; Byte 65 is 0x03 = 0b00000011. Bits 4-7 indicate the
+; binding scope, which is library scope. This means
+; that symbol is NOT available fo dynamic binding. However,
+; it is still available for static linking. This is due to the
+; hidden attribute on the function definition.
+; Note that the symbol name is written beginning in byte
+; 72. 0x86 0x96 0x96 spell `foo` in EBCDIC encoding.
+; CHECK: 03 00 00 02 00 00 00 0a 00 00 00 04 00 00 00 00
+; CHECK: 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 03
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK: 00 03 20 00 00 00 00 03 86 96 96 00 00 00 00 00
+
+; Record for Section Definition for global variable x.
+; Note that all initialized global variables require their
+; own section definition. This includes functions defined in
+; this module. Note that bytes 4-7 indicate that ESDID is 9.
+; Byte 3 is 0x00 to indicate SD.
+; CHECK: 03 00 00 00 00 00 00 0b 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 01 a7 00 00 00 00 00 00 00
+
+; Record for C_WSA64 belonging to Section for global variable x.
+; Byte 3 is 0x01 to indicate ED.
+; Bytes 8-11 indicate that Parent ESDID is 9.
+; CHECK: 03 00 00 01 00 00 00 0c 00 00 00 0b 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
+; CHECK: 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
+; Record for PR of global variable x.
+; Byte 3 is 0x03 to indicate PR.
+; Bytes 8-11 indicate that Parent ESDID is A, the above
+; C_WSA64.
+; Byte 65 is 0x04 = 0b00000100. Bits 4-7 indicate the
+; binding scope, which is Import-Export scope. This means
+; that symbol is available for dynamic binding.
+; Byte 66 is 0x20 = 0b00100000. Bits 1-2 indicate the linkage.
+; In this case 0b01 indicates XPLINK.
+; CHECK: 03 00 00 03 00 00 00 0d 00 00 00 0c 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK: 10 04 20 00 00 00 00 01 a7 00 00 00 00 00 00 00
+
+; Global variable y works much like x, but with a few
+; differences:
+; y is explicitly listed as internal, so its binding scope is
+; set to B'0001 (Section Scope). This is true for the SD record
+; as well as the PR record.
+; CHECK: 03 00 00 00 00 00 00 0e 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 01 00 00 00 00 00 01 a8 00 00 00 00 00 00 00
+; CHECK: 03 00 00 01 00 00 00 0f 00 00 00 0e 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
+; CHECK: 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+; CHECK: 03 00 00 03 00 00 00 10 00 00 00 0f 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK: 10 01 20 00 00 00 00 01 a8 00 00 00 00 00 00 00
+
+
+; Record for C_WSA64. Child of section basic-goff-64#C
+; and contains an extern global variable. (z)
+; CHECK: 03 00 00 01 00 00 00 11 00 00 00 01 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 03 80 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01
+; CHECK: 00 40 00 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00
+
+
+; Record for external global variable z. This is NOT
+; initialized in this compilation unit and so unlike
+; global variable x, it lacks its own section definition.
+; Byte 3 is 0x03 to indicate PR.
+; Bytes 8-11 indicate that parent ESDID is 0d, which is
+; above C_WSA64.
+; Byte 65 is 0x04 = 0b00000100. Bits 4-7 indicate the
+; binding scope, which is Import-Export scope. This is
+; required because it is imported (not defined in this
+; module.
+; CHECK: 03 00 00 03 00 00 00 12 00 00 00 11 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01
+; CHECK: 10 04 20 00 00 00 00 01 a9 00 00 00 00 00 00 00
+
+
+; Record for externally defined function bar().
+; Byte 3 is 0x04 to indicate External Reference (ErWx).
+; Bytes 8-11 indicate that parent ESDID is 01, the section
+; definition for this module. (basic-goff-64#C).
+; Byte 65 indicates that the binding scope is Import-Export
+; Scope, since the definition may be something we dynamically
+; link against.
+; CHECK: 03 00 00 04 00 00 00 13 00 00 00 01 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK: 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK: 00 04 20 00 00 00 00 03 82 81 99 00 00 00 00 00
+
+
+; TXT Records:
+
+; TXT Record corresponding to global variable y.
+; Bytes 4-7 indicate that the owning ESD has ID 0x10. This is the
+; PR for global variable x.
+; Byte 22-23 contain the data length, which is 4, as expected for
+; an i32 type.
+; CHECK-DAG: 03 10 00 00 00 00 00 10 00 00 00 00 00 00 00 00
+
+; TXT Record corresponding to global variable x.
+; CHECK-DAG: 03 10 00 00 00 00 00 0d 00 00 00 00 00 00 00 00
+
+; TXT Record corresponding to the C_CODE64 Section.
+; This contains the bodies of the function(s) that make up
+; a module.
+; CHECK-DAG: 03 11 00 00 00 00 00 04 00 00 00 00 00 00 00 00
+
+; TXT Record containing ADA.
+; CHECK-DAG: 03 10 00 00 00 00 00 03 00 00 00 00 00 00 00 00
diff --git a/llvm/test/MC/GOFF/empty-goff.s b/llvm/test/MC/GOFF/empty-goff.s
index f6d402863d71c8..48f50581335483 100644
--- a/llvm/test/MC/GOFF/empty-goff.s
+++ b/llvm/test/MC/GOFF/empty-goff.s
@@ -2,23 +2,24 @@
* RUN: od -Ax -tx1 -v | FileCheck --ignore-case %s
* REQUIRES: systemz-registered-target
-* Header record:
-* 03 is prefix byte
-* f. is header type
-* .0 is version
-* The 1 at offset 51 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
+* Header record:
+* 03 is prefix byte
+* f. is header type
+* .0 is version
+* The 1 at offset 51 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
+
+** End record:
+** 03 is prefix byte
+** 4. is header type
+** .0 is version
+* CHECK: 0001e0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: 0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: 000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: 000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+* CHECK: 000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-* End record:
-* 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
>From 7cfcd12891ae0a92120803801fa83fb1df6f8e2c Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Mon, 25 Mar 2024 15:27:51 -0400
Subject: [PATCH 02/12] Don't hardcode EsdId for ADA PR symbol
---
llvm/lib/MC/GOFFObjectWriter.cpp | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 60ab410e9765e2..f20d4f07d3aab1 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -310,8 +310,8 @@ class GOFFObjectWriter : public MCObjectWriter {
// The target specific GOFF writer instance.
std::unique_ptr<MCGOFFObjectTargetWriter> TargetObjectWriter;
- /// Lookup table for MCSymbols to GOFFSymbols. Needed to determine EsdIds
- /// of symbols in Relocations.
+ /// Lookup table for MCSymbols to the ESD IDs of the associated
+ /// GOFF Symbol.
SymbolMapType SymbolMap;
/// Lookup table for MCSections to GOFFSections. Needed to determine
@@ -325,6 +325,7 @@ class GOFFObjectWriter : public MCObjectWriter {
// The "root" SD node. This should have ESDID = 1
GOFFSymbol RootSD;
+ uint32_t ADAPREsdId;
uint32_t EntryEDEsdId;
uint32_t CodeLDEsdId;
@@ -370,7 +371,7 @@ class GOFFObjectWriter : public MCObjectWriter {
GOFFSymbol createGOFFSymbol(StringRef Name, GOFF::ESDSymbolType Type,
uint32_t ParentEsdId);
GOFFSymbol createSDSymbol(StringRef Name);
- GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId);
+ GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId, GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
GOFFSymbol createLDSymbol(StringRef Name, uint32_t ParentEsdId);
GOFFSymbol createERSymbol(StringRef Name, uint32_t ParentEsdId,
const MCSymbolGOFF *Source = nullptr);
@@ -390,10 +391,6 @@ class GOFFObjectWriter : public MCObjectWriter {
void writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol, MCAssembler &Asm,
const MCAsmLayout &Layout);
- // In XPLINK, the ESD Record owning the ADA is always the 4th record, behind
- // the HDR record, the Root SD, and the ED symbol for the ADA, meaning it
- // always has EsdId = 3.
- static constexpr uint32_t ADAEsdId = 3u;
};
} // end anonymous namespace
@@ -408,11 +405,12 @@ GOFFSymbol GOFFObjectWriter::createSDSymbol(StringRef Name) {
}
GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name,
- uint32_t ParentEsdId) {
+ uint32_t ParentEsdId,
+ GOFF::ESDAlignment Alignment) {
GOFFSymbol ED =
createGOFFSymbol(Name, GOFF::ESD_ST_ElementDefinition, ParentEsdId);
- ED.Alignment = GOFF::ESD_ALIGN_Doubleword;
+ ED.Alignment = Alignment;
return ED;
}
@@ -517,7 +515,7 @@ void GOFFObjectWriter::writeSymbolDefinedInModule(const MCSymbolGOFF &Symbol,
: GOFF::ESD_BSC_Module))
: GOFF::ESD_BSC_Section;
- LD.ADAEsdId = GOFFObjectWriter::ADAEsdId;
+ LD.ADAEsdId = ADAPREsdId;
if (Symbol.getName().equals("main")) {
LD.BindingScope = GOFF::ESD_BSC_Library;
@@ -585,7 +583,6 @@ void GOFFObjectWriter::writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol,
: Symbol.getName(),
SD.EsdId, &Symbol);
ER.BindingScope = GOFF::ESD_BSC_ImportExport;
- GSym.Indirect = IsIndirectSymbol;
GSym = ER;
GSymEsdId = ER.EsdId;
break;
@@ -710,7 +707,7 @@ void GOFFObjectWriter::writeSymbol(const GOFFSymbol &Symbol,
else
setExecutable(GOFF::ESD_EXE_DATA);
- if (Symbol.isForceRent() || Symbol.isReadOnly()) // TODO
+ if (Symbol.isForceRent() || Symbol.isReadOnly())
setReadOnly(true);
}
Offset = 0; // TODO ED and SD are 1-1 for now
@@ -724,8 +721,6 @@ void GOFFObjectWriter::writeSymbol(const GOFFSymbol &Symbol,
setBindingAlgorithm(Symbol.BindAlgorithm);
setLoadingBehavior(Symbol.LoadBehavior);
SymbolFlags.set(5, 3, GOFF::ESD_RQ_0); // Reserved Qwords
- if (Symbol.isForceRent())
- setReadOnly(true);
NameSpaceId = Symbol.NameSpace;
Length = Symbol.SectionLength;
break;
@@ -844,6 +839,7 @@ void GOFFObjectWriter::writeADAandCodeSectionSymbols(
ADA.SectionLength = std::max(getADASectionLength(Asm, Layout), 2u);
writeSymbol(ADAED, Layout);
writeSymbol(ADA, Layout);
+ ADAPREsdId = ADA.EsdId;
// Write ESD Records for Code Section
GOFFSymbol ED = createEDSymbol("C_CODE64", RootSD.EsdId);
@@ -866,7 +862,7 @@ void GOFFObjectWriter::writeADAandCodeSectionSymbols(
else
LD.BindingScope = GOFF::ESD_BSC_Library;
- LD.ADAEsdId = GOFFObjectWriter::ADAEsdId;
+ LD.ADAEsdId = ADAPREsdId;
EntryEDEsdId = ED.EsdId;
CodeLDEsdId = LD.EsdId;
@@ -954,7 +950,7 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
SectionMap.insert(std::make_pair(&Section, GoffSec));
} else if (Section.getName().equals(".ada")) {
GOFFSection GoffSec = GOFFSection(
- GOFFObjectWriter::ADAEsdId, GOFFObjectWriter::ADAEsdId, RootSD.EsdId);
+ ADAPREsdId, ADAPREsdId, RootSD.EsdId);
SectionMap.insert(std::make_pair(&Section, GoffSec));
} else if (Kind.isBSS() || Kind.isData() || Kind.isThreadData()) {
// We handle this with the symbol definition, so there is no need to do
>From ee9fb0b0c3181dbcbca203b37fe4df25a876b141 Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Tue, 26 Mar 2024 11:16:46 -0400
Subject: [PATCH 03/12] Add more 'constructors' (not really) for ED and PR
Symbols
---
llvm/lib/MC/GOFFObjectWriter.cpp | 176 +++++++++++++++++--------------
llvm/lib/MC/MCGOFFStreamer.cpp | 1 -
2 files changed, 98 insertions(+), 79 deletions(-)
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index f20d4f07d3aab1..85fac8694e94f6 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -274,13 +274,15 @@ class GOFFSymbol {
(BindingScope == GOFF::ESD_BSC_ImportExport);
}
- void setAlignment(Align A) {
+ static GOFF::ESDAlignment setGOFFAlignment(Align A) {
// The GOFF alignment is encoded as log_2 value.
+ GOFF::ESDAlignment Alignment;
uint8_t Log = Log2(A);
if (Log <= GOFF::ESD_ALIGN_4Kpage)
Alignment = static_cast<GOFF::ESDAlignment>(Log);
else
llvm_unreachable("Unsupported alignment");
+ return Alignment;
}
};
@@ -366,26 +368,35 @@ class GOFFObjectWriter : public MCObjectWriter {
uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
private:
- GOFFSection *createGOFFSection(GOFFSymbol *Pptr, GOFFSymbol *Rptr,
- GOFFSymbol *SD, const MCSectionGOFF *MC);
GOFFSymbol createGOFFSymbol(StringRef Name, GOFF::ESDSymbolType Type,
uint32_t ParentEsdId);
GOFFSymbol createSDSymbol(StringRef Name);
GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId, GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
+ GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
+ GOFF::ESDExecutable Executable, bool ForceRent,
+ GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
+ GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
+ GOFF::ESDExecutable Executable, GOFF::ESDBindingScope BindingScope,
+ GOFF::ESDNameSpaceId NameSpaceId, GOFF::ESDBindingAlgorithm BindingAlgorithm,
+ bool ReadOnly, GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior,
+ GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
GOFFSymbol createLDSymbol(StringRef Name, uint32_t ParentEsdId);
GOFFSymbol createERSymbol(StringRef Name, uint32_t ParentEsdId,
const MCSymbolGOFF *Source = nullptr);
GOFFSymbol createPRSymbol(StringRef Name, uint32_t ParentEsdId);
-
+ GOFFSymbol createPRSymbol(StringRef Name, uint32_t ParentEsdId,
+ GOFF::ESDNameSpaceId NameSpaceType,
+ GOFF::ESDExecutable Executable,
+ GOFF::ESDAlignment Alignment,
+ GOFF::ESDBindingScope BindingScope,
+ uint32_t SectionLength,
+ GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial,
+ GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink);
GOFFSymbol createWSASymbol(uint32_t ParentEsdId, bool ReserveQWords = false);
// Define the root SD node as well as the symbols that make up the
// ADA section.
void defineRootSD(MCAssembler &Asm, const MCAsmLayout &Layout);
-
- void defineSectionSymbols(const MCAssembler &Asm,
- const MCSectionGOFF &Section,
- const MCAsmLayout &Layout);
void writeSymbolDefinedInModule(const MCSymbolGOFF &Symbol, MCAssembler &Asm,
const MCAsmLayout &Layout);
void writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol, MCAssembler &Asm,
@@ -414,6 +425,35 @@ GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name,
return ED;
}
+GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
+ GOFF::ESDExecutable Executable, bool ForceRent,
+ GOFF::ESDAlignment Alignment) {
+ GOFFSymbol ED = createGOFFSymbol(Name, GOFF::ESD_ST_ElementDefinition, ParentEsdId);
+ ED.SectionLength = 0;
+ ED.Executable = Executable;
+ ED.ForceRent = ForceRent;
+ ED.Alignment = Alignment;
+ return ED;
+}
+
+GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
+ GOFF::ESDExecutable Executable, GOFF::ESDBindingScope BindingScope,
+ GOFF::ESDNameSpaceId NameSpaceId, GOFF::ESDBindingAlgorithm BindingAlgorithm,
+ bool ReadOnly, GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior,
+ GOFF::ESDAlignment Alignment) {
+ GOFFSymbol ED = createGOFFSymbol(Name, GOFF::ESD_ST_ElementDefinition, ParentEsdId);
+ ED.SectionLength = 0;
+ ED.Executable = Executable;
+ ED.BindingScope = BindingScope;
+ ED.NameSpace = NameSpaceId;
+ ED.BindAlgorithm = BindingAlgorithm;
+ ED.ReadOnly = ReadOnly;
+ ED.TextStyle = TextStyle;
+ ED.LoadBehavior = LoadBehavior;
+ ED.Alignment = Alignment;
+ return ED;
+}
+
GOFFSymbol GOFFObjectWriter::createLDSymbol(StringRef Name,
uint32_t ParentEsdId) {
return createGOFFSymbol(Name, GOFF::ESD_ST_LabelDefinition, ParentEsdId);
@@ -445,6 +485,26 @@ GOFFSymbol GOFFObjectWriter::createPRSymbol(StringRef Name,
return createGOFFSymbol(Name, GOFF::ESD_ST_PartReference, ParentEsdId);
}
+GOFFSymbol GOFFObjectWriter::createPRSymbol(StringRef Name, uint32_t ParentEsdId,
+ GOFF::ESDNameSpaceId NameSpaceType,
+ GOFF::ESDExecutable Executable,
+ GOFF::ESDAlignment Alignment,
+ GOFF::ESDBindingScope BindingScope,
+ uint32_t SectionLength,
+ GOFF::ESDLoadingBehavior LoadBehavior,
+ GOFF::ESDLinkageType Linkage) {
+ GOFFSymbol PR = createGOFFSymbol(Name, GOFF::ESD_ST_PartReference, ParentEsdId);
+ PR.NameSpace = NameSpaceType;
+ PR.Executable = Executable;
+ PR.Alignment = Alignment;
+ PR.BindingScope = BindingScope;
+ PR.SectionLength = SectionLength;
+ PR.LoadBehavior = LoadBehavior;
+ PR.Linkage = Linkage;
+ return PR;
+}
+
+
GOFFSymbol GOFFObjectWriter::createWSASymbol(uint32_t ParentEsdId,
bool ReserveQwords) {
const char *WSAClassName = "C_WSA64";
@@ -540,21 +600,13 @@ void GOFFObjectWriter::writeSymbolDefinedInModule(const MCSymbolGOFF &Symbol,
SD.BindingScope = GOFF::ESD_BSC_Section;
GOFFSymbol ED = createWSASymbol(SD.EsdId);
- GOFFSymbol PR = createPRSymbol(SectionName, ED.EsdId);
+ uint32_t PRSectionLen = Layout.getSectionAddressSize(&Section) ? Layout.getSectionAddressSize(&Section) : 0;
+ GOFFSymbol PR = createPRSymbol(SectionName, ED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA,
+ GOFFSymbol::setGOFFAlignment(Symbol.getAlignment()), BindingScope, PRSectionLen);
ED.Alignment =
std::max(static_cast<GOFF::ESDAlignment>(Log2(Section.getAlign())),
GOFF::ESD_ALIGN_Quadword);
- PR.Executable = GOFF::ESD_EXE_DATA;
- PR.NameSpace = GOFF::ESD_NS_Parts;
- PR.BindingScope = BindingScope;
- PR.setAlignment(Symbol.getAlignment());
- PR.SectionLength = Layout.getSectionAddressSize(&Section);
-
- // As above, avoid zero-length sections for data.
- if (!PR.SectionLength)
- PR.SectionLength = 2;
-
writeSymbol(SD, Layout);
writeSymbol(ED, Layout);
writeSymbol(PR, Layout);
@@ -589,13 +641,10 @@ void GOFFObjectWriter::writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol,
}
case GOFF::ESD_EXE_DATA: {
GOFFSymbol ED = createWSASymbol(SD.EsdId);
- ED.setAlignment(Symbol.getAlignment());
+ ED.Alignment = GOFFSymbol::setGOFFAlignment(Symbol.getAlignment());
writeSymbol(ED, Layout);
- GOFFSymbol PR = createPRSymbol(Symbol.getName(), ED.EsdId);
- PR.BindingScope = GOFF::ESD_BSC_ImportExport;
- PR.setAlignment(Symbol.getAlignment());
- PR.NameSpace = GOFF::ESD_NS_Parts;
- PR.SectionLength = 0;
+ GOFFSymbol PR = createPRSymbol(Symbol.getName(), ED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_Unspecified,
+ GOFFSymbol::setGOFFAlignment(Symbol.getAlignment()), GOFF::ESD_BSC_ImportExport, 0);
GSym = PR;
GSymEsdId = PR.EsdId;
break;
@@ -826,26 +875,16 @@ void GOFFObjectWriter::writeADAandCodeSectionSymbols(
GOFFSymbol ADA;
if (CsectNames.second.empty()) {
- ADA = createPRSymbol(FileName.str().append("#S"), ADAED.EsdId);
- ADA.BindingScope = GOFF::ESD_BSC_Section;
+ ADA = createPRSymbol(FileName.str().append("#S"), ADAED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA, GOFF::ESD_ALIGN_Quadword, GOFF::ESD_BSC_Section, std::max(getADASectionLength(Asm, Layout), 2u));
} else {
- ADA = createPRSymbol(CsectNames.second, ADAED.EsdId);
- ADA.BindingScope = GOFF::ESD_BSC_Library;
+ ADA = createPRSymbol(CsectNames.second, ADAED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA, GOFF::ESD_ALIGN_Quadword, GOFF::ESD_BSC_Library, std::max(getADASectionLength(Asm, Layout), 2u));
}
- ADA.Executable = GOFF::ESD_EXE_DATA;
- ADA.NameSpace = GOFF::ESD_NS_Parts;
- ADA.Alignment = GOFF::ESD_ALIGN_Quadword;
-
- ADA.SectionLength = std::max(getADASectionLength(Asm, Layout), 2u);
writeSymbol(ADAED, Layout);
writeSymbol(ADA, Layout);
ADAPREsdId = ADA.EsdId;
// Write ESD Records for Code Section
- GOFFSymbol ED = createEDSymbol("C_CODE64", RootSD.EsdId);
- ED.SectionLength = 0;
- ED.Executable = GOFF::ESD_EXE_CODE;
- ED.ForceRent = true;
+ GOFFSymbol ED = createEDSymbol("C_CODE64", RootSD.EsdId, 0, GOFF::ESD_EXE_CODE, true);
for (const MCSection &MCSec : Asm) {
SectionKind Kind = MCSec.getKind();
@@ -872,7 +911,6 @@ void GOFFObjectWriter::writeADAandCodeSectionSymbols(
void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
const MCAsmLayout &Layout) {
- bool IsOSLinkageType = false;
for (MCSection &S : Asm) {
auto &Section = cast<MCSectionGOFF>(S);
SectionKind Kind = Section.getKind();
@@ -888,19 +926,14 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
GOFFSymbol SD = RootSD;
const char *WSAClassName = "C_WSA64";
- GOFFSymbol ED = createEDSymbol(WSAClassName, SD.EsdId);
- if (IsOSLinkageType)
- ED.LoadBehavior = GOFF::ESDLoadingBehavior::ESD_LB_Deferred;
- ED.BindAlgorithm = GOFF::ESD_BA_Merge;
- ED.Executable = GOFF::ESD_EXE_DATA;
- ED.NameSpace = GOFF::ESD_NS_Parts;
-
- GOFFSymbol PR = createPRSymbol(Section.getName(), ED.EsdId);
- PR.Alignment = GOFF::ESD_ALIGN_Fullword;
- PR.SectionLength = Layout.getSectionAddressSize(&Section);
- PR.LoadBehavior = GOFF::ESD_LB_Deferred;
- PR.NameSpace = GOFF::ESD_NS_Parts;
- PR.BindingScope = GOFF::ESD_BSC_Section;
+ GOFFSymbol ED = createEDSymbol(WSAClassName, SD.EsdId, 0, GOFF::ESD_EXE_DATA,
+ GOFF::ESD_BSC_Unspecified, GOFF::ESD_NS_Parts,
+ GOFF::ESD_BA_Merge, /*ReadOnly*/false,
+ GOFF::ESD_TS_Unstructured, GOFF::ESD_LB_Initial);
+ GOFFSymbol PR = createPRSymbol(Section.getName(), ED.EsdId, GOFF::ESD_NS_Parts,
+ GOFF::ESD_EXE_Unspecified, GOFF::ESD_ALIGN_Fullword,
+ GOFF::ESD_BSC_Section, Layout.getSectionAddressSize(&Section),
+ GOFF::ESD_LB_Deferred);
writeSymbol(ED, Layout);
writeSymbol(PR, Layout);
@@ -911,22 +944,15 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
StringRef EDSectionName = "C_@@QPPA2";
StringRef PRSectionName = ".&ppa2";
GOFFSymbol SD = RootSD;
- GOFFSymbol ED = createEDSymbol(EDSectionName, SD.EsdId);
- GOFFSymbol PR = createPRSymbol(PRSectionName, ED.EsdId);
-
- // Set namespace
- ED.NameSpace = GOFF::ESD_NS_Parts;
- ED.BindAlgorithm = GOFF::ESD_BA_Merge;
- ED.Executable = GOFF::ESD_EXE_DATA;
- ED.ReadOnly = true;
-
- PR.SectionLength = Layout.getSectionAddressSize(&Section);
- PR.NameSpace = GOFF::ESD_NS_Parts;
- PR.BindingScope = GOFF::ESD_BSC_Section;
- PR.Alignment = GOFF::ESD_ALIGN_Doubleword;
- PR.Renamable = true;
- PR.Linkage = GOFF::ESD_LT_OS;
-
+ GOFFSymbol ED = createEDSymbol(EDSectionName, SD.EsdId, 0, GOFF::ESD_EXE_DATA,
+ GOFF::ESD_BSC_Unspecified, GOFF::ESD_NS_Parts,
+ GOFF::ESD_BA_Merge, /*ReadOnly*/ true, GOFF::ESD_TS_Unstructured,
+ GOFF::ESD_LB_Initial);
+ Align A = Align(Layout.getSectionAddressSize(&Section));
+ GOFFSymbol PR = createPRSymbol(PRSectionName, ED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_Unspecified,
+ GOFF::ESD_ALIGN_Doubleword, GOFF::ESD_BSC_Section,
+ GOFFSymbol::setGOFFAlignment(A),
+ GOFF::ESD_LB_Initial, GOFF::ESD_LT_OS);
writeSymbol(ED, Layout);
writeSymbol(PR, Layout);
@@ -934,16 +960,10 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
SectionMap.insert(std::make_pair(&Section, GoffSec));
} else if (Section.getName().equals("B_IDRL")) {
GOFFSymbol SD = RootSD;
- GOFFSymbol ED = createEDSymbol("B_IDRL", SD.EsdId);
- ED.Executable = GOFF::ESD_EXE_Unspecified;
- ED.BindingScope = GOFF::ESD_BSC_Module;
- ED.NameSpace = GOFF::ESD_NS_NormalName;
- ED.BindAlgorithm = GOFF::ESD_BA_Concatenate;
- ED.ReadOnly = true;
- ED.SectionLength = Layout.getSectionAddressSize(&Section);
- ED.TextStyle = GOFF::ESD_TS_Structured;
- ED.LoadBehavior = GOFF::ESD_LB_NoLoad;
-
+ GOFFSymbol ED = createEDSymbol("B_IDRL", SD.EsdId, Layout.getSectionAddressSize(&Section),
+ GOFF::ESD_EXE_Unspecified, GOFF::ESD_BSC_Module,
+ GOFF::ESD_NS_NormalName, GOFF::ESD_BA_Concatenate,
+ /*ReadOnly*/ true, GOFF::ESD_TS_Structured, GOFF::ESD_LB_NoLoad);
writeSymbol(ED, Layout);
GOFFSection GoffSec = GOFFSection(ED.EsdId, 0, 0);
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index bc9a30c52c15f8..39c01df2105383 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -87,7 +87,6 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
void MCGOFFStreamer::emitInstToData(const MCInst &Inst,
const MCSubtargetInfo &STI) {
- LLVM_DEBUG(dbgs() << "Entering " << __PRETTY_FUNCTION__ << "\n");
LLVM_DEBUG(dbgs() << "Inst: " << Inst << "\n");
MCAssembler &Assembler = getAssembler();
>From 3e2e318da980836548031b1c7ca5c3eddb73e370 Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Tue, 26 Mar 2024 23:18:57 -0400
Subject: [PATCH 04/12] Add some attributes to a MCGOFFSection, maybe we can
avoid checking names in the GOFFWriter
---
llvm/include/llvm/MC/MCSectionGOFF.h | 29 +++++++++++++++++++++++++++-
llvm/lib/MC/MCContext.cpp | 18 +++++++++++++++--
2 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index d866329461ceae..43612a45966942 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -24,13 +24,35 @@ namespace llvm {
class MCExpr;
class MCSectionGOFF final : public MCSection {
+ enum GOFFSectionType {
+ /// Code - This section belongs to the the Code CSECT.
+ Code,
+
+ /// Static - This section belongs to the Static CSECT.
+ Static,
+
+ /// PPA2Offset - This section contains the offset to the PPA2.
+ /// Note: This is NOT the PPA2 section itself, which should
+ /// reside within the Code CSECT.
+ PPA2Offset,
+
+ /// B_IDRL - What is this section again?
+ B_IDRL,
+
+ /// Other - All other sections.
+ Other,
+ };
private:
MCSection *Parent;
const MCExpr *SubsectionId;
+ GOFFSectionType Type;
friend class MCContext;
MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub)
- : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub) {}
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Other) {}
+
+ MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFFSectionType Type)
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Type) {}
public:
void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
@@ -43,6 +65,11 @@ class MCSectionGOFF final : public MCSection {
bool isVirtualSection() const override { return false; }
+ bool isCode() const { return Type == Code; }
+ bool isStatic() const { return Type == Static; }
+ bool isPPA2Offset() const { return Type == PPA2Offset; }
+ bool isB_IDRL() const { return Type == B_IDRL; }
+
MCSection *getParent() const { return Parent; }
const MCExpr *getSubsectionId() const { return SubsectionId; }
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index ba5cefaf18c1fd..e13b478d8c21de 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -657,8 +657,22 @@ MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
return Iter->second;
StringRef CachedName = Iter->first;
- MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId);
+ MCSectionGOFF *GOFFSection;
+ if (Kind.isText())
+ GOFFSection = new (GOFFAllocator.Allocate())
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, MCSectionGOFF::Code);
+ else if (Section.equals(".ada"))
+ GOFFSection = new (GOFFAllocator.Allocate())
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, MCSectionGOFF::Static);
+ else if (Section.equals(".ppa2list"))
+ GOFFSection = new (GOFFAllocator.Allocate())
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, MCSectionGOFF::PPA2Offset);
+ else if (Section.equals(".B_IDRL"))
+ GOFFSection = new (GOFFAllocator.Allocate())
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, MCSectionGOFF::B_IDRL);
+ else
+ GOFFSection = new (GOFFAllocator.Allocate())
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId);
Iter->second = GOFFSection;
return GOFFSection;
>From c9728f8cee0a45386d9bcc9dab6d4c9e286ea09c Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Wed, 27 Mar 2024 09:40:26 -0400
Subject: [PATCH 05/12] Add Class attributes as class attributes.
---
llvm/include/llvm/MC/MCSectionGOFF.h | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 43612a45966942..995d1f7d97dc89 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -10,6 +10,12 @@
/// This file declares the MCSectionGOFF class, which contains all of the
/// necessary machine code sections for the GOFF file format.
///
+/// GOFF doesn't truly have sections in the way object file formats on unix
+/// such as ELF does, so MCSectionGOFF (more or less) represents a Class in GOFF.
+/// A GOFF Class is defined by a tuple of ESD symbols; specifically a SD symbol,
+/// an ED symbol, and PR or LD symbols. One of these symbols (PR or ED) must be
+/// the owner of a TXT record, which contains the actual contents of this Class.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSECTIONGOFF_H
@@ -36,23 +42,38 @@ class MCSectionGOFF final : public MCSection {
/// reside within the Code CSECT.
PPA2Offset,
- /// B_IDRL - What is this section again?
+ /// B_IDRL -
B_IDRL,
/// Other - All other sections.
Other,
};
+
private:
MCSection *Parent;
const MCExpr *SubsectionId;
GOFFSectionType Type;
+ GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented;
+ GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial;
friend class MCContext;
MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub)
: MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Other) {}
+ MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior)
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Other),
+ TextStyle(TextStyle), LoadBehavior(LoadBehavior) {}
+
MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFFSectionType Type)
- : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Type) {}
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Type) {
+ if (Type == GOFFSectionType::PPA2Offset) {
+ TextStyle = GOFF::ESD_TS_ByteOriented;
+ }
+ else if (Type == GOFFSectionType::B_IDRL) {
+ TextStyle = GOFF::ESD_TS_Structured;
+ LoadBehavior = GOFF::ESD_LB_NoLoad;
+ }
+ }
public:
void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
>From 3f1b6db9cbb44dbf4a499e273c5ce74fcc396801 Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Wed, 27 Mar 2024 10:04:59 -0400
Subject: [PATCH 06/12] Try using the new MCSection attributes
---
llvm/lib/MC/GOFFObjectWriter.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 85fac8694e94f6..32fd261ff9272a 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -940,7 +940,7 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
GOFFSection GoffSec = GOFFSection(PR.EsdId, PR.EsdId, SD.EsdId);
SectionMap.insert(std::make_pair(&Section, GoffSec));
- } else if (Section.getName().equals(".ppa2list")) {
+ } else if (Section.isPPA2Offset()) {
StringRef EDSectionName = "C_@@QPPA2";
StringRef PRSectionName = ".&ppa2";
GOFFSymbol SD = RootSD;
@@ -958,7 +958,7 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
GOFFSection GoffSec = GOFFSection(PR.EsdId, PR.EsdId, SD.EsdId);
SectionMap.insert(std::make_pair(&Section, GoffSec));
- } else if (Section.getName().equals("B_IDRL")) {
+ } else if (Section.isB_IDRL()) {
GOFFSymbol SD = RootSD;
GOFFSymbol ED = createEDSymbol("B_IDRL", SD.EsdId, Layout.getSectionAddressSize(&Section),
GOFF::ESD_EXE_Unspecified, GOFF::ESD_BSC_Module,
>From c4fd23b29af81371b28a1d69506913c653f88d80 Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Wed, 27 Mar 2024 17:17:02 -0400
Subject: [PATCH 07/12] Change factory methods for creating GOFF Sections in
MCContext
---
llvm/include/llvm/BinaryFormat/GOFF.h | 20 +++++++
llvm/include/llvm/MC/MCContext.h | 8 ++-
llvm/include/llvm/MC/MCSectionGOFF.h | 53 +++++++------------
.../CodeGen/TargetLoweringObjectFileImpl.cpp | 3 +-
llvm/lib/MC/MCContext.cpp | 31 ++++++++---
5 files changed, 73 insertions(+), 42 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index b0cd2484536ea2..94e8a59b60bed8 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -173,6 +173,26 @@ enum SubsectionKind : uint8_t {
SK_PPA1 = 2,
SK_PPA2 = 4,
};
+
+// \brief Type of sections (properly - classes or modules) in the object file.
+enum GOFFSectionType : uint8_t {
+ /// Code - This section belongs to the the Code CSECT.
+ Code,
+
+ /// Static - This section belongs to the Static CSECT.
+ Static,
+
+ /// PPA2Offset - This section contains the offset to the PPA2.
+ /// Note: This is NOT the PPA2 section itself, which should
+ /// reside within the Code CSECT.
+ PPA2Offset,
+
+ /// B_IDRL -
+ B_IDRL,
+
+ /// Other - All other sections.
+ Other,
+};
} // end namespace GOFF
} // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index e9c7c96298d683..a8c324904f4a5d 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/MC/MCAsmMacro.h"
#include "llvm/MC/MCDwarf.h"
@@ -622,9 +623,14 @@ class MCContext {
unsigned Flags,
unsigned EntrySize);
+ MCSectionGOFF *getGOFFLSDASection(StringRef Section, SectionKind Kind);
+
MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind,
MCSection *Parent = nullptr,
- const MCExpr *SubsectionId = nullptr);
+ const MCExpr *SubsectionId = nullptr,
+ GOFF::GOFFSectionType SectionType = GOFF::Other,
+ GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented,
+ GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial);
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName,
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 995d1f7d97dc89..6c8f466771325b 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -10,7 +10,7 @@
/// This file declares the MCSectionGOFF class, which contains all of the
/// necessary machine code sections for the GOFF file format.
///
-/// GOFF doesn't truly have sections in the way object file formats on unix
+/// GOFF doesn't truly have sections in the way object file formats on Unix
/// such as ELF does, so MCSectionGOFF (more or less) represents a Class in GOFF.
/// A GOFF Class is defined by a tuple of ESD symbols; specifically a SD symbol,
/// an ED symbol, and PR or LD symbols. One of these symbols (PR or ED) must be
@@ -30,46 +30,29 @@ namespace llvm {
class MCExpr;
class MCSectionGOFF final : public MCSection {
- enum GOFFSectionType {
- /// Code - This section belongs to the the Code CSECT.
- Code,
-
- /// Static - This section belongs to the Static CSECT.
- Static,
-
- /// PPA2Offset - This section contains the offset to the PPA2.
- /// Note: This is NOT the PPA2 section itself, which should
- /// reside within the Code CSECT.
- PPA2Offset,
-
- /// B_IDRL -
- B_IDRL,
-
- /// Other - All other sections.
- Other,
- };
-
-private:
MCSection *Parent;
const MCExpr *SubsectionId;
- GOFFSectionType Type;
+ GOFF::GOFFSectionType Type = GOFF::Other;
GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented;
GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial;
+ /// IsRooted - true iff the SD symbol used to define the GOFF Class this MCSectionGOFF represents is the "root" SD symbol.
+ bool IsRooted = false;
+
friend class MCContext;
MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub)
- : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Other) {}
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub) {}
- MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior)
- : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Other),
- TextStyle(TextStyle), LoadBehavior(LoadBehavior) {}
+ MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior, bool IsRooted)
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub),
+ TextStyle(TextStyle), LoadBehavior(LoadBehavior), IsRooted(IsRooted) {}
- MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFFSectionType Type)
+ MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFF::GOFFSectionType Type)
: MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Type) {
- if (Type == GOFFSectionType::PPA2Offset) {
+ if (Type == GOFF::GOFFSectionType::PPA2Offset) {
TextStyle = GOFF::ESD_TS_ByteOriented;
}
- else if (Type == GOFFSectionType::B_IDRL) {
+ else if (Type == GOFF::GOFFSectionType::B_IDRL) {
TextStyle = GOFF::ESD_TS_Structured;
LoadBehavior = GOFF::ESD_LB_NoLoad;
}
@@ -86,10 +69,14 @@ class MCSectionGOFF final : public MCSection {
bool isVirtualSection() const override { return false; }
- bool isCode() const { return Type == Code; }
- bool isStatic() const { return Type == Static; }
- bool isPPA2Offset() const { return Type == PPA2Offset; }
- bool isB_IDRL() const { return Type == B_IDRL; }
+ bool isCode() const { return Type == GOFF::Code; }
+ bool isStatic() const { return Type == GOFF::Static; }
+ bool isPPA2Offset() const { return Type == GOFF::PPA2Offset; }
+ bool isB_IDRL() const { return Type == GOFF::B_IDRL; }
+
+ GOFF::ESDTextStyle getTextStyle() const { return TextStyle; }
+ GOFF::ESDLoadingBehavior getLoadBehavior() const { return LoadBehavior; }
+ bool getRooted() const { return IsRooted; }
MCSection *getParent() const { return Parent; }
const MCExpr *getSubsectionId() const { return SubsectionId; }
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 3b4f7faa99d590..8aaadd6be21c7f 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2737,8 +2737,7 @@ 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,
- nullptr);
+ return getContext().getGOFFLSDASection(Name, SectionKind::getData());
}
MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index e13b478d8c21de..8d8e9b0e17e4f4 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -646,9 +646,28 @@ MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
: std::nullopt;
}
+MCSectionGOFF *MCContext::getGOFFLSDASection(StringRef Section, SectionKind Kind) {
+ // 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 Iter = IterBool.first;
+ if (!IterBool.second)
+ return Iter->second;
+
+ StringRef CachedName = Iter->first;
+ MCSectionGOFF *GOFFSection;
+ GOFFSection = new (GOFFAllocator.Allocate())
+ MCSectionGOFF(CachedName, Kind, nullptr, nullptr, GOFF::ESD_TS_Unstructured, GOFF::ESD_LB_Deferred, true);
+ Iter->second = GOFFSection;
+ return GOFFSection;
+}
+
MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
MCSection *Parent,
- const MCExpr *SubsectionId) {
+ const MCExpr *SubsectionId,
+ GOFF::GOFFSectionType SectionType,
+ GOFF::ESDTextStyle TextStyle,
+ GOFF::ESDLoadingBehavior LoadBehavior) {
// Do the lookup. If we don't have a hit, return a new section.
auto IterBool =
GOFFUniquingMap.insert(std::make_pair(Section.str(), nullptr));
@@ -660,16 +679,16 @@ MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
MCSectionGOFF *GOFFSection;
if (Kind.isText())
GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, MCSectionGOFF::Code);
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, GOFF::GOFFSectionType::Code);
else if (Section.equals(".ada"))
GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, MCSectionGOFF::Static);
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, GOFF::GOFFSectionType::Static);
else if (Section.equals(".ppa2list"))
GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, MCSectionGOFF::PPA2Offset);
- else if (Section.equals(".B_IDRL"))
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, GOFF::GOFFSectionType::PPA2Offset);
+ else if (Section.equals("B_IDRL"))
GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, MCSectionGOFF::B_IDRL);
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, GOFF::GOFFSectionType::B_IDRL);
else
GOFFSection = new (GOFFAllocator.Allocate())
MCSectionGOFF(CachedName, Kind, Parent, SubsectionId);
>From 07c88d402c0577b7c1fd2f00bd2bfbe8da21aaee Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Fri, 29 Mar 2024 15:23:43 -0400
Subject: [PATCH 08/12] Use new interface for making MCSectionGOFFs, no more
looking at the names of things
---
llvm/include/llvm/MC/MCContext.h | 20 ++++++++++++++-
llvm/include/llvm/MC/MCSymbolGOFF.h | 2 --
llvm/lib/MC/GOFFObjectWriter.cpp | 4 +--
llvm/lib/MC/MCContext.cpp | 25 ++++++-------------
llvm/lib/MC/MCObjectFileInfo.cpp | 8 +++---
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 1 -
6 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index a8c324904f4a5d..3a7aa83e43afda 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -293,6 +293,24 @@ class MCContext {
}
};
+ struct GOFFSectionKey {
+ std::string SectionName;
+ GOFF::GOFFSectionType SectionType;
+ bool HasParentSection;
+
+ GOFFSectionKey(StringRef SectionName, GOFF::GOFFSectionType SectionType,
+ bool HasParentSection)
+ : SectionName(SectionName), SectionType(SectionType),
+ HasParentSection(HasParentSection) {}
+
+ bool operator<(const GOFFSectionKey &Other) const {
+ if (!HasParentSection && SectionType != GOFF::GOFFSectionType::Other) {
+ return SectionType < Other.SectionType;
+ }
+ return SectionName < Other.SectionName;
+ }
+ };
+
struct WasmSectionKey {
std::string SectionName;
StringRef GroupName;
@@ -346,7 +364,7 @@ class MCContext {
StringMap<MCSectionMachO *> MachOUniquingMap;
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
- std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
+ std::map<GOFFSectionKey, MCSectionGOFF *> GOFFUniquingMap;
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
StringMap<MCSectionDXContainer *> DXCUniquingMap;
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index bb3c3b07947aa3..9aa7928cdfacc4 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -43,8 +43,6 @@ class MCSymbolGOFF : public MCSymbol {
void setAliasName(StringRef Name) { AliasName = Name; }
StringRef getAliasName() const { return AliasName; }
- void setTemporary(bool Value) { IsTemporary = Value; }
-
void setOSLinkage(bool Value = true) const {
modifyFlags(Value ? SF_OSLinkage : 0, SF_OSLinkage);
}
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 32fd261ff9272a..54734585124e2a 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -915,7 +915,7 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
auto &Section = cast<MCSectionGOFF>(S);
SectionKind Kind = Section.getKind();
- if (Kind.isText()) {
+ if (Section.isCode()) {
// The only text section is the code section and the relevant ESD Records
// are already created. All we need to do is populate the SectionMap.
uint32_t RootSDEsdId = RootSD.EsdId;
@@ -968,7 +968,7 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
GOFFSection GoffSec = GOFFSection(ED.EsdId, 0, 0);
SectionMap.insert(std::make_pair(&Section, GoffSec));
- } else if (Section.getName().equals(".ada")) {
+ } else if (Section.isStatic()) {
GOFFSection GoffSec = GOFFSection(
ADAPREsdId, ADAPREsdId, RootSD.EsdId);
SectionMap.insert(std::make_pair(&Section, GoffSec));
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 8d8e9b0e17e4f4..95b26cfefd5288 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -648,13 +648,13 @@ MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
MCSectionGOFF *MCContext::getGOFFLSDASection(StringRef Section, SectionKind Kind) {
// 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(
+ GOFFSectionKey{Section.str(), GOFF::GOFFSectionType::Other, false}, nullptr));
auto Iter = IterBool.first;
if (!IterBool.second)
return Iter->second;
- StringRef CachedName = Iter->first;
+ auto CachedName = Iter->first.SectionName;
MCSectionGOFF *GOFFSection;
GOFFSection = new (GOFFAllocator.Allocate())
MCSectionGOFF(CachedName, Kind, nullptr, nullptr, GOFF::ESD_TS_Unstructured, GOFF::ESD_LB_Deferred, true);
@@ -669,26 +669,17 @@ MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
GOFF::ESDTextStyle TextStyle,
GOFF::ESDLoadingBehavior LoadBehavior) {
// 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(
+ GOFFSectionKey{Section.str(), GOFF::GOFFSectionType::Other, false}, nullptr));
auto Iter = IterBool.first;
if (!IterBool.second)
return Iter->second;
- StringRef CachedName = Iter->first;
+ StringRef CachedName = Iter->first.SectionName;
MCSectionGOFF *GOFFSection;
- if (Kind.isText())
- GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, GOFF::GOFFSectionType::Code);
- else if (Section.equals(".ada"))
- GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, GOFF::GOFFSectionType::Static);
- else if (Section.equals(".ppa2list"))
- GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, GOFF::GOFFSectionType::PPA2Offset);
- else if (Section.equals("B_IDRL"))
+ if (SectionType != GOFF::GOFFSectionType::Other)
GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, GOFF::GOFFSectionType::B_IDRL);
+ MCSectionGOFF(CachedName, Kind, Parent, SubsectionId, SectionType);
else
GOFFSection = new (GOFFAllocator.Allocate())
MCSectionGOFF(CachedName, Kind, Parent, SubsectionId);
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index b203f1a1945921..ee7b103972164f 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -545,7 +545,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
TextSection =
- Ctx->getGOFFSection(".text", SectionKind::getText(), nullptr, nullptr);
+ Ctx->getGOFFSection(".text", SectionKind::getText(), nullptr, nullptr, GOFF::GOFFSectionType::Code);
BSSSection =
Ctx->getGOFFSection(".bss", SectionKind::getBSS(), nullptr, nullptr);
ReadOnlySection =
@@ -556,16 +556,16 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
MCConstantExpr::create(GOFF::SK_PPA1, *Ctx));
PPA2Section =
Ctx->getGOFFSection(".ppa2", SectionKind::getMetadata(), TextSection,
- MCConstantExpr::create(GOFF::SK_PPA2, *Ctx));
+ MCConstantExpr::create(GOFF::SK_PPA2, *Ctx), GOFF::GOFFSectionType::PPA2Offset);
PPA2ListSection =
Ctx->getGOFFSection(".ppa2list", SectionKind::getData(),
nullptr, nullptr);
ADASection =
- Ctx->getGOFFSection(".ada", SectionKind::getData(), nullptr, nullptr);
+ Ctx->getGOFFSection(".ada", SectionKind::getText(), nullptr, nullptr, GOFF::GOFFSectionType::Static);
IDRLSection =
- Ctx->getGOFFSection("B_IDRL", SectionKind::getData(), nullptr, nullptr);
+ Ctx->getGOFFSection("B_IDRL", SectionKind::getData(), nullptr, nullptr, GOFF::GOFFSectionType::B_IDRL);
}
void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 46f126e061e15f..c3341f7c850d68 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1017,7 +1017,6 @@ void SystemZAsmPrinter::emitADASection() {
OutContext),
PointerSize);
Sym->setExecutable(GOFF::ESD_EXE_CODE);
- Sym->setTemporary(false);
EmittedBytes += PointerSize * 2;
break;
case SystemZII::MO_ADA_DATA_SYMBOL_ADDR:
>From 4739ff3f07ba5376dd5546f7da1c0811629aa94f Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Mon, 1 Apr 2024 12:18:17 -0400
Subject: [PATCH 09/12] Remove main handling for now. We need the CELQ* stuff
to properly use it anyways and we can add it there
---
llvm/lib/MC/GOFFObjectWriter.cpp | 5 -----
1 file changed, 5 deletions(-)
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 54734585124e2a..9808c1aad8d0d7 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -577,11 +577,6 @@ void GOFFObjectWriter::writeSymbolDefinedInModule(const MCSymbolGOFF &Symbol,
LD.ADAEsdId = ADAPREsdId;
- if (Symbol.getName().equals("main")) {
- LD.BindingScope = GOFF::ESD_BSC_Library;
- LD.Renamable = true;
- }
-
LD.MCSym = &Symbol;
SymbolMap.insert(std::make_pair(&Symbol, LD.EsdId));
writeSymbol(LD, Layout);
>From 57f954d53e8fdd1fd01146f6dc2bce6fc30c925b Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Mon, 1 Apr 2024 12:42:13 -0400
Subject: [PATCH 10/12] Apply clang format
---
llvm/include/llvm/BinaryFormat/GOFF.h | 4 +-
llvm/include/llvm/MC/MCContext.h | 17 +--
llvm/include/llvm/MC/MCSectionGOFF.h | 39 ++++---
llvm/lib/MC/GOFFObjectWriter.cpp | 159 +++++++++++++++-----------
llvm/lib/MC/MCContext.cpp | 22 ++--
llvm/lib/MC/MCObjectFileInfo.cpp | 15 +--
6 files changed, 144 insertions(+), 112 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index 94e8a59b60bed8..9b4c17dee7576a 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -187,12 +187,12 @@ enum GOFFSectionType : uint8_t {
/// reside within the Code CSECT.
PPA2Offset,
- /// B_IDRL -
+ /// B_IDRL -
B_IDRL,
/// Other - All other sections.
Other,
-};
+};
} // end namespace GOFF
} // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 3a7aa83e43afda..6430120a082748 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -295,14 +295,14 @@ class MCContext {
struct GOFFSectionKey {
std::string SectionName;
- GOFF::GOFFSectionType SectionType;
+ GOFF::GOFFSectionType SectionType;
bool HasParentSection;
GOFFSectionKey(StringRef SectionName, GOFF::GOFFSectionType SectionType,
bool HasParentSection)
: SectionName(SectionName), SectionType(SectionType),
HasParentSection(HasParentSection) {}
-
+
bool operator<(const GOFFSectionKey &Other) const {
if (!HasParentSection && SectionType != GOFF::GOFFSectionType::Other) {
return SectionType < Other.SectionType;
@@ -643,12 +643,13 @@ class MCContext {
MCSectionGOFF *getGOFFLSDASection(StringRef Section, SectionKind Kind);
- MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind,
- MCSection *Parent = nullptr,
- const MCExpr *SubsectionId = nullptr,
- GOFF::GOFFSectionType SectionType = GOFF::Other,
- GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented,
- GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial);
+ MCSectionGOFF *
+ getGOFFSection(StringRef Section, SectionKind Kind,
+ MCSection *Parent = nullptr,
+ const MCExpr *SubsectionId = nullptr,
+ GOFF::GOFFSectionType SectionType = GOFF::Other,
+ GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented,
+ GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial);
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName,
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 6c8f466771325b..2c0860dadabe11 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -11,10 +11,11 @@
/// necessary machine code sections for the GOFF file format.
///
/// GOFF doesn't truly have sections in the way object file formats on Unix
-/// such as ELF does, so MCSectionGOFF (more or less) represents a Class in GOFF.
-/// A GOFF Class is defined by a tuple of ESD symbols; specifically a SD symbol,
-/// an ED symbol, and PR or LD symbols. One of these symbols (PR or ED) must be
-/// the owner of a TXT record, which contains the actual contents of this Class.
+/// such as ELF does, so MCSectionGOFF (more or less) represents a Class in
+/// GOFF. A GOFF Class is defined by a tuple of ESD symbols; specifically a SD
+/// symbol, an ED symbol, and PR or LD symbols. One of these symbols (PR or ED)
+/// must be the owner of a TXT record, which contains the actual contents of
+/// this Class.
///
//===----------------------------------------------------------------------===//
@@ -36,27 +37,31 @@ class MCSectionGOFF final : public MCSection {
GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented;
GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial;
- /// IsRooted - true iff the SD symbol used to define the GOFF Class this MCSectionGOFF represents is the "root" SD symbol.
+ /// IsRooted - true iff the SD symbol used to define the GOFF Class this
+ /// MCSectionGOFF represents is the "root" SD symbol.
bool IsRooted = false;
friend class MCContext;
MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub)
: MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub) {}
- MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior, bool IsRooted)
- : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub),
+ MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub,
+ GOFF::ESDTextStyle TextStyle,
+ GOFF::ESDLoadingBehavior LoadBehavior, bool IsRooted)
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub),
TextStyle(TextStyle), LoadBehavior(LoadBehavior), IsRooted(IsRooted) {}
- MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub, GOFF::GOFFSectionType Type)
- : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub), Type(Type) {
- if (Type == GOFF::GOFFSectionType::PPA2Offset) {
- TextStyle = GOFF::ESD_TS_ByteOriented;
- }
- else if (Type == GOFF::GOFFSectionType::B_IDRL) {
- TextStyle = GOFF::ESD_TS_Structured;
- LoadBehavior = GOFF::ESD_LB_NoLoad;
- }
- }
+ MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub,
+ GOFF::GOFFSectionType Type)
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub),
+ Type(Type) {
+ if (Type == GOFF::GOFFSectionType::PPA2Offset) {
+ TextStyle = GOFF::ESD_TS_ByteOriented;
+ } else if (Type == GOFF::GOFFSectionType::B_IDRL) {
+ TextStyle = GOFF::ESD_TS_Structured;
+ LoadBehavior = GOFF::ESD_LB_NoLoad;
+ }
+ }
public:
void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 9808c1aad8d0d7..0e940768567deb 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -371,27 +371,31 @@ class GOFFObjectWriter : public MCObjectWriter {
GOFFSymbol createGOFFSymbol(StringRef Name, GOFF::ESDSymbolType Type,
uint32_t ParentEsdId);
GOFFSymbol createSDSymbol(StringRef Name);
- GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId, GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
- GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
- GOFF::ESDExecutable Executable, bool ForceRent,
- GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
- GOFFSymbol createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
- GOFF::ESDExecutable Executable, GOFF::ESDBindingScope BindingScope,
- GOFF::ESDNameSpaceId NameSpaceId, GOFF::ESDBindingAlgorithm BindingAlgorithm,
- bool ReadOnly, GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior,
- GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
+ GOFFSymbol
+ createEDSymbol(StringRef Name, uint32_t ParentEsdId,
+ GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
+ GOFFSymbol
+ createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
+ GOFF::ESDExecutable Executable, bool ForceRent,
+ GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
+ GOFFSymbol createEDSymbol(
+ StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
+ GOFF::ESDExecutable Executable, GOFF::ESDBindingScope BindingScope,
+ GOFF::ESDNameSpaceId NameSpaceId,
+ GOFF::ESDBindingAlgorithm BindingAlgorithm, bool ReadOnly,
+ GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior,
+ GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword);
GOFFSymbol createLDSymbol(StringRef Name, uint32_t ParentEsdId);
GOFFSymbol createERSymbol(StringRef Name, uint32_t ParentEsdId,
const MCSymbolGOFF *Source = nullptr);
GOFFSymbol createPRSymbol(StringRef Name, uint32_t ParentEsdId);
- GOFFSymbol createPRSymbol(StringRef Name, uint32_t ParentEsdId,
- GOFF::ESDNameSpaceId NameSpaceType,
- GOFF::ESDExecutable Executable,
- GOFF::ESDAlignment Alignment,
- GOFF::ESDBindingScope BindingScope,
- uint32_t SectionLength,
- GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial,
- GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink);
+ GOFFSymbol
+ createPRSymbol(StringRef Name, uint32_t ParentEsdId,
+ GOFF::ESDNameSpaceId NameSpaceType,
+ GOFF::ESDExecutable Executable, GOFF::ESDAlignment Alignment,
+ GOFF::ESDBindingScope BindingScope, uint32_t SectionLength,
+ GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial,
+ GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink);
GOFFSymbol createWSASymbol(uint32_t ParentEsdId, bool ReserveQWords = false);
// Define the root SD node as well as the symbols that make up the
@@ -401,7 +405,6 @@ class GOFFObjectWriter : public MCObjectWriter {
const MCAsmLayout &Layout);
void writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol, MCAssembler &Asm,
const MCAsmLayout &Layout);
-
};
} // end anonymous namespace
@@ -425,10 +428,14 @@ GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name,
return ED;
}
-GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
- GOFF::ESDExecutable Executable, bool ForceRent,
- GOFF::ESDAlignment Alignment) {
- GOFFSymbol ED = createGOFFSymbol(Name, GOFF::ESD_ST_ElementDefinition, ParentEsdId);
+GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name,
+ uint32_t ParentEsdId,
+ uint32_t SectionLength,
+ GOFF::ESDExecutable Executable,
+ bool ForceRent,
+ GOFF::ESDAlignment Alignment) {
+ GOFFSymbol ED =
+ createGOFFSymbol(Name, GOFF::ESD_ST_ElementDefinition, ParentEsdId);
ED.SectionLength = 0;
ED.Executable = Executable;
ED.ForceRent = ForceRent;
@@ -436,12 +443,15 @@ GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name, uint32_t ParentEsdId
return ED;
}
-GOFFSymbol GOFFObjectWriter::createEDSymbol(StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
- GOFF::ESDExecutable Executable, GOFF::ESDBindingScope BindingScope,
- GOFF::ESDNameSpaceId NameSpaceId, GOFF::ESDBindingAlgorithm BindingAlgorithm,
- bool ReadOnly, GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior,
- GOFF::ESDAlignment Alignment) {
- GOFFSymbol ED = createGOFFSymbol(Name, GOFF::ESD_ST_ElementDefinition, ParentEsdId);
+GOFFSymbol GOFFObjectWriter::createEDSymbol(
+ StringRef Name, uint32_t ParentEsdId, uint32_t SectionLength,
+ GOFF::ESDExecutable Executable, GOFF::ESDBindingScope BindingScope,
+ GOFF::ESDNameSpaceId NameSpaceId,
+ GOFF::ESDBindingAlgorithm BindingAlgorithm, bool ReadOnly,
+ GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior,
+ GOFF::ESDAlignment Alignment) {
+ GOFFSymbol ED =
+ createGOFFSymbol(Name, GOFF::ESD_ST_ElementDefinition, ParentEsdId);
ED.SectionLength = 0;
ED.Executable = Executable;
ED.BindingScope = BindingScope;
@@ -485,15 +495,13 @@ GOFFSymbol GOFFObjectWriter::createPRSymbol(StringRef Name,
return createGOFFSymbol(Name, GOFF::ESD_ST_PartReference, ParentEsdId);
}
-GOFFSymbol GOFFObjectWriter::createPRSymbol(StringRef Name, uint32_t ParentEsdId,
- GOFF::ESDNameSpaceId NameSpaceType,
- GOFF::ESDExecutable Executable,
- GOFF::ESDAlignment Alignment,
- GOFF::ESDBindingScope BindingScope,
- uint32_t SectionLength,
- GOFF::ESDLoadingBehavior LoadBehavior,
- GOFF::ESDLinkageType Linkage) {
- GOFFSymbol PR = createGOFFSymbol(Name, GOFF::ESD_ST_PartReference, ParentEsdId);
+GOFFSymbol GOFFObjectWriter::createPRSymbol(
+ StringRef Name, uint32_t ParentEsdId, GOFF::ESDNameSpaceId NameSpaceType,
+ GOFF::ESDExecutable Executable, GOFF::ESDAlignment Alignment,
+ GOFF::ESDBindingScope BindingScope, uint32_t SectionLength,
+ GOFF::ESDLoadingBehavior LoadBehavior, GOFF::ESDLinkageType Linkage) {
+ GOFFSymbol PR =
+ createGOFFSymbol(Name, GOFF::ESD_ST_PartReference, ParentEsdId);
PR.NameSpace = NameSpaceType;
PR.Executable = Executable;
PR.Alignment = Alignment;
@@ -504,7 +512,6 @@ GOFFSymbol GOFFObjectWriter::createPRSymbol(StringRef Name, uint32_t ParentEsdId
return PR;
}
-
GOFFSymbol GOFFObjectWriter::createWSASymbol(uint32_t ParentEsdId,
bool ReserveQwords) {
const char *WSAClassName = "C_WSA64";
@@ -595,9 +602,13 @@ void GOFFObjectWriter::writeSymbolDefinedInModule(const MCSymbolGOFF &Symbol,
SD.BindingScope = GOFF::ESD_BSC_Section;
GOFFSymbol ED = createWSASymbol(SD.EsdId);
- uint32_t PRSectionLen = Layout.getSectionAddressSize(&Section) ? Layout.getSectionAddressSize(&Section) : 0;
- GOFFSymbol PR = createPRSymbol(SectionName, ED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA,
- GOFFSymbol::setGOFFAlignment(Symbol.getAlignment()), BindingScope, PRSectionLen);
+ uint32_t PRSectionLen = Layout.getSectionAddressSize(&Section)
+ ? Layout.getSectionAddressSize(&Section)
+ : 0;
+ GOFFSymbol PR = createPRSymbol(
+ SectionName, ED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA,
+ GOFFSymbol::setGOFFAlignment(Symbol.getAlignment()), BindingScope,
+ PRSectionLen);
ED.Alignment =
std::max(static_cast<GOFF::ESDAlignment>(Log2(Section.getAlign())),
GOFF::ESD_ALIGN_Quadword);
@@ -638,8 +649,11 @@ void GOFFObjectWriter::writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol,
GOFFSymbol ED = createWSASymbol(SD.EsdId);
ED.Alignment = GOFFSymbol::setGOFFAlignment(Symbol.getAlignment());
writeSymbol(ED, Layout);
- GOFFSymbol PR = createPRSymbol(Symbol.getName(), ED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_Unspecified,
- GOFFSymbol::setGOFFAlignment(Symbol.getAlignment()), GOFF::ESD_BSC_ImportExport, 0);
+ GOFFSymbol PR =
+ createPRSymbol(Symbol.getName(), ED.EsdId, GOFF::ESD_NS_Parts,
+ GOFF::ESD_EXE_Unspecified,
+ GOFFSymbol::setGOFFAlignment(Symbol.getAlignment()),
+ GOFF::ESD_BSC_ImportExport, 0);
GSym = PR;
GSymEsdId = PR.EsdId;
break;
@@ -870,16 +884,23 @@ void GOFFObjectWriter::writeADAandCodeSectionSymbols(
GOFFSymbol ADA;
if (CsectNames.second.empty()) {
- ADA = createPRSymbol(FileName.str().append("#S"), ADAED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA, GOFF::ESD_ALIGN_Quadword, GOFF::ESD_BSC_Section, std::max(getADASectionLength(Asm, Layout), 2u));
+ ADA = createPRSymbol(FileName.str().append("#S"), ADAED.EsdId,
+ GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA,
+ GOFF::ESD_ALIGN_Quadword, GOFF::ESD_BSC_Section,
+ std::max(getADASectionLength(Asm, Layout), 2u));
} else {
- ADA = createPRSymbol(CsectNames.second, ADAED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA, GOFF::ESD_ALIGN_Quadword, GOFF::ESD_BSC_Library, std::max(getADASectionLength(Asm, Layout), 2u));
+ ADA = createPRSymbol(CsectNames.second, ADAED.EsdId, GOFF::ESD_NS_Parts,
+ GOFF::ESD_EXE_DATA, GOFF::ESD_ALIGN_Quadword,
+ GOFF::ESD_BSC_Library,
+ std::max(getADASectionLength(Asm, Layout), 2u));
}
writeSymbol(ADAED, Layout);
writeSymbol(ADA, Layout);
ADAPREsdId = ADA.EsdId;
// Write ESD Records for Code Section
- GOFFSymbol ED = createEDSymbol("C_CODE64", RootSD.EsdId, 0, GOFF::ESD_EXE_CODE, true);
+ GOFFSymbol ED =
+ createEDSymbol("C_CODE64", RootSD.EsdId, 0, GOFF::ESD_EXE_CODE, true);
for (const MCSection &MCSec : Asm) {
SectionKind Kind = MCSec.getKind();
@@ -921,14 +942,15 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
GOFFSymbol SD = RootSD;
const char *WSAClassName = "C_WSA64";
- GOFFSymbol ED = createEDSymbol(WSAClassName, SD.EsdId, 0, GOFF::ESD_EXE_DATA,
- GOFF::ESD_BSC_Unspecified, GOFF::ESD_NS_Parts,
- GOFF::ESD_BA_Merge, /*ReadOnly*/false,
- GOFF::ESD_TS_Unstructured, GOFF::ESD_LB_Initial);
- GOFFSymbol PR = createPRSymbol(Section.getName(), ED.EsdId, GOFF::ESD_NS_Parts,
- GOFF::ESD_EXE_Unspecified, GOFF::ESD_ALIGN_Fullword,
- GOFF::ESD_BSC_Section, Layout.getSectionAddressSize(&Section),
- GOFF::ESD_LB_Deferred);
+ GOFFSymbol ED = createEDSymbol(
+ WSAClassName, SD.EsdId, 0, GOFF::ESD_EXE_DATA,
+ GOFF::ESD_BSC_Unspecified, GOFF::ESD_NS_Parts, GOFF::ESD_BA_Merge,
+ /*ReadOnly*/ false, GOFF::ESD_TS_Unstructured, GOFF::ESD_LB_Initial);
+ GOFFSymbol PR = createPRSymbol(
+ Section.getName(), ED.EsdId, GOFF::ESD_NS_Parts,
+ GOFF::ESD_EXE_Unspecified, GOFF::ESD_ALIGN_Fullword,
+ GOFF::ESD_BSC_Section, Layout.getSectionAddressSize(&Section),
+ GOFF::ESD_LB_Deferred);
writeSymbol(ED, Layout);
writeSymbol(PR, Layout);
@@ -939,15 +961,16 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
StringRef EDSectionName = "C_@@QPPA2";
StringRef PRSectionName = ".&ppa2";
GOFFSymbol SD = RootSD;
- GOFFSymbol ED = createEDSymbol(EDSectionName, SD.EsdId, 0, GOFF::ESD_EXE_DATA,
- GOFF::ESD_BSC_Unspecified, GOFF::ESD_NS_Parts,
- GOFF::ESD_BA_Merge, /*ReadOnly*/ true, GOFF::ESD_TS_Unstructured,
- GOFF::ESD_LB_Initial);
+ GOFFSymbol ED = createEDSymbol(
+ EDSectionName, SD.EsdId, 0, GOFF::ESD_EXE_DATA,
+ GOFF::ESD_BSC_Unspecified, GOFF::ESD_NS_Parts, GOFF::ESD_BA_Merge,
+ /*ReadOnly*/ true, GOFF::ESD_TS_Unstructured, GOFF::ESD_LB_Initial);
Align A = Align(Layout.getSectionAddressSize(&Section));
- GOFFSymbol PR = createPRSymbol(PRSectionName, ED.EsdId, GOFF::ESD_NS_Parts, GOFF::ESD_EXE_Unspecified,
- GOFF::ESD_ALIGN_Doubleword, GOFF::ESD_BSC_Section,
- GOFFSymbol::setGOFFAlignment(A),
- GOFF::ESD_LB_Initial, GOFF::ESD_LT_OS);
+ GOFFSymbol PR =
+ createPRSymbol(PRSectionName, ED.EsdId, GOFF::ESD_NS_Parts,
+ GOFF::ESD_EXE_Unspecified, GOFF::ESD_ALIGN_Doubleword,
+ GOFF::ESD_BSC_Section, GOFFSymbol::setGOFFAlignment(A),
+ GOFF::ESD_LB_Initial, GOFF::ESD_LT_OS);
writeSymbol(ED, Layout);
writeSymbol(PR, Layout);
@@ -955,17 +978,17 @@ void GOFFObjectWriter::writeSectionSymbols(MCAssembler &Asm,
SectionMap.insert(std::make_pair(&Section, GoffSec));
} else if (Section.isB_IDRL()) {
GOFFSymbol SD = RootSD;
- GOFFSymbol ED = createEDSymbol("B_IDRL", SD.EsdId, Layout.getSectionAddressSize(&Section),
- GOFF::ESD_EXE_Unspecified, GOFF::ESD_BSC_Module,
- GOFF::ESD_NS_NormalName, GOFF::ESD_BA_Concatenate,
- /*ReadOnly*/ true, GOFF::ESD_TS_Structured, GOFF::ESD_LB_NoLoad);
+ GOFFSymbol ED = createEDSymbol(
+ "B_IDRL", SD.EsdId, Layout.getSectionAddressSize(&Section),
+ GOFF::ESD_EXE_Unspecified, GOFF::ESD_BSC_Module,
+ GOFF::ESD_NS_NormalName, GOFF::ESD_BA_Concatenate,
+ /*ReadOnly*/ true, GOFF::ESD_TS_Structured, GOFF::ESD_LB_NoLoad);
writeSymbol(ED, Layout);
GOFFSection GoffSec = GOFFSection(ED.EsdId, 0, 0);
SectionMap.insert(std::make_pair(&Section, GoffSec));
} else if (Section.isStatic()) {
- GOFFSection GoffSec = GOFFSection(
- ADAPREsdId, ADAPREsdId, RootSD.EsdId);
+ GOFFSection GoffSec = GOFFSection(ADAPREsdId, ADAPREsdId, RootSD.EsdId);
SectionMap.insert(std::make_pair(&Section, GoffSec));
} else if (Kind.isBSS() || Kind.isData() || Kind.isThreadData()) {
// We handle this with the symbol definition, so there is no need to do
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 95b26cfefd5288..341c90232a6d0e 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -646,10 +646,12 @@ MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
: std::nullopt;
}
-MCSectionGOFF *MCContext::getGOFFLSDASection(StringRef Section, SectionKind Kind) {
+MCSectionGOFF *MCContext::getGOFFLSDASection(StringRef Section,
+ SectionKind Kind) {
// Do the lookup. If we don't have a hit, return a new section.
auto IterBool = GOFFUniquingMap.insert(std::make_pair(
- GOFFSectionKey{Section.str(), GOFF::GOFFSectionType::Other, false}, nullptr));
+ GOFFSectionKey{Section.str(), GOFF::GOFFSectionType::Other, false},
+ nullptr));
auto Iter = IterBool.first;
if (!IterBool.second)
return Iter->second;
@@ -657,20 +659,20 @@ MCSectionGOFF *MCContext::getGOFFLSDASection(StringRef Section, SectionKind Kind
auto CachedName = Iter->first.SectionName;
MCSectionGOFF *GOFFSection;
GOFFSection = new (GOFFAllocator.Allocate())
- MCSectionGOFF(CachedName, Kind, nullptr, nullptr, GOFF::ESD_TS_Unstructured, GOFF::ESD_LB_Deferred, true);
+ MCSectionGOFF(CachedName, Kind, nullptr, nullptr,
+ GOFF::ESD_TS_Unstructured, GOFF::ESD_LB_Deferred, true);
Iter->second = GOFFSection;
return GOFFSection;
}
-MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
- MCSection *Parent,
- const MCExpr *SubsectionId,
- GOFF::GOFFSectionType SectionType,
- GOFF::ESDTextStyle TextStyle,
- GOFF::ESDLoadingBehavior LoadBehavior) {
+MCSectionGOFF *MCContext::getGOFFSection(
+ StringRef Section, SectionKind Kind, MCSection *Parent,
+ const MCExpr *SubsectionId, GOFF::GOFFSectionType SectionType,
+ GOFF::ESDTextStyle TextStyle, GOFF::ESDLoadingBehavior LoadBehavior) {
// Do the lookup. If we don't have a hit, return a new section.
auto IterBool = GOFFUniquingMap.insert(std::make_pair(
- GOFFSectionKey{Section.str(), GOFF::GOFFSectionType::Other, false}, nullptr));
+ GOFFSectionKey{Section.str(), GOFF::GOFFSectionType::Other, false},
+ nullptr));
auto Iter = IterBool.first;
if (!IterBool.second)
return Iter->second;
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index ee7b103972164f..61632148310beb 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -544,8 +544,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
}
void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
- TextSection =
- Ctx->getGOFFSection(".text", SectionKind::getText(), nullptr, nullptr, GOFF::GOFFSectionType::Code);
+ TextSection = Ctx->getGOFFSection(".text", SectionKind::getText(), nullptr,
+ nullptr, GOFF::GOFFSectionType::Code);
BSSSection =
Ctx->getGOFFSection(".bss", SectionKind::getBSS(), nullptr, nullptr);
ReadOnlySection =
@@ -556,16 +556,17 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
MCConstantExpr::create(GOFF::SK_PPA1, *Ctx));
PPA2Section =
Ctx->getGOFFSection(".ppa2", SectionKind::getMetadata(), TextSection,
- MCConstantExpr::create(GOFF::SK_PPA2, *Ctx), GOFF::GOFFSectionType::PPA2Offset);
+ MCConstantExpr::create(GOFF::SK_PPA2, *Ctx),
+ GOFF::GOFFSectionType::PPA2Offset);
PPA2ListSection =
Ctx->getGOFFSection(".ppa2list", SectionKind::getData(),
nullptr, nullptr);
- ADASection =
- Ctx->getGOFFSection(".ada", SectionKind::getText(), nullptr, nullptr, GOFF::GOFFSectionType::Static);
- IDRLSection =
- Ctx->getGOFFSection("B_IDRL", SectionKind::getData(), nullptr, nullptr, GOFF::GOFFSectionType::B_IDRL);
+ ADASection = Ctx->getGOFFSection(".ada", SectionKind::getText(), nullptr,
+ nullptr, GOFF::GOFFSectionType::Static);
+ IDRLSection = Ctx->getGOFFSection("B_IDRL", SectionKind::getData(), nullptr,
+ nullptr, GOFF::GOFFSectionType::B_IDRL);
}
void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
>From 33c657c71d1018c60f01b1b17f821a4dc3bd69b5 Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Mon, 1 Apr 2024 16:17:40 -0400
Subject: [PATCH 11/12] Remove the AliasName stuff + a few other minor changes
in GOFFWriter
---
llvm/include/llvm/CodeGen/AsmPrinter.h | 7 ++--
llvm/include/llvm/MC/MCSymbolGOFF.h | 8 +----
llvm/lib/MC/GOFFObjectWriter.cpp | 11 +++---
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 35 -------------------
llvm/lib/Target/SystemZ/SystemZAsmPrinter.h | 1 -
5 files changed, 7 insertions(+), 55 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 0fb696bbb68b13..c697a4911558ae 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -897,13 +897,10 @@ class AsmPrinter : public MachineFunctionPass {
virtual void emitModuleCommandLines(Module &M);
GCMetadataPrinter *getOrCreateGCPrinter(GCStrategy &S);
-
-protected:
virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA);
-
-private:
void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);
+private:
/// This method decides whether the specified basic block requires a label.
bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const;
@@ -915,4 +912,4 @@ class AsmPrinter : public MachineFunctionPass {
} // end namespace llvm
-#endif // LLVM_CODEGEN_ASMPRINTER_H
+#endif // LLVM_CODEGEN_ASMPRINTER_H
\ No newline at end of file
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 9aa7928cdfacc4..943b06912c9445 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -20,8 +20,6 @@ namespace llvm {
class MCSymbolGOFF : public MCSymbol {
Align Alignment;
- mutable StringRef AliasName; // ADA indirect
-
enum SymbolFlags : uint16_t {
SF_NoRent = 0x01, // Symbol is no-reentrant.
SF_Alias = 0x02, // Symbol is alias.
@@ -36,13 +34,9 @@ class MCSymbolGOFF : public MCSymbol {
public:
MCSymbolGOFF(const StringMapEntry<bool> *Name, bool IsTemporary)
- : MCSymbol(SymbolKindGOFF, Name, IsTemporary), AliasName() {}
+ : MCSymbol(SymbolKindGOFF, Name, IsTemporary) {}
static bool classof(const MCSymbol *S) { return S->isGOFF(); }
- bool hasAliasName() const { return !AliasName.empty(); }
- void setAliasName(StringRef Name) { AliasName = Name; }
- StringRef getAliasName() const { return AliasName; }
-
void setOSLinkage(bool Value = true) const {
modifyFlags(Value ? SF_OSLinkage : 0, SF_OSLinkage);
}
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 0e940768567deb..d638d855376c82 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -587,7 +587,7 @@ void GOFFObjectWriter::writeSymbolDefinedInModule(const MCSymbolGOFF &Symbol,
LD.MCSym = &Symbol;
SymbolMap.insert(std::make_pair(&Symbol, LD.EsdId));
writeSymbol(LD, Layout);
- } else if ((Kind.isBSS() || Kind.isData()) && Symbol.isAlias()) {
+ } else if ((Kind.isBSS() || Kind.isData()) && Symbol.isAlias() || Kind.isThreadData()) {
// Alias to variable at the object file level.
// Not supported in RENT mode.
llvm_unreachable("Alias to rent variable is unsupported");
@@ -636,10 +636,7 @@ void GOFFObjectWriter::writeSymbolDeclaredInModule(const MCSymbolGOFF &Symbol,
switch (Exec) {
case GOFF::ESD_EXE_CODE:
case GOFF::ESD_EXE_Unspecified: {
- bool IsIndirectSymbol = Symbol.hasAliasName();
- GOFFSymbol ER = createERSymbol(IsIndirectSymbol ? Symbol.getAliasName()
- : Symbol.getName(),
- SD.EsdId, &Symbol);
+ GOFFSymbol ER = createERSymbol(Symbol.getName(), SD.EsdId, &Symbol);
ER.BindingScope = GOFF::ESD_BSC_ImportExport;
GSym = ER;
GSymEsdId = ER.EsdId;
@@ -903,8 +900,8 @@ void GOFFObjectWriter::writeADAandCodeSectionSymbols(
createEDSymbol("C_CODE64", RootSD.EsdId, 0, GOFF::ESD_EXE_CODE, true);
for (const MCSection &MCSec : Asm) {
- SectionKind Kind = MCSec.getKind();
- if (Kind.isText()) {
+ auto &GSec = cast<MCSectionGOFF>(MCSec);
+ if (GSec.isCode()) {
if (!ED.SectionLength)
ED.SectionLength = Layout.getSectionAddressSize(&MCSec);
}
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index c3341f7c850d68..aa155fad7fbf2e 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1433,41 +1433,6 @@ void SystemZAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
return AsmPrinter::emitGlobalVariable(GV);
}
-void SystemZAsmPrinter::emitGlobalAlias(const Module &M,
- const GlobalAlias &GA) {
- if (!TM.getTargetTriple().isOSzOS()) {
- AsmPrinter::emitGlobalAlias(M, GA);
- return;
- }
-
- MCSymbol *Name = getSymbol(&GA);
- bool IsFunc = isa<Function>(GA.getAliasee()->stripPointerCasts());
-
- if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective())
- OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
- else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage())
- OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
- else
- assert(GA.hasLocalLinkage() && "Invalid alias linkage");
-
- emitVisibility(Name, GA.getVisibility());
-
- const MCExpr *Expr;
-
- // For XPLINK, create a VCON relocation in case of a function, and
- // a direct reference else.
- MCSymbol *Sym = getSymbol(GA.getAliaseeObject());
- if (IsFunc)
- Expr = SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
- MCSymbolRefExpr::create(Sym, OutContext),
- OutContext);
-
- else
- Expr = MCSymbolRefExpr::create(Sym, OutContext);
-
- OutStreamer->emitAssignment(Name, Expr);
-}
-
const MCExpr *SystemZAsmPrinter::lowerConstant(const Constant *CV) {
const Triple &TargetTriple = TM.getTargetTriple();
if (TargetTriple.isOSzOS()) {
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
index 5da1307571cc76..d648656dcb62cf 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
@@ -119,7 +119,6 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
void emitFunctionEntryLabel() override;
void emitFunctionBodyEnd() override;
void emitGlobalVariable(const GlobalVariable *GV) override;
- void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override;
const MCExpr *lowerConstant(const Constant *CV) override;
void emitStartOfAsmFile(Module &M) override;
>From ff82d0b2d81c377fe9ebc6a083b0de660f8ab92a Mon Sep 17 00:00:00 2001
From: Neumann Hon <neumann.hon at ibm.com>
Date: Mon, 1 Apr 2024 17:02:42 -0400
Subject: [PATCH 12/12] Change ADA size calculation + check for NULL in
lowerConstant
---
llvm/lib/MC/GOFFObjectWriter.cpp | 19 ++++++++----
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 30 ++++++++++---------
2 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index d638d855376c82..5f723a96db347a 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -531,10 +531,17 @@ GOFFSymbol GOFFObjectWriter::createWSASymbol(uint32_t ParentEsdId,
static uint32_t getADASectionLength(MCAssembler &Asm,
const MCAsmLayout &Layout) {
- for (MCSection &S : Asm)
- if (S.getName().equals(".ada"))
- return Layout.getSectionAddressSize(&S);
- return 0;
+ uint32_t SecLen = 0;
+ for (const MCSection &MCSec : Asm) {
+ auto &GSec = cast<MCSectionGOFF>(MCSec);
+ if (GSec.isStatic()) {
+ SecLen = Layout.getSectionAddressSize(&MCSec);
+ }
+ }
+
+ // The ADA section is not allowed to be zero-length. We also want to
+ // avoid odd alignments, so we use 2 bytes.
+ return std::max(SecLen, 2u);
}
void GOFFObjectWriter::defineRootSD(MCAssembler &Asm,
@@ -884,12 +891,12 @@ void GOFFObjectWriter::writeADAandCodeSectionSymbols(
ADA = createPRSymbol(FileName.str().append("#S"), ADAED.EsdId,
GOFF::ESD_NS_Parts, GOFF::ESD_EXE_DATA,
GOFF::ESD_ALIGN_Quadword, GOFF::ESD_BSC_Section,
- std::max(getADASectionLength(Asm, Layout), 2u));
+ getADASectionLength(Asm, Layout));
} else {
ADA = createPRSymbol(CsectNames.second, ADAED.EsdId, GOFF::ESD_NS_Parts,
GOFF::ESD_EXE_DATA, GOFF::ESD_ALIGN_Quadword,
GOFF::ESD_BSC_Library,
- std::max(getADASectionLength(Asm, Layout), 2u));
+ getADASectionLength(Asm, Layout));
}
writeSymbol(ADAED, Layout);
writeSymbol(ADA, Layout);
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index aa155fad7fbf2e..f51057f7cba272 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1446,21 +1446,23 @@ const MCExpr *SystemZAsmPrinter::lowerConstant(const Constant *CV) {
// TODO: Is it necessary to assert if CV is of type GlobalIFunc?
if (IsFunc) {
+ if (Sym) {
Sym->setExecutable(GOFF::ESD_EXE_CODE);
- if (Sym->isExternal())
- return SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
- MCSymbolRefExpr::create(Sym, OutContext),
- OutContext);
- // Trigger creation of function descriptor in ADA for internal
- // functions.
- unsigned Disp = ADATable.insert(Sym, SystemZII::MO_ADA_DIRECT_FUNC_DESC);
- return MCBinaryExpr::createAdd(
- SystemZMCExpr::create(MCSymbolRefExpr::create(ADASym, OutContext),
- OutContext),
- MCConstantExpr::create(Disp, OutContext), OutContext);
- } else if (Sym) {
- Sym->setExecutable(GOFF::ESD_EXE_DATA);
- return MCSymbolRefExpr::create(Sym, OutContext);
+ if (Sym->isExternal())
+ return SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
+ MCSymbolRefExpr::create(Sym, OutContext),
+ OutContext);
+ // Trigger creation of function descriptor in ADA for internal
+ // functions.
+ unsigned Disp = ADATable.insert(Sym, SystemZII::MO_ADA_DIRECT_FUNC_DESC);
+ return MCBinaryExpr::createAdd(
+ SystemZMCExpr::create(MCSymbolRefExpr::create(ADASym, OutContext),
+ OutContext),
+ MCConstantExpr::create(Disp, OutContext), OutContext);
+ } else {
+ Sym->setExecutable(GOFF::ESD_EXE_DATA);
+ return MCSymbolRefExpr::create(Sym, OutContext);
+ }
}
}
More information about the llvm-commits
mailing list