aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp293
1 files changed, 207 insertions, 86 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 66a5a6d..87659ef 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -54,6 +54,10 @@ static cl::opt<bool> UnknownLocations("use-unknown-locations", cl::Hidden,
cl::desc("Make an absence of debug location information explicit."),
cl::init(false));
+static cl::opt<bool> GenerateDwarfPubNamesSection("generate-dwarf-pubnames",
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::desc("Generate DWARF pubnames section"));
+
namespace {
enum DefaultOnOff {
Default, Enable, Disable
@@ -159,14 +163,13 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
PrevLabel(NULL), GlobalCUIndexCount(0),
InfoHolder(A, &AbbreviationsSet, &Abbreviations, "info_string",
DIEValueAllocator),
- SkeletonCU(0),
SkeletonAbbrevSet(InitAbbreviationsSetSize),
SkeletonHolder(A, &SkeletonAbbrevSet, &SkeletonAbbrevs, "skel_string",
DIEValueAllocator) {
DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
DwarfStrSectionSym = TextSectionSym = 0;
- DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = 0;
+ DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = DwarfLineSectionSym = 0;
DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0;
FunctionBeginSym = FunctionEndSym = 0;
@@ -237,6 +240,15 @@ unsigned DwarfUnits::getStringPoolIndex(StringRef Str) {
return Entry.second;
}
+unsigned DwarfUnits::getAddrPoolIndex(MCSymbol *Sym) {
+ std::pair<MCSymbol*, unsigned> &Entry = AddressPool[Sym];
+ if (Entry.first) return Entry.second;
+
+ Entry.second = NextAddrPoolNumber++;
+ Entry.first = Sym;
+ return Entry.second;
+}
+
// Define a unique number for the abbreviation.
//
void DwarfUnits::assignAbbrevNumber(DIEAbbrev &Abbrev) {
@@ -384,10 +396,12 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU,
}
}
- SPCU->addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
- SPCU->addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
+ SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc,
+ Asm->GetTempSymbol("func_begin",
+ Asm->getFunctionNumber()));
+ SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc,
+ Asm->GetTempSymbol("func_end",
+ Asm->getFunctionNumber()));
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
@@ -429,16 +443,16 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
return ScopeDIE;
}
- const MCSymbol *Start = getLabelBeforeInsn(RI->first);
- const MCSymbol *End = getLabelAfterInsn(RI->second);
+ MCSymbol *Start = getLabelBeforeInsn(RI->first);
+ MCSymbol *End = getLabelAfterInsn(RI->second);
if (End == 0) return 0;
assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
assert(End->isDefined() && "Invalid end label for an inlined scope!");
- TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start);
- TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End);
+ TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_low_pc, Start);
+ TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_high_pc, End);
return ScopeDIE;
}
@@ -462,8 +476,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
}
SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin();
- const MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
- const MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
+ MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
+ MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
if (StartLabel == 0 || EndLabel == 0) {
llvm_unreachable("Unexpected Start and End labels for an inlined scope!");
@@ -492,10 +506,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
DebugRangeSymbols.push_back(NULL);
DebugRangeSymbols.push_back(NULL);
} else {
- TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- StartLabel);
- TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- EndLabel);
+ TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_low_pc, StartLabel);
+ TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_high_pc, EndLabel);
}
InlinedSubprogramDIEs.insert(OriginDIE);
@@ -531,6 +543,12 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) {
if (!Scope || !Scope->getScopeNode())
return NULL;
+ DIScope DS(Scope->getScopeNode());
+ // Early return to avoid creating dangling variable|scope DIEs.
+ if (!Scope->getInlinedAt() && DS.isSubprogram() && Scope->isAbstractScope() &&
+ !TheCU->getDIE(DS))
+ return NULL;
+
SmallVector<DIE *, 8> Children;
DIE *ObjectPointer = NULL;
@@ -556,7 +574,6 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) {
for (unsigned j = 0, M = Scopes.size(); j < M; ++j)
if (DIE *Nested = constructScopeDIE(TheCU, Scopes[j]))
Children.push_back(Nested);
- DIScope DS(Scope->getScopeNode());
DIE *ScopeDIE = NULL;
if (Scope->getInlinedAt())
ScopeDIE = constructInlinedScopeDIE(TheCU, Scope);
@@ -646,15 +663,28 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
DIUnit.getLanguage());
NewCU->addString(Die, dwarf::DW_AT_name, FN);
// 2.17.1 requires that we use DW_AT_low_pc for a single entry point
- // into an entity.
- NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
+ // into an entity. We're using 0 (or a NULL label) for this.
+ NewCU->addLabelAddress(Die, dwarf::DW_AT_low_pc, NULL);
+
+ // Define start line table label for each Compile Unit.
+ MCSymbol *LineTableStartSym = Asm->GetTempSymbol("line_table_start",
+ NewCU->getUniqueID());
+ Asm->OutStreamer.getContext().setMCLineTableSymbol(LineTableStartSym,
+ NewCU->getUniqueID());
+
// DW_AT_stmt_list is a offset of line number information for this
// compile unit in debug_line section.
+ // The line table entries are not always emitted in assembly, so it
+ // is not okay to use line_table_start here.
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4,
- Asm->GetTempSymbol("section_line"));
- else
+ NewCU->getUniqueID() == 0 ?
+ Asm->GetTempSymbol("section_line") : LineTableStartSym);
+ else if (NewCU->getUniqueID() == 0)
NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
+ else
+ NewCU->addDelta(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4,
+ LineTableStartSym, DwarfLineSectionSym);
if (!CompilationDir.empty())
NewCU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
@@ -671,8 +701,13 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
if (!FirstCU)
FirstCU = NewCU;
- if (useSplitDwarf() && !SkeletonCU)
- SkeletonCU = constructSkeletonCU(N);
+
+ if (useSplitDwarf()) {
+ // This should be a unique identifier when we want to build .dwp files.
+ NewCU->addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8, 0);
+ // Now construct the skeleton CU associated.
+ constructSkeletonCU(N);
+ }
InfoHolder.addUnit(NewCU);
@@ -702,7 +737,9 @@ void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU,
// Add to context owner.
TheCU->addToContextOwner(SubprogramDie, SP.getContext());
- return;
+ // Expose as global, if requested.
+ if (GenerateDwarfPubNamesSection)
+ TheCU->addGlobalName(SP.getName(), SubprogramDie);
}
// Collect debug info from named mdnodes such as llvm.dbg.enum and llvm.dbg.ty.
@@ -754,6 +791,9 @@ bool DwarfDebug::collectLegacyDebugInfo(const Module *M) {
}
if (!HasDebugInfo) return false;
+ // Emit initial sections so we can refer to them later.
+ emitSectionLabels();
+
// Create all the compile unit DIEs.
for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
E = DbgFinder.compile_unit_end(); I != E; ++I)
@@ -791,6 +831,9 @@ void DwarfDebug::beginModule() {
// module using debug info finder to collect debug info.
NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
if (CU_Nodes) {
+ // Emit initial sections so we can reference labels later.
+ emitSectionLabels();
+
for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
DICompileUnit CUNode(CU_Nodes->getOperand(i));
CompileUnit *CU = constructCompileUnit(CUNode);
@@ -923,9 +966,6 @@ void DwarfDebug::endModule() {
// Finalize the debug info for the module.
finalizeModuleInfo();
- // Emit initial sections.
- emitSectionLabels();
-
if (!useSplitDwarf()) {
// Emit all the DIEs into a debug info section.
emitDebugInfo();
@@ -975,6 +1015,9 @@ void DwarfDebug::endModule() {
// Emit info into a debug macinfo section.
emitDebugMacInfo();
+ // Emit DWO addresses.
+ InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection());
+
// Emit inline info.
// TODO: When we don't need the option anymore we
// can remove all of the code that this section
@@ -991,6 +1034,10 @@ void DwarfDebug::endModule() {
emitAccelTypes();
}
+ // Emit info into a debug pubnames section, if requested.
+ if (GenerateDwarfPubNamesSection)
+ emitDebugPubnames();
+
// Emit info into a debug pubtypes section.
// TODO: When we don't need the option anymore we can
// remove all of the code that adds to the table.
@@ -1008,11 +1055,12 @@ void DwarfDebug::endModule() {
E = CUMap.end(); I != E; ++I)
delete I->second;
- delete SkeletonCU;
+ for (SmallVector<CompileUnit *, 1>::iterator I = SkeletonCUs.begin(),
+ E = SkeletonCUs.end(); I != E; ++I)
+ delete *I;
// Reset these for the next Module if we have one.
FirstCU = NULL;
- SkeletonCU = NULL;
}
// Find abstract variable, if any, associated with Var.
@@ -1179,7 +1227,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
continue;
}
- // handle multiple DBG_VALUE instructions describing one variable.
+ // Handle multiple DBG_VALUE instructions describing one variable.
RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
for (SmallVectorImpl<const MachineInstr*>::const_iterator
@@ -1234,14 +1282,14 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
}
// Return Label preceding the instruction.
-const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
+MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr *MI) {
MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
assert(Label && "Didn't insert label before instruction");
return Label;
}
// Return Label immediately following the instruction.
-const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
+MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
return LabelsAfterInsn.lookup(MI);
}
@@ -1377,6 +1425,13 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
if (LScopes.empty()) return;
identifyScopeMarkers();
+ // Set DwarfCompileUnitID in MCContext to the Compile Unit this function
+ // belongs to.
+ LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
+ CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
+ assert(TheCU && "Unable to find compile unit!");
+ Asm->OutStreamer.getContext().setDwarfCompileUnitID(TheCU->getUniqueID());
+
FunctionBeginSym = Asm->GetTempSymbol("func_begin",
Asm->getFunctionNumber());
// Assumes in correct section after the entry point.
@@ -1561,6 +1616,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
Asm->getFunctionNumber());
// Assumes in correct section after the entry point.
Asm->OutStreamer.EmitLabel(FunctionEndSym);
+ // Set DwarfCompileUnitID in MCContext to default value.
+ Asm->OutStreamer.getContext().setDwarfCompileUnitID(0);
SmallPtrSet<const MDNode *, 16> ProcessedVars;
collectVariableInfo(MF, ProcessedVars);
@@ -1734,8 +1791,11 @@ void DwarfDebug::emitSectionLabels() {
if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
emitSectionSym(Asm, MacroInfo);
- emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line");
+ DwarfLineSectionSym =
+ emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line");
emitSectionSym(Asm, TLOF.getDwarfLocSection());
+ if (GenerateDwarfPubNamesSection)
+ emitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
emitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
DwarfStrSectionSym =
emitSectionSym(Asm, TLOF.getDwarfStrSection(), "info_string");
@@ -1942,8 +2002,7 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Asm->OutStreamer.AddComment("Section end label");
Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
- Asm->getDataLayout().getPointerSize(),
- 0/*AddrSpace*/);
+ Asm->getDataLayout().getPointerSize());
// Mark end of matrix.
Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
@@ -2072,6 +2131,61 @@ void DwarfDebug::emitAccelTypes() {
AT.Emit(Asm, SectionBegin, &InfoHolder);
}
+/// emitDebugPubnames - Emit visible names into a debug pubnames section.
+///
+void DwarfDebug::emitDebugPubnames() {
+ const MCSection *ISec = Asm->getObjFileLowering().getDwarfInfoSection();
+
+ typedef DenseMap<const MDNode*, CompileUnit*> CUMapType;
+ for (CUMapType::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) {
+ CompileUnit *TheCU = I->second;
+ unsigned ID = TheCU->getUniqueID();
+
+ if (TheCU->getGlobalNames().empty())
+ continue;
+
+ // Start the dwarf pubnames section.
+ Asm->OutStreamer.SwitchSection(
+ Asm->getObjFileLowering().getDwarfPubNamesSection());
+
+ Asm->OutStreamer.AddComment("Length of Public Names Info");
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("pubnames_end", ID),
+ Asm->GetTempSymbol("pubnames_begin", ID), 4);
+
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin", ID));
+
+ Asm->OutStreamer.AddComment("DWARF Version");
+ Asm->EmitInt16(dwarf::DWARF_VERSION);
+
+ Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
+ Asm->EmitSectionOffset(Asm->GetTempSymbol(ISec->getLabelBeginName(), ID),
+ DwarfInfoSectionSym);
+
+ Asm->OutStreamer.AddComment("Compilation Unit Length");
+ Asm->EmitLabelDifference(Asm->GetTempSymbol(ISec->getLabelEndName(), ID),
+ Asm->GetTempSymbol(ISec->getLabelBeginName(), ID),
+ 4);
+
+ const StringMap<DIE*> &Globals = TheCU->getGlobalNames();
+ for (StringMap<DIE*>::const_iterator
+ GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
+ const char *Name = GI->getKeyData();
+ const DIE *Entity = GI->second;
+
+ Asm->OutStreamer.AddComment("DIE offset");
+ Asm->EmitInt32(Entity->getOffset());
+
+ if (Asm->isVerbose())
+ Asm->OutStreamer.AddComment("External Name");
+ Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
+ }
+
+ Asm->OutStreamer.AddComment("End Mark");
+ Asm->EmitInt32(0);
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end", ID));
+ }
+}
+
void DwarfDebug::emitDebugPubTypes() {
for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
E = CUMap.end(); I != E; ++I) {
@@ -2114,7 +2228,7 @@ void DwarfDebug::emitDebugPubTypes() {
if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
// Emit the name with a terminating null byte.
- Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
+ Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1));
}
Asm->OutStreamer.AddComment("End Mark");
@@ -2152,22 +2266,53 @@ void DwarfUnits::emitStrings(const MCSection *StrSection,
// Emit the string itself with a terminating null byte.
Asm->OutStreamer.EmitBytes(StringRef(Entries[i].second->getKeyData(),
- Entries[i].second->getKeyLength()+1),
- 0/*addrspace*/);
+ Entries[i].second->getKeyLength()+1));
}
// If we've got an offset section go ahead and emit that now as well.
if (OffsetSection) {
Asm->OutStreamer.SwitchSection(OffsetSection);
unsigned offset = 0;
- unsigned size = 4;
+ unsigned size = 4; // FIXME: DWARF64 is 8.
for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
- Asm->OutStreamer.EmitIntValue(offset, size, 0);
+ Asm->OutStreamer.EmitIntValue(offset, size);
offset += Entries[i].second->getKeyLength() + 1;
}
}
}
+// Emit strings into a string section.
+void DwarfUnits::emitAddresses(const MCSection *AddrSection) {
+
+ if (AddressPool.empty()) return;
+
+ // Start the dwarf addr section.
+ Asm->OutStreamer.SwitchSection(AddrSection);
+
+ // Get all of the string pool entries and put them in an array by their ID so
+ // we can sort them.
+ SmallVector<std::pair<unsigned,
+ std::pair<MCSymbol*, unsigned>* >, 64> Entries;
+
+ for (DenseMap<MCSymbol*, std::pair<MCSymbol*, unsigned> >::iterator
+ I = AddressPool.begin(), E = AddressPool.end();
+ I != E; ++I)
+ Entries.push_back(std::make_pair(I->second.second, &(I->second)));
+
+ array_pod_sort(Entries.begin(), Entries.end());
+
+ for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
+ // Emit a label for reference from debug information entries.
+ MCSymbol *Sym = Entries[i].second->first;
+ if (Sym)
+ Asm->EmitLabelReference(Entries[i].second->first,
+ Asm->getDataLayout().getPointerSize());
+ else
+ Asm->OutStreamer.EmitIntValue(0, Asm->getDataLayout().getPointerSize());
+ }
+
+}
+
// Emit visible names into a debug str section.
void DwarfDebug::emitDebugStr() {
DwarfUnits &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
@@ -2199,12 +2344,12 @@ void DwarfDebug::emitDebugLoc() {
DotDebugLocEntry &Entry = *I;
if (Entry.isMerged()) continue;
if (Entry.isEmpty()) {
- Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
- Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
+ Asm->OutStreamer.EmitIntValue(0, Size);
+ Asm->OutStreamer.EmitIntValue(0, Size);
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", index));
} else {
- Asm->OutStreamer.EmitSymbolValue(Entry.Begin, Size, 0);
- Asm->OutStreamer.EmitSymbolValue(Entry.End, Size, 0);
+ Asm->OutStreamer.EmitSymbolValue(Entry.Begin, Size);
+ Asm->OutStreamer.EmitSymbolValue(Entry.End, Size);
DIVariable DV(Entry.Variable);
Asm->OutStreamer.AddComment("Loc expr size");
MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol();
@@ -2290,9 +2435,9 @@ void DwarfDebug::emitDebugRanges() {
I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end();
I != E; ++I) {
if (*I)
- Asm->OutStreamer.EmitSymbolValue(const_cast<MCSymbol*>(*I), Size, 0);
+ Asm->OutStreamer.EmitSymbolValue(const_cast<MCSymbol*>(*I), Size);
else
- Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
+ Asm->OutStreamer.EmitIntValue(0, Size);
}
}
@@ -2376,7 +2521,7 @@ void DwarfDebug::emitDebugInlineInfo() {
if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
Asm->OutStreamer.EmitSymbolValue(LI->first,
- Asm->getDataLayout().getPointerSize(),0);
+ Asm->getDataLayout().getPointerSize());
}
}
@@ -2391,68 +2536,44 @@ void DwarfDebug::emitDebugInlineInfo() {
// DW_AT_low_pc and DW_AT_high_pc are not used, and vice versa.
CompileUnit *DwarfDebug::constructSkeletonCU(const MDNode *N) {
DICompileUnit DIUnit(N);
- StringRef FN = DIUnit.getFilename();
CompilationDir = DIUnit.getDirectory();
DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
CompileUnit *NewCU = new CompileUnit(GlobalCUIndexCount++,
DIUnit.getLanguage(), Die, Asm,
this, &SkeletonHolder);
- // FIXME: This should be the .dwo file.
- NewCU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name, FN);
- // FIXME: We also need DW_AT_addr_base and DW_AT_dwo_id.
+ NewCU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name,
+ DIUnit.getSplitDebugFilename());
+
+ // This should be a unique identifier when we want to build .dwp files.
+ NewCU->addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8, 0);
+
+ // FIXME: The addr base should be relative for each compile unit, however,
+ // this one is going to be 0 anyhow.
+ NewCU->addUInt(Die, dwarf::DW_AT_GNU_addr_base, dwarf::DW_FORM_sec_offset, 0);
// 2.17.1 requires that we use DW_AT_low_pc for a single entry point
- // into an entity.
+ // into an entity. We're using 0, or a NULL label for this.
NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
+
// DW_AT_stmt_list is a offset of line number information for this
// compile unit in debug_line section.
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4,
- Asm->GetTempSymbol("section_line"));
+ NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset,
+ DwarfLineSectionSym);
else
- NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
+ NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_sec_offset, 0);
if (!CompilationDir.empty())
NewCU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
SkeletonHolder.addUnit(NewCU);
+ SkeletonCUs.push_back(NewCU);
return NewCU;
}
-void DwarfDebug::emitSkeletonCU(const MCSection *Section) {
- Asm->OutStreamer.SwitchSection(Section);
- DIE *Die = SkeletonCU->getCUDie();
-
- // Emit the compile units header.
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol(Section->getLabelBeginName(),
- SkeletonCU->getUniqueID()));
-
- // Emit size of content not including length itself
- unsigned ContentSize = Die->getSize() +
- sizeof(int16_t) + // DWARF version number
- sizeof(int32_t) + // Offset Into Abbrev. Section
- sizeof(int8_t); // Pointer Size (in bytes)
-
- Asm->OutStreamer.AddComment("Length of Compilation Unit Info");
- Asm->EmitInt32(ContentSize);
- Asm->OutStreamer.AddComment("DWARF version number");
- Asm->EmitInt16(dwarf::DWARF_VERSION);
- Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
-
- const MCSection *ASec = Asm->getObjFileLowering().getDwarfAbbrevSection();
- Asm->EmitSectionOffset(Asm->GetTempSymbol(ASec->getLabelBeginName()),
- DwarfAbbrevSectionSym);
- Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(Asm->getDataLayout().getPointerSize());
-
- emitDIE(Die, &SkeletonAbbrevs);
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol(Section->getLabelEndName(),
- SkeletonCU->getUniqueID()));
-}
-
void DwarfDebug::emitSkeletonAbbrevs(const MCSection *Section) {
assert(useSplitDwarf() && "No split dwarf debug info?");
emitAbbrevs(Section, &SkeletonAbbrevs);