52constexpr unsigned DefaultSectionAlign = 4;
53constexpr int16_t MaxSectionIndex = INT16_MAX;
58struct XCOFFRelocation {
96 : MCSec(MCSec), SymbolTableIndex(-1),
Address(-1),
Size(0) {}
103using CsectGroup = std::deque<XCOFFSection>;
104using CsectGroups = std::deque<CsectGroup *>;
132 static constexpr int16_t UninitializedIndex =
137 FileOffsetToRelocations(0), RelocationCount(0),
Flags(
Flags),
138 Index(UninitializedIndex) {
140 memcpy(Name,
N.data(),
N.size());
143 virtual void reset() {
146 FileOffsetToData = 0;
147 FileOffsetToRelocations = 0;
149 Index = UninitializedIndex;
162 const bool IsVirtual;
171 memcpy(
Name,
N.data(),
N.size());
174 void reset()
override {
175 SectionEntry::reset();
177 for (
auto *Group : Groups)
181 virtual ~CsectSectionEntry() =
default;
186 std::unique_ptr<XCOFFSection> DwarfSect;
193 std::unique_ptr<XCOFFSection> Sect)
196 assert(DwarfSect->MCSec->isDwarfSect() &&
197 "This should be a DWARF section!");
199 memcpy(
Name,
N.data(),
N.size());
202 DwarfSectionEntry(DwarfSectionEntry &&s) =
default;
204 virtual ~DwarfSectionEntry() =
default;
207struct ExceptionTableEntry {
213 ExceptionTableEntry(
const MCSymbol *Trap,
unsigned Lang,
unsigned Reason)
214 :
Trap(
Trap), Lang(Lang), Reason(Reason) {}
217struct ExceptionInfo {
219 unsigned FunctionSize;
220 std::vector<ExceptionTableEntry> Entries;
224 std::map<const StringRef, ExceptionInfo> ExceptionTable;
225 bool isDebugEnabled =
false;
227 ExceptionSectionEntry(
StringRef N, int32_t Flags)
230 memcpy(
Name,
N.data(),
N.size());
233 virtual ~ExceptionSectionEntry() =
default;
242 std::vector<std::pair<std::string, size_t>> FileNames;
243 bool HasVisibility =
false;
246 std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter;
250 TargetObjectWriter->is64Bit() ?
UINT64_MAX : UINT32_MAX;
264 CsectGroup UndefinedCsects;
265 CsectGroup ProgramCodeCsects;
266 CsectGroup ReadOnlyCsects;
267 CsectGroup DataCsects;
268 CsectGroup FuncDSCsects;
269 CsectGroup TOCCsects;
270 CsectGroup BSSCsects;
271 CsectGroup TDataCsects;
272 CsectGroup TBSSCsects;
275 CsectSectionEntry
Text;
276 CsectSectionEntry
Data;
277 CsectSectionEntry BSS;
278 CsectSectionEntry TData;
279 CsectSectionEntry TBSS;
283 std::array<CsectSectionEntry *const, 5> Sections{
284 {&
Text, &
Data, &BSS, &TData, &TBSS}};
286 std::vector<DwarfSectionEntry> DwarfSections;
287 std::vector<SectionEntry> OverflowSections;
289 ExceptionSectionEntry ExceptionSection;
293 void reset()
override;
302 bool is64Bit()
const {
return TargetObjectWriter->is64Bit(); }
303 bool nameShouldBeInStringTable(
const StringRef &);
306 void writeSymbolEntryForCsectMemberLabel(
const Symbol &SymbolRef,
307 const XCOFFSection &CSectionRef,
308 int16_t SectionIndex,
310 void writeSymbolEntryForControlSection(
const XCOFFSection &CSectionRef,
311 int16_t SectionIndex,
313 void writeSymbolEntryForDwarfSection(
const XCOFFSection &DwarfSectionRef,
314 int16_t SectionIndex);
315 void writeFileHeader();
316 void writeAuxFileHeader();
318 void writeSectionHeaderTable();
320 void writeSectionForControlSectionEntry(
const MCAssembler &Asm,
322 const CsectSectionEntry &CsectEntry,
324 void writeSectionForDwarfSectionEntry(
const MCAssembler &Asm,
326 const DwarfSectionEntry &DwarfEntry,
328 void writeSectionForExceptionSectionEntry(
330 ExceptionSectionEntry &ExceptionEntry,
uint64_t &CurrentAddressLocation);
332 void writeSymbolAuxDwarfEntry(
uint64_t LengthOfSectionPortion,
334 void writeSymbolAuxCsectEntry(
uint64_t SectionOrLength,
335 uint8_t SymbolAlignmentAndType,
337 void writeSymbolAuxFunctionEntry(
uint32_t EntryOffset,
uint32_t FunctionSize,
340 void writeSymbolAuxExceptionEntry(
uint64_t EntryOffset,
uint32_t FunctionSize,
345 void writeRelocations();
346 void writeRelocation(XCOFFRelocation Reloc,
const XCOFFSection &Section);
356 void assignAddressesAndIndices(
const MCAsmLayout &);
358 void finalizeSectionInfo();
363 unsigned LanguageCode,
unsigned ReasonCode,
364 unsigned FunctionSize,
bool hasDebug)
override;
365 bool hasExceptionSection() {
366 return !ExceptionSection.ExceptionTable.empty();
368 unsigned getExceptionSectionSize();
369 unsigned getExceptionOffset(
const MCSymbol *Symbol);
371 size_t auxiliaryHeaderSize()
const {
377 XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
385XCOFFObjectWriter::XCOFFObjectWriter(
390 CsectGroups{&ProgramCodeCsects, &ReadOnlyCsects}),
392 CsectGroups{&DataCsects, &FuncDSCsects, &TOCCsects}),
394 CsectGroups{&BSSCsects}),
396 CsectGroups{&TDataCsects}),
398 CsectGroups{&TBSSCsects}),
401void XCOFFObjectWriter::reset() {
403 SymbolIndexMap.
clear();
406 UndefinedCsects.clear();
408 for (
auto *Sec : Sections)
410 for (
auto &DwarfSec : DwarfSections)
412 for (
auto &OverflowSec : OverflowSections)
414 ExceptionSection.reset();
417 SymbolTableEntryCount = 0;
418 SymbolTableOffset = 0;
420 PaddingsBeforeDwarf = 0;
426CsectGroup &XCOFFObjectWriter::getCsectGroup(
const MCSectionXCOFF *MCSec) {
430 "Only an initialized csect can contain program code.");
431 return ProgramCodeCsects;
434 "Only an initialized csect can contain read only data.");
435 return ReadOnlyCsects;
448 "Mapping invalid csect. CSECT with bss storage class must be "
453 "Mapping invalid csect. CSECT with tdata storage class must be "
454 "an initialized csect.");
458 "Mapping invalid csect. CSECT with tbss storage class must be "
459 "an uninitialized csect.");
463 "Only an initialized csect can contain TOC-base.");
464 assert(TOCCsects.empty() &&
465 "We should have only one TOC-base, and it should be the first csect "
466 "in this CsectGroup.");
472 "Only an initialized csect can contain TC entry.");
473 assert(!TOCCsects.empty() &&
474 "We should at least have a TOC-base in this CsectGroup.");
487void XCOFFObjectWriter::executePostLayoutBinding(
MCAssembler &Asm,
489 for (
const auto &S : Asm) {
490 const auto *MCSec = cast<const MCSectionXCOFF>(&S);
491 assert(!SectionMap.
contains(MCSec) &&
"Cannot add a section twice.");
502 "An undefined csect should not get registered.");
503 CsectGroup &Group = getCsectGroup(MCSec);
504 Group.emplace_back(MCSec);
505 SectionMap[MCSec] = &Group.back();
508 std::unique_ptr<XCOFFSection> DwarfSec =
509 std::make_unique<XCOFFSection>(MCSec);
510 SectionMap[MCSec] = DwarfSec.get();
512 DwarfSectionEntry SecEntry(MCSec->
getName(),
514 std::move(DwarfSec));
515 DwarfSections.push_back(std::move(SecEntry));
529 HasVisibility =
true;
533 UndefinedCsects.emplace_back(ContainingCsect);
534 SectionMap[ContainingCsect] = &UndefinedCsects.back();
550 "Expected containing csect to exist in map");
551 XCOFFSection *Csect = SectionMap[ContainingCsect];
553 assert(Csect->MCSec->isCsect() &&
"only csect is supported now!");
554 Csect->Syms.emplace_back(XSym);
562 FileNames =
Asm.getFileNames();
564 if (FileNames.empty())
565 FileNames.emplace_back(
".file", 0);
566 for (
const std::pair<std::string, size_t> &
F : FileNames) {
567 if (nameShouldBeInStringTable(
F.first))
568 Strings.add(
F.first);
572 assignAddressesAndIndices(Layout);
575void XCOFFObjectWriter::recordRelocation(
MCAssembler &Asm,
586 ? SymbolIndexMap[
Sym]
590 auto getVirtualAddress =
594 if (ContainingSect->isDwarfSect())
598 if (!
Sym->isDefined())
599 return SectionMap[ContainingSect]->Address;
602 assert(
Sym->isDefined() &&
"not a valid object that has address!");
614 std::tie(
Type, SignAndSize) =
615 TargetObjectWriter->getRelocTypeAndSignSize(
Target,
Fixup, IsPCRel);
617 const MCSectionXCOFF *SymASec = getContainingCsect(cast<MCSymbolXCOFF>(SymA));
619 "Expected containing csect to exist in map.");
622 if (
Type == XCOFF::RelocationType::R_POS ||
623 Type == XCOFF::RelocationType::R_TLS)
626 FixedValue = getVirtualAddress(SymA, SymASec) +
Target.getConstant();
627 else if (
Type == XCOFF::RelocationType::R_TLSM)
631 else if (
Type == XCOFF::RelocationType::R_TOC ||
632 Type == XCOFF::RelocationType::R_TOCL) {
643 const int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
644 TOCCsects.front().Address +
646 if (
Type == XCOFF::RelocationType::R_TOC && !isInt<16>(TOCEntryOffset))
649 FixedValue = TOCEntryOffset;
651 }
else if (
Type == XCOFF::RelocationType::R_RBR) {
655 "Only XMC_PR csect may have the R_RBR relocation.");
659 uint64_t BRInstrAddress = SectionMap[ParentSec]->Address +
665 SectionMap[SymASec]->Address - BRInstrAddress +
Target.getConstant();
666 }
else if (
Type == XCOFF::RelocationType::R_REF)
673 "Fragment offset + fixup offset is overflowed.");
677 XCOFFRelocation Reloc = {
Index, FixupOffsetInCsect, SignAndSize,
Type};
680 "Expected containing csect to exist in map.");
681 SectionMap[RelocationSec]->Relocations.push_back(Reloc);
690 const MCSectionXCOFF *SymBSec = getContainingCsect(cast<MCSymbolXCOFF>(SymB));
692 "Expected containing csect to exist in map.");
693 if (SymASec == SymBSec)
695 "relocation for paired relocatable term is not yet supported");
697 assert(
Type == XCOFF::RelocationType::R_POS &&
698 "SymA must be R_POS here if it's not opposite term or paired "
699 "relocatable term.");
700 const uint32_t IndexB = getIndex(SymB, SymBSec);
703 const uint8_t TypeB = XCOFF::RelocationType::R_NEG;
704 XCOFFRelocation RelocB = {IndexB, FixupOffsetInCsect, SignAndSize, TypeB};
705 SectionMap[RelocationSec]->Relocations.push_back(RelocB);
708 FixedValue -= getVirtualAddress(SymB, SymBSec);
711void XCOFFObjectWriter::writeSections(
const MCAssembler &Asm,
713 uint64_t CurrentAddressLocation = 0;
714 for (
const auto *Section : Sections)
715 writeSectionForControlSectionEntry(Asm, Layout, *Section,
716 CurrentAddressLocation);
717 for (
const auto &DwarfSection : DwarfSections)
718 writeSectionForDwarfSectionEntry(Asm, Layout, DwarfSection,
719 CurrentAddressLocation);
720 writeSectionForExceptionSectionEntry(Asm, Layout, ExceptionSection,
721 CurrentAddressLocation);
729 if (
Asm.isIncrementalLinkerCompatible())
732 finalizeSectionInfo();
736 writeAuxFileHeader();
737 writeSectionHeaderTable();
738 writeSections(Asm, Layout);
744 return W.OS.tell() - StartOffset;
747bool XCOFFObjectWriter::nameShouldBeInStringTable(
const StringRef &SymbolName) {
751void XCOFFObjectWriter::writeSymbolName(
const StringRef &SymbolName) {
753 if (nameShouldBeInStringTable(SymbolName)) {
755 W.write<
uint32_t>(Strings.getOffset(SymbolName));
765 int16_t SectionNumber,
768 uint8_t NumberOfAuxEntries) {
771 W.write<
uint32_t>(Strings.getOffset(SymbolName));
773 writeSymbolName(SymbolName);
776 W.write<int16_t>(SectionNumber);
779 W.write<uint8_t>(NumberOfAuxEntries);
782void XCOFFObjectWriter::writeSymbolAuxCsectEntry(
uint64_t SectionOrLength,
783 uint8_t SymbolAlignmentAndType,
788 W.write<uint8_t>(SymbolAlignmentAndType);
800void XCOFFObjectWriter::writeSymbolAuxDwarfEntry(
802 writeWord(LengthOfSectionPortion);
805 writeWord(NumberOfRelocEnt);
814void XCOFFObjectWriter::writeSymbolEntryForCsectMemberLabel(
815 const Symbol &SymbolRef,
const XCOFFSection &CSectionRef,
816 int16_t SectionIndex,
uint64_t SymbolOffset) {
817 assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address &&
818 "Symbol address overflowed.");
820 auto Entry = ExceptionSection.ExceptionTable.find(SymbolRef.MCSym->getName());
821 if (Entry != ExceptionSection.ExceptionTable.end()) {
822 writeSymbolEntry(SymbolRef.getSymbolTableName(),
823 CSectionRef.Address + SymbolOffset, SectionIndex,
827 is64Bit() ? SymbolRef.getVisibilityType()
828 : SymbolRef.getVisibilityType() | 0x0020,
829 SymbolRef.getStorageClass(),
830 (
is64Bit() && ExceptionSection.isDebugEnabled) ? 3 : 2);
831 if (
is64Bit() && ExceptionSection.isDebugEnabled) {
834 writeSymbolAuxExceptionEntry(
835 ExceptionSection.FileOffsetToData +
836 getExceptionOffset(Entry->second.FunctionSymbol),
837 Entry->second.FunctionSize,
838 SymbolIndexMap[Entry->second.FunctionSymbol] + 4);
842 writeSymbolAuxFunctionEntry(
843 ExceptionSection.FileOffsetToData +
844 getExceptionOffset(Entry->second.FunctionSymbol),
845 Entry->second.FunctionSize, 0,
846 (
is64Bit() && ExceptionSection.isDebugEnabled)
847 ? SymbolIndexMap[Entry->second.FunctionSymbol] + 4
848 : SymbolIndexMap[Entry->second.FunctionSymbol] + 3);
850 writeSymbolEntry(SymbolRef.getSymbolTableName(),
851 CSectionRef.Address + SymbolOffset, SectionIndex,
852 SymbolRef.getVisibilityType(),
853 SymbolRef.getStorageClass());
855 writeSymbolAuxCsectEntry(CSectionRef.SymbolTableIndex,
XCOFF::XTY_LD,
856 CSectionRef.MCSec->getMappingClass());
859void XCOFFObjectWriter::writeSymbolEntryForDwarfSection(
860 const XCOFFSection &DwarfSectionRef, int16_t SectionIndex) {
861 assert(DwarfSectionRef.MCSec->isDwarfSect() &&
"Not a DWARF section!");
863 writeSymbolEntry(DwarfSectionRef.getSymbolTableName(), 0,
866 writeSymbolAuxDwarfEntry(DwarfSectionRef.Size);
869void XCOFFObjectWriter::writeSymbolEntryForControlSection(
870 const XCOFFSection &CSectionRef, int16_t SectionIndex,
872 writeSymbolEntry(CSectionRef.getSymbolTableName(), CSectionRef.Address,
873 SectionIndex, CSectionRef.getVisibilityType(),
StorageClass);
875 writeSymbolAuxCsectEntry(CSectionRef.Size, getEncodedType(CSectionRef.MCSec),
876 CSectionRef.MCSec->getMappingClass());
879void XCOFFObjectWriter::writeSymbolAuxFunctionEntry(
uint32_t EntryOffset,
884 writeWord(LineNumberPointer);
889 writeWord(LineNumberPointer);
899void XCOFFObjectWriter::writeSymbolAuxExceptionEntry(
uint64_t EntryOffset,
902 assert(
is64Bit() &&
"Exception auxilliary entries are 64-bit only.");
910void XCOFFObjectWriter::writeFileHeader() {
914 writeWord(SymbolTableOffset);
916 W.write<
uint16_t>(auxiliaryHeaderSize());
918 W.write<int32_t>(SymbolTableEntryCount);
920 W.write<int32_t>(SymbolTableEntryCount);
921 W.write<
uint16_t>(auxiliaryHeaderSize());
926void XCOFFObjectWriter::writeAuxFileHeader() {
927 if (!auxiliaryHeaderSize())
942void XCOFFObjectWriter::writeSectionHeader(
const SectionEntry *Sec) {
946 if (Sec->Index == SectionEntry::UninitializedIndex)
955 writeWord(IsDwarf ? 0 : Sec->Address);
957 writeWord((IsDwarf || IsOvrflo) ? 0 : Sec->Address);
959 writeWord(Sec->Size);
960 writeWord(Sec->FileOffsetToData);
961 writeWord(Sec->FileOffsetToRelocations);
967 W.write<int32_t>(Sec->Flags);
976 ? Sec->RelocationCount
978 W.write<int32_t>(Sec->Flags);
982void XCOFFObjectWriter::writeSectionHeaderTable() {
983 for (
const auto *CsectSec : Sections)
984 writeSectionHeader(CsectSec);
985 for (
const auto &DwarfSec : DwarfSections)
986 writeSectionHeader(&DwarfSec);
987 for (
const auto &OverflowSec : OverflowSections)
988 writeSectionHeader(&OverflowSec);
989 if (hasExceptionSection())
990 writeSectionHeader(&ExceptionSection);
993void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
994 const XCOFFSection &Section) {
996 writeWord(
Section.Address + Reloc.FixupOffsetInCsect);
999 assert(
Section.MCSec->isDwarfSect() &&
"unsupport section type!");
1000 writeWord(Reloc.FixupOffsetInCsect);
1002 W.write<
uint32_t>(Reloc.SymbolTableIndex);
1003 W.write<uint8_t>(Reloc.SignAndSize);
1004 W.write<uint8_t>(Reloc.Type);
1007void XCOFFObjectWriter::writeRelocations() {
1008 for (
const auto *Section : Sections) {
1009 if (
Section->Index == SectionEntry::UninitializedIndex)
1013 for (
const auto *Group :
Section->Groups) {
1017 for (
const auto &Csect : *Group) {
1018 for (
const auto Reloc : Csect.Relocations)
1019 writeRelocation(Reloc, Csect);
1024 for (
const auto &DwarfSection : DwarfSections)
1025 for (
const auto &Reloc : DwarfSection.DwarfSect->Relocations)
1026 writeRelocation(Reloc, *DwarfSection.DwarfSect);
1029void XCOFFObjectWriter::writeSymbolTable(
const MCAsmLayout &Layout) {
1033 for (
const std::pair<std::string, size_t> &
F : FileNames) {
1034 writeSymbolEntry(
F.first, 0, XCOFF::ReservedSectionNum::N_DEBUG,
1039 for (
const auto &Csect : UndefinedCsects) {
1040 writeSymbolEntryForControlSection(Csect, XCOFF::ReservedSectionNum::N_UNDEF,
1041 Csect.MCSec->getStorageClass());
1044 for (
const auto *Section : Sections) {
1045 if (
Section->Index == SectionEntry::UninitializedIndex)
1049 for (
const auto *Group :
Section->Groups) {
1053 const int16_t SectionIndex =
Section->Index;
1054 for (
const auto &Csect : *Group) {
1056 writeSymbolEntryForControlSection(Csect, SectionIndex,
1057 Csect.MCSec->getStorageClass());
1059 for (
const auto &
Sym : Csect.Syms)
1060 writeSymbolEntryForCsectMemberLabel(
1066 for (
const auto &DwarfSection : DwarfSections)
1067 writeSymbolEntryForDwarfSection(*DwarfSection.DwarfSect,
1068 DwarfSection.Index);
1071void XCOFFObjectWriter::finalizeRelocationInfo(
SectionEntry *Sec,
1081 SecEntry.RelocationCount = Sec->Index;
1085 SecEntry.Address = RelCount;
1086 SecEntry.Index = ++SectionCount;
1087 OverflowSections.push_back(std::move(SecEntry));
1093 Sec->RelocationCount = RelCount;
1097void XCOFFObjectWriter::calcOffsetToRelocations(
SectionEntry *Sec,
1099 if (!Sec->RelocationCount)
1102 Sec->FileOffsetToRelocations = RawPointer;
1107 for (
auto &OverflowSec : OverflowSections) {
1108 if (OverflowSec.RelocationCount ==
static_cast<uint32_t>(Sec->Index)) {
1109 RelocationSizeInSec =
1114 OverflowSec.FileOffsetToRelocations = Sec->FileOffsetToRelocations;
1117 assert(RelocationSizeInSec &&
"Overflow section header doesn't exist.");
1119 RelocationSizeInSec = Sec->RelocationCount *
1124 RawPointer += RelocationSizeInSec;
1125 if (RawPointer > MaxRawDataSize)
1129void XCOFFObjectWriter::finalizeSectionInfo() {
1130 for (
auto *Section : Sections) {
1131 if (
Section->Index == SectionEntry::UninitializedIndex)
1136 for (
const auto *Group :
Section->Groups) {
1140 for (
auto &Csect : *Group)
1141 RelCount += Csect.Relocations.size();
1143 finalizeRelocationInfo(Section, RelCount);
1146 for (
auto &DwarfSection : DwarfSections)
1147 finalizeRelocationInfo(&DwarfSection,
1148 DwarfSection.DwarfSect->Relocations.size());
1156 auxiliaryHeaderSize();
1159 for (
auto *Sec : Sections) {
1160 if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual)
1163 Sec->FileOffsetToData = RawPointer;
1164 RawPointer += Sec->Size;
1165 if (RawPointer > MaxRawDataSize)
1169 if (!DwarfSections.empty()) {
1170 RawPointer += PaddingsBeforeDwarf;
1171 for (
auto &DwarfSection : DwarfSections) {
1172 DwarfSection.FileOffsetToData = RawPointer;
1173 RawPointer += DwarfSection.MemorySize;
1174 if (RawPointer > MaxRawDataSize)
1179 if (hasExceptionSection()) {
1180 ExceptionSection.FileOffsetToData = RawPointer;
1181 RawPointer += ExceptionSection.Size;
1183 assert(RawPointer <= MaxRawDataSize &&
1184 "Section raw data overflowed this object file.");
1187 for (
auto *Sec : Sections) {
1188 if (Sec->Index != SectionEntry::UninitializedIndex)
1189 calcOffsetToRelocations(Sec, RawPointer);
1192 for (
auto &DwarfSec : DwarfSections)
1193 calcOffsetToRelocations(&DwarfSec, RawPointer);
1197 if (SymbolTableEntryCount)
1198 SymbolTableOffset = RawPointer;
1201void XCOFFObjectWriter::addExceptionEntry(
1203 unsigned ReasonCode,
unsigned FunctionSize,
bool hasDebug) {
1207 ExceptionSection.isDebugEnabled =
true;
1208 auto Entry = ExceptionSection.ExceptionTable.find(
Symbol->getName());
1209 if (Entry != ExceptionSection.ExceptionTable.end()) {
1210 Entry->second.Entries.push_back(
1211 ExceptionTableEntry(
Trap, LanguageCode, ReasonCode));
1214 ExceptionInfo NewEntry;
1215 NewEntry.FunctionSymbol =
Symbol;
1216 NewEntry.FunctionSize = FunctionSize;
1217 NewEntry.Entries.push_back(
1218 ExceptionTableEntry(
Trap, LanguageCode, ReasonCode));
1219 ExceptionSection.ExceptionTable.insert(
1220 std::pair<const StringRef, ExceptionInfo>(
Symbol->getName(), NewEntry));
1223unsigned XCOFFObjectWriter::getExceptionSectionSize() {
1224 unsigned EntryNum = 0;
1226 for (
auto it = ExceptionSection.ExceptionTable.begin();
1227 it != ExceptionSection.ExceptionTable.end(); ++it)
1230 EntryNum += it->second.Entries.size() + 1;
1236unsigned XCOFFObjectWriter::getExceptionOffset(
const MCSymbol *Symbol) {
1237 unsigned EntryNum = 0;
1238 for (
auto it = ExceptionSection.ExceptionTable.begin();
1239 it != ExceptionSection.ExceptionTable.end(); ++it) {
1240 if (Symbol == it->second.FunctionSymbol)
1242 EntryNum += it->second.Entries.size() + 1;
1248void XCOFFObjectWriter::assignAddressesAndIndices(
const MCAsmLayout &Layout) {
1250 uint32_t SymbolTableIndex = FileNames.size();
1253 for (
auto &Csect : UndefinedCsects) {
1256 Csect.SymbolTableIndex = SymbolTableIndex;
1257 SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
1259 SymbolTableIndex += 2;
1267 int32_t SectionIndex = 1;
1268 bool HasTDataSection =
false;
1270 for (
auto *Section : Sections) {
1271 const bool IsEmpty =
1273 [](
const CsectGroup *Group) { return Group->empty(); });
1277 if (SectionIndex > MaxSectionIndex)
1279 Section->Index = SectionIndex++;
1282 bool SectionAddressSet =
false;
1286 HasTDataSection =
true;
1293 for (
auto *Group :
Section->Groups) {
1297 for (
auto &Csect : *Group) {
1301 Address = Csect.Address + Csect.Size;
1302 Csect.SymbolTableIndex = SymbolTableIndex;
1305 SymbolTableIndex += 2;
1307 for (
auto &
Sym : Csect.Syms) {
1308 bool hasExceptEntry =
false;
1310 ExceptionSection.ExceptionTable.find(
Sym.MCSym->getName());
1311 if (Entry != ExceptionSection.ExceptionTable.end()) {
1312 hasExceptEntry =
true;
1313 for (
auto &TrapEntry : Entry->second.Entries) {
1315 TrapEntry.Trap->getOffset();
1318 Sym.SymbolTableIndex = SymbolTableIndex;
1319 SymbolIndexMap[
Sym.MCSym] =
Sym.SymbolTableIndex;
1324 SymbolTableIndex += 2;
1325 if (hasExceptionSection() && hasExceptEntry) {
1326 if (
is64Bit() && ExceptionSection.isDebugEnabled)
1327 SymbolTableIndex += 2;
1329 SymbolTableIndex += 1;
1334 if (!SectionAddressSet) {
1335 Section->Address = Group->front().Address;
1336 SectionAddressSet =
true;
1351 if (!DwarfSections.empty())
1352 PaddingsBeforeDwarf =
1354 (*DwarfSections.begin()).DwarfSect->MCSec->getAlign()) -
1357 DwarfSectionEntry *LastDwarfSection =
nullptr;
1358 for (
auto &DwarfSection : DwarfSections) {
1359 assert((SectionIndex <= MaxSectionIndex) &&
"Section index overflow!");
1361 XCOFFSection &DwarfSect = *DwarfSection.DwarfSect;
1365 DwarfSection.Index = SectionIndex++;
1369 DwarfSect.SymbolTableIndex = SymbolTableIndex;
1372 SymbolTableIndex += 2;
1378 DwarfSection.Address = DwarfSect.Address =
1385 Address = DwarfSection.Address + DwarfSection.Size;
1387 if (LastDwarfSection)
1388 LastDwarfSection->MemorySize =
1389 DwarfSection.Address - LastDwarfSection->Address;
1390 LastDwarfSection = &DwarfSection;
1392 if (LastDwarfSection) {
1395 Address =
alignTo(LastDwarfSection->Address + LastDwarfSection->Size,
1396 DefaultSectionAlign);
1397 LastDwarfSection->MemorySize =
Address - LastDwarfSection->Address;
1399 if (hasExceptionSection()) {
1400 ExceptionSection.Index = SectionIndex++;
1402 ExceptionSection.Address = 0;
1403 ExceptionSection.Size = getExceptionSectionSize();
1404 Address += ExceptionSection.Size;
1408 SymbolTableEntryCount = SymbolTableIndex;
1411void XCOFFObjectWriter::writeSectionForControlSectionEntry(
1413 const CsectSectionEntry &CsectEntry,
uint64_t &CurrentAddressLocation) {
1415 if (CsectEntry.Index == SectionEntry::UninitializedIndex)
1422 assert(((CurrentAddressLocation <= CsectEntry.Address) ||
1425 "CurrentAddressLocation should be less than or equal to section "
1426 "address if the section is not TData or TBSS.");
1428 CurrentAddressLocation = CsectEntry.Address;
1433 if (CsectEntry.IsVirtual) {
1434 CurrentAddressLocation += CsectEntry.Size;
1438 for (
const auto &Group : CsectEntry.Groups) {
1439 for (
const auto &Csect : *Group) {
1440 if (
uint32_t PaddingSize = Csect.Address - CurrentAddressLocation)
1441 W.OS.write_zeros(PaddingSize);
1443 Asm.writeSectionData(
W.OS, Csect.MCSec, Layout);
1444 CurrentAddressLocation = Csect.Address + Csect.Size;
1452 CsectEntry.Address + CsectEntry.Size - CurrentAddressLocation) {
1453 W.OS.write_zeros(PaddingSize);
1454 CurrentAddressLocation += PaddingSize;
1458void XCOFFObjectWriter::writeSectionForDwarfSectionEntry(
1460 const DwarfSectionEntry &DwarfEntry,
uint64_t &CurrentAddressLocation) {
1464 assert(CurrentAddressLocation <= DwarfEntry.Address &&
1465 "CurrentAddressLocation should be less than or equal to section "
1468 if (
uint64_t PaddingSize = DwarfEntry.Address - CurrentAddressLocation)
1469 W.OS.write_zeros(PaddingSize);
1471 if (DwarfEntry.Size)
1472 Asm.writeSectionData(
W.OS, DwarfEntry.DwarfSect->MCSec, Layout);
1474 CurrentAddressLocation = DwarfEntry.Address + DwarfEntry.Size;
1478 uint32_t Mod = CurrentAddressLocation % DefaultSectionAlign;
1480 if (TailPaddingSize)
1481 W.OS.write_zeros(TailPaddingSize);
1483 CurrentAddressLocation += TailPaddingSize;
1486void XCOFFObjectWriter::writeSectionForExceptionSectionEntry(
1488 ExceptionSectionEntry &ExceptionEntry,
uint64_t &CurrentAddressLocation) {
1489 for (
auto it = ExceptionEntry.ExceptionTable.begin();
1490 it != ExceptionEntry.ExceptionTable.end(); it++) {
1493 W.write<
uint32_t>(SymbolIndexMap[it->second.FunctionSymbol]);
1496 W.OS.write_zeros(4);
1498 W.OS.write_zeros(2);
1499 for (
auto &TrapEntry : it->second.Entries) {
1500 writeWord(TrapEntry.TrapAddress);
1501 W.write<uint8_t>(TrapEntry.Lang);
1502 W.write<uint8_t>(TrapEntry.Reason);
1506 CurrentAddressLocation += getExceptionSectionSize();
1517 uint8_t EncodedAlign = Log2Align << 3;
1523std::unique_ptr<MCObjectWriter>
1526 return std::make_unique<XCOFFObjectWriter>(std::move(MOTW),
OS);
static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, StringRef StringTable, uint64_t MembersOffset, unsigned NumSyms, uint64_t PrevMemberOffset=0, uint64_t NextMemberOffset=0, bool Is64Bit=false)
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool is64Bit(const char *name)
static const X86InstrFMA3Group Groups[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Generic interface to target specific assembler backends.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Encapsulates the layout of an assembly file at a particular point in time.
uint64_t getSectionAddressSize(const MCSection *Sec) const
Get the address space size of the given section, as it effects layout.
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Get the offset of the given symbol, as computed in the current layout.
uint64_t getFragmentOffset(const MCFragment *F) const
Get the offset of the given fragment inside its containing section.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
MCSection * getParent() const
Defines the object file and target independent interfaces used by the assembler backend to write nati...
virtual uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Write the object file and returns the number of bytes written.
virtual void addExceptionEntry(const MCSymbol *Symbol, const MCSymbol *Trap, unsigned LanguageCode, unsigned ReasonCode, unsigned FunctionSize, bool hasDebug)
virtual void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout)=0
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
virtual void reset()
lifetime management
virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0
Record a relocation entry.
StringRef getSymbolTableName() const
XCOFF::VisibilityType getVisibilityType() const
std::optional< XCOFF::DwarfSectionSubtypeFlags > getDwarfSubtypeFlags() const
XCOFF::StorageMappingClass getMappingClass() const
MCSymbolXCOFF * getQualNameSymbol() const
XCOFF::SymbolType getCSectType() const
StringRef getName() const
XCOFF::VisibilityType getVisibilityType() const
StringRef getSymbolTableName() const
XCOFF::StorageClass getStorageClass() const
MCSectionXCOFF * getRepresentedCsect() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
MCFragment * getFragment(bool SetUsed=true) const
This represents an "assembler immediate".
SectionEntry - represents a section emitted into memory by the dynamic linker.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Utility for building string tables with deduplicated suffixes.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
An abstract base class for streams implementations that also support a pwrite operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr size_t RelocationSerializationSize32
constexpr size_t ExceptionSectionEntrySize64
constexpr size_t RelocationSerializationSize64
constexpr size_t ExceptionSectionEntrySize32
constexpr size_t FileHeaderSize64
constexpr size_t SectionHeaderSize64
@ AUX_SECT
Identifies a SECT auxiliary entry.
@ AUX_EXCEPT
Identifies an exception auxiliary entry.
@ AUX_FCN
Identifies a function auxiliary entry.
@ AUX_CSECT
Identifies a csect auxiliary entry.
VisibilityType
Values for visibility as they would appear when encoded in the high 4 bits of the 16-bit unsigned n_t...
constexpr size_t NameSize
constexpr uint16_t RelocOverflow
constexpr size_t AuxFileHeaderSizeShort
constexpr size_t FileHeaderSize32
StorageMappingClass
Storage Mapping Class definitions.
@ XMC_TE
Symbol mapped at the end of TOC.
@ XMC_TC0
TOC Anchor for TOC Addressability.
@ XMC_DS
Descriptor csect.
@ XMC_TL
Initialized thread-local variable.
@ XMC_RO
Read Only Constant.
@ XMC_TD
Scalar data item in the TOC.
@ XMC_UL
Uninitialized thread-local variable.
@ XMC_BS
BSS class (uninitialized static internal)
@ XMC_TC
General TOC item.
constexpr size_t SectionHeaderSize32
@ XTY_CM
Common csect definition. For uninitialized storage.
@ XTY_SD
Csect definition for initialized storage.
@ XTY_LD
Label definition.
@ XTY_ER
External reference.
support::ulittle32_t Word
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
unsigned Log2(Align A)
Returns the log2 of the alignment.
std::unique_ptr< MCObjectWriter > createXCOFFObjectWriter(std::unique_ptr< MCXCOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
unsigned Flags
Flags describing additional information on this fixup kind.
Adapter to write values to a stream in a particular byte order.