aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
commit706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch)
tree4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
parent7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff)
Notes
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp359
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());