Lines Matching +full:reset +full:- +full:time +full:- +full:sec

1 //===-- lib/MC/XCOFFObjectWriter.cpp - XCOFF file writer ------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
36 // .text --> contains program code and read-only data.
37 // .data --> contains initialized data, function descriptors, and the TOC.
38 // .bss --> contains uninitialized data.
42 // into a section based on its storage-mapping class, with the exception of
70 return MCSym->getVisibilityType();
74 return MCSym->getStorageClass();
76 StringRef getSymbolTableName() const { return MCSym->getSymbolTableName(); }
77 Symbol(const MCSymbolXCOFF *MCSym) : MCSym(MCSym), SymbolTableIndex(-1) {}
90 StringRef getSymbolTableName() const { return MCSec->getSymbolTableName(); }
92 return MCSec->getVisibilityType();
95 : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {}
134 // -2 Specifies N_DEBUG, a special symbolic debugging symbol.
135 // -1 Specifies N_ABS, an absolute symbol. The symbol has a value but is not
138 // Therefore, we choose -3 (N_DEBUG - 1) to represent a section index that
141 XCOFF::ReservedSectionNum::N_DEBUG - 1;
151 virtual void reset() {
166 // stored separately, e.g. the .data section containing read-write, descriptor,
167 // TOCBase and TOC-entry csects.
182 void reset() override {
183 SectionEntry::reset();
186 Group->clear();
203 // section. Then a dwarf-specific function wouldn't be needed.
217 assert(DwarfSect->MCSec->isDwarfSect() &&
268 return alignTo(Metadata.size(), sizeof(uint32_t)) - Metadata.size();
284 Entry->Offset = sizeof(uint32_t);
285 Size += Entry->size();
287 void reset() override {
288 SectionEntry::reset();
289 Entry.reset();
306 TargetObjectWriter->is64Bit() ? UINT64_MAX : UINT32_MAX;
350 void reset() override;
359 bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
376 void writeSectionHeader(const SectionEntry *Sec);
413 // *) Calculates physical/virtual addresses, raw-pointer offsets, and section
416 // *) Builds up the section header table by adding any non-empty sections to
421 void finalizeRelocationInfo(SectionEntry *Sec, uint64_t RelCount);
422 void calcOffsetToRelocations(SectionEntry *Sec, uint64_t &RawPointer);
431 // 64-bit object files have no auxiliary header.
466 void XCOFFObjectWriter::reset() {
472 // Reset any sections we have written to, and empty the section header table.
473 for (auto *Sec : Sections)
474 Sec->reset();
476 DwarfSec.reset();
478 OverflowSec.reset();
479 ExceptionSection.reset();
480 CInfoSymSection.reset();
482 // Reset states in XCOFFObjectWriter.
489 MCObjectWriter::reset();
493 switch (MCSec->getMappingClass()) {
495 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
499 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
503 if (XCOFF::XTY_CM == MCSec->getCSectType())
506 if (XCOFF::XTY_SD == MCSec->getCSectType())
509 report_fatal_error("Unhandled mapping of read-write csect to section.");
513 assert(XCOFF::XTY_CM == MCSec->getCSectType() &&
518 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
523 assert(XCOFF::XTY_CM == MCSec->getCSectType() &&
528 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
529 "Only an initialized csect can contain TOC-base.");
531 "We should have only one TOC-base, and it should be the first csect "
536 assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
539 "We should at least have a TOC-base in this CsectGroup.");
542 assert((XCOFF::XTY_SD == MCSec->getCSectType() ||
543 XCOFF::XTY_CM == MCSec->getCSectType()) &&
544 "Symbol type incompatible with toc-data.");
546 "We should at least have a TOC-base in this CsectGroup.");
554 if (XSym->isDefined())
555 return cast<MCSectionXCOFF>(XSym->getFragment()->getParent());
556 return XSym->getRepresentedCsect();
566 if (nameShouldBeInStringTable(MCSec->getSymbolTableName()))
567 Strings.add(MCSec->getSymbolTableName());
568 if (MCSec->isCsect()) {
572 assert(XCOFF::XTY_ER != MCSec->getCSectType() &&
577 } else if (MCSec->isDwarfSect()) {
583 DwarfSectionEntry SecEntry(MCSec->getName(),
584 *MCSec->getDwarfSubtypeFlags(),
599 if (ContainingCsect->isDwarfSect())
602 if (XSym->getVisibilityType() != XCOFF::SYM_V_UNSPECIFIED)
605 if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) {
609 if (nameShouldBeInStringTable(ContainingCsect->getSymbolTableName()))
610 Strings.add(ContainingCsect->getSymbolTableName());
616 if (XSym == ContainingCsect->getQualNameSymbol())
620 if (!XSym->isExternal())
627 assert(Csect->MCSec->isCsect() && "only csect is supported now!");
628 Csect->Syms.emplace_back(XSym);
632 if (nameShouldBeInStringTable(XSym->getSymbolTableName()))
633 Strings.add(XSym->getSymbolTableName());
637 if (CISI && nameShouldBeInStringTable(CISI->Name))
638 Strings.add(CISI->Name);
671 : SymbolIndexMap[ContainingCsect->getQualNameSymbol()];
676 const MCSectionXCOFF *ContainingSect) -> uint64_t {
678 if (ContainingSect->isDwarfSect())
682 if (!Sym->isDefined())
683 return SectionMap[ContainingSect]->Address;
686 assert(Sym->isDefined() && "not a valid object that has address!");
687 return SectionMap[ContainingSect]->Address + Asm.getSymbolOffset(*Sym);
690 const MCSymbol *const SymA = &Target.getSymA()->getSymbol();
699 TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel);
706 MaxRawDataSize - Asm.getFragmentOffset(*Fragment)) &&
722 // known at load time.
726 // For non toc-data external symbols, R_TOC type relocation will relocate to
727 // data symbols that have XCOFF::XTY_SD type csect. For toc-data external
731 if (SymASec->getCSectType() == XCOFF::XTY_ER) {
734 // The FixedValue should be the TOC entry offset from the TOC-base plus
736 int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
738 // For small code model, if the TOCEntryOffset overflows the 16-bit value,
740 // fix-up code when needed.
741 // For non toc-data symbols, we already did the truncation in
745 // For toc-data symbols, we were not able to calculate the offset from
749 // TODO: Since the time that the handling for offsets over 16-bits was
760 MCSectionXCOFF *ParentSec = cast<MCSectionXCOFF>(Fragment->getParent());
761 assert((SymASec->getMappingClass() == XCOFF::XMC_PR &&
762 ParentSec->getMappingClass() == XCOFF::XMC_PR) &&
768 SectionMap[ParentSec]->Address + FixupOffsetInCsect;
771 FixedValue = getVirtualAddress(SymA, SymASec) - BRInstrAddress +
781 MCSectionXCOFF *RelocationSec = cast<MCSectionXCOFF>(Fragment->getParent());
784 SectionMap[RelocationSec]->Relocations.push_back(Reloc);
789 const MCSymbol *const SymB = &Target.getSymB()->getSymbol();
805 // "SymbolA - SymbolB + imm64".
808 SectionMap[RelocationSec]->Relocations.push_back(RelocB);
810 // now we just need to fold "- SymbolB" here.
811 FixedValue -= getVirtualAddress(SymB, SymBSec);
843 return W.OS.tell() - StartOffset;
946 assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address &&
949 auto Entry = ExceptionSection.ExceptionTable.find(SymbolRef.MCSym->getName());
953 // In the old version of the 32-bit XCOFF interpretation,
965 getExceptionOffset(Entry->second.FunctionSymbol),
966 Entry->second.FunctionSize,
967 SymbolIndexMap[Entry->second.FunctionSymbol] + 4);
970 // must exist. On 64-bit there is also an exception auxilliary entry.
973 getExceptionOffset(Entry->second.FunctionSymbol),
974 Entry->second.FunctionSize, 0,
976 ? SymbolIndexMap[Entry->second.FunctionSymbol] + 4
977 : SymbolIndexMap[Entry->second.FunctionSymbol] + 3);
985 CSectionRef.MCSec->getMappingClass());
990 assert(DwarfSectionRef.MCSec->isDwarfSect() && "Not a DWARF section!");
1005 CSectionRef.MCSec->getMappingClass());
1031 assert(is64Bit() && "Exception auxilliary entries are 64-bit only.");
1063 W.write<uint32_t>(Sections[0]->Size); // TextSize
1064 W.write<uint32_t>(Sections[1]->Size); // InitDataSize
1065 W.write<uint32_t>(Sections[2]->Size); // BssDataSize
1067 W.write<uint32_t>(Sections[0]->Address); // TextStartAddr
1068 W.write<uint32_t>(Sections[1]->Address); // DataStartAddr
1071 void XCOFFObjectWriter::writeSectionHeader(const SectionEntry *Sec) {
1072 bool IsDwarf = (Sec->Flags & XCOFF::STYP_DWARF) != 0;
1073 bool IsOvrflo = (Sec->Flags & XCOFF::STYP_OVRFLO) != 0;
1075 if (Sec->Index == SectionEntry::UninitializedIndex)
1079 ArrayRef<char> NameRef(Sec->Name, XCOFF::NameSize);
1084 writeWord(IsDwarf ? 0 : Sec->Address);
1086 writeWord((IsDwarf || IsOvrflo) ? 0 : Sec->Address);
1088 writeWord(Sec->Size);
1089 writeWord(Sec->FileOffsetToData);
1090 writeWord(Sec->FileOffsetToRelocations);
1094 W.write<uint32_t>(Sec->RelocationCount);
1096 W.write<int32_t>(Sec->Flags);
1103 W.write<uint16_t>(Sec->RelocationCount);
1104 W.write<uint16_t>((IsOvrflo || Sec->RelocationCount == XCOFF::RelocOverflow)
1105 ? Sec->RelocationCount
1107 W.write<int32_t>(Sec->Flags);
1126 if (Section.MCSec->isCsect())
1130 assert(Section.MCSec->isDwarfSect() && "unsupport section type!");
1140 if (Section->Index == SectionEntry::UninitializedIndex)
1144 for (const auto *Group : Section->Groups) {
1145 if (Group->empty())
1156 for (const auto &Reloc : DwarfSection.DwarfSect->Relocations)
1169 // For C_FILE symbols, the Source Language ID overlays the high-order byte
1171 // low-order byte.
1204 writeSymbolEntry(CInfoSymSection.Entry->Name, CInfoSymSection.Entry->Offset,
1211 Csect.MCSec->getStorageClass());
1215 if (Section->Index == SectionEntry::UninitializedIndex)
1219 for (const auto *Group : Section->Groups) {
1220 if (Group->empty())
1223 const int16_t SectionIndex = Section->Index;
1227 Csect.MCSec->getStorageClass());
1241 void XCOFFObjectWriter::finalizeRelocationInfo(SectionEntry *Sec,
1251 SecEntry.RelocationCount = Sec->Index;
1261 Sec->RelocationCount = XCOFF::RelocOverflow;
1263 Sec->RelocationCount = RelCount;
1267 void XCOFFObjectWriter::calcOffsetToRelocations(SectionEntry *Sec,
1269 if (!Sec->RelocationCount)
1272 Sec->FileOffsetToRelocations = RawPointer;
1275 Sec->RelocationCount == static_cast<uint32_t>(XCOFF::RelocOverflow)) {
1278 if (OverflowSec.RelocationCount == static_cast<uint32_t>(Sec->Index)) {
1284 OverflowSec.FileOffsetToRelocations = Sec->FileOffsetToRelocations;
1289 RelocationSizeInSec = Sec->RelocationCount *
1301 if (Section->Index == SectionEntry::UninitializedIndex)
1306 for (const auto *Group : Section->Groups) {
1307 if (Group->empty())
1318 DwarfSection.DwarfSect->Relocations.size());
1329 for (auto *Sec : Sections) {
1330 if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual)
1333 RawPointer = Sec->advanceFileOffset(MaxRawDataSize, RawPointer);
1349 for (auto *Sec : Sections) {
1350 if (Sec->Index != SectionEntry::UninitializedIndex)
1351 calcOffsetToRelocations(Sec, RawPointer);
1357 // TODO Error check that the number of symbol table entries fits in 32-bits
1370 auto Entry = ExceptionSection.ExceptionTable.find(Symbol->getName());
1372 Entry->second.Entries.push_back(
1382 std::pair<const StringRef, ExceptionInfo>(Symbol->getName(), NewEntry));
1428 SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
1437 // Section indices are 1-based in XCOFF.
1443 llvm::all_of(Section->Groups,
1444 [](const CsectGroup *Group) { return Group->empty(); });
1450 Section->Index = SectionIndex++;
1454 // Reset the starting address to 0 for TData section.
1455 if (Section->Flags == XCOFF::STYP_TDATA) {
1459 // Reset the starting address to 0 for TBSS section if the object file does
1461 if ((Section->Flags == XCOFF::STYP_TBSS) && !HasTDataSection)
1464 for (auto *Group : Section->Groups) {
1465 if (Group->empty())
1470 Csect.Address = alignTo(Address, MCSec->getAlign());
1474 SymbolIndexMap[MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
1481 ExceptionSection.ExceptionTable.find(Sym.MCSym->getName());
1484 for (auto &TrapEntry : Entry->second.Entries) {
1486 TrapEntry.Trap->getOffset();
1493 // auxilliary entry is needed, and on 64-bit XCOFF with debugging
1506 Section->Address = Group->front().Address;
1514 Section->Size = Address - Section->Address;
1525 (*DwarfSections.begin()).DwarfSect->MCSec->getAlign()) -
1541 SymbolIndexMap[MCSec->getQualNameSymbol()] = DwarfSect.SymbolTableIndex;
1550 alignTo(Address, MCSec->getAlign());
1559 LastDwarfSection->MemorySize =
1560 DwarfSection.Address - LastDwarfSection->Address;
1566 Address = alignTo(LastDwarfSection->Address + LastDwarfSection->Size,
1568 LastDwarfSection->MemorySize = Address - LastDwarfSection->Address;
1619 if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation)
1631 CsectEntry.Address + CsectEntry.Size - CurrentAddressLocation) {
1647 if (uint64_t PaddingSize = DwarfEntry.Address - CurrentAddressLocation)
1651 Asm.writeSectionData(W.OS, DwarfEntry.DwarfSect->MCSec);
1658 uint32_t TailPaddingSize = Mod ? DefaultSectionAlign - Mod : 0;
1673 // 4-byte padding on 64-bit.
1695 const std::string &Metadata = CISI->Metadata;
1697 // Emit the 4-byte length of the metadata.
1703 // Write out the payload one word at a time.
1713 if (CISI->paddingSize()) {
1715 ::memcpy(LastWord.data(), Metadata.data() + Index, Metadata.size() - Index);
1719 CurrentAddressLocation += CISI->size();
1725 uint8_t getEncodedType(const MCSectionXCOFF *Sec) {
1726 unsigned Log2Align = Log2(Sec->getAlign());
1729 // bitwise-or in the csect type.
1731 return EncodedAlign | Sec->getCSectType();