[llvm] [SystemZ][z/OS] Implement executePostLayoutBinding for GOFFObjectWriter (PR #67868)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 29 16:58:51 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mc

<details>
<summary>Changes</summary>

Implement executePostLayoutBinding() for the GOFFObjectWriter. With this patch, we can now emit the ESD/TXT Records that are required by global variables and functions.

---

Patch is 52.85 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/67868.diff


13 Files Affected:

- (modified) llvm/include/llvm/BinaryFormat/GOFF.h (+7-3) 
- (modified) llvm/include/llvm/MC/MCAssembler.h (+5) 
- (modified) llvm/include/llvm/MC/MCContext.h (+2-1) 
- (modified) llvm/include/llvm/MC/MCGOFFObjectWriter.h (+1) 
- (modified) llvm/include/llvm/MC/MCGOFFStreamer.h (+7-3) 
- (modified) llvm/include/llvm/MC/MCSymbolGOFF.h (+40) 
- (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+4) 
- (modified) llvm/lib/MC/GOFFObjectWriter.cpp (+708-1) 
- (modified) llvm/lib/MC/MCGOFFStreamer.cpp (+50) 
- (modified) llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp (+37) 
- (modified) llvm/lib/Target/SystemZ/SystemZAsmPrinter.h (+2) 
- (added) llvm/test/MC/GOFF/basic-goff-64.ll (+242) 
- (modified) llvm/test/MC/GOFF/empty-goff.s (+9-9) 


``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
index f1a30e41b736bda..8d419e5d0189736 100644
--- a/llvm/include/llvm/BinaryFormat/GOFF.h
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -67,9 +67,7 @@ enum ESDNameSpaceId : uint8_t {
 
 enum ESDReserveQwords : uint8_t {
   ESD_RQ_0 = 0,
-  ESD_RQ_1 = 1,
-  ESD_RQ_2 = 2,
-  ESD_RQ_3 = 3
+  ESD_RQ_1 = 1
 };
 
 enum ESDAmode : uint8_t {
@@ -157,6 +155,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,
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 5e1fc738b1dab4b..506b6b02eb6a4e8 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -134,6 +134,9 @@ class MCAssembler {
   /// List of declared file names
   std::vector<std::pair<std::string, size_t>> FileNames;
 
+  /// GOFF Csect names.
+  std::pair<std::string, std::string> CsectNames;
+
   MCDwarfLineTableParams LTParams;
 
   /// The set of function symbols for which a .thumb_func directive has
@@ -483,6 +486,8 @@ class MCAssembler {
     FileNames.emplace_back(std::string(FileName), Symbols.size());
   }
 
+  std::pair<std::string, std::string> const &getCsectNames() { return CsectNames; }
+
   /// Write the necessary bundle padding to \p OS.
   /// Expects a fragment \p F containing instructions and its size \p FSize.
   void writeFragmentPadding(raw_ostream &OS, const MCEncodedFragment &F,
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 68d6f3e59d2d41a..dd5709d3be14c7f 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -621,7 +621,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/MCGOFFObjectWriter.h b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
index 85316a6fd5d0e17..26bddde706dc601 100644
--- a/llvm/include/llvm/MC/MCGOFFObjectWriter.h
+++ b/llvm/include/llvm/MC/MCGOFFObjectWriter.h
@@ -10,6 +10,7 @@
 #define LLVM_MC_MCGOFFOBJECTWRITER_H
 
 #include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/Casting.h"
 
 namespace llvm {
 class MCObjectWriter;
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 2345509b161da5b..235edc01e88d5a5 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -24,9 +24,13 @@ 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 {}
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index cc4e2bbe246e2de..6c4bad48df99f6c 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -18,10 +18,50 @@
 namespace llvm {
 
 class MCSymbolGOFF : public MCSymbol {
+  Align Alignment;
+  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.
+  };
+
+  enum {
+    // Shift value for GOFF::ESDExecutable. 3 possible values. 2 bits.
+    GOFF_Executable_Shift = 6,
+    GOFF_Executable_Bitmask = 0x3,
+  };
+
 public:
   MCSymbolGOFF(const StringMapEntry<bool> *Name, bool IsTemporary)
       : MCSymbol(SymbolKindGOFF, Name, IsTemporary) {}
   static bool classof(const MCSymbol *S) { return S->isGOFF(); }
+
+  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 6210e7fc128a30c..8d782b1532fb547 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2683,6 +2683,10 @@ MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
 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);
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 33244cbf88d919e..ca15d1323ea9cf2 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -13,8 +13,12 @@
 #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/ConvertEBCDIC.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Path.h"
@@ -216,13 +220,121 @@ 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;
+  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) {}
+
+  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");
+  }
+
+  void setMaxAlignment(Align A) {
+    GOFF::ESDAlignment CurrAlign = Alignment;
+    setAlignment(A);
+    if (CurrAlign > Alignment)
+      Alignment = CurrAlign;
+  }
+};
+
+/// \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.
+class GOFFSection {
+public:
+  GOFFSymbol *Pptr = nullptr;
+  GOFFSymbol *Rptr = nullptr;
+  GOFFSymbol *SD = nullptr;
+  const MCSectionGOFF *MCSec = nullptr;
+  bool IsStructured = false;
+
+  GOFFSection(GOFFSymbol *Pptr, GOFFSymbol *Rptr, GOFFSymbol *SD,
+              const MCSectionGOFF *MCSec)
+      : Pptr(Pptr), Rptr(Rptr), SD(SD), MCSec(MCSec), IsStructured(false) {}
+};
+
 class GOFFObjectWriter : public MCObjectWriter {
+  typedef std::vector<std::unique_ptr<GOFFSymbol>> SymbolListType;
+  typedef DenseMap<MCSymbol const *, GOFFSymbol *> SymbolMapType;
+  typedef std::vector<std::unique_ptr<GOFFSection>> SectionListType;
+  typedef DenseMap<MCSection const *, GOFFSection *> SectionMapType;
+
   // The target specific GOFF writer instance.
   std::unique_ptr<MCGOFFObjectTargetWriter> TargetObjectWriter;
 
+  /// The symbol table for a GOFF file.  It is order sensitive.
+  SymbolListType EsdSymbols;
+
+  /// Lookup table for MCSymbols to GOFFSymbols.  Needed to determine EsdIds
+  /// of symbols in Relocations.
+  SymbolMapType SymbolMap;
+
+  /// The list of sections for the GOFF file.
+  SectionListType Sections;
+
+  /// 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;
+
+  GOFFSymbol *RootSD = nullptr;
+  GOFFSymbol *CodeLD = nullptr;
+  GOFFSymbol *ADA = nullptr;
+  bool HasADA = false;
+
 public:
   GOFFObjectWriter(std::unique_ptr<MCGOFFObjectTargetWriter> MOTW,
                    raw_pwrite_stream &OS)
@@ -230,20 +342,349 @@ class GOFFObjectWriter : public MCObjectWriter {
 
   ~GOFFObjectWriter() override {}
 
+private:
   // Write GOFF records.
   void writeHeader();
+
+  void writeSymbol(const GOFFSymbol &Symbol, const MCAsmLayout &Layout);
+  void writeText(const GOFFSection &Section, const 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);
+  void defineRootAndADASD(MCAssembler &Asm);
+  void defineSectionSymbols(const MCAssembler &Asm,
+                            const MCSectionGOFF &Section,
+                            const MCAsmLayout &Layout);
+  void processSymbolDefinedInModule(const MCSymbolGOFF &MCSymbol,
+                                    const MCAssembler &Asm,
+                                    const MCAsmLayout &Layout);
+  void processSymbolDeclaredInModule(const MCSymbolGOFF &Symbol);
 };
 } // end anonymous namespace
 
+GOFFSection *GOFFObjectWriter::createGOFFSection(GOFFSymbol *Pptr,
+                                                 GOFFSymbol *Rptr,
+                                                 GOFFSymbol *SD,
+                                                 const MCSectionGOFF *MC) {
+  Sections.push_back(std::make_unique<GOFFSection>(Pptr, Rptr, SD, MC));
+
+  return Sections.back().get();
+}
+
+GOFFSymbol *GOFFObjectWriter::createGOFFSymbol(StringRef Name,
+                                               GOFF::ESDSymbolType Type,
+                                               uint32_t ParentEsdId) {
+  EsdSymbols.push_back(
+      std::make_unique<GOFFSymbol>(Name, Type, EsdCounter, ParentEsdId));
+  ++EsdCounter;
+  return EsdSymbols.back().get();
+}
+
+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 = 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) {
+  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;
+
+  return WSA;
+}
+
+void GOFFObjectWriter::defineRootAndADASD(MCAssembler &Asm) {
+  assert(!RootSD && !ADA && "SD already initialzed");
+  StringRef FileName = "";
+  if (Asm.getFileNames().size())
+    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;
+
+  GOFFSymbol *ADAED = createWSASymbol(RootSD->EsdId);
+  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;
+  // The ADA Section length can increase after this point. The final ADA
+  // length is assigned in populateADASection().
+  // We need to be careful, because a value of 0 causes issues with function
+  // labels. In populateADASection(), we make sure that the ADA content is
+  // defined before createing function labels.
+  ADA->SectionLength = 0;
+  // Assume there is an ADA.
+  HasADA = true;
+}
+
+void GOFFObjectWriter::defineSectionSymbols(const MCAssembler &Asm,
+                                            const MCSectionGOFF &Section,
+                                            const MCAsmLayout &Layout) {
+  GOFFSection *GSection = nullptr;
+  SectionKind Kind = Section.getKind();
+
+  if (Kind.isText()) {
+    GOFFSymbol *SD = RootSD;
+    const char *CodeClassName = "C_CODE64";
+    GOFFSymbol *ED = createEDSymbol(CodeClassName, SD->EsdId);
+    GOFFSymbol *LD = createLDSymbol(SD->Name, ED->EsdId);
+
+    ED->SectionLength = Layout.getSectionAddressSize(&Section);
+    ED->Executable = GOFF::ESD_EXE_CODE;
+    ED->ForceRent = true;
+
+    LD->Executable = GOFF::ESD_EXE_CODE;
+    if (SD->BindingScope == GOFF::ESD_BSC_Section) {
+      LD->BindingScope = GOFF::ESD_BSC_Section;
+    } else {
+      LD->BindingScope = GOFF::ESD_BSC_Library;
+    }
+
+    CodeLD = LD;
+
+    GSection = createGOFFSection(ED, LD, SD, &Section);
+  } else if (Section.getName().equals(".ada")) {
+    // Symbols already defined in defineRootAndADASD, nothing to do.
+    ADA->SectionLength = Layout.getSectionAddressSize(&Section);
+    if (ADA->SectionLength)
+      CodeLD->ADAEsdId = ADA->EsdId;
+    else {
+      // We cannot have a zero-length section for data.  If we do, artificially
+      // inflate it.  Use 2 bytes to avoid odd alignments.
+      ADA->SectionLength = 2;
+      HasADA = false;
+    }
+    GSection = createGOFFSection(ADA, ADA, RootSD, &Section);
+  } else if (Kind.isBSS() || Kind.isData()) {
+    // Statics and globals that are defined.
+    StringRef SectionName = Section.getName();
+    GOFFSymbol *SD = createSDSymbol(SectionName);
+
+    // Determine if static/global variable is marked with the norent attribute.
+    MCContext &Ctx = Asm.getContext();
+    auto *Sym = cast_or_null<MCSymbolGOFF>(Ctx.lookupSymbol(SectionName));
+
+    if (Sym) {
+      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;
+
+      GSection = createGOFFSection(PR, PR, SD, &Section);
+    }
+  } else
+    llvm_unreachable("Unhandled section kin...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/67868


More information about the llvm-commits mailing list