Lines Matching +full:group +full:- +full:index +full:- +full:shift
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(); in getVisibilityType()
74 return MCSym->getStorageClass(); in getStorageClass()
76 StringRef getSymbolTableName() const { return MCSym->getSymbolTableName(); } in getSymbolTableName()
77 Symbol(const MCSymbolXCOFF *MCSym) : MCSym(MCSym), SymbolTableIndex(-1) {} in Symbol()
90 StringRef getSymbolTableName() const { return MCSec->getSymbolTableName(); } in getSymbolTableName()
92 return MCSec->getVisibilityType(); in getVisibilityType()
95 : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {} in XCOFFSection()
122 int16_t Index; member
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;
146 Index(UninitializedIndex) { in SectionEntry()
157 Index = UninitializedIndex; in reset()
166 // stored separately, e.g. the .data section containing read-write, descriptor,
167 // TOCBase and TOC-entry csects.
185 for (auto *Group : Groups) in reset() local
186 Group->clear(); in reset()
203 // section. Then a dwarf-specific function wouldn't be needed.
217 assert(DwarfSect->MCSec->isDwarfSect() && in DwarfSectionEntry()
268 return alignTo(Metadata.size(), sizeof(uint32_t)) - Metadata.size(); in paddingSize()
284 Entry->Offset = sizeof(uint32_t); in addEntry()
285 Size += Entry->size(); in addEntry()
306 TargetObjectWriter->is64Bit() ? UINT64_MAX : UINT32_MAX;
313 // Maps the MCSymbol representation to its corrresponding symbol table index.
359 bool is64Bit() const { return TargetObjectWriter->is64Bit(); } in is64Bit()
413 // *) Calculates physical/virtual addresses, raw-pointer offsets, and section
416 // *) Builds up the section header table by adding any non-empty sections to
431 // 64-bit object files have no auxiliary header. in auxiliaryHeaderSize()
474 Sec->reset(); in reset()
493 switch (MCSec->getMappingClass()) { in getCsectGroup()
495 assert(XCOFF::XTY_SD == MCSec->getCSectType() && in getCsectGroup()
499 assert(XCOFF::XTY_SD == MCSec->getCSectType() && in getCsectGroup()
503 if (XCOFF::XTY_CM == MCSec->getCSectType()) in getCsectGroup()
506 if (XCOFF::XTY_SD == MCSec->getCSectType()) in getCsectGroup()
509 report_fatal_error("Unhandled mapping of read-write csect to section."); in getCsectGroup()
513 assert(XCOFF::XTY_CM == MCSec->getCSectType() && in getCsectGroup()
518 assert(XCOFF::XTY_SD == MCSec->getCSectType() && in getCsectGroup()
523 assert(XCOFF::XTY_CM == MCSec->getCSectType() && in getCsectGroup()
528 assert(XCOFF::XTY_SD == MCSec->getCSectType() && in getCsectGroup()
529 "Only an initialized csect can contain TOC-base."); in getCsectGroup()
531 "We should have only one TOC-base, and it should be the first csect " in getCsectGroup()
536 assert(XCOFF::XTY_SD == MCSec->getCSectType() && in getCsectGroup()
539 "We should at least have a TOC-base in this CsectGroup."); in getCsectGroup()
542 assert((XCOFF::XTY_SD == MCSec->getCSectType() || in getCsectGroup()
543 XCOFF::XTY_CM == MCSec->getCSectType()) && in getCsectGroup()
544 "Symbol type incompatible with toc-data."); in getCsectGroup()
546 "We should at least have a TOC-base in this CsectGroup."); in getCsectGroup()
554 if (XSym->isDefined()) in getContainingCsect()
555 return cast<MCSectionXCOFF>(XSym->getFragment()->getParent()); in getContainingCsect()
556 return XSym->getRepresentedCsect(); in getContainingCsect()
566 if (nameShouldBeInStringTable(MCSec->getSymbolTableName())) in executePostLayoutBinding()
567 Strings.add(MCSec->getSymbolTableName()); in executePostLayoutBinding()
568 if (MCSec->isCsect()) { in executePostLayoutBinding()
570 // generated as Text/Data/BSS/TDATA/TBSS. Add this section to the group of in executePostLayoutBinding()
572 assert(XCOFF::XTY_ER != MCSec->getCSectType() && in executePostLayoutBinding()
574 CsectGroup &Group = getCsectGroup(MCSec); in executePostLayoutBinding() local
575 Group.emplace_back(MCSec); in executePostLayoutBinding()
576 SectionMap[MCSec] = &Group.back(); in executePostLayoutBinding()
577 } else if (MCSec->isDwarfSect()) { in executePostLayoutBinding()
583 DwarfSectionEntry SecEntry(MCSec->getName(), in executePostLayoutBinding()
584 *MCSec->getDwarfSubtypeFlags(), in executePostLayoutBinding()
599 if (ContainingCsect->isDwarfSect()) in executePostLayoutBinding()
602 if (XSym->getVisibilityType() != XCOFF::SYM_V_UNSPECIFIED) in executePostLayoutBinding()
605 if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) { in executePostLayoutBinding()
609 if (nameShouldBeInStringTable(ContainingCsect->getSymbolTableName())) in executePostLayoutBinding()
610 Strings.add(ContainingCsect->getSymbolTableName()); in executePostLayoutBinding()
616 if (XSym == ContainingCsect->getQualNameSymbol()) in executePostLayoutBinding()
620 if (!XSym->isExternal()) in executePostLayoutBinding()
627 assert(Csect->MCSec->isCsect() && "only csect is supported now!"); in executePostLayoutBinding()
628 Csect->Syms.emplace_back(XSym); in executePostLayoutBinding()
632 if (nameShouldBeInStringTable(XSym->getSymbolTableName())) in executePostLayoutBinding()
633 Strings.add(XSym->getSymbolTableName()); in executePostLayoutBinding()
637 if (CISI && nameShouldBeInStringTable(CISI->Name)) in executePostLayoutBinding()
638 Strings.add(CISI->Name); in executePostLayoutBinding()
671 : SymbolIndexMap[ContainingCsect->getQualNameSymbol()]; in recordRelocation()
676 const MCSectionXCOFF *ContainingSect) -> uint64_t { in recordRelocation()
678 if (ContainingSect->isDwarfSect()) in recordRelocation()
682 if (!Sym->isDefined()) in recordRelocation()
683 return SectionMap[ContainingSect]->Address; in recordRelocation()
686 assert(Sym->isDefined() && "not a valid object that has address!"); in recordRelocation()
687 return SectionMap[ContainingSect]->Address + Asm.getSymbolOffset(*Sym); in recordRelocation()
690 const MCSymbol *const SymA = &Target.getSymA()->getSymbol(); in recordRelocation()
699 TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel); in recordRelocation()
706 MaxRawDataSize - Asm.getFragmentOffset(*Fragment)) && in recordRelocation()
711 const uint32_t Index = getIndex(SymA, SymASec); in recordRelocation() local
726 // For non toc-data external symbols, R_TOC type relocation will relocate to in recordRelocation()
727 // data symbols that have XCOFF::XTY_SD type csect. For toc-data external in recordRelocation()
731 if (SymASec->getCSectType() == XCOFF::XTY_ER) { in recordRelocation()
734 // The FixedValue should be the TOC entry offset from the TOC-base plus in recordRelocation()
736 int64_t TOCEntryOffset = SectionMap[SymASec]->Address - in recordRelocation()
738 // For small code model, if the TOCEntryOffset overflows the 16-bit value, in recordRelocation()
740 // fix-up code when needed. in recordRelocation()
741 // For non toc-data symbols, we already did the truncation in in recordRelocation()
745 // For toc-data symbols, we were not able to calculate the offset from in recordRelocation()
749 // TODO: Since the time that the handling for offsets over 16-bits was in recordRelocation()
760 MCSectionXCOFF *ParentSec = cast<MCSectionXCOFF>(Fragment->getParent()); in recordRelocation()
761 assert((SymASec->getMappingClass() == XCOFF::XMC_PR && in recordRelocation()
762 ParentSec->getMappingClass() == XCOFF::XMC_PR) && in recordRelocation()
768 SectionMap[ParentSec]->Address + FixupOffsetInCsect; in recordRelocation()
771 FixedValue = getVirtualAddress(SymA, SymASec) - BRInstrAddress + in recordRelocation()
780 XCOFFRelocation Reloc = {Index, FixupOffsetInCsect, SignAndSize, Type}; in recordRelocation()
781 MCSectionXCOFF *RelocationSec = cast<MCSectionXCOFF>(Fragment->getParent()); in recordRelocation()
784 SectionMap[RelocationSec]->Relocations.push_back(Reloc); in recordRelocation()
789 const MCSymbol *const SymB = &Target.getSymB()->getSymbol(); in recordRelocation()
805 // "SymbolA - SymbolB + imm64". in recordRelocation()
808 SectionMap[RelocationSec]->Relocations.push_back(RelocB); in recordRelocation()
810 // now we just need to fold "- SymbolB" here. in recordRelocation()
811 FixedValue -= getVirtualAddress(SymB, SymBSec); in recordRelocation()
843 return W.OS.tell() - StartOffset; in writeObject()
946 assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address && in writeSymbolEntryForCsectMemberLabel()
949 auto Entry = ExceptionSection.ExceptionTable.find(SymbolRef.MCSym->getName()); in writeSymbolEntryForCsectMemberLabel()
953 // In the old version of the 32-bit XCOFF interpretation, in writeSymbolEntryForCsectMemberLabel()
962 // function auxilliary entries, so we must increment symbol index by 4. in writeSymbolEntryForCsectMemberLabel()
965 getExceptionOffset(Entry->second.FunctionSymbol), in writeSymbolEntryForCsectMemberLabel()
966 Entry->second.FunctionSize, in writeSymbolEntryForCsectMemberLabel()
967 SymbolIndexMap[Entry->second.FunctionSymbol] + 4); in writeSymbolEntryForCsectMemberLabel()
970 // must exist. On 64-bit there is also an exception auxilliary entry. in writeSymbolEntryForCsectMemberLabel()
973 getExceptionOffset(Entry->second.FunctionSymbol), in writeSymbolEntryForCsectMemberLabel()
974 Entry->second.FunctionSize, 0, in writeSymbolEntryForCsectMemberLabel()
976 ? SymbolIndexMap[Entry->second.FunctionSymbol] + 4 in writeSymbolEntryForCsectMemberLabel()
977 : SymbolIndexMap[Entry->second.FunctionSymbol] + 3); in writeSymbolEntryForCsectMemberLabel()
985 CSectionRef.MCSec->getMappingClass()); in writeSymbolEntryForCsectMemberLabel()
990 assert(DwarfSectionRef.MCSec->isDwarfSect() && "Not a DWARF section!"); in writeSymbolEntryForDwarfSection()
1005 CSectionRef.MCSec->getMappingClass()); in writeSymbolEntryForControlSection()
1031 assert(is64Bit() && "Exception auxilliary entries are 64-bit only."); in writeSymbolAuxExceptionEntry()
1063 W.write<uint32_t>(Sections[0]->Size); // TextSize in writeAuxFileHeader()
1064 W.write<uint32_t>(Sections[1]->Size); // InitDataSize in writeAuxFileHeader()
1065 W.write<uint32_t>(Sections[2]->Size); // BssDataSize in writeAuxFileHeader()
1067 W.write<uint32_t>(Sections[0]->Address); // TextStartAddr in writeAuxFileHeader()
1068 W.write<uint32_t>(Sections[1]->Address); // DataStartAddr in writeAuxFileHeader()
1072 bool IsDwarf = (Sec->Flags & XCOFF::STYP_DWARF) != 0; in writeSectionHeader()
1073 bool IsOvrflo = (Sec->Flags & XCOFF::STYP_OVRFLO) != 0; in writeSectionHeader()
1075 if (Sec->Index == SectionEntry::UninitializedIndex) in writeSectionHeader()
1079 ArrayRef<char> NameRef(Sec->Name, XCOFF::NameSize); in writeSectionHeader()
1084 writeWord(IsDwarf ? 0 : Sec->Address); in writeSectionHeader()
1086 writeWord((IsDwarf || IsOvrflo) ? 0 : Sec->Address); in writeSectionHeader()
1088 writeWord(Sec->Size); in writeSectionHeader()
1089 writeWord(Sec->FileOffsetToData); in writeSectionHeader()
1090 writeWord(Sec->FileOffsetToRelocations); in writeSectionHeader()
1094 W.write<uint32_t>(Sec->RelocationCount); in writeSectionHeader()
1096 W.write<int32_t>(Sec->Flags); in writeSectionHeader()
1103 W.write<uint16_t>(Sec->RelocationCount); in writeSectionHeader()
1104 W.write<uint16_t>((IsOvrflo || Sec->RelocationCount == XCOFF::RelocOverflow) in writeSectionHeader()
1105 ? Sec->RelocationCount in writeSectionHeader()
1107 W.write<int32_t>(Sec->Flags); in writeSectionHeader()
1126 if (Section.MCSec->isCsect()) in writeRelocation()
1130 assert(Section.MCSec->isDwarfSect() && "unsupport section type!"); in writeRelocation()
1140 if (Section->Index == SectionEntry::UninitializedIndex) in writeRelocations()
1144 for (const auto *Group : Section->Groups) { in writeRelocations() local
1145 if (Group->empty()) in writeRelocations()
1148 for (const auto &Csect : *Group) { in writeRelocations()
1156 for (const auto &Reloc : DwarfSection.DwarfSect->Relocations) in writeRelocations()
1169 // For C_FILE symbols, the Source Language ID overlays the high-order byte in writeSymbolTable()
1171 // low-order byte. in writeSymbolTable()
1204 writeSymbolEntry(CInfoSymSection.Entry->Name, CInfoSymSection.Entry->Offset, in writeSymbolTable()
1205 CInfoSymSection.Index, in writeSymbolTable()
1211 Csect.MCSec->getStorageClass()); in writeSymbolTable()
1215 if (Section->Index == SectionEntry::UninitializedIndex) in writeSymbolTable()
1219 for (const auto *Group : Section->Groups) { in writeSymbolTable() local
1220 if (Group->empty()) in writeSymbolTable()
1223 const int16_t SectionIndex = Section->Index; in writeSymbolTable()
1224 for (const auto &Csect : *Group) { in writeSymbolTable()
1227 Csect.MCSec->getStorageClass()); in writeSymbolTable()
1238 DwarfSection.Index); in writeSymbolTable()
1251 SecEntry.RelocationCount = Sec->Index; in finalizeRelocationInfo()
1256 SecEntry.Index = ++SectionCount; in finalizeRelocationInfo()
1261 Sec->RelocationCount = XCOFF::RelocOverflow; in finalizeRelocationInfo()
1263 Sec->RelocationCount = RelCount; in finalizeRelocationInfo()
1269 if (!Sec->RelocationCount) in calcOffsetToRelocations()
1272 Sec->FileOffsetToRelocations = RawPointer; in calcOffsetToRelocations()
1275 Sec->RelocationCount == static_cast<uint32_t>(XCOFF::RelocOverflow)) { in calcOffsetToRelocations()
1278 if (OverflowSec.RelocationCount == static_cast<uint32_t>(Sec->Index)) { in calcOffsetToRelocations()
1284 OverflowSec.FileOffsetToRelocations = Sec->FileOffsetToRelocations; in calcOffsetToRelocations()
1289 RelocationSizeInSec = Sec->RelocationCount * in calcOffsetToRelocations()
1301 if (Section->Index == SectionEntry::UninitializedIndex) in finalizeSectionInfo()
1306 for (const auto *Group : Section->Groups) { in finalizeSectionInfo() local
1307 if (Group->empty()) in finalizeSectionInfo()
1310 for (auto &Csect : *Group) in finalizeSectionInfo()
1318 DwarfSection.DwarfSect->Relocations.size()); in finalizeSectionInfo()
1330 if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual) in finalizeSectionInfo()
1333 RawPointer = Sec->advanceFileOffset(MaxRawDataSize, RawPointer); in finalizeSectionInfo()
1350 if (Sec->Index != SectionEntry::UninitializedIndex) in finalizeSectionInfo()
1357 // TODO Error check that the number of symbol table entries fits in 32-bits in finalizeSectionInfo()
1370 auto Entry = ExceptionSection.ExceptionTable.find(Symbol->getName()); in addExceptionEntry()
1372 Entry->second.Entries.push_back( in addExceptionEntry()
1382 std::pair<const StringRef, ExceptionInfo>(Symbol->getName(), NewEntry)); in addExceptionEntry()
1390 // symbol table index. in getExceptionSectionSize()
1428 SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex; in assignAddressesAndIndices()
1437 // Section indices are 1-based in XCOFF. in assignAddressesAndIndices()
1443 llvm::all_of(Section->Groups, in assignAddressesAndIndices()
1444 [](const CsectGroup *Group) { return Group->empty(); }); in assignAddressesAndIndices() argument
1449 report_fatal_error("Section index overflow!"); in assignAddressesAndIndices()
1450 Section->Index = SectionIndex++; in assignAddressesAndIndices()
1455 if (Section->Flags == XCOFF::STYP_TDATA) { in assignAddressesAndIndices()
1461 if ((Section->Flags == XCOFF::STYP_TBSS) && !HasTDataSection) in assignAddressesAndIndices()
1464 for (auto *Group : Section->Groups) { in assignAddressesAndIndices() local
1465 if (Group->empty()) in assignAddressesAndIndices()
1468 for (auto &Csect : *Group) { in assignAddressesAndIndices()
1470 Csect.Address = alignTo(Address, MCSec->getAlign()); in assignAddressesAndIndices()
1474 SymbolIndexMap[MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex; in assignAddressesAndIndices()
1481 ExceptionSection.ExceptionTable.find(Sym.MCSym->getName()); in assignAddressesAndIndices()
1484 for (auto &TrapEntry : Entry->second.Entries) { in assignAddressesAndIndices()
1486 TrapEntry.Trap->getOffset(); in assignAddressesAndIndices()
1493 // auxilliary entry is needed, and on 64-bit XCOFF with debugging in assignAddressesAndIndices()
1506 Section->Address = Group->front().Address; in assignAddressesAndIndices()
1514 Section->Size = Address - Section->Address; in assignAddressesAndIndices()
1525 (*DwarfSections.begin()).DwarfSect->MCSec->getAlign()) - in assignAddressesAndIndices()
1530 assert((SectionIndex <= MaxSectionIndex) && "Section index overflow!"); in assignAddressesAndIndices()
1535 // Section index. in assignAddressesAndIndices()
1536 DwarfSection.Index = SectionIndex++; in assignAddressesAndIndices()
1539 // Symbol index. in assignAddressesAndIndices()
1541 SymbolIndexMap[MCSec->getQualNameSymbol()] = DwarfSect.SymbolTableIndex; in assignAddressesAndIndices()
1550 alignTo(Address, MCSec->getAlign()); in assignAddressesAndIndices()
1559 LastDwarfSection->MemorySize = in assignAddressesAndIndices()
1560 DwarfSection.Address - LastDwarfSection->Address; in assignAddressesAndIndices()
1566 Address = alignTo(LastDwarfSection->Address + LastDwarfSection->Size, in assignAddressesAndIndices()
1568 LastDwarfSection->MemorySize = Address - LastDwarfSection->Address; in assignAddressesAndIndices()
1571 ExceptionSection.Index = SectionIndex++; in assignAddressesAndIndices()
1580 CInfoSymSection.Index = SectionIndex++; in assignAddressesAndIndices()
1594 if (CsectEntry.Index == SectionEntry::UninitializedIndex) in writeSectionForControlSectionEntry()
1617 for (const auto &Group : CsectEntry.Groups) { in writeSectionForControlSectionEntry() local
1618 for (const auto &Csect : *Group) { in writeSectionForControlSectionEntry()
1619 if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation) in writeSectionForControlSectionEntry()
1631 CsectEntry.Address + CsectEntry.Size - CurrentAddressLocation) { in writeSectionForControlSectionEntry()
1647 if (uint64_t PaddingSize = DwarfEntry.Address - CurrentAddressLocation) in writeSectionForDwarfSectionEntry()
1651 Asm.writeSectionData(W.OS, DwarfEntry.DwarfSect->MCSec); in writeSectionForDwarfSectionEntry()
1658 uint32_t TailPaddingSize = Mod ? DefaultSectionAlign - Mod : 0; in writeSectionForDwarfSectionEntry()
1670 // with an initial symbol table index entry in writeSectionForExceptionSectionEntry()
1673 // 4-byte padding on 64-bit. in writeSectionForExceptionSectionEntry()
1695 const std::string &Metadata = CISI->Metadata; in writeSectionForCInfoSymSectionEntry()
1697 // Emit the 4-byte length of the metadata. in writeSectionForCInfoSymSectionEntry()
1704 size_t Index = 0; in writeSectionForCInfoSymSectionEntry() local
1705 while (Index + WordSize <= Metadata.size()) { in writeSectionForCInfoSymSectionEntry()
1707 llvm::support::endian::read32be(Metadata.data() + Index); in writeSectionForCInfoSymSectionEntry()
1709 Index += WordSize; in writeSectionForCInfoSymSectionEntry()
1713 if (CISI->paddingSize()) { in writeSectionForCInfoSymSectionEntry()
1715 ::memcpy(LastWord.data(), Metadata.data() + Index, Metadata.size() - Index); in writeSectionForCInfoSymSectionEntry()
1719 CurrentAddressLocation += CISI->size(); in writeSectionForCInfoSymSectionEntry()
1726 unsigned Log2Align = Log2(Sec->getAlign()); in getEncodedType()
1728 // significant bits. Shift this value into the 5 most significant bits, and in getEncodedType()
1729 // bitwise-or in the csect type. in getEncodedType()
1731 return EncodedAlign | Sec->getCSectType(); in getEncodedType()