1*1db9f3b2SDimitry Andric //===- DWARFLinkerUnit.cpp ------------------------------------------------===// 2*1db9f3b2SDimitry Andric // 3*1db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*1db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*1db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*1db9f3b2SDimitry Andric // 7*1db9f3b2SDimitry Andric //===----------------------------------------------------------------------===// 8*1db9f3b2SDimitry Andric 9*1db9f3b2SDimitry Andric #include "DWARFLinkerUnit.h" 10*1db9f3b2SDimitry Andric #include "DWARFEmitterImpl.h" 11*1db9f3b2SDimitry Andric #include "DebugLineSectionEmitter.h" 12*1db9f3b2SDimitry Andric 13*1db9f3b2SDimitry Andric using namespace llvm; 14*1db9f3b2SDimitry Andric using namespace dwarf_linker; 15*1db9f3b2SDimitry Andric using namespace dwarf_linker::parallel; 16*1db9f3b2SDimitry Andric 17*1db9f3b2SDimitry Andric void DwarfUnit::assignAbbrev(DIEAbbrev &Abbrev) { 18*1db9f3b2SDimitry Andric // Check the set for priors. 19*1db9f3b2SDimitry Andric FoldingSetNodeID ID; 20*1db9f3b2SDimitry Andric Abbrev.Profile(ID); 21*1db9f3b2SDimitry Andric void *InsertToken; 22*1db9f3b2SDimitry Andric 23*1db9f3b2SDimitry Andric DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken); 24*1db9f3b2SDimitry Andric // If it's newly added. 25*1db9f3b2SDimitry Andric if (InSet) { 26*1db9f3b2SDimitry Andric // Assign existing abbreviation number. 27*1db9f3b2SDimitry Andric Abbrev.setNumber(InSet->getNumber()); 28*1db9f3b2SDimitry Andric } else { 29*1db9f3b2SDimitry Andric // Add to abbreviation list. 30*1db9f3b2SDimitry Andric Abbreviations.push_back( 31*1db9f3b2SDimitry Andric std::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren())); 32*1db9f3b2SDimitry Andric for (const auto &Attr : Abbrev.getData()) 33*1db9f3b2SDimitry Andric Abbreviations.back()->AddAttribute(Attr); 34*1db9f3b2SDimitry Andric AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken); 35*1db9f3b2SDimitry Andric // Assign the unique abbreviation number. 36*1db9f3b2SDimitry Andric Abbrev.setNumber(Abbreviations.size()); 37*1db9f3b2SDimitry Andric Abbreviations.back()->setNumber(Abbreviations.size()); 38*1db9f3b2SDimitry Andric } 39*1db9f3b2SDimitry Andric } 40*1db9f3b2SDimitry Andric 41*1db9f3b2SDimitry Andric Error DwarfUnit::emitAbbreviations() { 42*1db9f3b2SDimitry Andric const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs = getAbbreviations(); 43*1db9f3b2SDimitry Andric if (Abbrevs.empty()) 44*1db9f3b2SDimitry Andric return Error::success(); 45*1db9f3b2SDimitry Andric 46*1db9f3b2SDimitry Andric SectionDescriptor &AbbrevSection = 47*1db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev); 48*1db9f3b2SDimitry Andric 49*1db9f3b2SDimitry Andric // For each abbreviation. 50*1db9f3b2SDimitry Andric for (const auto &Abbrev : Abbrevs) 51*1db9f3b2SDimitry Andric emitDwarfAbbrevEntry(*Abbrev, AbbrevSection); 52*1db9f3b2SDimitry Andric 53*1db9f3b2SDimitry Andric // Mark end of abbreviations. 54*1db9f3b2SDimitry Andric encodeULEB128(0, AbbrevSection.OS); 55*1db9f3b2SDimitry Andric 56*1db9f3b2SDimitry Andric return Error::success(); 57*1db9f3b2SDimitry Andric } 58*1db9f3b2SDimitry Andric 59*1db9f3b2SDimitry Andric void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev, 60*1db9f3b2SDimitry Andric SectionDescriptor &AbbrevSection) { 61*1db9f3b2SDimitry Andric // Emit the abbreviations code (base 1 index.) 62*1db9f3b2SDimitry Andric encodeULEB128(Abbrev.getNumber(), AbbrevSection.OS); 63*1db9f3b2SDimitry Andric 64*1db9f3b2SDimitry Andric // Emit the abbreviations data. 65*1db9f3b2SDimitry Andric // Emit its Dwarf tag type. 66*1db9f3b2SDimitry Andric encodeULEB128(Abbrev.getTag(), AbbrevSection.OS); 67*1db9f3b2SDimitry Andric 68*1db9f3b2SDimitry Andric // Emit whether it has children DIEs. 69*1db9f3b2SDimitry Andric encodeULEB128((unsigned)Abbrev.hasChildren(), AbbrevSection.OS); 70*1db9f3b2SDimitry Andric 71*1db9f3b2SDimitry Andric // For each attribute description. 72*1db9f3b2SDimitry Andric const SmallVectorImpl<DIEAbbrevData> &Data = Abbrev.getData(); 73*1db9f3b2SDimitry Andric for (unsigned i = 0, N = Data.size(); i < N; ++i) { 74*1db9f3b2SDimitry Andric const DIEAbbrevData &AttrData = Data[i]; 75*1db9f3b2SDimitry Andric 76*1db9f3b2SDimitry Andric // Emit attribute type. 77*1db9f3b2SDimitry Andric encodeULEB128(AttrData.getAttribute(), AbbrevSection.OS); 78*1db9f3b2SDimitry Andric 79*1db9f3b2SDimitry Andric // Emit form type. 80*1db9f3b2SDimitry Andric encodeULEB128(AttrData.getForm(), AbbrevSection.OS); 81*1db9f3b2SDimitry Andric 82*1db9f3b2SDimitry Andric // Emit value for DW_FORM_implicit_const. 83*1db9f3b2SDimitry Andric if (AttrData.getForm() == dwarf::DW_FORM_implicit_const) 84*1db9f3b2SDimitry Andric encodeSLEB128(AttrData.getValue(), AbbrevSection.OS); 85*1db9f3b2SDimitry Andric } 86*1db9f3b2SDimitry Andric 87*1db9f3b2SDimitry Andric // Mark end of abbreviation. 88*1db9f3b2SDimitry Andric encodeULEB128(0, AbbrevSection.OS); 89*1db9f3b2SDimitry Andric encodeULEB128(0, AbbrevSection.OS); 90*1db9f3b2SDimitry Andric } 91*1db9f3b2SDimitry Andric 92*1db9f3b2SDimitry Andric Error DwarfUnit::emitDebugInfo(const Triple &TargetTriple) { 93*1db9f3b2SDimitry Andric DIE *OutUnitDIE = getOutUnitDIE(); 94*1db9f3b2SDimitry Andric if (OutUnitDIE == nullptr) 95*1db9f3b2SDimitry Andric return Error::success(); 96*1db9f3b2SDimitry Andric 97*1db9f3b2SDimitry Andric // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs 98*1db9f3b2SDimitry Andric // directly. 99*1db9f3b2SDimitry Andric 100*1db9f3b2SDimitry Andric SectionDescriptor &OutSection = 101*1db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 102*1db9f3b2SDimitry Andric DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, OutSection.OS); 103*1db9f3b2SDimitry Andric if (Error Err = Emitter.init(TargetTriple, "__DWARF")) 104*1db9f3b2SDimitry Andric return Err; 105*1db9f3b2SDimitry Andric 106*1db9f3b2SDimitry Andric // Emit compile unit header. 107*1db9f3b2SDimitry Andric Emitter.emitCompileUnitHeader(*this); 108*1db9f3b2SDimitry Andric size_t OffsetToAbbreviationTableOffset = 109*1db9f3b2SDimitry Andric (getFormParams().Version >= 5) ? 8 : 6; 110*1db9f3b2SDimitry Andric OutSection.notePatch(DebugOffsetPatch{ 111*1db9f3b2SDimitry Andric OffsetToAbbreviationTableOffset, 112*1db9f3b2SDimitry Andric &getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev)}); 113*1db9f3b2SDimitry Andric 114*1db9f3b2SDimitry Andric // Emit DIEs. 115*1db9f3b2SDimitry Andric Emitter.emitDIE(*OutUnitDIE); 116*1db9f3b2SDimitry Andric Emitter.finish(); 117*1db9f3b2SDimitry Andric 118*1db9f3b2SDimitry Andric // Set start offset ans size for .debug_info section. 119*1db9f3b2SDimitry Andric OutSection.setSizesForSectionCreatedByAsmPrinter(); 120*1db9f3b2SDimitry Andric return Error::success(); 121*1db9f3b2SDimitry Andric } 122*1db9f3b2SDimitry Andric 123*1db9f3b2SDimitry Andric Error DwarfUnit::emitDebugLine(const Triple &TargetTriple, 124*1db9f3b2SDimitry Andric const DWARFDebugLine::LineTable &OutLineTable) { 125*1db9f3b2SDimitry Andric DebugLineSectionEmitter DebugLineEmitter(TargetTriple, *this); 126*1db9f3b2SDimitry Andric 127*1db9f3b2SDimitry Andric return DebugLineEmitter.emit(OutLineTable); 128*1db9f3b2SDimitry Andric } 129*1db9f3b2SDimitry Andric 130*1db9f3b2SDimitry Andric Error DwarfUnit::emitDebugStringOffsetSection() { 131*1db9f3b2SDimitry Andric if (getVersion() < 5) 132*1db9f3b2SDimitry Andric return Error::success(); 133*1db9f3b2SDimitry Andric 134*1db9f3b2SDimitry Andric if (DebugStringIndexMap.empty()) 135*1db9f3b2SDimitry Andric return Error::success(); 136*1db9f3b2SDimitry Andric 137*1db9f3b2SDimitry Andric SectionDescriptor &OutDebugStrOffsetsSection = 138*1db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets); 139*1db9f3b2SDimitry Andric 140*1db9f3b2SDimitry Andric // Emit section header. 141*1db9f3b2SDimitry Andric 142*1db9f3b2SDimitry Andric // Emit length. 143*1db9f3b2SDimitry Andric OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF); 144*1db9f3b2SDimitry Andric uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell(); 145*1db9f3b2SDimitry Andric 146*1db9f3b2SDimitry Andric // Emit version. 147*1db9f3b2SDimitry Andric OutDebugStrOffsetsSection.emitIntVal(5, 2); 148*1db9f3b2SDimitry Andric 149*1db9f3b2SDimitry Andric // Emit padding. 150*1db9f3b2SDimitry Andric OutDebugStrOffsetsSection.emitIntVal(0, 2); 151*1db9f3b2SDimitry Andric 152*1db9f3b2SDimitry Andric // Emit index to offset map. 153*1db9f3b2SDimitry Andric for (const StringEntry *String : DebugStringIndexMap.getValues()) { 154*1db9f3b2SDimitry Andric // Note patch for string offset value. 155*1db9f3b2SDimitry Andric OutDebugStrOffsetsSection.notePatch( 156*1db9f3b2SDimitry Andric DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String}); 157*1db9f3b2SDimitry Andric 158*1db9f3b2SDimitry Andric // Emit placeholder for offset value. 159*1db9f3b2SDimitry Andric OutDebugStrOffsetsSection.emitOffset(0xBADDEF); 160*1db9f3b2SDimitry Andric } 161*1db9f3b2SDimitry Andric 162*1db9f3b2SDimitry Andric // Patch section length. 163*1db9f3b2SDimitry Andric OutDebugStrOffsetsSection.apply( 164*1db9f3b2SDimitry Andric OffsetAfterSectionLength - 165*1db9f3b2SDimitry Andric OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(), 166*1db9f3b2SDimitry Andric dwarf::DW_FORM_sec_offset, 167*1db9f3b2SDimitry Andric OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength); 168*1db9f3b2SDimitry Andric 169*1db9f3b2SDimitry Andric return Error::success(); 170*1db9f3b2SDimitry Andric } 171*1db9f3b2SDimitry Andric 172*1db9f3b2SDimitry Andric /// Emit the pubnames or pubtypes section contribution for \p 173*1db9f3b2SDimitry Andric /// Unit into \p Sec. The data is provided in \p Info. 174*1db9f3b2SDimitry Andric std::optional<uint64_t> 175*1db9f3b2SDimitry Andric DwarfUnit::emitPubAcceleratorEntry(SectionDescriptor &OutSection, 176*1db9f3b2SDimitry Andric const DwarfUnit::AccelInfo &Info, 177*1db9f3b2SDimitry Andric std::optional<uint64_t> LengthOffset) { 178*1db9f3b2SDimitry Andric if (!LengthOffset) { 179*1db9f3b2SDimitry Andric // Emit the header. 180*1db9f3b2SDimitry Andric OutSection.emitIntVal(0xBADDEF, 181*1db9f3b2SDimitry Andric getFormParams().getDwarfOffsetByteSize()); // Length 182*1db9f3b2SDimitry Andric LengthOffset = OutSection.OS.tell(); 183*1db9f3b2SDimitry Andric 184*1db9f3b2SDimitry Andric OutSection.emitIntVal(dwarf::DW_PUBNAMES_VERSION, 2); // Version 185*1db9f3b2SDimitry Andric 186*1db9f3b2SDimitry Andric OutSection.notePatch(DebugOffsetPatch{ 187*1db9f3b2SDimitry Andric OutSection.OS.tell(), 188*1db9f3b2SDimitry Andric &getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)}); 189*1db9f3b2SDimitry Andric OutSection.emitOffset(0xBADDEF); // Unit offset 190*1db9f3b2SDimitry Andric 191*1db9f3b2SDimitry Andric OutSection.emitIntVal(getUnitSize(), 4); // Size 192*1db9f3b2SDimitry Andric } 193*1db9f3b2SDimitry Andric OutSection.emitOffset(Info.OutOffset); 194*1db9f3b2SDimitry Andric 195*1db9f3b2SDimitry Andric // Emit the string itself. 196*1db9f3b2SDimitry Andric OutSection.emitInplaceString(Info.String->first()); 197*1db9f3b2SDimitry Andric 198*1db9f3b2SDimitry Andric return LengthOffset; 199*1db9f3b2SDimitry Andric } 200*1db9f3b2SDimitry Andric 201*1db9f3b2SDimitry Andric /// Emit .debug_pubnames and .debug_pubtypes for \p Unit. 202*1db9f3b2SDimitry Andric void DwarfUnit::emitPubAccelerators() { 203*1db9f3b2SDimitry Andric std::optional<uint64_t> NamesLengthOffset; 204*1db9f3b2SDimitry Andric std::optional<uint64_t> TypesLengthOffset; 205*1db9f3b2SDimitry Andric 206*1db9f3b2SDimitry Andric forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) { 207*1db9f3b2SDimitry Andric if (Info.AvoidForPubSections) 208*1db9f3b2SDimitry Andric return; 209*1db9f3b2SDimitry Andric 210*1db9f3b2SDimitry Andric switch (Info.Type) { 211*1db9f3b2SDimitry Andric case DwarfUnit::AccelType::Name: { 212*1db9f3b2SDimitry Andric NamesLengthOffset = emitPubAcceleratorEntry( 213*1db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames), Info, 214*1db9f3b2SDimitry Andric NamesLengthOffset); 215*1db9f3b2SDimitry Andric } break; 216*1db9f3b2SDimitry Andric case DwarfUnit::AccelType::Type: { 217*1db9f3b2SDimitry Andric TypesLengthOffset = emitPubAcceleratorEntry( 218*1db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes), Info, 219*1db9f3b2SDimitry Andric TypesLengthOffset); 220*1db9f3b2SDimitry Andric } break; 221*1db9f3b2SDimitry Andric default: { 222*1db9f3b2SDimitry Andric // Nothing to do. 223*1db9f3b2SDimitry Andric } break; 224*1db9f3b2SDimitry Andric } 225*1db9f3b2SDimitry Andric }); 226*1db9f3b2SDimitry Andric 227*1db9f3b2SDimitry Andric if (NamesLengthOffset) { 228*1db9f3b2SDimitry Andric SectionDescriptor &OutSection = 229*1db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames); 230*1db9f3b2SDimitry Andric OutSection.emitIntVal(0, 4); // End marker. 231*1db9f3b2SDimitry Andric 232*1db9f3b2SDimitry Andric OutSection.apply(*NamesLengthOffset - 233*1db9f3b2SDimitry Andric OutSection.getFormParams().getDwarfOffsetByteSize(), 234*1db9f3b2SDimitry Andric dwarf::DW_FORM_sec_offset, 235*1db9f3b2SDimitry Andric OutSection.OS.tell() - *NamesLengthOffset); 236*1db9f3b2SDimitry Andric } 237*1db9f3b2SDimitry Andric 238*1db9f3b2SDimitry Andric if (TypesLengthOffset) { 239*1db9f3b2SDimitry Andric SectionDescriptor &OutSection = 240*1db9f3b2SDimitry Andric getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes); 241*1db9f3b2SDimitry Andric OutSection.emitIntVal(0, 4); // End marker. 242*1db9f3b2SDimitry Andric 243*1db9f3b2SDimitry Andric OutSection.apply(*TypesLengthOffset - 244*1db9f3b2SDimitry Andric OutSection.getFormParams().getDwarfOffsetByteSize(), 245*1db9f3b2SDimitry Andric dwarf::DW_FORM_sec_offset, 246*1db9f3b2SDimitry Andric OutSection.OS.tell() - *TypesLengthOffset); 247*1db9f3b2SDimitry Andric } 248*1db9f3b2SDimitry Andric } 249