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

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 6 12:28:23 PDT 2023


================
@@ -216,34 +220,471 @@ 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)
       : TargetObjectWriter(std::move(MOTW)), OS(OS) {}
 
   ~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);
----------------
diggerlin wrote:

since the content of `Asm` is not changed in the function, please change all the `MCAssembler &Asm`  to `const MCAssembler &Asm` in the following function

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


More information about the llvm-commits mailing list