diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 359 |
1 files changed, 205 insertions, 154 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index c505e77e5acd..fa6800de7955 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -241,6 +241,11 @@ static DbgValueLoc getDebugLocValue(const MachineInstr *MI) { MachineLocation MLoc(RegOp.getReg(), Op1.isImm()); return DbgValueLoc(Expr, MLoc); } + if (MI->getOperand(0).isTargetIndex()) { + auto Op = MI->getOperand(0); + return DbgValueLoc(Expr, + TargetIndexLocation(Op.getIndex(), Op.getOffset())); + } if (MI->getOperand(0).isImm()) return DbgValueLoc(Expr, MI->getOperand(0).getImm()); if (MI->getOperand(0).isFPImm()) @@ -535,6 +540,14 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, } } +DIE &DwarfDebug::constructSubprogramDefinitionDIE(const DISubprogram *SP) { + DICompileUnit *Unit = SP->getUnit(); + assert(SP->isDefinition() && "Subprogram not a definition"); + assert(Unit && "Subprogram definition without parent unit"); + auto &CU = getOrCreateDwarfCompileUnit(Unit); + return *CU.getOrCreateSubprogramDIE(SP); +} + /// Try to interpret values loaded into registers that forward parameters /// for \p CallMI. Store parameters with interpreted value into \p Params. static void collectCallSiteParameters(const MachineInstr *CallMI, @@ -595,7 +608,6 @@ static void collectCallSiteParameters(const MachineInstr *CallMI, Implicit.push_back(FwdReg); else Explicit.push_back(FwdReg); - break; } } } @@ -615,8 +627,12 @@ static void collectCallSiteParameters(const MachineInstr *CallMI, ++NumCSParams; }; - // Search for a loading value in forwaring registers. + // Search for a loading value in forwarding registers. for (; I != MBB->rend(); ++I) { + // Skip bundle headers. + if (I->isBundle()) + continue; + // If the next instruction is a call we can not interpret parameter's // forwarding registers or we finished the interpretation of all parameters. if (I->isCall()) @@ -636,32 +652,33 @@ static void collectCallSiteParameters(const MachineInstr *CallMI, for (auto Reg : concat<unsigned>(ExplicitFwdRegDefs, ImplicitFwdRegDefs)) ForwardedRegWorklist.erase(Reg); - // The describeLoadedValue() hook currently does not have any information - // about which register it should describe in case of multiple defines, so - // for now we only handle instructions where a forwarded register is (at - // least partially) defined by the instruction's single explicit define. - if (I->getNumExplicitDefs() != 1 || ExplicitFwdRegDefs.empty()) - continue; - unsigned Reg = ExplicitFwdRegDefs[0]; - - if (auto ParamValue = TII->describeLoadedValue(*I)) { - if (ParamValue->first.isImm()) { - int64_t Val = ParamValue->first.getImm(); - DbgValueLoc DbgLocVal(ParamValue->second, Val); - finishCallSiteParam(DbgLocVal, Reg); - } else if (ParamValue->first.isReg()) { - Register RegLoc = ParamValue->first.getReg(); - unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); - Register FP = TRI->getFrameRegister(*MF); - bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP); - if (TRI->isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP) { - DbgValueLoc DbgLocVal(ParamValue->second, - MachineLocation(RegLoc, - /*IsIndirect=*/IsSPorFP)); - finishCallSiteParam(DbgLocVal, Reg); - } else if (ShouldTryEmitEntryVals) { - ForwardedRegWorklist.insert(RegLoc); - RegsForEntryValues[RegLoc] = Reg; + for (auto ParamFwdReg : ExplicitFwdRegDefs) { + if (auto ParamValue = TII->describeLoadedValue(*I, ParamFwdReg)) { + if (ParamValue->first.isImm()) { + int64_t Val = ParamValue->first.getImm(); + DbgValueLoc DbgLocVal(ParamValue->second, Val); + finishCallSiteParam(DbgLocVal, ParamFwdReg); + } else if (ParamValue->first.isReg()) { + Register RegLoc = ParamValue->first.getReg(); + // TODO: For now, there is no use of describing the value loaded into the + // register that is also the source registers (e.g. $r0 = add $r0, x). + if (ParamFwdReg == RegLoc) + continue; + + unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); + Register FP = TRI->getFrameRegister(*MF); + bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP); + if (TRI->isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP) { + DbgValueLoc DbgLocVal(ParamValue->second, + MachineLocation(RegLoc, + /*IsIndirect=*/IsSPorFP)); + finishCallSiteParam(DbgLocVal, ParamFwdReg); + // TODO: Add support for entry value plus an expression. + } else if (ShouldTryEmitEntryVals && + ParamValue->second->getNumElements() == 0) { + ForwardedRegWorklist.insert(RegLoc); + RegsForEntryValues[RegLoc] = ParamFwdReg; + } } } } @@ -707,6 +724,12 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP, // Emit call site entries for each call or tail call in the function. for (const MachineBasicBlock &MBB : MF) { for (const MachineInstr &MI : MBB.instrs()) { + // Bundles with call in them will pass the isCall() test below but do not + // have callee operand information so skip them here. Iterator will + // eventually reach the call MI. + if (MI.isBundle()) + continue; + // Skip instructions which aren't calls. Both calls and tail-calling jump // instructions (e.g TAILJMPd64) are classified correctly here. if (!MI.isCall()) @@ -735,25 +758,45 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP, if (!CalleeDecl || !CalleeDecl->getSubprogram()) continue; CalleeSP = CalleeDecl->getSubprogram(); + + if (CalleeSP->isDefinition()) { + // Ensure that a subprogram DIE for the callee is available in the + // appropriate CU. + constructSubprogramDefinitionDIE(CalleeSP); + } else { + // Create the declaration DIE if it is missing. This is required to + // support compilation of old bitcode with an incomplete list of + // retained metadata. + CU.getOrCreateSubprogramDIE(CalleeSP); + } } // TODO: Omit call site entries for runtime calls (objc_msgSend, etc). bool IsTail = TII->isTailCall(MI); + // If MI is in a bundle, the label was created after the bundle since + // EmitFunctionBody iterates over top-level MIs. Get that top-level MI + // to search for that label below. + const MachineInstr *TopLevelCallMI = + MI.isInsideBundle() ? &*getBundleStart(MI.getIterator()) : &MI; + // For tail calls, for non-gdb tuning, no return PC information is needed. // For regular calls (and tail calls in GDB tuning), the return PC // is needed to disambiguate paths in the call graph which could lead to // some target function. const MCExpr *PCOffset = - (IsTail && !tuneForGDB()) ? nullptr - : getFunctionLocalOffsetAfterInsn(&MI); + (IsTail && !tuneForGDB()) + ? nullptr + : getFunctionLocalOffsetAfterInsn(TopLevelCallMI); - // Address of a call-like instruction for a normal call or a jump-like - // instruction for a tail call. This is needed for GDB + DWARF 4 tuning. + // Return address of a call-like instruction for a normal call or a + // jump-like instruction for a tail call. This is needed for + // GDB + DWARF 4 tuning. const MCSymbol *PCAddr = - ApplyGNUExtensions ? const_cast<MCSymbol*>(getLabelAfterInsn(&MI)) - : nullptr; + ApplyGNUExtensions + ? const_cast<MCSymbol *>(getLabelAfterInsn(TopLevelCallMI)) + : nullptr; assert((IsTail || PCOffset || PCAddr) && "Call without return PC information"); @@ -837,10 +880,13 @@ void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit, // This CU is either a clang module DWO or a skeleton CU. NewCU.addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8, DIUnit->getDWOId()); - if (!DIUnit->getSplitDebugFilename().empty()) + if (!DIUnit->getSplitDebugFilename().empty()) { // This is a prefabricated skeleton CU. - NewCU.addString(Die, dwarf::DW_AT_GNU_dwo_name, - DIUnit->getSplitDebugFilename()); + dwarf::Attribute attrDWOName = getDwarfVersion() >= 5 + ? dwarf::DW_AT_dwo_name + : dwarf::DW_AT_GNU_dwo_name; + NewCU.addString(Die, attrDWOName, DIUnit->getSplitDebugFilename()); + } } } // Create new DwarfCompileUnit for the given metadata node with tag @@ -878,11 +924,6 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection()); } - // Create DIEs for function declarations used for call site debug info. - for (auto Scope : DIUnit->getRetainedTypes()) - if (auto *SP = dyn_cast_or_null<DISubprogram>(Scope)) - NewCU.getOrCreateSubprogramDIE(SP); - CUMap.insert({DIUnit, &NewCU}); CUDieMap.insert({&NewCU.getUnitDie(), &NewCU}); return NewCU; @@ -974,6 +1015,7 @@ void DwarfDebug::beginModule() { // Create the symbol that points to the first entry following the debug // address table (.debug_addr) header. AddrPool.setLabel(Asm->createTempSymbol("addr_table_base")); + DebugLocs.setSym(Asm->createTempSymbol("loclists_table_base")); for (DICompileUnit *CUNode : M->debug_compile_units()) { // FIXME: Move local imported entities into a list attached to the @@ -1077,11 +1119,17 @@ void DwarfDebug::finalizeModuleInfo() { // If we're splitting the dwarf out now that we've got the entire // CU then add the dwo id to it. auto *SkCU = TheCU.getSkeleton(); - if (useSplitDwarf() && !TheCU.getUnitDie().children().empty()) { + + bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty(); + + if (HasSplitUnit) { + dwarf::Attribute attrDWOName = getDwarfVersion() >= 5 + ? dwarf::DW_AT_dwo_name + : dwarf::DW_AT_GNU_dwo_name; finishUnitAttributes(TheCU.getCUNode(), TheCU); - TheCU.addString(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_name, + TheCU.addString(TheCU.getUnitDie(), attrDWOName, Asm->TM.Options.MCOptions.SplitDwarfFile); - SkCU->addString(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_name, + SkCU->addString(SkCU->getUnitDie(), attrDWOName, Asm->TM.Options.MCOptions.SplitDwarfFile); // Emit a unique identifier for this CU. uint64_t ID = @@ -1127,29 +1175,34 @@ void DwarfDebug::finalizeModuleInfo() { // We don't keep track of which addresses are used in which CU so this // is a bit pessimistic under LTO. - if (!AddrPool.isEmpty() && - (getDwarfVersion() >= 5 || - (SkCU && !TheCU.getUnitDie().children().empty()))) + if ((!AddrPool.isEmpty() || TheCU.hasRangeLists()) && + (getDwarfVersion() >= 5 || HasSplitUnit)) U.addAddrTableBase(); if (getDwarfVersion() >= 5) { if (U.hasRangeLists()) U.addRnglistsBase(); - if (!DebugLocs.getLists().empty() && !useSplitDwarf()) { - DebugLocs.setSym(Asm->createTempSymbol("loclists_table_base")); - U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_loclists_base, - DebugLocs.getSym(), - TLOF.getDwarfLoclistsSection()->getBeginSymbol()); + if (!DebugLocs.getLists().empty()) { + if (!useSplitDwarf()) + U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_loclists_base, + DebugLocs.getSym(), + TLOF.getDwarfLoclistsSection()->getBeginSymbol()); } } auto *CUNode = cast<DICompileUnit>(P.first); // If compile Unit has macros, emit "DW_AT_macro_info" attribute. - if (CUNode->getMacros()) - U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info, - U.getMacroLabelBegin(), - TLOF.getDwarfMacinfoSection()->getBeginSymbol()); + if (CUNode->getMacros()) { + if (useSplitDwarf()) + TheCU.addSectionDelta(TheCU.getUnitDie(), dwarf::DW_AT_macro_info, + U.getMacroLabelBegin(), + TLOF.getDwarfMacinfoDWOSection()->getBeginSymbol()); + else + U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info, + U.getMacroLabelBegin(), + TLOF.getDwarfMacinfoSection()->getBeginSymbol()); + } } // Emit all frontend-produced Skeleton CUs, i.e., Clang modules. @@ -1185,9 +1238,10 @@ void DwarfDebug::endModule() { emitDebugStr(); if (useSplitDwarf()) + // Emit debug_loc.dwo/debug_loclists.dwo section. emitDebugLocDWO(); else - // Emit info into a debug loc section. + // Emit debug_loc/debug_loclists section. emitDebugLoc(); // Corresponding abbreviations into a abbrev section. @@ -1203,8 +1257,12 @@ void DwarfDebug::endModule() { // Emit info into a debug ranges section. emitDebugRanges(); + if (useSplitDwarf()) + // Emit info into a debug macinfo.dwo section. + emitDebugMacinfoDWO(); + else // Emit info into a debug macinfo section. - emitDebugMacinfo(); + emitDebugMacinfo(); if (useSplitDwarf()) { emitDebugStrDWO(); @@ -2208,6 +2266,11 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) return; return DwarfExpr.addExpression(std::move(Cursor)); + } else if (Value.isTargetIndexLocation()) { + TargetIndexLocation Loc = Value.getTargetIndexLocation(); + // TODO TargetIndexLocation is a target-independent. Currently only the WebAssembly-specific + // encoding is supported. + DwarfExpr.addWasmLocation(Loc.Index, Loc.Offset); } else if (Value.isConstantFP()) { APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt(); DwarfExpr.addUnsignedConstant(RawBytes); @@ -2242,6 +2305,8 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, DwarfDebug::emitDebugLocValue(AP, BT, Value, DwarfExpr); } DwarfExpr.finalize(); + if (DwarfExpr.TagOffset) + List.setTagOffset(*DwarfExpr.TagOffset); } void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, @@ -2296,7 +2361,7 @@ static MCSymbol *emitRnglistsTableHeader(AsmPrinter *Asm, Asm->OutStreamer->EmitLabel(Holder.getRnglistsTableBaseSym()); for (const RangeSpanList &List : Holder.getRangeLists()) - Asm->EmitLabelDifference(List.getSym(), Holder.getRnglistsTableBaseSym(), + Asm->EmitLabelDifference(List.Label, Holder.getRnglistsTableBaseSym(), 4); return TableEnd; @@ -2313,12 +2378,13 @@ static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm, const auto &DebugLocs = DD.getDebugLocs(); - // FIXME: Generate the offsets table and use DW_FORM_loclistx with the - // DW_AT_loclists_base attribute. Until then set the number of offsets to 0. Asm->OutStreamer->AddComment("Offset entry count"); - Asm->emitInt32(0); + Asm->emitInt32(DebugLocs.getLists().size()); Asm->OutStreamer->EmitLabel(DebugLocs.getSym()); + for (const auto &List : DebugLocs.getLists()) + Asm->EmitLabelDifference(List.Label, DebugLocs.getSym(), 4); + return TableEnd; } @@ -2418,32 +2484,27 @@ static void emitRangeList( } } +// Handles emission of both debug_loclist / debug_loclist.dwo static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List) { - emitRangeList( - DD, Asm, List.Label, DD.getDebugLocs().getEntries(List), *List.CU, - dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair, - dwarf::DW_LLE_startx_length, dwarf::DW_LLE_end_of_list, - llvm::dwarf::LocListEncodingString, - /* ShouldUseBaseAddress */ true, - [&](const DebugLocStream::Entry &E) { - DD.emitDebugLocEntryLocation(E, List.CU); - }); + emitRangeList(DD, Asm, List.Label, DD.getDebugLocs().getEntries(List), + *List.CU, dwarf::DW_LLE_base_addressx, + dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length, + dwarf::DW_LLE_end_of_list, llvm::dwarf::LocListEncodingString, + /* ShouldUseBaseAddress */ true, + [&](const DebugLocStream::Entry &E) { + DD.emitDebugLocEntryLocation(E, List.CU); + }); } -// Emit locations into the .debug_loc/.debug_rnglists section. -void DwarfDebug::emitDebugLoc() { +void DwarfDebug::emitDebugLocImpl(MCSection *Sec) { if (DebugLocs.getLists().empty()) return; + Asm->OutStreamer->SwitchSection(Sec); + MCSymbol *TableEnd = nullptr; - if (getDwarfVersion() >= 5) { - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getDwarfLoclistsSection()); + if (getDwarfVersion() >= 5) TableEnd = emitLoclistsTableHeader(Asm, *this); - } else { - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getDwarfLocSection()); - } for (const auto &List : DebugLocs.getLists()) emitLocList(*this, Asm, List); @@ -2452,11 +2513,28 @@ void DwarfDebug::emitDebugLoc() { Asm->OutStreamer->EmitLabel(TableEnd); } +// Emit locations into the .debug_loc/.debug_loclists section. +void DwarfDebug::emitDebugLoc() { + emitDebugLocImpl( + getDwarfVersion() >= 5 + ? Asm->getObjFileLowering().getDwarfLoclistsSection() + : Asm->getObjFileLowering().getDwarfLocSection()); +} + +// Emit locations into the .debug_loc.dwo/.debug_loclists.dwo section. void DwarfDebug::emitDebugLocDWO() { + if (getDwarfVersion() >= 5) { + emitDebugLocImpl( + Asm->getObjFileLowering().getDwarfLoclistsDWOSection()); + + return; + } + for (const auto &List : DebugLocs.getLists()) { Asm->OutStreamer->SwitchSection( Asm->getObjFileLowering().getDwarfLocDWOSection()); Asm->OutStreamer->EmitLabel(List.Label); + for (const auto &Entry : DebugLocs.getEntries(List)) { // GDB only supports startx_length in pre-standard split-DWARF. // (in v5 standard loclists, it currently* /only/ supports base_address + @@ -2468,8 +2546,9 @@ void DwarfDebug::emitDebugLocDWO() { Asm->emitInt8(dwarf::DW_LLE_startx_length); unsigned idx = AddrPool.getIndex(Entry.Begin); Asm->EmitULEB128(idx); + // Also the pre-standard encoding is slightly different, emitting this as + // an address-length entry here, but its a ULEB128 in DWARFv5 loclists. Asm->EmitLabelDifference(Entry.End, Entry.Begin, 4); - emitDebugLocEntryLocation(Entry, List.CU); } Asm->emitInt8(dwarf::DW_LLE_end_of_list); @@ -2639,19 +2718,33 @@ void DwarfDebug::emitDebugARanges() { /// Emit a single range list. We handle both DWARF v5 and earlier. static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, const RangeSpanList &List) { - emitRangeList(DD, Asm, List.getSym(), List.getRanges(), List.getCU(), + emitRangeList(DD, Asm, List.Label, List.Ranges, *List.CU, dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair, dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list, llvm::dwarf::RangeListEncodingString, - List.getCU().getCUNode()->getRangesBaseAddress() || + List.CU->getCUNode()->getRangesBaseAddress() || DD.getDwarfVersion() >= 5, [](auto) {}); } -static void emitDebugRangesImpl(DwarfDebug &DD, AsmPrinter *Asm, - const DwarfFile &Holder, MCSymbol *TableEnd) { +void DwarfDebug::emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section) { + if (Holder.getRangeLists().empty()) + return; + + assert(useRangesSection()); + assert(!CUMap.empty()); + assert(llvm::any_of(CUMap, [](const decltype(CUMap)::value_type &Pair) { + return !Pair.second->getCUNode()->isDebugDirectivesOnly(); + })); + + Asm->OutStreamer->SwitchSection(Section); + + MCSymbol *TableEnd = nullptr; + if (getDwarfVersion() >= 5) + TableEnd = emitRnglistsTableHeader(Asm, Holder); + for (const RangeSpanList &List : Holder.getRangeLists()) - emitRangeList(DD, Asm, List); + emitRangeList(*this, Asm, List); if (TableEnd) Asm->OutStreamer->EmitLabel(TableEnd); @@ -2660,55 +2753,17 @@ static void emitDebugRangesImpl(DwarfDebug &DD, AsmPrinter *Asm, /// Emit address ranges into the .debug_ranges section or into the DWARF v5 /// .debug_rnglists section. void DwarfDebug::emitDebugRanges() { - if (CUMap.empty()) - return; - const auto &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; - if (Holder.getRangeLists().empty()) - return; - - assert(useRangesSection()); - assert(llvm::none_of(CUMap, [](const decltype(CUMap)::value_type &Pair) { - return Pair.second->getCUNode()->isDebugDirectivesOnly(); - })); - - // Start the dwarf ranges section. - MCSymbol *TableEnd = nullptr; - if (getDwarfVersion() >= 5) { - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getDwarfRnglistsSection()); - TableEnd = emitRnglistsTableHeader(Asm, Holder); - } else - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getDwarfRangesSection()); - - emitDebugRangesImpl(*this, Asm, Holder, TableEnd); + emitDebugRangesImpl(Holder, + getDwarfVersion() >= 5 + ? Asm->getObjFileLowering().getDwarfRnglistsSection() + : Asm->getObjFileLowering().getDwarfRangesSection()); } void DwarfDebug::emitDebugRangesDWO() { - assert(useSplitDwarf()); - - if (CUMap.empty()) - return; - - const auto &Holder = InfoHolder; - - if (Holder.getRangeLists().empty()) - return; - - assert(getDwarfVersion() >= 5); - assert(useRangesSection()); - assert(llvm::none_of(CUMap, [](const decltype(CUMap)::value_type &Pair) { - return Pair.second->getCUNode()->isDebugDirectivesOnly(); - })); - - // Start the dwarf ranges section. - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getDwarfRnglistsDWOSection()); - MCSymbol *TableEnd = emitRnglistsTableHeader(Asm, Holder); - - emitDebugRangesImpl(*this, Asm, Holder, TableEnd); + emitDebugRangesImpl(InfoHolder, + Asm->getObjFileLowering().getDwarfRnglistsDWOSection()); } void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) { @@ -2745,35 +2800,30 @@ void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) { Asm->EmitULEB128(dwarf::DW_MACINFO_end_file); } -/// Emit macros into a debug macinfo section. -void DwarfDebug::emitDebugMacinfo() { - if (CUMap.empty()) - return; - - if (llvm::all_of(CUMap, [](const decltype(CUMap)::value_type &Pair) { - return Pair.second->getCUNode()->isDebugDirectivesOnly(); - })) - return; - - // Start the dwarf macinfo section. - Asm->OutStreamer->SwitchSection( - Asm->getObjFileLowering().getDwarfMacinfoSection()); - +void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) { for (const auto &P : CUMap) { auto &TheCU = *P.second; - if (TheCU.getCUNode()->isDebugDirectivesOnly()) - continue; auto *SkCU = TheCU.getSkeleton(); DwarfCompileUnit &U = SkCU ? *SkCU : TheCU; auto *CUNode = cast<DICompileUnit>(P.first); DIMacroNodeArray Macros = CUNode->getMacros(); - if (!Macros.empty()) { - Asm->OutStreamer->EmitLabel(U.getMacroLabelBegin()); - handleMacroNodes(Macros, U); - } + if (Macros.empty()) + continue; + Asm->OutStreamer->SwitchSection(Section); + Asm->OutStreamer->EmitLabel(U.getMacroLabelBegin()); + handleMacroNodes(Macros, U); + Asm->OutStreamer->AddComment("End Of Macro List Mark"); + Asm->emitInt8(0); } - Asm->OutStreamer->AddComment("End Of Macro List Mark"); - Asm->emitInt8(0); +} + +/// Emit macros into a debug macinfo section. +void DwarfDebug::emitDebugMacinfo() { + emitDebugMacinfoImpl(Asm->getObjFileLowering().getDwarfMacinfoSection()); +} + +void DwarfDebug::emitDebugMacinfoDWO() { + emitDebugMacinfoImpl(Asm->getObjFileLowering().getDwarfMacinfoDWOSection()); } // DWARF5 Experimental Separate Dwarf emitters. @@ -2792,7 +2842,8 @@ void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die, DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) { auto OwnedUnit = std::make_unique<DwarfCompileUnit>( - CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder); + CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder, + UnitKind::Skeleton); DwarfCompileUnit &NewCU = *OwnedUnit; NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection()); |