// Emit offset in .debug_range as a relocatable label. emitDIE will handle
// emitting it appropriately.
MCSymbol *RangeSym = Asm->GetTempSymbol("debug_ranges", GlobalRangeCount++);
- addSectionLabel(Asm, TheCU, ScopeDIE, dwarf::DW_AT_ranges, RangeSym,
- DwarfDebugRangeSectionSym);
+
+ // Under fission, ranges are specified by constant offsets relative to the
+ // CU's DW_AT_GNU_ranges_base.
+ if (useSplitDwarf())
+ TheCU->addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, RangeSym,
+ DwarfDebugRangeSectionSym);
+ else
+ addSectionLabel(Asm, TheCU, ScopeDIE, dwarf::DW_AT_ranges, RangeSym,
+ DwarfDebugRangeSectionSym);
RangeSpanList List(RangeSym);
for (const InsnRange &R : Range) {
// Handle multiple DBG_VALUE instructions describing one variable.
RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
+ SmallVector<DebugLocEntry, 4> DebugLoc;
for (SmallVectorImpl<const MachineInstr *>::const_iterator
HI = History.begin(),
HE = History.end();
// The value is valid until the next DBG_VALUE or clobber.
LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
- DotDebugLocEntries.push_back(
- getDebugLocEntry(Asm, FLabel, SLabel, Begin, TheCU));
+ DebugLocEntry Loc = getDebugLocEntry(Asm, FLabel, SLabel, Begin, TheCU);
+ if (DebugLoc.empty() || !DebugLoc.back().Merge(Loc))
+ DebugLoc.push_back(std::move(Loc));
}
- DotDebugLocEntries.push_back(DebugLocEntry());
+ DotDebugLocEntries.push_back(std::move(DebugLoc));
}
// Collect info for variables that were optimized out.
// Emit locations into the debug loc section.
void DwarfDebug::emitDebugLoc() {
- if (DotDebugLocEntries.empty())
- return;
-
- for (SmallVectorImpl<DebugLocEntry>::iterator
- I = DotDebugLocEntries.begin(),
- E = DotDebugLocEntries.end();
- I != E; ++I) {
- DebugLocEntry &Entry = *I;
- if (I + 1 != DotDebugLocEntries.end())
- Entry.Merge(I + 1);
- }
-
// Start the dwarf loc section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfLocSection());
unsigned char Size = Asm->getDataLayout().getPointerSize();
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", 0));
- unsigned index = 1;
- for (SmallVectorImpl<DebugLocEntry>::const_iterator
- I = DotDebugLocEntries.begin(),
- E = DotDebugLocEntries.end();
- I != E; ++I, ++index) {
- const DebugLocEntry &Entry = *I;
- if (Entry.isMerged())
- continue;
-
- if (Entry.isEmpty()) {
- Asm->OutStreamer.EmitIntValue(0, Size);
- Asm->OutStreamer.EmitIntValue(0, Size);
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index));
- } else {
+ unsigned index = 0;
+ for (const auto &DebugLoc : DotDebugLocEntries) {
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index));
+ for (const auto &Entry : DebugLoc) {
// Set up the range. This range is relative to the entry point of the
// compile unit. This is a hard coded 0 for low_pc when we're emitting
// ranges, or the DW_AT_low_pc on the compile unit otherwise.
// Close the range.
Asm->OutStreamer.EmitLabel(end);
}
+ Asm->OutStreamer.EmitIntValue(0, Size);
+ Asm->OutStreamer.EmitIntValue(0, Size);
+ ++index;
}
}
// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_stmt_list,
// DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_dwo_name, DW_AT_dwo_id,
-// DW_AT_ranges_base, DW_AT_addr_base.
-// TODO: Implement DW_AT_ranges_base.
+// DW_AT_addr_base, DW_AT_ranges_base.
DwarfCompileUnit *DwarfDebug::constructSkeletonCU(const DwarfCompileUnit *CU) {
DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
// Relocate to the beginning of the addr_base section, else 0 for the
// beginning of the one for this compile unit.
- if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
+ // We could shave off some space if we deferred adding these attributes until
+ // the end of the CU to see if we have a non-empty debug_addr and debug_ranges
+ // sections so we don't bother with extra attributes and relocations.
+ if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) {
NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym);
- else
+ NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base, DwarfDebugRangeSectionSym);
+ } else {
NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0);
+ NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_ranges_base, 0);
+ }
return NewCU;
}
// compile units that would normally be in debug_info.
void DwarfDebug::emitDebugInfoDWO() {
assert(useSplitDwarf() && "No split dwarf debug info?");
- InfoHolder.emitUnits(this, DwarfAbbrevDWOSectionSym);
+ InfoHolder.emitUnits(this, nullptr);
}
// Emit the .debug_abbrev.dwo section for separated dwarf. This contains the