diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -73,32 +73,30 @@ }; // Wrapper for an MCSectionXCOFF. -struct ControlSection { - const MCSectionXCOFF *const MCCsect; +// It can be a Csect or debug section or DWARF section and so on. +struct XCOFFSection { + const MCSectionXCOFF *const MCSec; uint32_t SymbolTableIndex; uint32_t Address; uint32_t Size; SmallVector Syms; SmallVector Relocations; - StringRef getSymbolTableName() const { return MCCsect->getSymbolTableName(); } - ControlSection(const MCSectionXCOFF *MCSec) - : MCCsect(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {} + StringRef getSymbolTableName() const { return MCSec->getSymbolTableName(); } + XCOFFSection(const MCSectionXCOFF *MCSec) + : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {} }; // Type to be used for a container representing a set of csects with // (approximately) the same storage mapping class. For example all the csects // with a storage mapping class of `xmc_pr` will get placed into the same // container. -using CsectGroup = std::deque; +using CsectGroup = std::deque; using CsectGroups = std::deque; -// Represents the data related to a section excluding the csects that make up -// the raw data of the section. The csects are stored separately as not all -// sections contain csects, and some sections contain csects which are better -// stored separately, e.g. the .data section containing read-write, descriptor, -// TOCBase and TOC-entry csects. -struct Section { +// The basic section entry defination. This Section represents a section entry +// in XCOFF section header table. +struct SectionEntry { char Name[XCOFF::NameSize]; // The physical/virtual address of the section. For an object file // these values are equivalent. @@ -111,9 +109,6 @@ int16_t Index; - // Virtual sections do not need storage allocated in the object file. - const bool IsVirtual; - // XCOFF has special section numbers for symbols: // -2 Specifies N_DEBUG, a special symbolic debugging symbol. // -1 Specifies N_ABS, an absolute symbol. The symbol has a value but is not @@ -124,28 +119,53 @@ static constexpr int16_t UninitializedIndex = XCOFF::ReservedSectionNum::N_DEBUG - 1; - CsectGroups Groups; + SectionEntry(StringRef N, int32_t Flags) + : Name(), Address(0), Size(0), FileOffsetToData(0), + FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags), + Index(UninitializedIndex) { + assert(N.size() <= XCOFF::NameSize && "section name too long"); + memcpy(Name, N.data(), N.size()); + } - void reset() { + virtual void reset() { Address = 0; Size = 0; FileOffsetToData = 0; FileOffsetToRelocations = 0; RelocationCount = 0; Index = UninitializedIndex; - // Clear any csects we have stored. - for (auto *Group : Groups) - Group->clear(); } - Section(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual, - CsectGroups Groups) - : Name(), Address(0), Size(0), FileOffsetToData(0), - FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags), - Index(UninitializedIndex), IsVirtual(IsVirtual), Groups(Groups) { + virtual ~SectionEntry() {} +}; + +// Represents the data related to a section excluding the csects that make up +// the raw data of the section. The csects are stored separately as not all +// sections contain csects, and some sections contain csects which are better +// stored separately, e.g. the .data section containing read-write, descriptor, +// TOCBase and TOC-entry csects. +struct CsectSectionEntry : public SectionEntry { + // Virtual sections do not need storage allocated in the object file. + const bool IsVirtual; + + // This is a section containing csect groups. + CsectGroups Groups; + + CsectSectionEntry(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual, + CsectGroups Groups) + : SectionEntry(N, Flags), IsVirtual(IsVirtual), Groups(Groups) { assert(N.size() <= XCOFF::NameSize && "section name too long"); memcpy(Name, N.data(), N.size()); } + + void reset() override { + SectionEntry::reset(); + // Clear any csects we have stored. + for (auto *Group : Groups) + Group->clear(); + } + + virtual ~CsectSectionEntry() {} }; class XCOFFObjectWriter : public MCObjectWriter { @@ -159,10 +179,10 @@ std::unique_ptr TargetObjectWriter; StringTableBuilder Strings; - // Maps the MCSection representation to its corresponding ControlSection - // wrapper. Needed for finding the ControlSection to insert an MCSymbol into + // Maps the MCSection representation to its corresponding XCOFFSection + // wrapper. Needed for finding the XCOFFSection to insert an MCSymbol into // from its containing MCSectionXCOFF. - DenseMap SectionMap; + DenseMap SectionMap; // Maps the MCSymbol representation to its corrresponding symbol table index. // Needed for relocation. @@ -182,15 +202,16 @@ CsectGroup TBSSCsects; // The Predefined sections. - Section Text; - Section Data; - Section BSS; - Section TData; - Section TBSS; + CsectSectionEntry Text; + CsectSectionEntry Data; + CsectSectionEntry BSS; + CsectSectionEntry TData; + CsectSectionEntry TBSS; // All the XCOFF sections, in the order they will appear in the section header // table. - std::array
Sections{{&Text, &Data, &BSS, &TData, &TBSS}}; + std::array Sections{ + {&Text, &Data, &BSS, &TData, &TBSS}}; CsectGroup &getCsectGroup(const MCSectionXCOFF *MCSec); @@ -206,16 +227,16 @@ static bool nameShouldBeInStringTable(const StringRef &); void writeSymbolName(const StringRef &); void writeSymbolTableEntryForCsectMemberLabel(const Symbol &, - const ControlSection &, int16_t, + const XCOFFSection &, int16_t, uint64_t); - void writeSymbolTableEntryForControlSection(const ControlSection &, int16_t, + void writeSymbolTableEntryForControlSection(const XCOFFSection &, int16_t, XCOFF::StorageClass); void writeFileHeader(); void writeSectionHeaderTable(); void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout); void writeSymbolTable(const MCAsmLayout &Layout); void writeRelocations(); - void writeRelocation(XCOFFRelocation Reloc, const ControlSection &CSection); + void writeRelocation(XCOFFRelocation Reloc, const XCOFFSection &CSection); // Called after all the csects and symbols have been processed by // `executePostLayoutBinding`, this function handles building up the majority @@ -350,7 +371,7 @@ for (const auto &S : Asm) { const auto *MCSec = cast(&S); assert(SectionMap.find(MCSec) == SectionMap.end() && - "Cannot add a csect twice."); + "Cannot add a section twice."); assert(XCOFF::XTY_ER != MCSec->getCSectType() && "An undefined csect should not get registered."); @@ -392,8 +413,10 @@ assert(SectionMap.find(ContainingCsect) != SectionMap.end() && "Expected containing csect to exist in map"); + XCOFFSection *Csect = SectionMap[ContainingCsect]; // Lookup the containing csect and add the symbol to it. - SectionMap[ContainingCsect]->Syms.emplace_back(XSym); + assert(Csect->MCSec->isCsect() && "only csect is supported now!"); + Csect->Syms.emplace_back(XSym); // If the name does not fit in the storage provided in the symbol table // entry, add it to the string table. @@ -517,7 +540,8 @@ uint32_t CurrentAddressLocation = 0; for (const auto *Section : Sections) { // Nothing to write for this Section. - if (Section->Index == Section::UninitializedIndex || Section->IsVirtual) + if (Section->Index == SectionEntry::UninitializedIndex || + Section->IsVirtual) continue; // There could be a gap (without corresponding zero padding) between @@ -535,7 +559,7 @@ if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation) W.OS.write_zeros(PaddingSize); if (Csect.Size) - Asm.writeSectionData(W.OS, Csect.MCCsect, Layout); + Asm.writeSectionData(W.OS, Csect.MCSec, Layout); CurrentAddressLocation = Csect.Address + Csect.Size; } } @@ -594,7 +618,7 @@ } void XCOFFObjectWriter::writeSymbolTableEntryForCsectMemberLabel( - const Symbol &SymbolRef, const ControlSection &CSectionRef, + const Symbol &SymbolRef, const XCOFFSection &CSectionRef, int16_t SectionIndex, uint64_t SymbolOffset) { // Name or Zeros and string table offset writeSymbolName(SymbolRef.getSymbolTableName()); @@ -623,7 +647,7 @@ // Symbol type: Label W.write(XCOFF::XTY_LD); // Storage mapping class. - W.write(CSectionRef.MCCsect->getMappingClass()); + W.write(CSectionRef.MCSec->getMappingClass()); // Reserved (x_stab). W.write(0); // Reserved (x_snstab). @@ -631,7 +655,7 @@ } void XCOFFObjectWriter::writeSymbolTableEntryForControlSection( - const ControlSection &CSectionRef, int16_t SectionIndex, + const XCOFFSection &CSectionRef, int16_t SectionIndex, XCOFF::StorageClass StorageClass) { // n_name, n_zeros, n_offset writeSymbolName(CSectionRef.getSymbolTableName()); @@ -659,9 +683,9 @@ // Typecheck section number. Not supported. W.write(0); // Symbol type. - W.write(getEncodedType(CSectionRef.MCCsect)); + W.write(getEncodedType(CSectionRef.MCSec)); // Storage mapping class. - W.write(CSectionRef.MCCsect->getMappingClass()); + W.write(CSectionRef.MCSec->getMappingClass()); // Reserved (x_stab). W.write(0); // Reserved (x_snstab). @@ -689,7 +713,7 @@ void XCOFFObjectWriter::writeSectionHeaderTable() { for (const auto *Sec : Sections) { // Nothing to write for this Section. - if (Sec->Index == Section::UninitializedIndex) + if (Sec->Index == SectionEntry::UninitializedIndex) continue; // Write Name. @@ -718,7 +742,7 @@ } void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc, - const ControlSection &CSection) { + const XCOFFSection &CSection) { W.write(CSection.Address + Reloc.FixupOffsetInCsect); W.write(Reloc.SymbolTableIndex); W.write(Reloc.SignAndSize); @@ -727,7 +751,7 @@ void XCOFFObjectWriter::writeRelocations() { for (const auto *Section : Sections) { - if (Section->Index == Section::UninitializedIndex) + if (Section->Index == SectionEntry::UninitializedIndex) // Nothing to write for this Section. continue; @@ -769,12 +793,13 @@ W.write(0); for (const auto &Csect : UndefinedCsects) { - writeSymbolTableEntryForControlSection( - Csect, XCOFF::ReservedSectionNum::N_UNDEF, Csect.MCCsect->getStorageClass()); + writeSymbolTableEntryForControlSection(Csect, + XCOFF::ReservedSectionNum::N_UNDEF, + Csect.MCSec->getStorageClass()); } for (const auto *Section : Sections) { - if (Section->Index == Section::UninitializedIndex) + if (Section->Index == SectionEntry::UninitializedIndex) // Nothing to write for this Section. continue; @@ -785,8 +810,8 @@ const int16_t SectionIndex = Section->Index; for (const auto &Csect : *Group) { // Write out the control section first and then each symbol in it. - writeSymbolTableEntryForControlSection( - Csect, SectionIndex, Csect.MCCsect->getStorageClass()); + writeSymbolTableEntryForControlSection(Csect, SectionIndex, + Csect.MCSec->getStorageClass()); for (const auto &Sym : Csect.Syms) writeSymbolTableEntryForCsectMemberLabel( @@ -798,7 +823,7 @@ void XCOFFObjectWriter::finalizeSectionInfo() { for (auto *Section : Sections) { - if (Section->Index == Section::UninitializedIndex) + if (Section->Index == SectionEntry::UninitializedIndex) // Nothing to record for this Section. continue; @@ -822,7 +847,7 @@ // Calculate the file offset to the relocation entries. uint64_t RawPointer = RelocationEntryOffset; for (auto Sec : Sections) { - if (Sec->Index == Section::UninitializedIndex || !Sec->RelocationCount) + if (Sec->Index == SectionEntry::UninitializedIndex || !Sec->RelocationCount) continue; Sec->FileOffsetToRelocations = RawPointer; @@ -848,7 +873,7 @@ Csect.Size = 0; Csect.Address = 0; Csect.SymbolTableIndex = SymbolTableIndex; - SymbolIndexMap[Csect.MCCsect->getQualNameSymbol()] = Csect.SymbolTableIndex; + SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex; // 1 main and 1 auxiliary symbol table entry for each contained symbol. SymbolTableIndex += 2; } @@ -889,7 +914,7 @@ continue; for (auto &Csect : *Group) { - const MCSectionXCOFF *MCSec = Csect.MCCsect; + const MCSectionXCOFF *MCSec = Csect.MCSec; Csect.Address = alignTo(Address, MCSec->getAlignment()); Csect.Size = Layout.getSectionAddressSize(MCSec); Address = Csect.Address + Csect.Size; @@ -925,7 +950,7 @@ uint64_t RawPointer = sizeof(XCOFF::FileHeader32) + auxiliaryHeaderSize() + SectionCount * sizeof(XCOFF::SectionHeader32); for (auto *Sec : Sections) { - if (Sec->Index == Section::UninitializedIndex || Sec->IsVirtual) + if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual) continue; Sec->FileOffsetToData = RawPointer;