1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[XCOFF][NFC] add DWARF section support in XCOFF object writer

Reviewed By: jsji

Differential Revision: https://reviews.llvm.org/D97049
This commit is contained in:
Chen Zheng 2021-07-05 02:53:30 +00:00
parent 3cc10c45ba
commit e4aa7692e8

View File

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