Skip to content

Commit 26d72bd

Browse files
author
Chen Zheng
committed
[XCOFF][NFC] add DWARF section support in XCOFF object writer
Reviewed By: jsji Differential Revision: https://reviews.llvm.org/D97049
1 parent 1a001de commit 26d72bd

File tree

1 file changed

+84
-59
lines changed

1 file changed

+84
-59
lines changed

llvm/lib/MC/XCOFFObjectWriter.cpp

+84-59
Original file line numberDiff line numberDiff line change
@@ -73,32 +73,30 @@ struct Symbol {
7373
};
7474

7575
// Wrapper for an MCSectionXCOFF.
76-
struct ControlSection {
77-
const MCSectionXCOFF *const MCCsect;
76+
// It can be a Csect or debug section or DWARF section and so on.
77+
struct XCOFFSection {
78+
const MCSectionXCOFF *const MCSec;
7879
uint32_t SymbolTableIndex;
7980
uint32_t Address;
8081
uint32_t Size;
8182

8283
SmallVector<Symbol, 1> Syms;
8384
SmallVector<XCOFFRelocation, 1> Relocations;
84-
StringRef getSymbolTableName() const { return MCCsect->getSymbolTableName(); }
85-
ControlSection(const MCSectionXCOFF *MCSec)
86-
: MCCsect(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {}
85+
StringRef getSymbolTableName() const { return MCSec->getSymbolTableName(); }
86+
XCOFFSection(const MCSectionXCOFF *MCSec)
87+
: MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {}
8788
};
8889

8990
// Type to be used for a container representing a set of csects with
9091
// (approximately) the same storage mapping class. For example all the csects
9192
// with a storage mapping class of `xmc_pr` will get placed into the same
9293
// container.
93-
using CsectGroup = std::deque<ControlSection>;
94+
using CsectGroup = std::deque<XCOFFSection>;
9495
using CsectGroups = std::deque<CsectGroup *>;
9596

96-
// Represents the data related to a section excluding the csects that make up
97-
// the raw data of the section. The csects are stored separately as not all
98-
// sections contain csects, and some sections contain csects which are better
99-
// stored separately, e.g. the .data section containing read-write, descriptor,
100-
// TOCBase and TOC-entry csects.
101-
struct Section {
97+
// The basic section entry defination. This Section represents a section entry
98+
// in XCOFF section header table.
99+
struct SectionEntry {
102100
char Name[XCOFF::NameSize];
103101
// The physical/virtual address of the section. For an object file
104102
// these values are equivalent.
@@ -111,9 +109,6 @@ struct Section {
111109

112110
int16_t Index;
113111

114-
// Virtual sections do not need storage allocated in the object file.
115-
const bool IsVirtual;
116-
117112
// XCOFF has special section numbers for symbols:
118113
// -2 Specifies N_DEBUG, a special symbolic debugging symbol.
119114
// -1 Specifies N_ABS, an absolute symbol. The symbol has a value but is not
@@ -124,28 +119,53 @@ struct Section {
124119
static constexpr int16_t UninitializedIndex =
125120
XCOFF::ReservedSectionNum::N_DEBUG - 1;
126121

127-
CsectGroups Groups;
122+
SectionEntry(StringRef N, int32_t Flags)
123+
: Name(), Address(0), Size(0), FileOffsetToData(0),
124+
FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags),
125+
Index(UninitializedIndex) {
126+
assert(N.size() <= XCOFF::NameSize && "section name too long");
127+
memcpy(Name, N.data(), N.size());
128+
}
128129

129-
void reset() {
130+
virtual void reset() {
130131
Address = 0;
131132
Size = 0;
132133
FileOffsetToData = 0;
133134
FileOffsetToRelocations = 0;
134135
RelocationCount = 0;
135136
Index = UninitializedIndex;
136-
// Clear any csects we have stored.
137-
for (auto *Group : Groups)
138-
Group->clear();
139137
}
140138

141-
Section(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual,
142-
CsectGroups Groups)
143-
: Name(), Address(0), Size(0), FileOffsetToData(0),
144-
FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags),
145-
Index(UninitializedIndex), IsVirtual(IsVirtual), Groups(Groups) {
139+
virtual ~SectionEntry() {}
140+
};
141+
142+
// Represents the data related to a section excluding the csects that make up
143+
// the raw data of the section. The csects are stored separately as not all
144+
// sections contain csects, and some sections contain csects which are better
145+
// stored separately, e.g. the .data section containing read-write, descriptor,
146+
// TOCBase and TOC-entry csects.
147+
struct CsectSectionEntry : public SectionEntry {
148+
// Virtual sections do not need storage allocated in the object file.
149+
const bool IsVirtual;
150+
151+
// This is a section containing csect groups.
152+
CsectGroups Groups;
153+
154+
CsectSectionEntry(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual,
155+
CsectGroups Groups)
156+
: SectionEntry(N, Flags), IsVirtual(IsVirtual), Groups(Groups) {
146157
assert(N.size() <= XCOFF::NameSize && "section name too long");
147158
memcpy(Name, N.data(), N.size());
148159
}
160+
161+
void reset() override {
162+
SectionEntry::reset();
163+
// Clear any csects we have stored.
164+
for (auto *Group : Groups)
165+
Group->clear();
166+
}
167+
168+
virtual ~CsectSectionEntry() {}
149169
};
150170

151171
class XCOFFObjectWriter : public MCObjectWriter {
@@ -159,10 +179,10 @@ class XCOFFObjectWriter : public MCObjectWriter {
159179
std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter;
160180
StringTableBuilder Strings;
161181

162-
// Maps the MCSection representation to its corresponding ControlSection
163-
// wrapper. Needed for finding the ControlSection to insert an MCSymbol into
182+
// Maps the MCSection representation to its corresponding XCOFFSection
183+
// wrapper. Needed for finding the XCOFFSection to insert an MCSymbol into
164184
// from its containing MCSectionXCOFF.
165-
DenseMap<const MCSectionXCOFF *, ControlSection *> SectionMap;
185+
DenseMap<const MCSectionXCOFF *, XCOFFSection *> SectionMap;
166186

167187
// Maps the MCSymbol representation to its corrresponding symbol table index.
168188
// Needed for relocation.
@@ -182,15 +202,16 @@ class XCOFFObjectWriter : public MCObjectWriter {
182202
CsectGroup TBSSCsects;
183203

184204
// The Predefined sections.
185-
Section Text;
186-
Section Data;
187-
Section BSS;
188-
Section TData;
189-
Section TBSS;
205+
CsectSectionEntry Text;
206+
CsectSectionEntry Data;
207+
CsectSectionEntry BSS;
208+
CsectSectionEntry TData;
209+
CsectSectionEntry TBSS;
190210

191211
// All the XCOFF sections, in the order they will appear in the section header
192212
// table.
193-
std::array<Section *const, 5> Sections{{&Text, &Data, &BSS, &TData, &TBSS}};
213+
std::array<CsectSectionEntry *const, 5> Sections{
214+
{&Text, &Data, &BSS, &TData, &TBSS}};
194215

195216
CsectGroup &getCsectGroup(const MCSectionXCOFF *MCSec);
196217

@@ -206,16 +227,16 @@ class XCOFFObjectWriter : public MCObjectWriter {
206227
static bool nameShouldBeInStringTable(const StringRef &);
207228
void writeSymbolName(const StringRef &);
208229
void writeSymbolTableEntryForCsectMemberLabel(const Symbol &,
209-
const ControlSection &, int16_t,
230+
const XCOFFSection &, int16_t,
210231
uint64_t);
211-
void writeSymbolTableEntryForControlSection(const ControlSection &, int16_t,
232+
void writeSymbolTableEntryForControlSection(const XCOFFSection &, int16_t,
212233
XCOFF::StorageClass);
213234
void writeFileHeader();
214235
void writeSectionHeaderTable();
215236
void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
216237
void writeSymbolTable(const MCAsmLayout &Layout);
217238
void writeRelocations();
218-
void writeRelocation(XCOFFRelocation Reloc, const ControlSection &CSection);
239+
void writeRelocation(XCOFFRelocation Reloc, const XCOFFSection &CSection);
219240

220241
// Called after all the csects and symbols have been processed by
221242
// `executePostLayoutBinding`, this function handles building up the majority
@@ -350,7 +371,7 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
350371
for (const auto &S : Asm) {
351372
const auto *MCSec = cast<const MCSectionXCOFF>(&S);
352373
assert(SectionMap.find(MCSec) == SectionMap.end() &&
353-
"Cannot add a csect twice.");
374+
"Cannot add a section twice.");
354375
assert(XCOFF::XTY_ER != MCSec->getCSectType() &&
355376
"An undefined csect should not get registered.");
356377

@@ -392,8 +413,10 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
392413

393414
assert(SectionMap.find(ContainingCsect) != SectionMap.end() &&
394415
"Expected containing csect to exist in map");
416+
XCOFFSection *Csect = SectionMap[ContainingCsect];
395417
// Lookup the containing csect and add the symbol to it.
396-
SectionMap[ContainingCsect]->Syms.emplace_back(XSym);
418+
assert(Csect->MCSec->isCsect() && "only csect is supported now!");
419+
Csect->Syms.emplace_back(XSym);
397420

398421
// If the name does not fit in the storage provided in the symbol table
399422
// entry, add it to the string table.
@@ -517,7 +540,8 @@ void XCOFFObjectWriter::writeSections(const MCAssembler &Asm,
517540
uint32_t CurrentAddressLocation = 0;
518541
for (const auto *Section : Sections) {
519542
// Nothing to write for this Section.
520-
if (Section->Index == Section::UninitializedIndex || Section->IsVirtual)
543+
if (Section->Index == SectionEntry::UninitializedIndex ||
544+
Section->IsVirtual)
521545
continue;
522546

523547
// There could be a gap (without corresponding zero padding) between
@@ -535,7 +559,7 @@ void XCOFFObjectWriter::writeSections(const MCAssembler &Asm,
535559
if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation)
536560
W.OS.write_zeros(PaddingSize);
537561
if (Csect.Size)
538-
Asm.writeSectionData(W.OS, Csect.MCCsect, Layout);
562+
Asm.writeSectionData(W.OS, Csect.MCSec, Layout);
539563
CurrentAddressLocation = Csect.Address + Csect.Size;
540564
}
541565
}
@@ -594,7 +618,7 @@ void XCOFFObjectWriter::writeSymbolName(const StringRef &SymbolName) {
594618
}
595619

596620
void XCOFFObjectWriter::writeSymbolTableEntryForCsectMemberLabel(
597-
const Symbol &SymbolRef, const ControlSection &CSectionRef,
621+
const Symbol &SymbolRef, const XCOFFSection &CSectionRef,
598622
int16_t SectionIndex, uint64_t SymbolOffset) {
599623
// Name or Zeros and string table offset
600624
writeSymbolName(SymbolRef.getSymbolTableName());
@@ -623,15 +647,15 @@ void XCOFFObjectWriter::writeSymbolTableEntryForCsectMemberLabel(
623647
// Symbol type: Label
624648
W.write<uint8_t>(XCOFF::XTY_LD);
625649
// Storage mapping class.
626-
W.write<uint8_t>(CSectionRef.MCCsect->getMappingClass());
650+
W.write<uint8_t>(CSectionRef.MCSec->getMappingClass());
627651
// Reserved (x_stab).
628652
W.write<uint32_t>(0);
629653
// Reserved (x_snstab).
630654
W.write<uint16_t>(0);
631655
}
632656

633657
void XCOFFObjectWriter::writeSymbolTableEntryForControlSection(
634-
const ControlSection &CSectionRef, int16_t SectionIndex,
658+
const XCOFFSection &CSectionRef, int16_t SectionIndex,
635659
XCOFF::StorageClass StorageClass) {
636660
// n_name, n_zeros, n_offset
637661
writeSymbolName(CSectionRef.getSymbolTableName());
@@ -659,9 +683,9 @@ void XCOFFObjectWriter::writeSymbolTableEntryForControlSection(
659683
// Typecheck section number. Not supported.
660684
W.write<uint16_t>(0);
661685
// Symbol type.
662-
W.write<uint8_t>(getEncodedType(CSectionRef.MCCsect));
686+
W.write<uint8_t>(getEncodedType(CSectionRef.MCSec));
663687
// Storage mapping class.
664-
W.write<uint8_t>(CSectionRef.MCCsect->getMappingClass());
688+
W.write<uint8_t>(CSectionRef.MCSec->getMappingClass());
665689
// Reserved (x_stab).
666690
W.write<uint32_t>(0);
667691
// Reserved (x_snstab).
@@ -689,7 +713,7 @@ void XCOFFObjectWriter::writeFileHeader() {
689713
void XCOFFObjectWriter::writeSectionHeaderTable() {
690714
for (const auto *Sec : Sections) {
691715
// Nothing to write for this Section.
692-
if (Sec->Index == Section::UninitializedIndex)
716+
if (Sec->Index == SectionEntry::UninitializedIndex)
693717
continue;
694718

695719
// Write Name.
@@ -718,7 +742,7 @@ void XCOFFObjectWriter::writeSectionHeaderTable() {
718742
}
719743

720744
void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
721-
const ControlSection &CSection) {
745+
const XCOFFSection &CSection) {
722746
W.write<uint32_t>(CSection.Address + Reloc.FixupOffsetInCsect);
723747
W.write<uint32_t>(Reloc.SymbolTableIndex);
724748
W.write<uint8_t>(Reloc.SignAndSize);
@@ -727,7 +751,7 @@ void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
727751

728752
void XCOFFObjectWriter::writeRelocations() {
729753
for (const auto *Section : Sections) {
730-
if (Section->Index == Section::UninitializedIndex)
754+
if (Section->Index == SectionEntry::UninitializedIndex)
731755
// Nothing to write for this Section.
732756
continue;
733757

@@ -769,12 +793,13 @@ void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) {
769793
W.write<uint8_t>(0);
770794

771795
for (const auto &Csect : UndefinedCsects) {
772-
writeSymbolTableEntryForControlSection(
773-
Csect, XCOFF::ReservedSectionNum::N_UNDEF, Csect.MCCsect->getStorageClass());
796+
writeSymbolTableEntryForControlSection(Csect,
797+
XCOFF::ReservedSectionNum::N_UNDEF,
798+
Csect.MCSec->getStorageClass());
774799
}
775800

776801
for (const auto *Section : Sections) {
777-
if (Section->Index == Section::UninitializedIndex)
802+
if (Section->Index == SectionEntry::UninitializedIndex)
778803
// Nothing to write for this Section.
779804
continue;
780805

@@ -785,8 +810,8 @@ void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) {
785810
const int16_t SectionIndex = Section->Index;
786811
for (const auto &Csect : *Group) {
787812
// Write out the control section first and then each symbol in it.
788-
writeSymbolTableEntryForControlSection(
789-
Csect, SectionIndex, Csect.MCCsect->getStorageClass());
813+
writeSymbolTableEntryForControlSection(Csect, SectionIndex,
814+
Csect.MCSec->getStorageClass());
790815

791816
for (const auto &Sym : Csect.Syms)
792817
writeSymbolTableEntryForCsectMemberLabel(
@@ -798,7 +823,7 @@ void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) {
798823

799824
void XCOFFObjectWriter::finalizeSectionInfo() {
800825
for (auto *Section : Sections) {
801-
if (Section->Index == Section::UninitializedIndex)
826+
if (Section->Index == SectionEntry::UninitializedIndex)
802827
// Nothing to record for this Section.
803828
continue;
804829

@@ -822,7 +847,7 @@ void XCOFFObjectWriter::finalizeSectionInfo() {
822847
// Calculate the file offset to the relocation entries.
823848
uint64_t RawPointer = RelocationEntryOffset;
824849
for (auto Sec : Sections) {
825-
if (Sec->Index == Section::UninitializedIndex || !Sec->RelocationCount)
850+
if (Sec->Index == SectionEntry::UninitializedIndex || !Sec->RelocationCount)
826851
continue;
827852

828853
Sec->FileOffsetToRelocations = RawPointer;
@@ -848,7 +873,7 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
848873
Csect.Size = 0;
849874
Csect.Address = 0;
850875
Csect.SymbolTableIndex = SymbolTableIndex;
851-
SymbolIndexMap[Csect.MCCsect->getQualNameSymbol()] = Csect.SymbolTableIndex;
876+
SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
852877
// 1 main and 1 auxiliary symbol table entry for each contained symbol.
853878
SymbolTableIndex += 2;
854879
}
@@ -889,7 +914,7 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
889914
continue;
890915

891916
for (auto &Csect : *Group) {
892-
const MCSectionXCOFF *MCSec = Csect.MCCsect;
917+
const MCSectionXCOFF *MCSec = Csect.MCSec;
893918
Csect.Address = alignTo(Address, MCSec->getAlignment());
894919
Csect.Size = Layout.getSectionAddressSize(MCSec);
895920
Address = Csect.Address + Csect.Size;
@@ -925,7 +950,7 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
925950
uint64_t RawPointer = XCOFF::FileHeaderSize32 + auxiliaryHeaderSize() +
926951
SectionCount * XCOFF::SectionHeaderSize32;
927952
for (auto *Sec : Sections) {
928-
if (Sec->Index == Section::UninitializedIndex || Sec->IsVirtual)
953+
if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual)
929954
continue;
930955

931956
Sec->FileOffsetToData = RawPointer;

0 commit comments

Comments
 (0)