11db9f3b2SDimitry Andric //===- DWARFLinkerUnit.cpp ------------------------------------------------===// 21db9f3b2SDimitry Andric // 31db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 51db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61db9f3b2SDimitry Andric // 71db9f3b2SDimitry Andric //===----------------------------------------------------------------------===// 81db9f3b2SDimitry Andric 91db9f3b2SDimitry Andric #include "DWARFLinkerUnit.h" 101db9f3b2SDimitry Andric #include "DWARFEmitterImpl.h" 111db9f3b2SDimitry Andric #include "DebugLineSectionEmitter.h" 121db9f3b2SDimitry Andric 131db9f3b2SDimitry Andric using namespace llvm; 141db9f3b2SDimitry Andric using namespace dwarf_linker; 151db9f3b2SDimitry Andric using namespace dwarf_linker::parallel; 161db9f3b2SDimitry Andric 171db9f3b2SDimitry Andric void DwarfUnit::assignAbbrev(DIEAbbrev &Abbrev) { 181db9f3b2SDimitry Andric // Check the set for priors. 191db9f3b2SDimitry Andric FoldingSetNodeID ID; 201db9f3b2SDimitry Andric Abbrev.Profile(ID); 211db9f3b2SDimitry Andric void *InsertToken; 221db9f3b2SDimitry Andric 231db9f3b2SDimitry Andric DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken); 241db9f3b2SDimitry Andric // If it's newly added. 251db9f3b2SDimitry Andric if (InSet) { 261db9f3b2SDimitry Andric // Assign existing abbreviation number. 271db9f3b2SDimitry Andric Abbrev.setNumber(InSet->getNumber()); 281db9f3b2SDimitry Andric } else { 291db9f3b2SDimitry Andric // Add to abbreviation list. 301db9f3b2SDimitry Andric Abbreviations.push_back( 311db9f3b2SDimitry Andric std::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren())); 321db9f3b2SDimitry Andric for (const auto &Attr : Abbrev.getData()) 331db9f3b2SDimitry Andric Abbreviations.back()->AddAttribute(Attr); 341db9f3b2SDimitry Andric AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken); 351db9f3b2SDimitry Andric // Assign the unique abbreviation number. 361db9f3b2SDimitry Andric Abbrev.setNumber(Abbreviations.size()); 371db9f3b2SDimitry Andric Abbreviations.back()->setNumber(Abbreviations.size()); 381db9f3b2SDimitry Andric } 391db9f3b2SDimitry Andric } 401db9f3b2SDimitry Andric 411db9f3b2SDimitry Andric Error DwarfUnit::emitAbbreviations() { 421db9f3b2SDimitry Andric const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs = getAbbreviations(); 431db9f3b2SDimitry Andric if (Abbrevs.empty()) 441db9f3b2SDimitry Andric return Error::success(); 451db9f3b2SDimitry Andric 461db9f3b2SDimitry Andric SectionDescriptor &AbbrevSection = 471db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev); 481db9f3b2SDimitry Andric 491db9f3b2SDimitry Andric // For each abbreviation. 501db9f3b2SDimitry Andric for (const auto &Abbrev : Abbrevs) 511db9f3b2SDimitry Andric emitDwarfAbbrevEntry(*Abbrev, AbbrevSection); 521db9f3b2SDimitry Andric 531db9f3b2SDimitry Andric // Mark end of abbreviations. 541db9f3b2SDimitry Andric encodeULEB128(0, AbbrevSection.OS); 551db9f3b2SDimitry Andric 561db9f3b2SDimitry Andric return Error::success(); 571db9f3b2SDimitry Andric } 581db9f3b2SDimitry Andric 591db9f3b2SDimitry Andric void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev, 601db9f3b2SDimitry Andric SectionDescriptor &AbbrevSection) { 611db9f3b2SDimitry Andric // Emit the abbreviations code (base 1 index.) 621db9f3b2SDimitry Andric encodeULEB128(Abbrev.getNumber(), AbbrevSection.OS); 631db9f3b2SDimitry Andric 641db9f3b2SDimitry Andric // Emit the abbreviations data. 651db9f3b2SDimitry Andric // Emit its Dwarf tag type. 661db9f3b2SDimitry Andric encodeULEB128(Abbrev.getTag(), AbbrevSection.OS); 671db9f3b2SDimitry Andric 681db9f3b2SDimitry Andric // Emit whether it has children DIEs. 691db9f3b2SDimitry Andric encodeULEB128((unsigned)Abbrev.hasChildren(), AbbrevSection.OS); 701db9f3b2SDimitry Andric 711db9f3b2SDimitry Andric // For each attribute description. 721db9f3b2SDimitry Andric const SmallVectorImpl<DIEAbbrevData> &Data = Abbrev.getData(); 73*0fca6ea1SDimitry Andric for (const DIEAbbrevData &AttrData : Data) { 741db9f3b2SDimitry Andric // Emit attribute type. 751db9f3b2SDimitry Andric encodeULEB128(AttrData.getAttribute(), AbbrevSection.OS); 761db9f3b2SDimitry Andric 771db9f3b2SDimitry Andric // Emit form type. 781db9f3b2SDimitry Andric encodeULEB128(AttrData.getForm(), AbbrevSection.OS); 791db9f3b2SDimitry Andric 801db9f3b2SDimitry Andric // Emit value for DW_FORM_implicit_const. 811db9f3b2SDimitry Andric if (AttrData.getForm() == dwarf::DW_FORM_implicit_const) 821db9f3b2SDimitry Andric encodeSLEB128(AttrData.getValue(), AbbrevSection.OS); 831db9f3b2SDimitry Andric } 841db9f3b2SDimitry Andric 851db9f3b2SDimitry Andric // Mark end of abbreviation. 861db9f3b2SDimitry Andric encodeULEB128(0, AbbrevSection.OS); 871db9f3b2SDimitry Andric encodeULEB128(0, AbbrevSection.OS); 881db9f3b2SDimitry Andric } 891db9f3b2SDimitry Andric 901db9f3b2SDimitry Andric Error DwarfUnit::emitDebugInfo(const Triple &TargetTriple) { 911db9f3b2SDimitry Andric DIE *OutUnitDIE = getOutUnitDIE(); 921db9f3b2SDimitry Andric if (OutUnitDIE == nullptr) 931db9f3b2SDimitry Andric return Error::success(); 941db9f3b2SDimitry Andric 951db9f3b2SDimitry Andric // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs 961db9f3b2SDimitry Andric // directly. 971db9f3b2SDimitry Andric 981db9f3b2SDimitry Andric SectionDescriptor &OutSection = 991db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 1001db9f3b2SDimitry Andric DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, OutSection.OS); 1011db9f3b2SDimitry Andric if (Error Err = Emitter.init(TargetTriple, "__DWARF")) 1021db9f3b2SDimitry Andric return Err; 1031db9f3b2SDimitry Andric 1041db9f3b2SDimitry Andric // Emit compile unit header. 1051db9f3b2SDimitry Andric Emitter.emitCompileUnitHeader(*this); 1061db9f3b2SDimitry Andric size_t OffsetToAbbreviationTableOffset = 1071db9f3b2SDimitry Andric (getFormParams().Version >= 5) ? 8 : 6; 1081db9f3b2SDimitry Andric OutSection.notePatch(DebugOffsetPatch{ 1091db9f3b2SDimitry Andric OffsetToAbbreviationTableOffset, 1101db9f3b2SDimitry Andric &getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev)}); 1111db9f3b2SDimitry Andric 1121db9f3b2SDimitry Andric // Emit DIEs. 1131db9f3b2SDimitry Andric Emitter.emitDIE(*OutUnitDIE); 1141db9f3b2SDimitry Andric Emitter.finish(); 1151db9f3b2SDimitry Andric 1161db9f3b2SDimitry Andric // Set start offset ans size for .debug_info section. 1171db9f3b2SDimitry Andric OutSection.setSizesForSectionCreatedByAsmPrinter(); 1181db9f3b2SDimitry Andric return Error::success(); 1191db9f3b2SDimitry Andric } 1201db9f3b2SDimitry Andric 1211db9f3b2SDimitry Andric Error DwarfUnit::emitDebugLine(const Triple &TargetTriple, 1221db9f3b2SDimitry Andric const DWARFDebugLine::LineTable &OutLineTable) { 1231db9f3b2SDimitry Andric DebugLineSectionEmitter DebugLineEmitter(TargetTriple, *this); 1241db9f3b2SDimitry Andric 1251db9f3b2SDimitry Andric return DebugLineEmitter.emit(OutLineTable); 1261db9f3b2SDimitry Andric } 1271db9f3b2SDimitry Andric 1281db9f3b2SDimitry Andric Error DwarfUnit::emitDebugStringOffsetSection() { 1291db9f3b2SDimitry Andric if (getVersion() < 5) 1301db9f3b2SDimitry Andric return Error::success(); 1311db9f3b2SDimitry Andric 1321db9f3b2SDimitry Andric if (DebugStringIndexMap.empty()) 1331db9f3b2SDimitry Andric return Error::success(); 1341db9f3b2SDimitry Andric 1351db9f3b2SDimitry Andric SectionDescriptor &OutDebugStrOffsetsSection = 1361db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets); 1371db9f3b2SDimitry Andric 1381db9f3b2SDimitry Andric // Emit section header. 1391db9f3b2SDimitry Andric 1401db9f3b2SDimitry Andric // Emit length. 1411db9f3b2SDimitry Andric OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF); 1421db9f3b2SDimitry Andric uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell(); 1431db9f3b2SDimitry Andric 1441db9f3b2SDimitry Andric // Emit version. 1451db9f3b2SDimitry Andric OutDebugStrOffsetsSection.emitIntVal(5, 2); 1461db9f3b2SDimitry Andric 1471db9f3b2SDimitry Andric // Emit padding. 1481db9f3b2SDimitry Andric OutDebugStrOffsetsSection.emitIntVal(0, 2); 1491db9f3b2SDimitry Andric 1501db9f3b2SDimitry Andric // Emit index to offset map. 1511db9f3b2SDimitry Andric for (const StringEntry *String : DebugStringIndexMap.getValues()) { 1521db9f3b2SDimitry Andric // Note patch for string offset value. 1531db9f3b2SDimitry Andric OutDebugStrOffsetsSection.notePatch( 1541db9f3b2SDimitry Andric DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String}); 1551db9f3b2SDimitry Andric 1561db9f3b2SDimitry Andric // Emit placeholder for offset value. 1571db9f3b2SDimitry Andric OutDebugStrOffsetsSection.emitOffset(0xBADDEF); 1581db9f3b2SDimitry Andric } 1591db9f3b2SDimitry Andric 1601db9f3b2SDimitry Andric // Patch section length. 1611db9f3b2SDimitry Andric OutDebugStrOffsetsSection.apply( 1621db9f3b2SDimitry Andric OffsetAfterSectionLength - 1631db9f3b2SDimitry Andric OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(), 1641db9f3b2SDimitry Andric dwarf::DW_FORM_sec_offset, 1651db9f3b2SDimitry Andric OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength); 1661db9f3b2SDimitry Andric 1671db9f3b2SDimitry Andric return Error::success(); 1681db9f3b2SDimitry Andric } 1691db9f3b2SDimitry Andric 1701db9f3b2SDimitry Andric /// Emit the pubnames or pubtypes section contribution for \p 1711db9f3b2SDimitry Andric /// Unit into \p Sec. The data is provided in \p Info. 1721db9f3b2SDimitry Andric std::optional<uint64_t> 1731db9f3b2SDimitry Andric DwarfUnit::emitPubAcceleratorEntry(SectionDescriptor &OutSection, 1741db9f3b2SDimitry Andric const DwarfUnit::AccelInfo &Info, 1751db9f3b2SDimitry Andric std::optional<uint64_t> LengthOffset) { 1761db9f3b2SDimitry Andric if (!LengthOffset) { 1771db9f3b2SDimitry Andric // Emit the header. 1781db9f3b2SDimitry Andric OutSection.emitIntVal(0xBADDEF, 1791db9f3b2SDimitry Andric getFormParams().getDwarfOffsetByteSize()); // Length 1801db9f3b2SDimitry Andric LengthOffset = OutSection.OS.tell(); 1811db9f3b2SDimitry Andric 1821db9f3b2SDimitry Andric OutSection.emitIntVal(dwarf::DW_PUBNAMES_VERSION, 2); // Version 1831db9f3b2SDimitry Andric 1841db9f3b2SDimitry Andric OutSection.notePatch(DebugOffsetPatch{ 1851db9f3b2SDimitry Andric OutSection.OS.tell(), 1861db9f3b2SDimitry Andric &getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)}); 1871db9f3b2SDimitry Andric OutSection.emitOffset(0xBADDEF); // Unit offset 1881db9f3b2SDimitry Andric 1891db9f3b2SDimitry Andric OutSection.emitIntVal(getUnitSize(), 4); // Size 1901db9f3b2SDimitry Andric } 1911db9f3b2SDimitry Andric OutSection.emitOffset(Info.OutOffset); 1921db9f3b2SDimitry Andric 1931db9f3b2SDimitry Andric // Emit the string itself. 1941db9f3b2SDimitry Andric OutSection.emitInplaceString(Info.String->first()); 1951db9f3b2SDimitry Andric 1961db9f3b2SDimitry Andric return LengthOffset; 1971db9f3b2SDimitry Andric } 1981db9f3b2SDimitry Andric 1991db9f3b2SDimitry Andric /// Emit .debug_pubnames and .debug_pubtypes for \p Unit. 2001db9f3b2SDimitry Andric void DwarfUnit::emitPubAccelerators() { 2011db9f3b2SDimitry Andric std::optional<uint64_t> NamesLengthOffset; 2021db9f3b2SDimitry Andric std::optional<uint64_t> TypesLengthOffset; 2031db9f3b2SDimitry Andric 2041db9f3b2SDimitry Andric forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) { 2051db9f3b2SDimitry Andric if (Info.AvoidForPubSections) 2061db9f3b2SDimitry Andric return; 2071db9f3b2SDimitry Andric 2081db9f3b2SDimitry Andric switch (Info.Type) { 2091db9f3b2SDimitry Andric case DwarfUnit::AccelType::Name: { 2101db9f3b2SDimitry Andric NamesLengthOffset = emitPubAcceleratorEntry( 2111db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames), Info, 2121db9f3b2SDimitry Andric NamesLengthOffset); 2131db9f3b2SDimitry Andric } break; 2141db9f3b2SDimitry Andric case DwarfUnit::AccelType::Type: { 2151db9f3b2SDimitry Andric TypesLengthOffset = emitPubAcceleratorEntry( 2161db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes), Info, 2171db9f3b2SDimitry Andric TypesLengthOffset); 2181db9f3b2SDimitry Andric } break; 2191db9f3b2SDimitry Andric default: { 2201db9f3b2SDimitry Andric // Nothing to do. 2211db9f3b2SDimitry Andric } break; 2221db9f3b2SDimitry Andric } 2231db9f3b2SDimitry Andric }); 2241db9f3b2SDimitry Andric 2251db9f3b2SDimitry Andric if (NamesLengthOffset) { 2261db9f3b2SDimitry Andric SectionDescriptor &OutSection = 2271db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames); 2281db9f3b2SDimitry Andric OutSection.emitIntVal(0, 4); // End marker. 2291db9f3b2SDimitry Andric 2301db9f3b2SDimitry Andric OutSection.apply(*NamesLengthOffset - 2311db9f3b2SDimitry Andric OutSection.getFormParams().getDwarfOffsetByteSize(), 2321db9f3b2SDimitry Andric dwarf::DW_FORM_sec_offset, 2331db9f3b2SDimitry Andric OutSection.OS.tell() - *NamesLengthOffset); 2341db9f3b2SDimitry Andric } 2351db9f3b2SDimitry Andric 2361db9f3b2SDimitry Andric if (TypesLengthOffset) { 2371db9f3b2SDimitry Andric SectionDescriptor &OutSection = 2381db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes); 2391db9f3b2SDimitry Andric OutSection.emitIntVal(0, 4); // End marker. 2401db9f3b2SDimitry Andric 2411db9f3b2SDimitry Andric OutSection.apply(*TypesLengthOffset - 2421db9f3b2SDimitry Andric OutSection.getFormParams().getDwarfOffsetByteSize(), 2431db9f3b2SDimitry Andric dwarf::DW_FORM_sec_offset, 2441db9f3b2SDimitry Andric OutSection.OS.tell() - *TypesLengthOffset); 2451db9f3b2SDimitry Andric } 2461db9f3b2SDimitry Andric } 247