https://github.com/redstar updated https://github.com/llvm/llvm-project/pull/133799
>From 77c230f82a61769714bee98b2e848820850d9cb5 Mon Sep 17 00:00:00 2001 From: Kai Nacke <kai.peter.na...@ibm.com> Date: Mon, 24 Mar 2025 16:26:19 -0400 Subject: [PATCH 1/7] [GOFF] Add writing of section symbols The GOFF format uses symbol definitions to represent sections and symbols. Introducing a section can require up to 3 symbol definitions. However, most of these details are not needed by the AsmPrinter. To mapped from a section (a MCSectionGOFF) to the symbol definitions, a new class called MCGOFFSymbolMapper is used. The same information can also be used by the assembly output, which justifies this centralized approach. Writing the mapped symbols is then straight forward. --- llvm/include/llvm/BinaryFormat/GOFF.h | 85 +++++++ llvm/include/llvm/MC/MCGOFFSymbolMapper.h | 148 +++++++++++ llvm/lib/MC/CMakeLists.txt | 1 + llvm/lib/MC/GOFFObjectWriter.cpp | 290 +++++++++++++++++++--- llvm/lib/MC/MCGOFFSymbolMapper.cpp | 203 +++++++++++++++ llvm/lib/MC/MCObjectFileInfo.cpp | 2 +- llvm/test/CodeGen/SystemZ/zos-ppa2.ll | 2 +- llvm/test/MC/GOFF/section.ll | 73 ++++++ 8 files changed, 765 insertions(+), 39 deletions(-) create mode 100644 llvm/include/llvm/MC/MCGOFFSymbolMapper.h create mode 100644 llvm/lib/MC/MCGOFFSymbolMapper.cpp create mode 100644 llvm/test/MC/GOFF/section.ll diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h index 443bcfc9479a8..43d80e0c247e9 100644 --- a/llvm/include/llvm/BinaryFormat/GOFF.h +++ b/llvm/include/llvm/BinaryFormat/GOFF.h @@ -169,6 +169,91 @@ enum SubsectionKind : uint8_t { SK_PPA1 = 2, SK_PPA2 = 4, }; + +// The standard System/390 convention is to name the high-order (leftmost) bit +// in a byte as bit zero. The Flags type helps to set bits in byte according +// to this numeration order. +class Flags { + uint8_t Val; + + constexpr static uint8_t bits(uint8_t BitIndex, uint8_t Length, uint8_t Value, + uint8_t OldValue) { + uint8_t Pos = 8 - BitIndex - Length; + uint8_t Mask = ((1 << Length) - 1) << Pos; + Value = Value << Pos; + return (OldValue & ~Mask) | Value; + } + +public: + constexpr Flags() : Val(0) {} + constexpr Flags(uint8_t BitIndex, uint8_t Length, uint8_t Value) + : Val(bits(BitIndex, Length, Value, 0)) {} + + template <typename T> + constexpr void set(uint8_t BitIndex, uint8_t Length, T NewValue) { + Val = bits(BitIndex, Length, static_cast<uint8_t>(NewValue), Val); + } + + template <typename T> + constexpr T get(uint8_t BitIndex, uint8_t Length) const { + return static_cast<T>((Val >> (8 - BitIndex - Length)) & + ((1 << Length) - 1)); + } + + constexpr operator uint8_t() const { return Val; } +}; + +// Structure for the flag field of a symbol. See +// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record, +// offset 41, for the definition. +struct SymbolFlags { + Flags SymFlags; + +#define GOFF_SYMBOL_FLAG(NAME, TYPE, BITINDEX, LENGTH) \ + void set##NAME(TYPE Val) { SymFlags.set<TYPE>(BITINDEX, LENGTH, Val); } \ + TYPE get##NAME() const { return SymFlags.get<TYPE>(BITINDEX, LENGTH); } + + GOFF_SYMBOL_FLAG(FillBytePresence, bool, 0, 1) + GOFF_SYMBOL_FLAG(Mangled, bool, 1, 1) + GOFF_SYMBOL_FLAG(Renameable, bool, 2, 1) + GOFF_SYMBOL_FLAG(RemovableClass, bool, 3, 1) + GOFF_SYMBOL_FLAG(ReservedQwords, ESDReserveQwords, 5, 3) + +#undef GOFF_SYMBOL_FLAG + +constexpr operator uint8_t() const { return static_cast<uint8_t>(SymFlags); } +}; + +// Structure for the behavioral attributes. See +// https://www.ibm.com/docs/en/zos/3.1.0?topic=record-external-symbol-definition-behavioral-attributes +// for the definition. +struct BehavioralAttributes { + Flags Attr[10]; + +#define GOFF_BEHAVIORAL_ATTRIBUTE(NAME, TYPE, ATTRIDX, BITINDEX, LENGTH) \ + void set##NAME(TYPE Val) { Attr[ATTRIDX].set<TYPE>(BITINDEX, LENGTH, Val); } \ + TYPE get##NAME() const { return Attr[ATTRIDX].get<TYPE>(BITINDEX, LENGTH); } + + GOFF_BEHAVIORAL_ATTRIBUTE(Amode, GOFF::ESDAmode, 0, 0, 8) + GOFF_BEHAVIORAL_ATTRIBUTE(Rmode, GOFF::ESDRmode, 1, 0, 8) + GOFF_BEHAVIORAL_ATTRIBUTE(TextStyle, GOFF::ESDTextStyle, 2, 0, 4) + GOFF_BEHAVIORAL_ATTRIBUTE(BindingAlgorithm, GOFF::ESDBindingAlgorithm, 2, 4, + 4) + GOFF_BEHAVIORAL_ATTRIBUTE(TaskingBehavior, GOFF::ESDTaskingBehavior, 3, 0, 3) + GOFF_BEHAVIORAL_ATTRIBUTE(ReadOnly, bool, 3, 4, 1) + GOFF_BEHAVIORAL_ATTRIBUTE(Executable, GOFF::ESDExecutable, 3, 5, 3) + GOFF_BEHAVIORAL_ATTRIBUTE(DuplicateSymbolSeverity, + GOFF::ESDDuplicateSymbolSeverity, 4, 2, 2) + GOFF_BEHAVIORAL_ATTRIBUTE(BindingStrength, GOFF::ESDBindingStrength, 4, 4, 4) + GOFF_BEHAVIORAL_ATTRIBUTE(LoadingBehavior, GOFF::ESDLoadingBehavior, 5, 0, 2) + GOFF_BEHAVIORAL_ATTRIBUTE(COMMON, bool, 5, 2, 1) + GOFF_BEHAVIORAL_ATTRIBUTE(IndirectReference, bool, 5, 3, 1) + GOFF_BEHAVIORAL_ATTRIBUTE(BindingScope, GOFF::ESDBindingScope, 5, 4, 4) + GOFF_BEHAVIORAL_ATTRIBUTE(LinkageType, GOFF::ESDLinkageType, 6, 2, 1) + GOFF_BEHAVIORAL_ATTRIBUTE(Alignment, GOFF::ESDAlignment, 6, 3, 5) + +#undef GOFF_BEHAVIORAL_ATTRIBUTE +}; } // end namespace GOFF } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h new file mode 100644 index 0000000000000..dbdc1408dab2f --- /dev/null +++ b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h @@ -0,0 +1,148 @@ +//===- MCGOFFSymbolMapper.h - Maps MC section/symbol to GOFF symbols ------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Maps a section or a symbol to the GOFF symbols it is composed of, and their +// attributes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCGOFFSYMBOLMAPPER_H +#define LLVM_MC_MCGOFFSYMBOLMAPPER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/GOFF.h" +#include "llvm/Support/Alignment.h" +#include <string> +#include <utility> + +namespace llvm { +class MCAssembler; +class MCContext; +class MCSectionGOFF; + +// An "External Symbol Definition" in the GOFF file has a type, and depending on +// the type a different subset of the fields is used. +// +// Unlike other formats, a 2 dimensional structure is used to define the +// location of data. For example, the equivalent of the ELF .text section is +// made up of a Section Definition (SD) and a class (Element Definition; ED). +// The name of the SD symbol depends on the application, while the class has the +// predefined name C_CODE64. +// +// Data can be placed into this structure in 2 ways. First, the data (in a text +// record) can be associated with an ED symbol. To refer to data, a Label +// Definition (LD) is used to give an offset into the data a name. When binding, +// the whole data is pulled into the resulting executable, and the addresses +// given by the LD symbols are resolved. +// +// The alternative is to use a Part Defiition (PR). In this case, the data (in a +// text record) is associated with the part. When binding, only the data of +// referenced PRs is pulled into the resulting binary. +// +// Both approaches are used, which means that the equivalent of a section in ELF +// results in 3 GOFF symbol, either SD/ED/LD or SD/ED/PR. Moreover, certain +// sections are fine with just defining SD/ED symbols. The SymbolMapper takes +// care of all those details. + +// Attributes for SD symbols. +struct SDAttr { + GOFF::ESDTaskingBehavior TaskingBehavior = GOFF::ESD_TA_Unspecified; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; +}; + +// Attributes for ED symbols. +struct EDAttr { + bool IsReadOnly = false; + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDAmode Amode; + GOFF::ESDRmode Rmode; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDTextStyle TextStyle = GOFF::ESD_TS_ByteOriented; + GOFF::ESDBindingAlgorithm BindAlgorithm = GOFF::ESD_BA_Concatenate; + GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial; + GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0; + GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword; +}; + +// Attributes for LD symbols. +struct LDAttr { + bool IsRenamable = false; + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong; + GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink; + GOFF::ESDAmode Amode; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; +}; + +// Attributes for PR symbols. +struct PRAttr { + bool IsRenamable = false; + bool IsReadOnly = false; // ???? Not documented. + GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_NormalName; + GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink; + GOFF::ESDAmode Amode; + GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified; + GOFF::ESDDuplicateSymbolSeverity DuplicateSymbolSeverity = + GOFF::ESD_DSS_NoWarning; + GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Byte; + uint32_t SortKey = 0; +}; + +struct GOFFSectionData { + // Name and attributes of SD symbol. + StringRef SDName; + SDAttr SDAttributes; + + // Name and attributes of ED symbol. + StringRef EDName; + EDAttr EDAttributes; + + // Name and attributes of LD or PR symbol. + StringRef LDorPRName; + LDAttr LDAttributes; + PRAttr PRAttributes; + + // Indicates if there is a LD or PR symbol. + enum { None, LD, PR } Tag; + + // Indicates if the SD symbol is to root symbol (aka the Csect Code). + bool IsSDRootSD; +}; + +class GOFFSymbolMapper { + MCContext &Ctx; + + std::string RootSDName; + SDAttr RootSDAttributes; + + std::string ADALDName; + + StringRef BaseName; + + bool IsCsectCodeNameEmpty; + bool Is64Bit; + bool UsesXPLINK; + +public: + GOFFSymbolMapper(MCContext &Ctx); + GOFFSymbolMapper(MCAssembler &Asm); + + // Required order: .text first, then .ada. + std::pair<GOFFSectionData, bool> getSection(const MCSectionGOFF &Section); + + void setBaseName(); + void determineRootSD(StringRef CSectCodeName); + llvm::StringRef getRootSDName() const; + const SDAttr &getRootSD() const; +}; + +} // namespace llvm + +#endif diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index f49f14c848b90..967ec73a2be5b 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -26,6 +26,7 @@ add_llvm_component_library(LLVMMC MCExpr.cpp MCFragment.cpp MCGOFFStreamer.cpp + MCGOFFSymbolMapper.cpp MCInst.cpp MCInstPrinter.cpp MCInstrAnalysis.cpp diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp index efaf5ff006ddc..92603c6fb1002 100644 --- a/llvm/lib/MC/GOFFObjectWriter.cpp +++ b/llvm/lib/MC/GOFFObjectWriter.cpp @@ -13,7 +13,11 @@ #include "llvm/BinaryFormat/GOFF.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCGOFFObjectWriter.h" +#include "llvm/MC/MCGOFFSymbolMapper.h" +#include "llvm/MC/MCSectionGOFF.h" #include "llvm/MC/MCValue.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ConvertEBCDIC.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/raw_ostream.h" @@ -23,44 +27,13 @@ using namespace llvm; #define DEBUG_TYPE "goff-writer" namespace { - -// The standard System/390 convention is to name the high-order (leftmost) bit -// in a byte as bit zero. The Flags type helps to set bits in a byte according -// to this numeration order. -class Flags { - uint8_t Val; - - constexpr static uint8_t bits(uint8_t BitIndex, uint8_t Length, uint8_t Value, - uint8_t OldValue) { - assert(BitIndex < 8 && "Bit index out of bounds!"); - assert(Length + BitIndex <= 8 && "Bit length too long!"); - - uint8_t Mask = ((1 << Length) - 1) << (8 - BitIndex - Length); - Value = Value << (8 - BitIndex - Length); - assert((Value & Mask) == Value && "Bits set outside of range!"); - - return (OldValue & ~Mask) | Value; - } - -public: - constexpr Flags() : Val(0) {} - constexpr Flags(uint8_t BitIndex, uint8_t Length, uint8_t Value) - : Val(bits(BitIndex, Length, Value, 0)) {} - - void set(uint8_t BitIndex, uint8_t Length, uint8_t Value) { - Val = bits(BitIndex, Length, Value, Val); - } - - constexpr operator uint8_t() const { return Val; } -}; - // Common flag values on records. // Flag: This record is continued. -constexpr uint8_t RecContinued = Flags(7, 1, 1); +constexpr uint8_t RecContinued = GOFF::Flags(7, 1, 1); // Flag: This record is a continuation. -constexpr uint8_t RecContinuation = Flags(6, 1, 1); +constexpr uint8_t RecContinuation = GOFF::Flags(6, 1, 1); // The GOFFOstream is responsible to write the data into the fixed physical // records of the format. A user of this class announces the begin of a new @@ -223,13 +196,113 @@ void GOFFOstream::finalizeRecord() { } namespace { +// A GOFFSymbol holds all the data required for writing an ESD record. +class GOFFSymbol { +public: + std::string Name; + uint32_t EsdId; + uint32_t ParentEsdId; + uint64_t Offset = 0; // Offset of the symbol into the section. LD only. + // Offset is only 32 bit, the larger type is used to + // enable error checking. + GOFF::ESDSymbolType SymbolType; + GOFF::ESDNameSpaceId NameSpace = GOFF::ESD_NS_ProgramManagementBinder; + + GOFF::BehavioralAttributes BehavAttrs; + GOFF::SymbolFlags SymbolFlags; + uint32_t SortKey = 0; + uint32_t SectionLength = 0; + uint32_t ADAEsdId = 0; + uint32_t EASectionEDEsdId = 0; + uint32_t EASectionOffset = 0; + uint8_t FillByteValue = 0; + + GOFFSymbol() : EsdId(0), ParentEsdId(0) {} + + GOFFSymbol(StringRef Name, uint32_t EsdID, const SDAttr &Attr) + : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(0), + SymbolType(GOFF::ESD_ST_SectionDefinition) { + BehavAttrs.setTaskingBehavior(Attr.TaskingBehavior); + BehavAttrs.setBindingScope(Attr.BindingScope); + } + + GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, + const EDAttr &Attr) + : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), + SymbolType(GOFF::ESD_ST_ElementDefinition) { + this->NameSpace = Attr.NameSpace; + // TODO Do we need/should set the "mangled" flag? + SymbolFlags.setFillBytePresence(1); + SymbolFlags.setReservedQwords(Attr.ReservedQwords); + BehavAttrs.setReadOnly(Attr.IsReadOnly); + BehavAttrs.setExecutable(Attr.Executable); + BehavAttrs.setAmode(Attr.Amode); + BehavAttrs.setRmode(Attr.Rmode); + BehavAttrs.setTextStyle(Attr.TextStyle); + BehavAttrs.setBindingAlgorithm(Attr.BindAlgorithm); + BehavAttrs.setLoadingBehavior(Attr.LoadBehavior); + BehavAttrs.setAlignment(Attr.Alignment); + } + + GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, + const LDAttr &Attr) + : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), + SymbolType(GOFF::ESD_ST_LabelDefinition) { + this->NameSpace = Attr.NameSpace; + SymbolFlags.setRenameable(Attr.IsRenamable); + BehavAttrs.setExecutable(Attr.Executable); + BehavAttrs.setBindingStrength(Attr.BindingStrength); + BehavAttrs.setLinkageType(Attr.Linkage); + BehavAttrs.setAmode(Attr.Amode); + BehavAttrs.setBindingScope(Attr.BindingScope); + } + + GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, + const PRAttr &Attr) + : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), + SymbolType(GOFF::ESD_ST_PartReference) { + this->NameSpace = Attr.NameSpace; + SymbolFlags.setRenameable(Attr.IsRenamable); + BehavAttrs.setExecutable(Attr.Executable); + BehavAttrs.setAlignment(Attr.Alignment); + BehavAttrs.setAmode(Attr.Amode); + BehavAttrs.setLinkageType(Attr.Linkage); + BehavAttrs.setBindingScope(Attr.BindingScope); + BehavAttrs.setDuplicateSymbolSeverity(Attr.DuplicateSymbolSeverity); + BehavAttrs.setReadOnly(Attr.IsReadOnly); + } +}; + class GOFFWriter { GOFFOstream OS; [[maybe_unused]] MCAssembler &Asm; + /// Mapping from MCSectionGOFF/MCSymbolGOFF to GOFF symbols and attributes. + GOFFSymbolMapper SymbolMapper; + + /// Counter for symbol id's. + uint32_t EsdIdCounter = 0; + + /// Id's of some special symbols. + uint32_t RootSDEsdId = 0; + uint32_t ADAEsdId = 0; + void writeHeader(); + void writeSymbol(const GOFFSymbol &Symbol); void writeEnd(); + GOFFSymbol createGOFFSymbol(StringRef Name, const SDAttr &Attr); + GOFFSymbol createGOFFSymbol(StringRef Name, const EDAttr &Attr, + uint32_t ParentEsdId); + GOFFSymbol createGOFFSymbol(StringRef Name, const LDAttr &Attr, + uint32_t ParentEsdId); + GOFFSymbol createGOFFSymbol(StringRef Name, const PRAttr &Attr, + uint32_t ParentEsdId); + + void defineRootSymbol(const MCSectionGOFF *Text); + void defineSectionSymbols(const MCSectionGOFF &Section); + void defineSymbols(); + public: GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm); uint64_t writeObject(); @@ -237,7 +310,108 @@ class GOFFWriter { } // namespace GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm) - : OS(OS), Asm(Asm) {} + : OS(OS), Asm(Asm), SymbolMapper(Asm) {} + +GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const SDAttr &Attr) { + return GOFFSymbol(Name, ++EsdIdCounter, Attr); +} + +GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const EDAttr &Attr, + uint32_t ParentEsdId) { + return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr); +} + +GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const LDAttr &Attr, + uint32_t ParentEsdId) { + return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr); +} + +GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const PRAttr &Attr, + uint32_t ParentEsdId) { + return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr); +} + +void GOFFWriter::defineRootSymbol(const MCSectionGOFF *Text) { + // There is always a text section except for DWARF unit tests. + SymbolMapper.determineRootSD(""); + GOFFSymbol RootSD = + createGOFFSymbol(SymbolMapper.getRootSDName(), SymbolMapper.getRootSD()); + writeSymbol(RootSD); + RootSDEsdId = RootSD.EsdId; +} + +void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) { + auto [GOFFSectionData, Found] = SymbolMapper.getSection(Section); + if (Found) { + uint32_t SDEsdId = RootSDEsdId; + if (!GOFFSectionData.IsSDRootSD) { + GOFFSymbol SD = createGOFFSymbol(GOFFSectionData.SDName, + GOFFSectionData.SDAttributes); + SDEsdId = SD.EsdId; + writeSymbol(SD); + } + + GOFFSymbol ED = createGOFFSymbol(GOFFSectionData.EDName, + GOFFSectionData.EDAttributes, SDEsdId); + if (GOFFSectionData.Tag == GOFFSectionData::None || + GOFFSectionData.Tag == GOFFSectionData::LD) { + ED.SectionLength = Asm.getSectionAddressSize(Section); + } + writeSymbol(ED); + + if (GOFFSectionData.Tag == GOFFSectionData::LD) { + GOFFSymbol LD = createGOFFSymbol(GOFFSectionData.LDorPRName, + GOFFSectionData.LDAttributes, ED.EsdId); + if (Section.isText()) + LD.ADAEsdId = ADAEsdId; + writeSymbol(LD); + } + + if (GOFFSectionData.Tag == GOFFSectionData::PR) { + GOFFSymbol PR = createGOFFSymbol(GOFFSectionData.LDorPRName, + GOFFSectionData.PRAttributes, ED.EsdId); + PR.SectionLength = Asm.getSectionAddressSize(Section); + if (Section.getName() == ".ada") { + // We cannot have a zero-length section for data. If we do, + // artificially inflate it. Use 2 bytes to avoid odd alignments. Note: + // if this is ever changed, you will need to update the code in + // SystemZAsmPrinter::emitCEEMAIN and SystemZAsmPrinter::emitCELQMAIN to + // generate -1 if there is no ADA + if (!PR.SectionLength) + PR.SectionLength = 2; + ADAEsdId = PR.EsdId; + } + writeSymbol(PR); + } + return; + } + // TODO It is possible to get here. This will be handled later. +} + +void GOFFWriter::defineSymbols() { + // Search for .text and .ada sections. These should be the first sections in + // the list, so the loop should be cheap. + MCSectionGOFF *Text = nullptr; + MCSectionGOFF *ADA = nullptr; + for (MCSection &S : Asm) { + if (S.getName() == ".text") + Text = &cast<MCSectionGOFF>(S); + if (S.getName() == ".ada") + ADA = &cast<MCSectionGOFF>(S); + } + defineRootSymbol(Text); + if (ADA) + defineSectionSymbols(*ADA); + if (Text) + defineSectionSymbols(*Text); + + // Process the other sections. + for (MCSection &S : Asm) { + auto &Section = cast<MCSectionGOFF>(S); + if (Text != &Section && ADA != &Section) + defineSectionSymbols(Section); + } +} void GOFFWriter::writeHeader() { OS.newRecord(GOFF::RT_HDR); @@ -253,6 +427,45 @@ void GOFFWriter::writeHeader() { OS.write_zeros(6); // Reserved } +void GOFFWriter::writeSymbol(const GOFFSymbol &Symbol) { + if (Symbol.Offset >= (((uint64_t)1) << 31)) + report_fatal_error("ESD offset outof range"); + + // All symbol names are in EBCDIC. + SmallString<256> Name; + ConverterEBCDIC::convertToEBCDIC(Symbol.Name, Name); + + // Check length here since this number is technically signed but we need uint + // for writing to records. + if (Name.size() >= GOFF::MaxDataLength) + report_fatal_error("Symbol max name length exceeded"); + uint16_t NameLength = Name.size(); + + OS.newRecord(GOFF::RT_ESD); + OS.writebe<uint8_t>(Symbol.SymbolType); // Symbol Type + OS.writebe<uint32_t>(Symbol.EsdId); // ESDID + OS.writebe<uint32_t>(Symbol.ParentEsdId); // Parent or Owning ESDID + OS.writebe<uint32_t>(0); // Reserved + OS.writebe<uint32_t>( + static_cast<uint32_t>(Symbol.Offset)); // Offset or Address + OS.writebe<uint32_t>(0); // Reserved + OS.writebe<uint32_t>(Symbol.SectionLength); // Length + OS.writebe<uint32_t>(Symbol.EASectionEDEsdId); // Extended Attribute ESDID + OS.writebe<uint32_t>(Symbol.EASectionOffset); // Extended Attribute Offset + OS.writebe<uint32_t>(0); // Reserved + OS.writebe<uint8_t>(Symbol.NameSpace); // Name Space ID + OS.writebe<uint8_t>(Symbol.SymbolFlags); // Flags + OS.writebe<uint8_t>(Symbol.FillByteValue); // Fill-Byte Value + OS.writebe<uint8_t>(0); // Reserved + OS.writebe<uint32_t>(Symbol.ADAEsdId); // ADA ESDID + OS.writebe<uint32_t>(Symbol.SortKey); // Sort Priority + OS.writebe<uint64_t>(0); // Reserved + for (auto F : Symbol.BehavAttrs.Attr) + OS.writebe<uint8_t>(F); // Behavioral Attributes + OS.writebe<uint16_t>(NameLength); // Name Length + OS.write(Name.data(), NameLength); // Name +} + void GOFFWriter::writeEnd() { uint8_t F = GOFF::END_EPR_None; uint8_t AMODE = 0; @@ -261,9 +474,9 @@ void GOFFWriter::writeEnd() { // TODO Set Flags/AMODE/ESDID for entry point. OS.newRecord(GOFF::RT_END); - OS.writebe<uint8_t>(Flags(6, 2, F)); // Indicator flags - OS.writebe<uint8_t>(AMODE); // AMODE - OS.write_zeros(3); // Reserved + OS.writebe<uint8_t>(GOFF::Flags(6, 2, F)); // Indicator flags + OS.writebe<uint8_t>(AMODE); // AMODE + OS.write_zeros(3); // Reserved // The record count is the number of logical records. In principle, this value // is available as OS.logicalRecords(). However, some tools rely on this field // being zero. @@ -273,6 +486,9 @@ void GOFFWriter::writeEnd() { uint64_t GOFFWriter::writeObject() { writeHeader(); + + defineSymbols(); + writeEnd(); // Make sure all records are written. diff --git a/llvm/lib/MC/MCGOFFSymbolMapper.cpp b/llvm/lib/MC/MCGOFFSymbolMapper.cpp new file mode 100644 index 0000000000000..57012c34a94f1 --- /dev/null +++ b/llvm/lib/MC/MCGOFFSymbolMapper.cpp @@ -0,0 +1,203 @@ +//===- MCGOFFSymbolMapper.cpp - Maps MC section/symbol to GOFF symbols ----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Maps a section or a symbol to the GOFF symbols it is composed of, and their +// attributes. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCGOFFSymbolMapper.h" +#include "llvm/BinaryFormat/GOFF.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSectionGOFF.h" +#include "llvm/Support/Alignment.h" +#include "llvm/Support/Path.h" + +using namespace llvm; + +namespace { +const StringLiteral CODE[2]{"C_CODE", "C_CODE64"}; +const StringLiteral WSA[2]{"C_WSA", "C_WSA64"}; +const StringLiteral PPA2[2]{"C_@@PPA2", "C_@@QPPA2"}; + +const GOFF::ESDAmode AMODE[2]{GOFF::ESD_AMODE_ANY, GOFF::ESD_AMODE_64}; +const GOFF::ESDRmode RMODE[2]{GOFF::ESD_RMODE_31, GOFF::ESD_RMODE_64}; + +const GOFF::ESDLinkageType LINKAGE[2]{GOFF::ESD_LT_OS, GOFF::ESD_LT_XPLink}; +} // namespace + +GOFFSymbolMapper::GOFFSymbolMapper(MCContext &Ctx) : Ctx(Ctx) { + IsCsectCodeNameEmpty = true; + Is64Bit = true; + UsesXPLINK = true; +} + +GOFFSymbolMapper::GOFFSymbolMapper(MCAssembler &Asm) + : GOFFSymbolMapper(Asm.getContext()) { + if (!Asm.getWriter().getFileNames().empty()) + BaseName = + sys::path::stem((*(Asm.getWriter().getFileNames().begin())).first); +} + +void GOFFSymbolMapper::determineRootSD(StringRef CSectCodeName) { + IsCsectCodeNameEmpty = CSectCodeName.empty(); + if (IsCsectCodeNameEmpty) { + RootSDName = BaseName.str().append("#C"); + } else { + RootSDName = CSectCodeName; + } + RootSDAttributes = {GOFF::ESD_TA_Rent, IsCsectCodeNameEmpty + ? GOFF::ESD_BSC_Section + : GOFF::ESD_BSC_Unspecified}; +} + +llvm::StringRef GOFFSymbolMapper::getRootSDName() const { return RootSDName; } + +const SDAttr &GOFFSymbolMapper::getRootSD() const { return RootSDAttributes; } + +std::pair<GOFFSectionData, bool> +GOFFSymbolMapper::getSection(const MCSectionGOFF &Section) { + // Look up GOFFSection from name in MCSectionGOFF. + // Customize result, e.g. csect names, 32/64 bit, etc. + GOFFSectionData GOFFSec; + if (Section.getName() == ".text") { + GOFFSec.SDName = RootSDName; + GOFFSec.SDAttributes = RootSDAttributes; + GOFFSec.IsSDRootSD = true; + GOFFSec.EDName = CODE[Is64Bit]; + // The GOFF alignment is encoded as log_2 value. + uint8_t Log = Log2(Section.getAlign()); + assert(Log <= GOFF::ESD_ALIGN_4Kpage && "Alignment too large"); + GOFFSec.EDAttributes = {true, + GOFF::ESD_EXE_CODE, + AMODE[Is64Bit], + RMODE[Is64Bit], + GOFF::ESD_NS_NormalName, + GOFF::ESD_TS_ByteOriented, + GOFF::ESD_BA_Concatenate, + GOFF::ESD_LB_Initial, + GOFF::ESD_RQ_0, + static_cast<GOFF::ESDAlignment>(Log)}; + GOFFSec.LDorPRName = GOFFSec.SDName; + GOFFSec.LDAttributes = {false, + GOFF::ESD_EXE_CODE, + GOFF::ESD_NS_NormalName, + GOFF::ESD_BST_Strong, + LINKAGE[UsesXPLINK], + AMODE[Is64Bit], + IsCsectCodeNameEmpty ? GOFF::ESD_BSC_Section + : GOFF::ESD_BSC_Library}; + GOFFSec.Tag = GOFFSectionData::LD; + } else if (Section.getName() == ".ada") { + assert(!RootSDName.empty() && "RootSD must be defined already"); + GOFFSec.SDName = RootSDName; + GOFFSec.SDAttributes = RootSDAttributes; + GOFFSec.IsSDRootSD = true; + GOFFSec.EDName = WSA[Is64Bit]; + GOFFSec.EDAttributes = {false, + GOFF::ESD_EXE_DATA, + AMODE[Is64Bit], + RMODE[Is64Bit], + GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, + GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Deferred, + GOFF::ESD_RQ_1, + Is64Bit ? GOFF::ESD_ALIGN_Quadword + : GOFF::ESD_ALIGN_Doubleword}; + ADALDName = BaseName.str().append("#S"); + GOFFSec.LDorPRName = ADALDName; + GOFFSec.PRAttributes = {false, + false, + GOFF::ESD_EXE_DATA, + GOFF::ESD_NS_Parts, + GOFF::ESD_LT_XPLink, + AMODE[Is64Bit], + GOFF::ESD_BSC_Section, + GOFF::ESD_DSS_NoWarning, + Is64Bit ? GOFF::ESD_ALIGN_Quadword + : GOFF::ESD_ALIGN_Doubleword, + 0}; + GOFFSec.Tag = GOFFSectionData::PR; + } else if (Section.getName().starts_with(".gcc_exception_table")) { + GOFFSec.SDName = RootSDName; + GOFFSec.SDAttributes = RootSDAttributes; + GOFFSec.IsSDRootSD = true; + GOFFSec.EDName = WSA[Is64Bit]; + GOFFSec.EDAttributes = {false, + GOFF::ESD_EXE_DATA, + AMODE[Is64Bit], + RMODE[Is64Bit], + GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, + GOFF::ESD_BA_Merge, + UsesXPLINK ? GOFF::ESD_LB_Initial + : GOFF::ESD_LB_Deferred, + GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Doubleword}; + GOFFSec.LDorPRName = Section.getName(); + GOFFSec.PRAttributes = {true, + false, + GOFF::ESD_EXE_Unspecified, + GOFF::ESD_NS_Parts, + LINKAGE[UsesXPLINK], + AMODE[Is64Bit], + GOFF::ESD_BSC_Section, + GOFF::ESD_DSS_NoWarning, + GOFF::ESD_ALIGN_Fullword, + 0}; + GOFFSec.Tag = GOFFSectionData::PR; + } else if (Section.getName() == ".ppa2list") { + GOFFSec.SDName = RootSDName; + GOFFSec.SDAttributes = RootSDAttributes; + GOFFSec.IsSDRootSD = true; + GOFFSec.EDName = PPA2[Is64Bit]; + GOFFSec.EDAttributes = {true, + GOFF::ESD_EXE_DATA, + AMODE[Is64Bit], + RMODE[Is64Bit], + GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, + GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Initial, + GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Doubleword}; + GOFFSec.LDorPRName = ".&ppa2"; + GOFFSec.PRAttributes = {true, + false, + GOFF::ESD_EXE_Unspecified, + GOFF::ESD_NS_Parts, + GOFF::ESD_LT_OS, + AMODE[Is64Bit], + GOFF::ESD_BSC_Section, + GOFF::ESD_DSS_NoWarning, + GOFF::ESD_ALIGN_Doubleword, + 0}; + GOFFSec.Tag = GOFFSectionData::PR; + } else if (Section.getName() == ".idrl") { + GOFFSec.SDName = RootSDName; + GOFFSec.SDAttributes = RootSDAttributes; + GOFFSec.IsSDRootSD = true; + GOFFSec.EDName = "B_IDRL"; + GOFFSec.EDAttributes = {true, + GOFF::ESD_EXE_Unspecified, + AMODE[Is64Bit], + RMODE[Is64Bit], + GOFF::ESD_NS_NormalName, + GOFF::ESD_TS_Structured, + GOFF::ESD_BA_Concatenate, + GOFF::ESD_LB_NoLoad, + GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Doubleword}; + GOFFSec.Tag = GOFFSectionData::None; + } else + return std::pair(GOFFSec, false); + return std::pair(GOFFSec, true); +} diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index ab7552ca01061..a514a07ef7d3e 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -557,7 +557,7 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { Ctx->getGOFFSection(".ppa2list", SectionKind::getData(), nullptr); ADASection = Ctx->getGOFFSection(".ada", SectionKind::getData(), nullptr); - IDRLSection = Ctx->getGOFFSection("B_IDRL", SectionKind::getData(), nullptr); + IDRLSection = Ctx->getGOFFSection(".idrl", SectionKind::getData(), nullptr); } void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) { diff --git a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll index 07025091fb240..82f416ddb8bf9 100644 --- a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll +++ b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll @@ -19,7 +19,7 @@ ; CHECK: .quad L#PPA2-CELQSTRT * A(PPA2-CELQSTRT) ; CHECK: L#PPA1_void_test_0: ; CHECK: .long L#PPA2-L#PPA1_void_test_0 * Offset to PPA2 -; CHECK: .section "B_IDRL" +; CHECK: .section ".idrl" ; CHECK: .byte 0 ; CHECK: .byte 3 ; CHECK: .short 30 diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll new file mode 100644 index 0000000000000..a0c64f0b83013 --- /dev/null +++ b/llvm/test/MC/GOFF/section.ll @@ -0,0 +1,73 @@ +; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj -o - | \ +; RUN: od -Ax -tx1 -v | FileCheck --ignore-case %s +; REQUIRES: systemz-registered-target + +source_filename = "test.ll" + +declare void @other(...) + +define void @me() { +entry: + tail call void @other() + ret void +} + +; Header record: +; 03 is prefix byte +; f. is header type +; .0 is flag +; 00 is version +; The 1 at offset 0x33 is the architecture level. +; CHECK: 000000 03 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +; CHECK: 000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +; CHECK: 000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +; CHECK: 000030 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 +; CHECK: 000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +; ESD record, type SD. +; 03 is prefix byte +; 0. is header type +; .0 is flag +; 00 is version +; 00 is type = SD +; The 01 at offset 0x57 is the id of the symbol. +; The 60 at offset 0x89 is the tasking behavior. +; The 01 at offset 0x91 is the binding scope. +; The name begins at offset 0x97, and is test#C. +; CHECK: 0000050 03 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 +; CHECK: 0000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +; CHECK: 0000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +; CHECK: 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60 +; CHECK: 0000090 00 01 00 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00 + +; ESD record, type ED. +; The name is C_WSA64. +; CHECK: 00000a0 03 00 00 01 00 00 00 02 00 00 00 01 00 00 00 00 +; CHECK: 00000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +; CHECK: 00000c0 00 00 00 00 00 00 00 00 03 81 00 00 00 00 00 00 +; CHECK: 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 04 04 01 01 +; CHECK: 00000e0 00 40 04 00 00 00 00 07 c3 6d e6 e2 c1 f6 f4 00 + +; ESD record, type PR. +; The name is test#S. +; CHECK: 00000f0 03 00 00 03 00 00 00 03 00 00 00 02 00 00 00 00 +; CHECK: 0000100 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 +; CHECK: 0000110 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 +; CHECK: 0000120 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 01 +; CHECK: 0000130 00 01 24 00 00 00 00 06 a3 85 a2 a3 7b e2 00 00 + +; ESD record, type ED. +; The name is C_CODE64. +; CHECK: 0000140 03 00 00 01 00 00 00 04 00 00 00 01 00 00 00 00 +; CHECK: 0000150 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 +; CHECK: 0000160 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00 +; CHECK: 0000170 00 00 00 00 00 00 00 00 00 00 00 00 04 04 00 0a +; CHECK: 0000180 00 00 04 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4 + +; ESD record, type LD. +; The name is test#C. +; CHECK: 0000190 03 00 00 02 00 00 00 05 00 00 00 04 00 00 00 00 +; CHECK: 00001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +; CHECK: 00001b0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 03 +; CHECK: 00001c0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02 +; CHECK: 00001d0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00 >From bb71a074a822a18140f6d312dbdde259fe6c6a71 Mon Sep 17 00:00:00 2001 From: Kai Nacke <kai.peter.na...@ibm.com> Date: Wed, 2 Apr 2025 11:25:15 -0400 Subject: [PATCH 2/7] Update llvm/include/llvm/MC/MCGOFFSymbolMapper.h Co-authored-by: Neumann Hon <neumann....@ibm.com> --- llvm/include/llvm/MC/MCGOFFSymbolMapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h index dbdc1408dab2f..1402f8ad9713e 100644 --- a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h +++ b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h @@ -45,7 +45,7 @@ class MCSectionGOFF; // referenced PRs is pulled into the resulting binary. // // Both approaches are used, which means that the equivalent of a section in ELF -// results in 3 GOFF symbol, either SD/ED/LD or SD/ED/PR. Moreover, certain +// results in 3 GOFF symbols, either SD/ED/LD or SD/ED/PR. Moreover, certain // sections are fine with just defining SD/ED symbols. The SymbolMapper takes // care of all those details. >From a0a2a1f52137923a78470c4d74822f0518b45082 Mon Sep 17 00:00:00 2001 From: Kai Nacke <kai.peter.na...@ibm.com> Date: Wed, 2 Apr 2025 11:27:57 -0400 Subject: [PATCH 3/7] Update llvm/include/llvm/MC/MCGOFFSymbolMapper.h Co-authored-by: Neumann Hon <neumann....@ibm.com> --- llvm/include/llvm/MC/MCGOFFSymbolMapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h index 1402f8ad9713e..252fc20454536 100644 --- a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h +++ b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h @@ -40,7 +40,7 @@ class MCSectionGOFF; // the whole data is pulled into the resulting executable, and the addresses // given by the LD symbols are resolved. // -// The alternative is to use a Part Defiition (PR). In this case, the data (in a +// The alternative is to use a Part Definition (PR). In this case, the data (in a // text record) is associated with the part. When binding, only the data of // referenced PRs is pulled into the resulting binary. // >From 18cd9eb5e1a042800648dff3d5872552797c9108 Mon Sep 17 00:00:00 2001 From: Kai Nacke <kai.peter.na...@ibm.com> Date: Wed, 2 Apr 2025 11:28:22 -0400 Subject: [PATCH 4/7] Update llvm/lib/MC/GOFFObjectWriter.cpp Co-authored-by: Neumann Hon <neumann....@ibm.com> --- llvm/lib/MC/GOFFObjectWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp index 92603c6fb1002..062e62f31be40 100644 --- a/llvm/lib/MC/GOFFObjectWriter.cpp +++ b/llvm/lib/MC/GOFFObjectWriter.cpp @@ -429,7 +429,7 @@ void GOFFWriter::writeHeader() { void GOFFWriter::writeSymbol(const GOFFSymbol &Symbol) { if (Symbol.Offset >= (((uint64_t)1) << 31)) - report_fatal_error("ESD offset outof range"); + report_fatal_error("ESD offset out of range"); // All symbol names are in EBCDIC. SmallString<256> Name; >From f2be856fba17f7b9f8ba462b2cfbada00af5cd49 Mon Sep 17 00:00:00 2001 From: Kai Nacke <kai.peter.na...@ibm.com> Date: Wed, 2 Apr 2025 11:46:30 -0400 Subject: [PATCH 5/7] More updates --- llvm/include/llvm/BinaryFormat/GOFF.h | 8 ++++---- llvm/include/llvm/MC/MCGOFFSymbolMapper.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h index 43d80e0c247e9..bfa41d100a3b7 100644 --- a/llvm/include/llvm/BinaryFormat/GOFF.h +++ b/llvm/include/llvm/BinaryFormat/GOFF.h @@ -174,7 +174,7 @@ enum SubsectionKind : uint8_t { // in a byte as bit zero. The Flags type helps to set bits in byte according // to this numeration order. class Flags { - uint8_t Val; + uint8_t Val = 0; constexpr static uint8_t bits(uint8_t BitIndex, uint8_t Length, uint8_t Value, uint8_t OldValue) { @@ -185,7 +185,7 @@ class Flags { } public: - constexpr Flags() : Val(0) {} + constexpr Flags() = default; constexpr Flags(uint8_t BitIndex, uint8_t Length, uint8_t Value) : Val(bits(BitIndex, Length, Value, 0)) {} @@ -204,7 +204,7 @@ class Flags { }; // Structure for the flag field of a symbol. See -// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record, +// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record , // offset 41, for the definition. struct SymbolFlags { Flags SymFlags; @@ -221,7 +221,7 @@ struct SymbolFlags { #undef GOFF_SYMBOL_FLAG -constexpr operator uint8_t() const { return static_cast<uint8_t>(SymFlags); } + constexpr operator uint8_t() const { return static_cast<uint8_t>(SymFlags); } }; // Structure for the behavioral attributes. See diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h index 252fc20454536..c1aba6f1a413c 100644 --- a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h +++ b/llvm/include/llvm/MC/MCGOFFSymbolMapper.h @@ -32,7 +32,7 @@ class MCSectionGOFF; // location of data. For example, the equivalent of the ELF .text section is // made up of a Section Definition (SD) and a class (Element Definition; ED). // The name of the SD symbol depends on the application, while the class has the -// predefined name C_CODE64. +// predefined name C_CODE/C_CODE64 in AMODE31 and AMODE64 respectively. // // Data can be placed into this structure in 2 ways. First, the data (in a text // record) can be associated with an ED symbol. To refer to data, a Label >From 3cf7324ec5b335d75d1b887a49d0992abc31a6d2 Mon Sep 17 00:00:00 2001 From: Kai Nacke <kai.peter.na...@ibm.com> Date: Wed, 2 Apr 2025 19:44:01 -0400 Subject: [PATCH 6/7] Remove the class GOFFSymbolMapper --- llvm/include/llvm/BinaryFormat/GOFF.h | 4 +- .../CodeGen/TargetLoweringObjectFileImpl.h | 2 + llvm/include/llvm/MC/MCContext.h | 35 ++- ...CGOFFSymbolMapper.h => MCGOFFAttributes.h} | 89 +++----- llvm/include/llvm/MC/MCGOFFStreamer.h | 5 + llvm/include/llvm/MC/MCObjectFileInfo.h | 4 - llvm/include/llvm/MC/MCSectionGOFF.h | 71 +++++- .../CodeGen/TargetLoweringObjectFileImpl.cpp | 59 ++++- llvm/lib/MC/CMakeLists.txt | 1 - llvm/lib/MC/GOFFObjectWriter.cpp | 80 ++++--- llvm/lib/MC/MCContext.cpp | 72 ++++++- llvm/lib/MC/MCGOFFStreamer.cpp | 18 ++ llvm/lib/MC/MCGOFFSymbolMapper.cpp | 203 ------------------ llvm/lib/MC/MCObjectFileInfo.cpp | 58 +++-- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 7 +- llvm/test/MC/GOFF/section.ll | 1 - 16 files changed, 362 insertions(+), 347 deletions(-) rename llvm/include/llvm/MC/{MCGOFFSymbolMapper.h => MCGOFFAttributes.h} (69%) delete mode 100644 llvm/lib/MC/MCGOFFSymbolMapper.cpp diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h index bfa41d100a3b7..49d2809cb6524 100644 --- a/llvm/include/llvm/BinaryFormat/GOFF.h +++ b/llvm/include/llvm/BinaryFormat/GOFF.h @@ -204,8 +204,8 @@ class Flags { }; // Structure for the flag field of a symbol. See -// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record , -// offset 41, for the definition. +// https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-external-symbol-definition-record +// at offset 41 for the definition. struct SymbolFlags { Flags SymFlags; diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 10f0594c267ae..b2ff064297809 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -320,6 +320,8 @@ class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile { TargetLoweringObjectFileGOFF(); ~TargetLoweringObjectFileGOFF() override = default; + void getModuleMetadata(Module &M) override; + MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override; MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind, diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index e97c890ce9135..a35df1bba4bc1 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -19,8 +19,10 @@ #include "llvm/BinaryFormat/XCOFF.h" #include "llvm/MC/MCAsmMacro.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCPseudoProbe.h" #include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSectionGOFF.h" #include "llvm/MC/MCSymbolTableEntry.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Allocator.h" @@ -54,7 +56,6 @@ class MCSection; class MCSectionCOFF; class MCSectionDXContainer; class MCSectionELF; -class MCSectionGOFF; class MCSectionMachO; class MCSectionSPIRV; class MCSectionWasm; @@ -599,8 +600,36 @@ class MCContext { unsigned Flags, unsigned EntrySize); - MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind, - MCSection *Parent, uint32_t Subsection = 0); +private: + MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName, + GOFF::SDAttr SDAttributes, StringRef EDName, + GOFF::EDAttr EDAttributes, StringRef LDorPRName, + GOFF::LDAttr LDAttributes, + GOFF::PRAttr PRAttributes, + MCSectionGOFF::SectionFlags Flags); + +public: + // Create a section with SD/ED/LD symbols. + MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName, + GOFF::SDAttr SDAttributes, StringRef EDName, + GOFF::EDAttr EDAttributes, StringRef LDorPRName, + GOFF::LDAttr LDAttributes); + // Create a section with SD/ED/PR symbols. + MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef SDName, + GOFF::SDAttr SDAttributes, StringRef EDName, + GOFF::EDAttr EDAttributes, StringRef LDorPRName, + GOFF::PRAttr PRAttributes); + // Create a section with root-SD/ED/LD symbols, using the root-SD name for LD. + MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName, + GOFF::EDAttr EDAttributes, + GOFF::LDAttr LDAttributes); + // Create a section with root-SD/ED/PR symbols. + MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName, + GOFF::EDAttr EDAttributes, StringRef PRName, + GOFF::PRAttr PRAttributes); + // Create a section with root-SD/ED symbols. + MCSectionGOFF *getGOFFSection(SectionKind Kind, StringRef EDName, + GOFF::EDAttr EDAttributes); MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, StringRef COMDATSymName, int Selection, diff --git a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h b/llvm/include/llvm/MC/MCGOFFAttributes.h similarity index 69% rename from llvm/include/llvm/MC/MCGOFFSymbolMapper.h rename to llvm/include/llvm/MC/MCGOFFAttributes.h index c1aba6f1a413c..6a27438b6e81a 100644 --- a/llvm/include/llvm/MC/MCGOFFSymbolMapper.h +++ b/llvm/include/llvm/MC/MCGOFFAttributes.h @@ -1,4 +1,4 @@ -//===- MCGOFFSymbolMapper.h - Maps MC section/symbol to GOFF symbols ------===// +//===- MCGOFFAttributes.h - Attributes of GOFF symbols --------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,25 +6,18 @@ // //===----------------------------------------------------------------------===// // -// Maps a section or a symbol to the GOFF symbols it is composed of, and their -// attributes. +// Defines the various attribute collections defining GOFF symbols. // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCGOFFSYMBOLMAPPER_H -#define LLVM_MC_MCGOFFSYMBOLMAPPER_H +#ifndef LLVM_MC_MCGOFFATTRIBUTES_H +#define LLVM_MC_MCGOFFATTRIBUTES_H #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/GOFF.h" -#include "llvm/Support/Alignment.h" -#include <string> -#include <utility> namespace llvm { -class MCAssembler; -class MCContext; -class MCSectionGOFF; - +namespace GOFF { // An "External Symbol Definition" in the GOFF file has a type, and depending on // the type a different subset of the fields is used. // @@ -40,8 +33,8 @@ class MCSectionGOFF; // the whole data is pulled into the resulting executable, and the addresses // given by the LD symbols are resolved. // -// The alternative is to use a Part Definition (PR). In this case, the data (in a -// text record) is associated with the part. When binding, only the data of +// The alternative is to use a Part Definition (PR). In this case, the data (in +// a text record) is associated with the part. When binding, only the data of // referenced PRs is pulled into the resulting binary. // // Both approaches are used, which means that the equivalent of a section in ELF @@ -95,54 +88,40 @@ struct PRAttr { uint32_t SortKey = 0; }; -struct GOFFSectionData { - // Name and attributes of SD symbol. - StringRef SDName; - SDAttr SDAttributes; - - // Name and attributes of ED symbol. - StringRef EDName; - EDAttr EDAttributes; - - // Name and attributes of LD or PR symbol. - StringRef LDorPRName; - LDAttr LDAttributes; - PRAttr PRAttributes; +// Class names and other values depending on AMODE64 or AMODE31, and other +// environment properties. +template <bool Is64Bit> +constexpr StringLiteral CODE = + Is64Bit ? StringLiteral("C_CODE64") : StringLiteral("C_CODE"); - // Indicates if there is a LD or PR symbol. - enum { None, LD, PR } Tag; - - // Indicates if the SD symbol is to root symbol (aka the Csect Code). - bool IsSDRootSD; -}; +template <bool Is64Bit> +constexpr StringLiteral WSA = + Is64Bit ? StringLiteral("C_WSA64") : StringLiteral("C_WSA"); -class GOFFSymbolMapper { - MCContext &Ctx; +template <bool Is64Bit> +constexpr StringLiteral DATA = + Is64Bit ? StringLiteral("C_DATA64") : StringLiteral("C_DATA"); - std::string RootSDName; - SDAttr RootSDAttributes; +template <bool Is64Bit> +constexpr StringLiteral PPA2 = + Is64Bit ? StringLiteral("C_@@QPPA2") : StringLiteral("C_@@PPA2"); - std::string ADALDName; +template <bool Is64Bit> +constexpr GOFF::ESDAmode AMODE = + Is64Bit ? GOFF::ESD_AMODE_64 : GOFF::ESD_AMODE_ANY; - StringRef BaseName; +template <bool Is64Bit> +constexpr GOFF::ESDRmode RMODE = + Is64Bit ? GOFF::ESD_RMODE_64 : GOFF::ESD_RMODE_31; - bool IsCsectCodeNameEmpty; - bool Is64Bit; - bool UsesXPLINK; - -public: - GOFFSymbolMapper(MCContext &Ctx); - GOFFSymbolMapper(MCAssembler &Asm); - - // Required order: .text first, then .ada. - std::pair<GOFFSectionData, bool> getSection(const MCSectionGOFF &Section); - - void setBaseName(); - void determineRootSD(StringRef CSectCodeName); - llvm::StringRef getRootSDName() const; - const SDAttr &getRootSD() const; -}; +template <bool IsXPLINK> +constexpr GOFF::ESDLinkageType LINKAGE = + IsXPLINK ? GOFF::ESD_LT_XPLink : GOFF::ESD_LT_OS; +template <bool IsXPLINK> +constexpr GOFF::ESDLoadingBehavior LOADBEHAVIOR = + IsXPLINK ? GOFF::ESD_LB_Initial : GOFF::ESD_LB_Deferred; +} // namespace GOFF } // namespace llvm #endif diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h index 78c1f5b60434b..779d44a8930b3 100644 --- a/llvm/include/llvm/MC/MCGOFFStreamer.h +++ b/llvm/include/llvm/MC/MCGOFFStreamer.h @@ -16,6 +16,9 @@ namespace llvm { class GOFFObjectWriter; class MCGOFFStreamer : public MCObjectStreamer { + std::string RootSDName; + std::string ADAPRName; + public: MCGOFFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, std::unique_ptr<MCObjectWriter> OW, @@ -25,6 +28,8 @@ class MCGOFFStreamer : public MCObjectStreamer { ~MCGOFFStreamer() override; + void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override; + GOFFObjectWriter &getWriter(); bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override { diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h index fb575fe721015..56697ee3ae962 100644 --- a/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -230,8 +230,6 @@ class MCObjectFileInfo { MCSection *GLJMPSection = nullptr; // GOFF specific sections. - MCSection *PPA1Section = nullptr; - MCSection *PPA2Section = nullptr; MCSection *PPA2ListSection = nullptr; MCSection *ADASection = nullptr; MCSection *IDRLSection = nullptr; @@ -438,8 +436,6 @@ class MCObjectFileInfo { MCSection *getGLJMPSection() const { return GLJMPSection; } // GOFF specific sections. - MCSection *getPPA1Section() const { return PPA1Section; } - MCSection *getPPA2Section() const { return PPA2Section; } MCSection *getPPA2ListSection() const { return PPA2ListSection; } MCSection *getADASection() const { return ADASection; } MCSection *getIDRLSection() const { return IDRLSection; } diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h index 11c0f95364037..0683c4690b0ba 100644 --- a/llvm/include/llvm/MC/MCSectionGOFF.h +++ b/llvm/include/llvm/MC/MCSectionGOFF.h @@ -15,7 +15,9 @@ #ifndef LLVM_MC_MCSECTIONGOFF_H #define LLVM_MC_MCSECTIONGOFF_H +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/BinaryFormat/GOFF.h" +#include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCSection.h" #include "llvm/Support/raw_ostream.h" @@ -25,13 +27,38 @@ class MCExpr; class MCSectionGOFF final : public MCSection { private: - MCSection *Parent; - uint32_t Subsection; + // The names of the GOFF symbols. + StringRef SDName; + StringRef EDName; + StringRef LDorPRName; + + // The attributes of the GOFF symbols. + GOFF::SDAttr SDAttributes; + GOFF::EDAttr EDAttributes; + GOFF::LDAttr LDAttributes; + GOFF::PRAttr PRAttributes; + +public: + enum SectionFlags { + UsesRootSD = 1, // Uses the common root SD. + HasLD = 2, // Has a LD symbol. + HasPR = 4, // Has a PR symbol. + LDorPRNameIsSD = 8, // The LD or PR name is the same as the SD name. + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ 8) + }; + +private: + SectionFlags Flags; + bool IsADA; friend class MCContext; - MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, uint32_t Sub) - : MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr), - Parent(P), Subsection(Sub) {} + MCSectionGOFF(StringRef SynName, SectionKind K, SectionFlags Flags, + StringRef SDName, GOFF::SDAttr SDAttributes, StringRef EDName, + GOFF::EDAttr EDAttributes, StringRef LDorPRName, + GOFF::LDAttr LDAttributes, GOFF::PRAttr PRAttributes) + : MCSection(SV_GOFF, SynName, K.isText(), /*IsVirtual=*/false, nullptr), + SDName(SDName), EDName(EDName), LDorPRName(LDorPRName), + SDAttributes(SDAttributes), EDAttributes(EDAttributes), Flags(Flags) {} public: void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, @@ -42,8 +69,38 @@ class MCSectionGOFF final : public MCSection { bool useCodeAlign() const override { return false; } - MCSection *getParent() const { return Parent; } - uint32_t getSubsection() const { return Subsection; } + // Accessors to the various symbol names. + StringRef getSDName() const { return SDName; }; + StringRef getEDName() const { return EDName; }; + StringRef getLDorPRName() const { + assert(Flags & (HasLD | HasPR) && "LD/PR name not available"); + return (Flags & LDorPRNameIsSD) ? SDName : LDorPRName; + }; + + // Setters for the SD and LD/PR symbol names. + void setSDName(StringRef Name) { SDName = Name; } + void setLDorPRName(StringRef Name) { LDorPRName = Name; } + + // Accessors to the various attributes. + GOFF::SDAttr getSDAttributes() const { return SDAttributes; } + GOFF::EDAttr getEDAttributes() const { return EDAttributes; } + GOFF::LDAttr getLDAttributes() const { + assert(Flags & HasLD && "LD not available"); + return LDAttributes; + } + GOFF::PRAttr getPRAttributes() const { + assert(Flags & HasPR && "PR not available"); + return PRAttributes; + } + + // Query various flags. + bool usesRootSD() const { return Flags & UsesRootSD; } + bool hasLD() const { return Flags & HasLD; } + bool hasPR() const { return Flags & HasPR; } + bool isLDorPRNameTheSD() const { return Flags & LDorPRNameIsSD; } + + bool isADA() const { return IsADA; } + void setADA() { IsADA = true; } static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; } }; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 00e4533559c28..529e86c0b893a 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -47,6 +47,7 @@ #include "llvm/MC/MCAsmInfoDarwin.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionGOFF.h" @@ -2759,6 +2760,12 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA( //===----------------------------------------------------------------------===// TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default; +void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) { + // Set the main file name if not set previously by the tool. + if (getContext().getMainFileName().empty()) + getContext().setMainFileName(M.getSourceFileName()); +} + MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { return SelectSectionForGlobal(GO, Kind, TM); @@ -2767,15 +2774,55 @@ MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA( const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { std::string Name = ".gcc_exception_table." + F.getName().str(); - return getContext().getGOFFSection(Name, SectionKind::getData(), nullptr, 0); + constexpr bool Is64Bit = true; + constexpr bool UsesXPLINK = true; + return getContext().getGOFFSection( + SectionKind::getData(), GOFF::WSA<true>, + GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>, + GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::LOADBEHAVIOR<UsesXPLINK>, GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Doubleword}, + Name, + GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts, + GOFF::LINKAGE<UsesXPLINK>, GOFF::AMODE<Is64Bit>, + GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning, + GOFF::ESD_ALIGN_Fullword, 0}); } MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { auto *Symbol = TM.getSymbol(GO); - if (Kind.isBSS()) - return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(), - nullptr, 0); - - return getContext().getObjectFileInfo()->getTextSection(); + constexpr bool Is64Bit = true; + constexpr bool UsesXPLINK = true; + + if (Kind.isBSS() || Kind.isData()) { + GOFF::ESDBindingScope PRBindingScope = + GO->hasExternalLinkage() + ? (GO->hasDefaultVisibility() ? GOFF::ESD_BSC_ImportExport + : GOFF::ESD_BSC_Library) + : GOFF::ESD_BSC_Section; + GOFF::ESDBindingScope SDBindingScope = + PRBindingScope == GOFF::ESD_BSC_Section ? GOFF::ESD_BSC_Section + : GOFF::ESD_BSC_Unspecified; + return getContext().getGOFFSection( + Kind, Symbol->getName(), + GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope}, + GOFF::WSA<Is64Bit>, + GOFF::EDAttr{false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>, + GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, + static_cast<GOFF::ESDAlignment>(GO->getAlignment()) + + }, + Symbol->getName(), + GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts, + GOFF::LINKAGE<UsesXPLINK>, GOFF::AMODE<Is64Bit>, + PRBindingScope, GOFF::ESD_DSS_NoWarning, + static_cast<GOFF::ESDAlignment>(GO->getAlignment()), 0 + + }); + } + return TextSection; } diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index 967ec73a2be5b..f49f14c848b90 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -26,7 +26,6 @@ add_llvm_component_library(LLVMMC MCExpr.cpp MCFragment.cpp MCGOFFStreamer.cpp - MCGOFFSymbolMapper.cpp MCInst.cpp MCInstPrinter.cpp MCInstrAnalysis.cpp diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp index 062e62f31be40..cb8820d82f65f 100644 --- a/llvm/lib/MC/GOFFObjectWriter.cpp +++ b/llvm/lib/MC/GOFFObjectWriter.cpp @@ -13,7 +13,7 @@ #include "llvm/BinaryFormat/GOFF.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCGOFFObjectWriter.h" -#include "llvm/MC/MCGOFFSymbolMapper.h" +#include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCSectionGOFF.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/Casting.h" @@ -219,7 +219,7 @@ class GOFFSymbol { GOFFSymbol() : EsdId(0), ParentEsdId(0) {} - GOFFSymbol(StringRef Name, uint32_t EsdID, const SDAttr &Attr) + GOFFSymbol(StringRef Name, uint32_t EsdID, const GOFF::SDAttr &Attr) : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(0), SymbolType(GOFF::ESD_ST_SectionDefinition) { BehavAttrs.setTaskingBehavior(Attr.TaskingBehavior); @@ -227,7 +227,7 @@ class GOFFSymbol { } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, - const EDAttr &Attr) + const GOFF::EDAttr &Attr) : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), SymbolType(GOFF::ESD_ST_ElementDefinition) { this->NameSpace = Attr.NameSpace; @@ -245,7 +245,7 @@ class GOFFSymbol { } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, - const LDAttr &Attr) + const GOFF::LDAttr &Attr) : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), SymbolType(GOFF::ESD_ST_LabelDefinition) { this->NameSpace = Attr.NameSpace; @@ -258,7 +258,7 @@ class GOFFSymbol { } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, - const PRAttr &Attr) + const GOFF::PRAttr &Attr) : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), SymbolType(GOFF::ESD_ST_PartReference) { this->NameSpace = Attr.NameSpace; @@ -277,9 +277,6 @@ class GOFFWriter { GOFFOstream OS; [[maybe_unused]] MCAssembler &Asm; - /// Mapping from MCSectionGOFF/MCSymbolGOFF to GOFF symbols and attributes. - GOFFSymbolMapper SymbolMapper; - /// Counter for symbol id's. uint32_t EsdIdCounter = 0; @@ -291,12 +288,12 @@ class GOFFWriter { void writeSymbol(const GOFFSymbol &Symbol); void writeEnd(); - GOFFSymbol createGOFFSymbol(StringRef Name, const SDAttr &Attr); - GOFFSymbol createGOFFSymbol(StringRef Name, const EDAttr &Attr, + GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::SDAttr &Attr); + GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::EDAttr &Attr, uint32_t ParentEsdId); - GOFFSymbol createGOFFSymbol(StringRef Name, const LDAttr &Attr, + GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::LDAttr &Attr, uint32_t ParentEsdId); - GOFFSymbol createGOFFSymbol(StringRef Name, const PRAttr &Attr, + GOFFSymbol createGOFFSymbol(StringRef Name, const GOFF::PRAttr &Attr, uint32_t ParentEsdId); void defineRootSymbol(const MCSectionGOFF *Text); @@ -310,66 +307,64 @@ class GOFFWriter { } // namespace GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm) - : OS(OS), Asm(Asm), SymbolMapper(Asm) {} + : OS(OS), Asm(Asm) {} -GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const SDAttr &Attr) { +GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::SDAttr &Attr) { return GOFFSymbol(Name, ++EsdIdCounter, Attr); } -GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const EDAttr &Attr, +GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::EDAttr &Attr, uint32_t ParentEsdId) { return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr); } -GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const LDAttr &Attr, +GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::LDAttr &Attr, uint32_t ParentEsdId) { return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr); } -GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const PRAttr &Attr, +GOFFSymbol GOFFWriter::createGOFFSymbol(StringRef Name, const GOFF::PRAttr &Attr, uint32_t ParentEsdId) { return GOFFSymbol(Name, ++EsdIdCounter, ParentEsdId, Attr); } void GOFFWriter::defineRootSymbol(const MCSectionGOFF *Text) { - // There is always a text section except for DWARF unit tests. - SymbolMapper.determineRootSD(""); + // There is always a text section except for DWARF unit tests, so be lenient. GOFFSymbol RootSD = - createGOFFSymbol(SymbolMapper.getRootSDName(), SymbolMapper.getRootSD()); + Text ? createGOFFSymbol(Text->getSDName(), Text->getSDAttributes()) + : createGOFFSymbol("", GOFF::SDAttr{GOFF::ESD_TA_Unspecified, + GOFF::ESD_BSC_Unspecified}); writeSymbol(RootSD); RootSDEsdId = RootSD.EsdId; } void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) { - auto [GOFFSectionData, Found] = SymbolMapper.getSection(Section); - if (Found) { uint32_t SDEsdId = RootSDEsdId; - if (!GOFFSectionData.IsSDRootSD) { - GOFFSymbol SD = createGOFFSymbol(GOFFSectionData.SDName, - GOFFSectionData.SDAttributes); + if (!Section.usesRootSD()) { + GOFFSymbol SD = + createGOFFSymbol(Section.getSDName(), Section.getSDAttributes()); SDEsdId = SD.EsdId; writeSymbol(SD); } - GOFFSymbol ED = createGOFFSymbol(GOFFSectionData.EDName, - GOFFSectionData.EDAttributes, SDEsdId); - if (GOFFSectionData.Tag == GOFFSectionData::None || - GOFFSectionData.Tag == GOFFSectionData::LD) { + GOFFSymbol ED = createGOFFSymbol(Section.getEDName(), + Section.getEDAttributes(), SDEsdId); + if ((!Section.hasLD() && !Section.hasPR()) || Section.hasLD()) { ED.SectionLength = Asm.getSectionAddressSize(Section); } writeSymbol(ED); - if (GOFFSectionData.Tag == GOFFSectionData::LD) { - GOFFSymbol LD = createGOFFSymbol(GOFFSectionData.LDorPRName, - GOFFSectionData.LDAttributes, ED.EsdId); + if (Section.hasLD()) { + GOFFSymbol LD = createGOFFSymbol(Section.getLDorPRName(), + Section.getLDAttributes(), ED.EsdId); if (Section.isText()) LD.ADAEsdId = ADAEsdId; writeSymbol(LD); } - if (GOFFSectionData.Tag == GOFFSectionData::PR) { - GOFFSymbol PR = createGOFFSymbol(GOFFSectionData.LDorPRName, - GOFFSectionData.PRAttributes, ED.EsdId); + if (Section.hasPR()) { + GOFFSymbol PR = createGOFFSymbol(Section.getLDorPRName(), + Section.getPRAttributes(), ED.EsdId); PR.SectionLength = Asm.getSectionAddressSize(Section); if (Section.getName() == ".ada") { // We cannot have a zero-length section for data. If we do, @@ -383,21 +378,18 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) { } writeSymbol(PR); } - return; - } - // TODO It is possible to get here. This will be handled later. } void GOFFWriter::defineSymbols() { - // Search for .text and .ada sections. These should be the first sections in - // the list, so the loop should be cheap. + // Search for .text and .ada sections. MCSectionGOFF *Text = nullptr; MCSectionGOFF *ADA = nullptr; for (MCSection &S : Asm) { - if (S.getName() == ".text") - Text = &cast<MCSectionGOFF>(S); - if (S.getName() == ".ada") - ADA = &cast<MCSectionGOFF>(S); + auto &Section = cast<MCSectionGOFF>(S); + if (Section.isText()) + Text = &Section; + if (Section.isADA()) + ADA = &Section; } defineRootSymbol(Text); if (ADA) diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 09d4b518cc1c5..38b54ef50489d 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -671,24 +671,82 @@ MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags, : std::nullopt; } -MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind, - MCSection *Parent, - uint32_t Subsection) { +MCSectionGOFF * +MCContext::getGOFFSection(SectionKind Kind, StringRef SDName, + GOFF::SDAttr SDAttributes, StringRef EDName, + GOFF::EDAttr EDAttributes, StringRef LDorPRName, + GOFF::LDAttr LDAttributes, GOFF::PRAttr PRAttributes, + MCSectionGOFF::SectionFlags Flags) { + std::string SynName = Twine(SDName) + .concat("/") + .concat(EDName) + .concat("/") + .concat(LDorPRName) + .str(); // Do the lookup. If we don't have a hit, return a new section. - auto IterBool = - GOFFUniquingMap.insert(std::make_pair(Section.str(), nullptr)); + auto IterBool = GOFFUniquingMap.insert(std::make_pair(SynName, nullptr)); auto Iter = IterBool.first; if (!IterBool.second) return Iter->second; - StringRef CachedName = Iter->first; + StringRef CachedSynName = Iter->first; MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate()) - MCSectionGOFF(CachedName, Kind, Parent, Subsection); + MCSectionGOFF(CachedSynName, Kind, Flags, SDName, SDAttributes, EDName, + EDAttributes, LDorPRName, LDAttributes, PRAttributes); Iter->second = GOFFSection; allocInitialFragment(*GOFFSection); return GOFFSection; } +MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef SDName, + GOFF::SDAttr SDAttributes, + StringRef EDName, + GOFF::EDAttr EDAttributes, + StringRef LDorPRName, + GOFF::LDAttr LDAttributes) { + return getGOFFSection(Kind, SDName, SDAttributes, EDName, EDAttributes, + LDorPRName, LDAttributes, GOFF::PRAttr{}, + MCSectionGOFF::HasLD); +} + +MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef SDName, + GOFF::SDAttr SDAttributes, + StringRef EDName, + GOFF::EDAttr EDAttributes, + StringRef LDorPRName, + GOFF::PRAttr PRAttributes) { + return getGOFFSection(Kind, SDName, SDAttributes, EDName, EDAttributes, + LDorPRName, GOFF::LDAttr{}, PRAttributes, + MCSectionGOFF::HasPR); +} + +MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName, + GOFF::EDAttr EDAttributes, + GOFF::LDAttr LDAttributes) { + return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes, "", + LDAttributes, GOFF::PRAttr{}, + MCSectionGOFF::UsesRootSD | + MCSectionGOFF::LDorPRNameIsSD | + MCSectionGOFF::HasLD); +} + +MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName, + GOFF::EDAttr EDAttributes, + StringRef LDorPRName, + GOFF::PRAttr PRAttributes) { + return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes, + LDorPRName, GOFF::LDAttr{}, PRAttributes, + MCSectionGOFF::UsesRootSD | MCSectionGOFF::HasPR); +} + +MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef EDName, + GOFF::EDAttr EDAttributes) { + return getGOFFSection(Kind, "", GOFF::SDAttr{}, EDName, EDAttributes, "", + GOFF::LDAttr{}, GOFF::PRAttr{}, + MCSectionGOFF::UsesRootSD | + MCSectionGOFF::LDorPRNameIsSD); +} + MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, unsigned Characteristics, StringRef COMDATSymName, int Selection, diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp index c9e4c21c857ce..9b97c147ef5b3 100644 --- a/llvm/lib/MC/MCGOFFStreamer.cpp +++ b/llvm/lib/MC/MCGOFFStreamer.cpp @@ -26,6 +26,24 @@ GOFFObjectWriter &MCGOFFStreamer::getWriter() { return static_cast<GOFFObjectWriter &>(getAssembler().getWriter()); } +void MCGOFFStreamer::initSections(bool NoExecStack, + const MCSubtargetInfo &STI) { + MCContext &Ctx = getContext(); + + // Initialize the special names for the code and ada section. + StringRef FileName = Ctx.getMainFileName(); + RootSDName = Twine(FileName).concat("#C").str(); + ADAPRName = Twine(FileName).concat("#S").str(); + MCSectionGOFF *TextSection = static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getTextSection()); + MCSectionGOFF *ADASection = static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getADASection()); + TextSection->setSDName(RootSDName); + ADASection->setLDorPRName(ADAPRName); + ADASection->setADA(); + + // Switch to the code section. + switchSection(TextSection); +} + MCStreamer *llvm::createGOFFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> &&MAB, std::unique_ptr<MCObjectWriter> &&OW, diff --git a/llvm/lib/MC/MCGOFFSymbolMapper.cpp b/llvm/lib/MC/MCGOFFSymbolMapper.cpp deleted file mode 100644 index 57012c34a94f1..0000000000000 --- a/llvm/lib/MC/MCGOFFSymbolMapper.cpp +++ /dev/null @@ -1,203 +0,0 @@ -//===- MCGOFFSymbolMapper.cpp - Maps MC section/symbol to GOFF symbols ----===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Maps a section or a symbol to the GOFF symbols it is composed of, and their -// attributes. -// -//===----------------------------------------------------------------------===// - -#include "llvm/MC/MCGOFFSymbolMapper.h" -#include "llvm/BinaryFormat/GOFF.h" -#include "llvm/MC/MCAssembler.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCObjectWriter.h" -#include "llvm/MC/MCSectionGOFF.h" -#include "llvm/Support/Alignment.h" -#include "llvm/Support/Path.h" - -using namespace llvm; - -namespace { -const StringLiteral CODE[2]{"C_CODE", "C_CODE64"}; -const StringLiteral WSA[2]{"C_WSA", "C_WSA64"}; -const StringLiteral PPA2[2]{"C_@@PPA2", "C_@@QPPA2"}; - -const GOFF::ESDAmode AMODE[2]{GOFF::ESD_AMODE_ANY, GOFF::ESD_AMODE_64}; -const GOFF::ESDRmode RMODE[2]{GOFF::ESD_RMODE_31, GOFF::ESD_RMODE_64}; - -const GOFF::ESDLinkageType LINKAGE[2]{GOFF::ESD_LT_OS, GOFF::ESD_LT_XPLink}; -} // namespace - -GOFFSymbolMapper::GOFFSymbolMapper(MCContext &Ctx) : Ctx(Ctx) { - IsCsectCodeNameEmpty = true; - Is64Bit = true; - UsesXPLINK = true; -} - -GOFFSymbolMapper::GOFFSymbolMapper(MCAssembler &Asm) - : GOFFSymbolMapper(Asm.getContext()) { - if (!Asm.getWriter().getFileNames().empty()) - BaseName = - sys::path::stem((*(Asm.getWriter().getFileNames().begin())).first); -} - -void GOFFSymbolMapper::determineRootSD(StringRef CSectCodeName) { - IsCsectCodeNameEmpty = CSectCodeName.empty(); - if (IsCsectCodeNameEmpty) { - RootSDName = BaseName.str().append("#C"); - } else { - RootSDName = CSectCodeName; - } - RootSDAttributes = {GOFF::ESD_TA_Rent, IsCsectCodeNameEmpty - ? GOFF::ESD_BSC_Section - : GOFF::ESD_BSC_Unspecified}; -} - -llvm::StringRef GOFFSymbolMapper::getRootSDName() const { return RootSDName; } - -const SDAttr &GOFFSymbolMapper::getRootSD() const { return RootSDAttributes; } - -std::pair<GOFFSectionData, bool> -GOFFSymbolMapper::getSection(const MCSectionGOFF &Section) { - // Look up GOFFSection from name in MCSectionGOFF. - // Customize result, e.g. csect names, 32/64 bit, etc. - GOFFSectionData GOFFSec; - if (Section.getName() == ".text") { - GOFFSec.SDName = RootSDName; - GOFFSec.SDAttributes = RootSDAttributes; - GOFFSec.IsSDRootSD = true; - GOFFSec.EDName = CODE[Is64Bit]; - // The GOFF alignment is encoded as log_2 value. - uint8_t Log = Log2(Section.getAlign()); - assert(Log <= GOFF::ESD_ALIGN_4Kpage && "Alignment too large"); - GOFFSec.EDAttributes = {true, - GOFF::ESD_EXE_CODE, - AMODE[Is64Bit], - RMODE[Is64Bit], - GOFF::ESD_NS_NormalName, - GOFF::ESD_TS_ByteOriented, - GOFF::ESD_BA_Concatenate, - GOFF::ESD_LB_Initial, - GOFF::ESD_RQ_0, - static_cast<GOFF::ESDAlignment>(Log)}; - GOFFSec.LDorPRName = GOFFSec.SDName; - GOFFSec.LDAttributes = {false, - GOFF::ESD_EXE_CODE, - GOFF::ESD_NS_NormalName, - GOFF::ESD_BST_Strong, - LINKAGE[UsesXPLINK], - AMODE[Is64Bit], - IsCsectCodeNameEmpty ? GOFF::ESD_BSC_Section - : GOFF::ESD_BSC_Library}; - GOFFSec.Tag = GOFFSectionData::LD; - } else if (Section.getName() == ".ada") { - assert(!RootSDName.empty() && "RootSD must be defined already"); - GOFFSec.SDName = RootSDName; - GOFFSec.SDAttributes = RootSDAttributes; - GOFFSec.IsSDRootSD = true; - GOFFSec.EDName = WSA[Is64Bit]; - GOFFSec.EDAttributes = {false, - GOFF::ESD_EXE_DATA, - AMODE[Is64Bit], - RMODE[Is64Bit], - GOFF::ESD_NS_Parts, - GOFF::ESD_TS_ByteOriented, - GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Deferred, - GOFF::ESD_RQ_1, - Is64Bit ? GOFF::ESD_ALIGN_Quadword - : GOFF::ESD_ALIGN_Doubleword}; - ADALDName = BaseName.str().append("#S"); - GOFFSec.LDorPRName = ADALDName; - GOFFSec.PRAttributes = {false, - false, - GOFF::ESD_EXE_DATA, - GOFF::ESD_NS_Parts, - GOFF::ESD_LT_XPLink, - AMODE[Is64Bit], - GOFF::ESD_BSC_Section, - GOFF::ESD_DSS_NoWarning, - Is64Bit ? GOFF::ESD_ALIGN_Quadword - : GOFF::ESD_ALIGN_Doubleword, - 0}; - GOFFSec.Tag = GOFFSectionData::PR; - } else if (Section.getName().starts_with(".gcc_exception_table")) { - GOFFSec.SDName = RootSDName; - GOFFSec.SDAttributes = RootSDAttributes; - GOFFSec.IsSDRootSD = true; - GOFFSec.EDName = WSA[Is64Bit]; - GOFFSec.EDAttributes = {false, - GOFF::ESD_EXE_DATA, - AMODE[Is64Bit], - RMODE[Is64Bit], - GOFF::ESD_NS_Parts, - GOFF::ESD_TS_ByteOriented, - GOFF::ESD_BA_Merge, - UsesXPLINK ? GOFF::ESD_LB_Initial - : GOFF::ESD_LB_Deferred, - GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword}; - GOFFSec.LDorPRName = Section.getName(); - GOFFSec.PRAttributes = {true, - false, - GOFF::ESD_EXE_Unspecified, - GOFF::ESD_NS_Parts, - LINKAGE[UsesXPLINK], - AMODE[Is64Bit], - GOFF::ESD_BSC_Section, - GOFF::ESD_DSS_NoWarning, - GOFF::ESD_ALIGN_Fullword, - 0}; - GOFFSec.Tag = GOFFSectionData::PR; - } else if (Section.getName() == ".ppa2list") { - GOFFSec.SDName = RootSDName; - GOFFSec.SDAttributes = RootSDAttributes; - GOFFSec.IsSDRootSD = true; - GOFFSec.EDName = PPA2[Is64Bit]; - GOFFSec.EDAttributes = {true, - GOFF::ESD_EXE_DATA, - AMODE[Is64Bit], - RMODE[Is64Bit], - GOFF::ESD_NS_Parts, - GOFF::ESD_TS_ByteOriented, - GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Initial, - GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword}; - GOFFSec.LDorPRName = ".&ppa2"; - GOFFSec.PRAttributes = {true, - false, - GOFF::ESD_EXE_Unspecified, - GOFF::ESD_NS_Parts, - GOFF::ESD_LT_OS, - AMODE[Is64Bit], - GOFF::ESD_BSC_Section, - GOFF::ESD_DSS_NoWarning, - GOFF::ESD_ALIGN_Doubleword, - 0}; - GOFFSec.Tag = GOFFSectionData::PR; - } else if (Section.getName() == ".idrl") { - GOFFSec.SDName = RootSDName; - GOFFSec.SDAttributes = RootSDAttributes; - GOFFSec.IsSDRootSD = true; - GOFFSec.EDName = "B_IDRL"; - GOFFSec.EDAttributes = {true, - GOFF::ESD_EXE_Unspecified, - AMODE[Is64Bit], - RMODE[Is64Bit], - GOFF::ESD_NS_NormalName, - GOFF::ESD_TS_Structured, - GOFF::ESD_BA_Concatenate, - GOFF::ESD_LB_NoLoad, - GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword}; - GOFFSec.Tag = GOFFSectionData::None; - } else - return std::pair(GOFFSec, false); - return std::pair(GOFFSec, true); -} diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index a514a07ef7d3e..8def94ad51038 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -13,6 +13,7 @@ #include "llvm/BinaryFormat/Wasm.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionDXContainer.h" @@ -546,18 +547,51 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { } void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { - TextSection = Ctx->getGOFFSection(".text", SectionKind::getText(), nullptr); - BSSSection = Ctx->getGOFFSection(".bss", SectionKind::getBSS(), nullptr); - PPA1Section = Ctx->getGOFFSection(".ppa1", SectionKind::getMetadata(), - TextSection, GOFF::SK_PPA1); - PPA2Section = Ctx->getGOFFSection(".ppa2", SectionKind::getMetadata(), - TextSection, GOFF::SK_PPA2); - - PPA2ListSection = - Ctx->getGOFFSection(".ppa2list", SectionKind::getData(), nullptr); - - ADASection = Ctx->getGOFFSection(".ada", SectionKind::getData(), nullptr); - IDRLSection = Ctx->getGOFFSection(".idrl", SectionKind::getData(), nullptr); + // Some values depend on AMODE31 or AMODE64, or other properties. + constexpr bool Is64Bit = true; + constexpr bool UsesXPLINK = true; + + TextSection = Ctx->getGOFFSection( + SectionKind::getText(), GOFF::CODE<Is64Bit>, + GOFF::EDAttr{true, GOFF::ESD_EXE_CODE, GOFF::AMODE<Is64Bit>, + GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_NormalName, + GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Doubleword}, + GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, GOFF::ESD_NS_NormalName, + GOFF::ESD_BST_Strong, GOFF::LINKAGE<UsesXPLINK>, + GOFF::AMODE<Is64Bit>, GOFF::ESD_BSC_Section}); + + PPA2ListSection = Ctx->getGOFFSection( + SectionKind::getData(), GOFF::PPA2<Is64Bit>, + GOFF::EDAttr{ + true, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>, GOFF::RMODE<Is64Bit>, + GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, GOFF::ESD_ALIGN_Doubleword}, + ".&ppa2", + GOFF::PRAttr{true, false, GOFF::ESD_EXE_Unspecified, GOFF::ESD_NS_Parts, + GOFF::ESD_LT_OS, GOFF::AMODE<Is64Bit>, GOFF::ESD_BSC_Section, + GOFF::ESD_DSS_NoWarning, GOFF::ESD_ALIGN_Doubleword, 0}); + + ADASection = Ctx->getGOFFSection( + SectionKind::getData(), GOFF::WSA<Is64Bit>, + GOFF::EDAttr{ + false, GOFF::ESD_EXE_DATA, GOFF::AMODE<Is64Bit>, GOFF::RMODE<Is64Bit>, + GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1, GOFF::ESD_ALIGN_Quadword}, + "", + GOFF::PRAttr{false, false, GOFF::ESD_EXE_DATA, GOFF::ESD_NS_Parts, + GOFF::ESD_LT_XPLink, GOFF::AMODE<Is64Bit>, + GOFF::ESD_BSC_Section, GOFF::ESD_DSS_NoWarning, + GOFF::ESD_ALIGN_Quadword, 0}); + + IDRLSection = Ctx->getGOFFSection( + SectionKind::getData(), "B_IDRL", + GOFF::EDAttr{true, GOFF::ESD_EXE_Unspecified, GOFF::AMODE<Is64Bit>, + GOFF::RMODE<Is64Bit>, GOFF::ESD_NS_NormalName, + GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate, + GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Doubleword}); } void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) { diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 448753fa43dc1..e18630b710e10 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -21,6 +21,7 @@ #include "TargetInfo/SystemZTargetInfo.h" #include "llvm/ADT/StringExtras.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/BinaryFormat/GOFF.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/IR/Mangler.h" @@ -1229,7 +1230,8 @@ void SystemZAsmPrinter::emitFunctionBodyEnd() { OutStreamer->emitLabel(FnEndSym); OutStreamer->pushSection(); - OutStreamer->switchSection(getObjFileLowering().getPPA1Section()); + OutStreamer->switchSection(getObjFileLowering().getTextSection(), + GOFF::SK_PPA1); emitPPA1(FnEndSym); OutStreamer->popSection(); @@ -1534,7 +1536,8 @@ void SystemZAsmPrinter::emitStartOfAsmFile(Module &M) { void SystemZAsmPrinter::emitPPA2(Module &M) { OutStreamer->pushSection(); - OutStreamer->switchSection(getObjFileLowering().getPPA2Section()); + OutStreamer->switchSection(getObjFileLowering().getTextSection(), + GOFF::SK_PPA2); MCContext &OutContext = OutStreamer->getContext(); // Make CELQSTRT symbol. const char *StartSymbolName = "CELQSTRT"; diff --git a/llvm/test/MC/GOFF/section.ll b/llvm/test/MC/GOFF/section.ll index a0c64f0b83013..16c3580fcf924 100644 --- a/llvm/test/MC/GOFF/section.ll +++ b/llvm/test/MC/GOFF/section.ll @@ -1,6 +1,5 @@ ; RUN: llc <%s --mtriple s390x-ibm-zos --filetype=obj -o - | \ ; RUN: od -Ax -tx1 -v | FileCheck --ignore-case %s -; REQUIRES: systemz-registered-target source_filename = "test.ll" >From 686b6284b3682b330f99839e3928ca46c5a44c6a Mon Sep 17 00:00:00 2001 From: Kai Nacke <kai.peter.na...@ibm.com> Date: Wed, 2 Apr 2025 19:48:21 -0400 Subject: [PATCH 7/7] Update formatting --- llvm/lib/MC/MCGOFFStreamer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp index 9b97c147ef5b3..b05cd46ef3fcf 100644 --- a/llvm/lib/MC/MCGOFFStreamer.cpp +++ b/llvm/lib/MC/MCGOFFStreamer.cpp @@ -34,8 +34,10 @@ void MCGOFFStreamer::initSections(bool NoExecStack, StringRef FileName = Ctx.getMainFileName(); RootSDName = Twine(FileName).concat("#C").str(); ADAPRName = Twine(FileName).concat("#S").str(); - MCSectionGOFF *TextSection = static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getTextSection()); - MCSectionGOFF *ADASection = static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getADASection()); + MCSectionGOFF *TextSection = + static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getTextSection()); + MCSectionGOFF *ADASection = + static_cast<MCSectionGOFF *>(Ctx.getObjectFileInfo()->getADASection()); TextSection->setSDName(RootSDName); ADASection->setLDorPRName(ADAPRName); ADASection->setADA(); _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits