[llvm-branch-commits] [llvm] [GOFF] Add writing of section symbols (PR #133799)
Neumann Hon via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Apr 1 23:13:48 PDT 2025
================
@@ -223,21 +196,222 @@ 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();
};
} // 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);
----------------
Everybody0523 wrote:
Actually, judging by the testcase `section.ll` it seems more likely the above comment is incorrect and this is fine.
If that's the case then nevermind 😅
https://github.com/llvm/llvm-project/pull/133799
More information about the llvm-branch-commits
mailing list