12357e899Savl-llvm //===- DWARFLinkerUnit.cpp ------------------------------------------------===// 22357e899Savl-llvm // 32357e899Savl-llvm // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42357e899Savl-llvm // See https://llvm.org/LICENSE.txt for license information. 52357e899Savl-llvm // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62357e899Savl-llvm // 72357e899Savl-llvm //===----------------------------------------------------------------------===// 82357e899Savl-llvm 92357e899Savl-llvm #include "DWARFLinkerUnit.h" 102357e899Savl-llvm #include "DWARFEmitterImpl.h" 112357e899Savl-llvm #include "DebugLineSectionEmitter.h" 122357e899Savl-llvm 132357e899Savl-llvm using namespace llvm; 142357e899Savl-llvm using namespace dwarf_linker; 152357e899Savl-llvm using namespace dwarf_linker::parallel; 162357e899Savl-llvm 172357e899Savl-llvm void DwarfUnit::assignAbbrev(DIEAbbrev &Abbrev) { 182357e899Savl-llvm // Check the set for priors. 192357e899Savl-llvm FoldingSetNodeID ID; 202357e899Savl-llvm Abbrev.Profile(ID); 212357e899Savl-llvm void *InsertToken; 222357e899Savl-llvm 232357e899Savl-llvm DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken); 242357e899Savl-llvm // If it's newly added. 252357e899Savl-llvm if (InSet) { 262357e899Savl-llvm // Assign existing abbreviation number. 272357e899Savl-llvm Abbrev.setNumber(InSet->getNumber()); 282357e899Savl-llvm } else { 292357e899Savl-llvm // Add to abbreviation list. 302357e899Savl-llvm Abbreviations.push_back( 312357e899Savl-llvm std::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren())); 322357e899Savl-llvm for (const auto &Attr : Abbrev.getData()) 332357e899Savl-llvm Abbreviations.back()->AddAttribute(Attr); 342357e899Savl-llvm AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken); 352357e899Savl-llvm // Assign the unique abbreviation number. 362357e899Savl-llvm Abbrev.setNumber(Abbreviations.size()); 372357e899Savl-llvm Abbreviations.back()->setNumber(Abbreviations.size()); 382357e899Savl-llvm } 392357e899Savl-llvm } 402357e899Savl-llvm 412357e899Savl-llvm Error DwarfUnit::emitAbbreviations() { 422357e899Savl-llvm const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs = getAbbreviations(); 432357e899Savl-llvm if (Abbrevs.empty()) 442357e899Savl-llvm return Error::success(); 452357e899Savl-llvm 462357e899Savl-llvm SectionDescriptor &AbbrevSection = 472357e899Savl-llvm getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev); 482357e899Savl-llvm 492357e899Savl-llvm // For each abbreviation. 502357e899Savl-llvm for (const auto &Abbrev : Abbrevs) 512357e899Savl-llvm emitDwarfAbbrevEntry(*Abbrev, AbbrevSection); 522357e899Savl-llvm 532357e899Savl-llvm // Mark end of abbreviations. 542357e899Savl-llvm encodeULEB128(0, AbbrevSection.OS); 552357e899Savl-llvm 562357e899Savl-llvm return Error::success(); 572357e899Savl-llvm } 582357e899Savl-llvm 592357e899Savl-llvm void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev, 602357e899Savl-llvm SectionDescriptor &AbbrevSection) { 612357e899Savl-llvm // Emit the abbreviations code (base 1 index.) 622357e899Savl-llvm encodeULEB128(Abbrev.getNumber(), AbbrevSection.OS); 632357e899Savl-llvm 642357e899Savl-llvm // Emit the abbreviations data. 652357e899Savl-llvm // Emit its Dwarf tag type. 662357e899Savl-llvm encodeULEB128(Abbrev.getTag(), AbbrevSection.OS); 672357e899Savl-llvm 682357e899Savl-llvm // Emit whether it has children DIEs. 692357e899Savl-llvm encodeULEB128((unsigned)Abbrev.hasChildren(), AbbrevSection.OS); 702357e899Savl-llvm 712357e899Savl-llvm // For each attribute description. 722357e899Savl-llvm const SmallVectorImpl<DIEAbbrevData> &Data = Abbrev.getData(); 73*83845b17SKazu Hirata for (const DIEAbbrevData &AttrData : Data) { 742357e899Savl-llvm // Emit attribute type. 752357e899Savl-llvm encodeULEB128(AttrData.getAttribute(), AbbrevSection.OS); 762357e899Savl-llvm 772357e899Savl-llvm // Emit form type. 782357e899Savl-llvm encodeULEB128(AttrData.getForm(), AbbrevSection.OS); 792357e899Savl-llvm 802357e899Savl-llvm // Emit value for DW_FORM_implicit_const. 812357e899Savl-llvm if (AttrData.getForm() == dwarf::DW_FORM_implicit_const) 822357e899Savl-llvm encodeSLEB128(AttrData.getValue(), AbbrevSection.OS); 832357e899Savl-llvm } 842357e899Savl-llvm 852357e899Savl-llvm // Mark end of abbreviation. 862357e899Savl-llvm encodeULEB128(0, AbbrevSection.OS); 872357e899Savl-llvm encodeULEB128(0, AbbrevSection.OS); 882357e899Savl-llvm } 892357e899Savl-llvm 902357e899Savl-llvm Error DwarfUnit::emitDebugInfo(const Triple &TargetTriple) { 912357e899Savl-llvm DIE *OutUnitDIE = getOutUnitDIE(); 922357e899Savl-llvm if (OutUnitDIE == nullptr) 932357e899Savl-llvm return Error::success(); 942357e899Savl-llvm 952357e899Savl-llvm // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs 962357e899Savl-llvm // directly. 972357e899Savl-llvm 982357e899Savl-llvm SectionDescriptor &OutSection = 992357e899Savl-llvm getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 1002357e899Savl-llvm DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, OutSection.OS); 1012357e899Savl-llvm if (Error Err = Emitter.init(TargetTriple, "__DWARF")) 1022357e899Savl-llvm return Err; 1032357e899Savl-llvm 1042357e899Savl-llvm // Emit compile unit header. 1052357e899Savl-llvm Emitter.emitCompileUnitHeader(*this); 1062357e899Savl-llvm size_t OffsetToAbbreviationTableOffset = 1072357e899Savl-llvm (getFormParams().Version >= 5) ? 8 : 6; 1082357e899Savl-llvm OutSection.notePatch(DebugOffsetPatch{ 1092357e899Savl-llvm OffsetToAbbreviationTableOffset, 1102357e899Savl-llvm &getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev)}); 1112357e899Savl-llvm 1122357e899Savl-llvm // Emit DIEs. 1132357e899Savl-llvm Emitter.emitDIE(*OutUnitDIE); 1142357e899Savl-llvm Emitter.finish(); 1152357e899Savl-llvm 1162357e899Savl-llvm // Set start offset ans size for .debug_info section. 1172357e899Savl-llvm OutSection.setSizesForSectionCreatedByAsmPrinter(); 1182357e899Savl-llvm return Error::success(); 1192357e899Savl-llvm } 1202357e899Savl-llvm 1212357e899Savl-llvm Error DwarfUnit::emitDebugLine(const Triple &TargetTriple, 1222357e899Savl-llvm const DWARFDebugLine::LineTable &OutLineTable) { 1232357e899Savl-llvm DebugLineSectionEmitter DebugLineEmitter(TargetTriple, *this); 1242357e899Savl-llvm 1252357e899Savl-llvm return DebugLineEmitter.emit(OutLineTable); 1262357e899Savl-llvm } 1272357e899Savl-llvm 1282357e899Savl-llvm Error DwarfUnit::emitDebugStringOffsetSection() { 1292357e899Savl-llvm if (getVersion() < 5) 1302357e899Savl-llvm return Error::success(); 1312357e899Savl-llvm 1322357e899Savl-llvm if (DebugStringIndexMap.empty()) 1332357e899Savl-llvm return Error::success(); 1342357e899Savl-llvm 1352357e899Savl-llvm SectionDescriptor &OutDebugStrOffsetsSection = 1362357e899Savl-llvm getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets); 1372357e899Savl-llvm 1382357e899Savl-llvm // Emit section header. 1392357e899Savl-llvm 1402357e899Savl-llvm // Emit length. 1412357e899Savl-llvm OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF); 1422357e899Savl-llvm uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell(); 1432357e899Savl-llvm 1442357e899Savl-llvm // Emit version. 1452357e899Savl-llvm OutDebugStrOffsetsSection.emitIntVal(5, 2); 1462357e899Savl-llvm 1472357e899Savl-llvm // Emit padding. 1482357e899Savl-llvm OutDebugStrOffsetsSection.emitIntVal(0, 2); 1492357e899Savl-llvm 1502357e899Savl-llvm // Emit index to offset map. 1512357e899Savl-llvm for (const StringEntry *String : DebugStringIndexMap.getValues()) { 1522357e899Savl-llvm // Note patch for string offset value. 1532357e899Savl-llvm OutDebugStrOffsetsSection.notePatch( 1542357e899Savl-llvm DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String}); 1552357e899Savl-llvm 1562357e899Savl-llvm // Emit placeholder for offset value. 1572357e899Savl-llvm OutDebugStrOffsetsSection.emitOffset(0xBADDEF); 1582357e899Savl-llvm } 1592357e899Savl-llvm 1602357e899Savl-llvm // Patch section length. 1612357e899Savl-llvm OutDebugStrOffsetsSection.apply( 1622357e899Savl-llvm OffsetAfterSectionLength - 1632357e899Savl-llvm OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(), 1642357e899Savl-llvm dwarf::DW_FORM_sec_offset, 1652357e899Savl-llvm OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength); 1662357e899Savl-llvm 1672357e899Savl-llvm return Error::success(); 1682357e899Savl-llvm } 1692357e899Savl-llvm 1702357e899Savl-llvm /// Emit the pubnames or pubtypes section contribution for \p 1712357e899Savl-llvm /// Unit into \p Sec. The data is provided in \p Info. 1722357e899Savl-llvm std::optional<uint64_t> 1732357e899Savl-llvm DwarfUnit::emitPubAcceleratorEntry(SectionDescriptor &OutSection, 1742357e899Savl-llvm const DwarfUnit::AccelInfo &Info, 1752357e899Savl-llvm std::optional<uint64_t> LengthOffset) { 1762357e899Savl-llvm if (!LengthOffset) { 1772357e899Savl-llvm // Emit the header. 1782357e899Savl-llvm OutSection.emitIntVal(0xBADDEF, 1792357e899Savl-llvm getFormParams().getDwarfOffsetByteSize()); // Length 1802357e899Savl-llvm LengthOffset = OutSection.OS.tell(); 1812357e899Savl-llvm 1822357e899Savl-llvm OutSection.emitIntVal(dwarf::DW_PUBNAMES_VERSION, 2); // Version 1832357e899Savl-llvm 1842357e899Savl-llvm OutSection.notePatch(DebugOffsetPatch{ 1852357e899Savl-llvm OutSection.OS.tell(), 1862357e899Savl-llvm &getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)}); 1872357e899Savl-llvm OutSection.emitOffset(0xBADDEF); // Unit offset 1882357e899Savl-llvm 1892357e899Savl-llvm OutSection.emitIntVal(getUnitSize(), 4); // Size 1902357e899Savl-llvm } 1912357e899Savl-llvm OutSection.emitOffset(Info.OutOffset); 1922357e899Savl-llvm 1932357e899Savl-llvm // Emit the string itself. 1942357e899Savl-llvm OutSection.emitInplaceString(Info.String->first()); 1952357e899Savl-llvm 1962357e899Savl-llvm return LengthOffset; 1972357e899Savl-llvm } 1982357e899Savl-llvm 1992357e899Savl-llvm /// Emit .debug_pubnames and .debug_pubtypes for \p Unit. 2002357e899Savl-llvm void DwarfUnit::emitPubAccelerators() { 2012357e899Savl-llvm std::optional<uint64_t> NamesLengthOffset; 2022357e899Savl-llvm std::optional<uint64_t> TypesLengthOffset; 2032357e899Savl-llvm 2042357e899Savl-llvm forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) { 2052357e899Savl-llvm if (Info.AvoidForPubSections) 2062357e899Savl-llvm return; 2072357e899Savl-llvm 2082357e899Savl-llvm switch (Info.Type) { 2092357e899Savl-llvm case DwarfUnit::AccelType::Name: { 2102357e899Savl-llvm NamesLengthOffset = emitPubAcceleratorEntry( 2112357e899Savl-llvm getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames), Info, 2122357e899Savl-llvm NamesLengthOffset); 2132357e899Savl-llvm } break; 2142357e899Savl-llvm case DwarfUnit::AccelType::Type: { 2152357e899Savl-llvm TypesLengthOffset = emitPubAcceleratorEntry( 2162357e899Savl-llvm getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes), Info, 2172357e899Savl-llvm TypesLengthOffset); 2182357e899Savl-llvm } break; 2192357e899Savl-llvm default: { 2202357e899Savl-llvm // Nothing to do. 2212357e899Savl-llvm } break; 2222357e899Savl-llvm } 2232357e899Savl-llvm }); 2242357e899Savl-llvm 2252357e899Savl-llvm if (NamesLengthOffset) { 2262357e899Savl-llvm SectionDescriptor &OutSection = 2272357e899Savl-llvm getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames); 2282357e899Savl-llvm OutSection.emitIntVal(0, 4); // End marker. 2292357e899Savl-llvm 2302357e899Savl-llvm OutSection.apply(*NamesLengthOffset - 2312357e899Savl-llvm OutSection.getFormParams().getDwarfOffsetByteSize(), 2322357e899Savl-llvm dwarf::DW_FORM_sec_offset, 2332357e899Savl-llvm OutSection.OS.tell() - *NamesLengthOffset); 2342357e899Savl-llvm } 2352357e899Savl-llvm 2362357e899Savl-llvm if (TypesLengthOffset) { 2372357e899Savl-llvm SectionDescriptor &OutSection = 2382357e899Savl-llvm getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes); 2392357e899Savl-llvm OutSection.emitIntVal(0, 4); // End marker. 2402357e899Savl-llvm 2412357e899Savl-llvm OutSection.apply(*TypesLengthOffset - 2422357e899Savl-llvm OutSection.getFormParams().getDwarfOffsetByteSize(), 2432357e899Savl-llvm dwarf::DW_FORM_sec_offset, 2442357e899Savl-llvm OutSection.OS.tell() - *TypesLengthOffset); 2452357e899Savl-llvm } 2462357e899Savl-llvm } 247