X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp;h=010dcdf05556a9a687d99055dafefd2f8cfc86a9;hb=ac07cd54ed48cdc160eba7625eefe09c5f484eb2;hp=25cf95d37b273c59160431d37e16e8e3211eb264;hpb=7487eb6df3e9ce3b41e9cd83c165c02217589c49;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 25cf95d37b2..010dcdf0555 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -16,7 +16,7 @@ #include "DIE.h" #include "DIEHash.h" #include "DwarfAccelTable.h" -#include "DwarfCompileUnit.h" +#include "DwarfUnit.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" @@ -185,8 +185,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), FirstCU(0), AbbreviationsSet(InitAbbreviationsSetSize), SourceIdMap(DIEValueAllocator), PrevLabel(NULL), GlobalCUIndexCount(0), - InfoHolder(A, &AbbreviationsSet, Abbreviations, "info_string", - DIEValueAllocator), + GlobalRangeCount(0), InfoHolder(A, &AbbreviationsSet, Abbreviations, + "info_string", DIEValueAllocator), SkeletonAbbrevSet(InitAbbreviationsSetSize), SkeletonHolder(A, &SkeletonAbbrevSet, SkeletonAbbrevs, "skel_string", DIEValueAllocator) { @@ -197,6 +197,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) DwarfAddrSectionSym = 0; DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0; FunctionBeginSym = FunctionEndSym = 0; + CurFn = 0; CurMI = 0; // Turn on accelerator tables for Darwin by default, pubnames by // default for non-Darwin, and handle split dwarf. @@ -341,26 +342,26 @@ static bool SectionSort(const MCSection *A, const MCSection *B) { // TODO: Determine whether or not we should add names for programs // that do not have a DW_AT_name or DW_AT_linkage_name field - this // is only slightly different than the lookup of non-standard ObjC names. -static void addSubprogramNames(Unit *TheCU, DISubprogram SP, DIE *Die) { +static void addSubprogramNames(Unit *TheU, DISubprogram SP, DIE *Die) { if (!SP.isDefinition()) return; - TheCU->addAccelName(SP.getName(), Die); + TheU->addAccelName(SP.getName(), Die); // If the linkage name is different than the name, go ahead and output // that as well into the name table. if (SP.getLinkageName() != "" && SP.getName() != SP.getLinkageName()) - TheCU->addAccelName(SP.getLinkageName(), Die); + TheU->addAccelName(SP.getLinkageName(), Die); // If this is an Objective-C selector name add it to the ObjC accelerator // too. if (isObjCClass(SP.getName())) { StringRef Class, Category; getObjCClassCategory(SP.getName(), Class, Category); - TheCU->addAccelObjC(Class, Die); + TheU->addAccelObjC(Class, Die); if (Category != "") - TheCU->addAccelObjC(Category, Die); + TheU->addAccelObjC(Category, Die); // Also add the base method name to the name table. - TheCU->addAccelName(getObjCMethodName(SP.getName()), Die); + TheU->addAccelName(getObjCMethodName(SP.getName()), Die); } } @@ -390,7 +391,8 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { // concrete DIE twice. if (DIE *AbsSPDIE = AbstractSPDies.lookup(SP)) { // Pick up abstract subprogram DIE. - SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getCUDie()); + SPDie = + SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getUnitDie()); SPCU->addDIEEntry(SPDie, dwarf::DW_AT_abstract_origin, AbsSPDIE); } else { DISubprogram SPDecl = SP.getFunctionDeclaration(); @@ -421,19 +423,19 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg); } DIE *SPDeclDie = SPDie; - SPDie = - SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getCUDie()); + SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, + *SPCU->getUnitDie()); SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, SPDeclDie); } } } - 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())); + MCSymbol *FuncBegin = + Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()); + MCSymbol *FuncEnd = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()); + SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc, FuncBegin); + SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc, FuncEnd); + const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); MachineLocation Location(RI->getFrameRegister(*Asm->MF)); SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location); @@ -466,6 +468,25 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { return !End; } +void DwarfDebug::addScopeRangeList(CompileUnit *TheCU, DIE *ScopeDIE, + const SmallVectorImpl &Range) { + // Emit offset in .debug_range as a relocatable label. emitDIE will handle + // emitting it appropriately. + TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, + Asm->GetTempSymbol("debug_ranges", GlobalRangeCount)); + RangeSpanList *List = new RangeSpanList(GlobalRangeCount++); + for (SmallVectorImpl::const_iterator RI = Range.begin(), + RE = Range.end(); + RI != RE; ++RI) { + RangeSpan Span(getLabelBeforeInsn(RI->first), + getLabelAfterInsn(RI->second)); + List->addRange(Span); + } + + // Add the range list to the set of ranges to be emitted. + TheCU->addRangeList(List); +} + // Construct new DW_TAG_lexical_block for this scope and attach // DW_AT_low_pc/DW_AT_high_pc labels. DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, @@ -477,30 +498,16 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, if (Scope->isAbstractScope()) return ScopeDIE; - const SmallVectorImpl &Ranges = Scope->getRanges(); - // If we have multiple ranges, emit them into the range section. - if (Ranges.size() > 1) { - // .debug_range section has not been laid out yet. Emit offset in - // .debug_range as a relocatable label. emitDIE will handle - // emitting it appropriately. - unsigned Offset = DebugRangeSymbols.size(); - TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, - Asm->GetTempSymbol("debug_ranges", Offset)); - for (SmallVectorImpl::const_iterator RI = Ranges.begin(), - RE = Ranges.end(); - RI != RE; ++RI) { - DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); - DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); - } + const SmallVectorImpl &ScopeRanges = Scope->getRanges(); - // Terminate the range list. - DebugRangeSymbols.push_back(NULL); - DebugRangeSymbols.push_back(NULL); + // If we have multiple ranges, emit them into the range section. + if (ScopeRanges.size() > 1) { + addScopeRangeList(TheCU, ScopeDIE, ScopeRanges); return ScopeDIE; } // Construct the address range for this DIE. - SmallVectorImpl::const_iterator RI = Ranges.begin(); + SmallVectorImpl::const_iterator RI = ScopeRanges.begin(); MCSymbol *Start = getLabelBeforeInsn(RI->first); MCSymbol *End = getLabelAfterInsn(RI->second); assert(End && "End label should not be null!"); @@ -518,8 +525,8 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, // represent this concrete inlined copy of the function. DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { - const SmallVectorImpl &Ranges = Scope->getRanges(); - assert(Ranges.empty() == false && + const SmallVectorImpl &ScopeRanges = Scope->getRanges(); + assert(ScopeRanges.empty() == false && "LexicalScope does not have instruction markers!"); if (!Scope->getScopeNode()) @@ -535,23 +542,11 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine); TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, OriginDIE); - if (Ranges.size() > 1) { - // .debug_range section has not been laid out yet. Emit offset in - // .debug_range as a relocatable label. emitDIE will handle - // emitting it appropriately. - unsigned Offset = DebugRangeSymbols.size(); - TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, - Asm->GetTempSymbol("debug_ranges", Offset)); - for (SmallVectorImpl::const_iterator RI = Ranges.begin(), - RE = Ranges.end(); - RI != RE; ++RI) { - DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); - DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); - } - DebugRangeSymbols.push_back(NULL); - DebugRangeSymbols.push_back(NULL); - } else { - SmallVectorImpl::const_iterator RI = Ranges.begin(); + // If we have multiple ranges, emit them into the range section. + if (ScopeRanges.size() > 1) + addScopeRangeList(TheCU, ScopeDIE, ScopeRanges); + else { + SmallVectorImpl::const_iterator RI = ScopeRanges.begin(); MCSymbol *StartLabel = getLabelBeforeInsn(RI->first); MCSymbol *EndLabel = getLabelAfterInsn(RI->second); @@ -1066,28 +1061,27 @@ void DwarfDebug::finalizeModuleInfo() { for (SmallVectorImpl::const_iterator I = getUnits().begin(), E = getUnits().end(); I != E; ++I) { - Unit *TheCU = *I; + Unit *TheU = *I; // Emit DW_AT_containing_type attribute to connect types with their // vtable holding type. - TheCU->constructContainingTypeDIEs(); + TheU->constructContainingTypeDIEs(); // If we're splitting the dwarf out now that we've got the entire // CU then construct a skeleton CU based upon it. if (useSplitDwarf() && - TheCU->getCUDie()->getTag() == dwarf::DW_TAG_compile_unit) { + TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) { uint64_t ID = 0; if (GenerateCUHash) { DIEHash CUHash; - ID = CUHash.computeCUSignature(*TheCU->getCUDie()); + ID = CUHash.computeCUSignature(*TheU->getUnitDie()); } // This should be a unique identifier when we want to build .dwp files. - TheCU->addUInt(TheCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); + TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); // Now construct the skeleton CU associated. - CompileUnit *SkCU = - constructSkeletonCU(static_cast(TheCU)); + CompileUnit *SkCU = constructSkeletonCU(static_cast(TheU)); // This should be a unique identifier when we want to build .dwp files. - SkCU->addUInt(SkCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id, + SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8, ID); } } @@ -1151,6 +1145,8 @@ void DwarfDebug::endSections() { // Emit all Dwarf sections that should come after the content. void DwarfDebug::endModule() { + assert(CurFn == 0); + assert(CurMI == 0); if (!FirstCU) return; @@ -1232,8 +1228,7 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, } // If Var is a current function argument then add it to CurrentFnArguments list. -bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, - DbgVariable *Var, LexicalScope *Scope) { +bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) { if (!LScopes.isCurrentFunctionScope(Scope)) return false; DIVariable DV = Var->getVariable(); @@ -1245,7 +1240,7 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, size_t Size = CurrentFnArguments.size(); if (Size == 0) - CurrentFnArguments.resize(MF->getFunction()->arg_size()); + CurrentFnArguments.resize(CurFn->getFunction()->arg_size()); // llvm::Function argument size is not good indicator of how many // arguments does the function have at source level. if (ArgNo > Size) @@ -1256,7 +1251,7 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, // Collect variable information from side table maintained by MMI. void DwarfDebug::collectVariableInfoFromMMITable( - const MachineFunction *MF, SmallPtrSet &Processed) { + SmallPtrSet &Processed) { MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo(); for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(), VE = VMap.end(); @@ -1277,7 +1272,7 @@ void DwarfDebug::collectVariableInfoFromMMITable( DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second); DbgVariable *RegVar = new DbgVariable(DV, AbsDbgVariable, this); RegVar->setFrameIndex(VP.first); - if (!addCurrentFnArgument(MF, RegVar, Scope)) + if (!addCurrentFnArgument(RegVar, Scope)) addScopeVariable(Scope, RegVar); if (AbsDbgVariable) AbsDbgVariable->setFrameIndex(VP.first); @@ -1324,11 +1319,10 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm, // Find variables for each lexical scope. void -DwarfDebug::collectVariableInfo(const MachineFunction *MF, - SmallPtrSet &Processed) { +DwarfDebug::collectVariableInfo(SmallPtrSet &Processed) { // Grab the variable info that was squirreled away in the MMI side-table. - collectVariableInfoFromMMITable(MF, Processed); + collectVariableInfoFromMMITable(Processed); for (SmallVectorImpl::const_iterator UVI = UserVariables.begin(), @@ -1348,7 +1342,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, DIVariable DV(Var); LexicalScope *Scope = NULL; if (DV.getTag() == dwarf::DW_TAG_arg_variable && - DISubprogram(DV.getContext()).describes(MF->getFunction())) + DISubprogram(DV.getContext()).describes(CurFn->getFunction())) Scope = LScopes.getCurrentFunctionScope(); else if (MDNode *IA = DV.getInlinedAt()) Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA)); @@ -1362,7 +1356,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, assert(MInsn->isDebugValue() && "History must begin with debug value"); DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc()); DbgVariable *RegVar = new DbgVariable(DV, AbsVar, this); - if (!addCurrentFnArgument(MF, RegVar, Scope)) + if (!addCurrentFnArgument(RegVar, Scope)) addScopeVariable(Scope, RegVar); if (AbsVar) AbsVar->setMInsn(MInsn); @@ -1444,6 +1438,8 @@ MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) { // Process beginning of an instruction. void DwarfDebug::beginInstruction(const MachineInstr *MI) { + assert(CurMI == 0); + CurMI = MI; // Check if source location changes, but ignore DBG_VALUE locations. if (!MI->isDebugValue()) { DebugLoc DL = MI->getDebugLoc(); @@ -1485,14 +1481,16 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { } // Process end of an instruction. -void DwarfDebug::endInstruction(const MachineInstr *MI) { +void DwarfDebug::endInstruction() { + assert(CurMI != 0); // Don't create a new label after DBG_VALUE instructions. // They don't generate code. - if (!MI->isDebugValue()) + if (!CurMI->isDebugValue()) PrevLabel = 0; DenseMap::iterator I = - LabelsAfterInsn.find(MI); + LabelsAfterInsn.find(CurMI); + CurMI = 0; // No label needed. if (I == LabelsAfterInsn.end()) @@ -1572,6 +1570,7 @@ static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) { // Gather pre-function debug information. Assumes being called immediately // after the function entry point has been emitted. void DwarfDebug::beginFunction(const MachineFunction *MF) { + CurFn = MF; // If there's no debug info for the function we're not going to do anything. if (!MMI->hasDebugInfo()) @@ -1799,8 +1798,19 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { // Gather and emit post-function debug information. void DwarfDebug::endFunction(const MachineFunction *MF) { - if (!MMI->hasDebugInfo() || LScopes.empty()) + // Every beginFunction(MF) call should be followed by an endFunction(MF) call, + // though the beginFunction may not be called at all. + // We should handle both cases. + if (CurFn == 0) + CurFn = MF; + else + assert(CurFn == MF); + assert(CurFn != 0); + + if (!MMI->hasDebugInfo() || LScopes.empty()) { + CurFn = 0; return; + } // Define end label for subprogram. FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()); @@ -1810,7 +1820,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); SmallPtrSet ProcessedVars; - collectVariableInfo(MF, ProcessedVars); + collectVariableInfo(ProcessedVars); LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); @@ -1844,7 +1854,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope); - if (!MF->getTarget().Options.DisableFramePointerElim(*MF)) + if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn)) TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr); // Clear debug info @@ -1860,6 +1870,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); PrevLabel = NULL; + CurFn = 0; } // Register a source line with debug info. Returns the unique label that was @@ -1965,7 +1976,7 @@ void DwarfUnits::computeSizeAndOffsets() { // EndOffset here is CU-relative, after laying out // all of the CU DIE. - unsigned EndOffset = computeSizeAndOffset((*I)->getCUDie(), Offset); + unsigned EndOffset = computeSizeAndOffset((*I)->getUnitDie(), Offset); SecOffset += EndOffset; } } @@ -2134,22 +2145,22 @@ void DwarfUnits::emitUnits(DwarfDebug *DD, const MCSection *USection, Asm->OutStreamer.SwitchSection(USection); for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); I != E; ++I) { - Unit *TheCU = *I; - DIE *Die = TheCU->getCUDie(); + Unit *TheU = *I; + DIE *Die = TheU->getUnitDie(); // Emit the compile units header. - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol(USection->getLabelBeginName(), - TheCU->getUniqueID())); + Asm->OutStreamer.EmitLabel( + Asm->GetTempSymbol(USection->getLabelBeginName(), TheU->getUniqueID())); // Emit size of content not including length itself Asm->OutStreamer.AddComment("Length of Unit"); - Asm->EmitInt32(TheCU->getHeaderSize() + Die->getSize()); + Asm->EmitInt32(TheU->getHeaderSize() + Die->getSize()); - TheCU->emitHeader(ASection, ASectionSym); + TheU->emitHeader(ASection, ASectionSym); DD->emitDIE(Die, Abbreviations); Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol(USection->getLabelEndName(), TheCU->getUniqueID())); + Asm->GetTempSymbol(USection->getLabelEndName(), TheU->getUniqueID())); } } @@ -2232,8 +2243,8 @@ void DwarfDebug::emitAccelNames() { for (SmallVectorImpl::const_iterator I = getUnits().begin(), E = getUnits().end(); I != E; ++I) { - Unit *TheCU = *I; - const StringMap > &Names = TheCU->getAccelNames(); + Unit *TheU = *I; + const StringMap > &Names = TheU->getAccelNames(); for (StringMap >::const_iterator GI = Names.begin(), GE = Names.end(); @@ -2265,8 +2276,8 @@ void DwarfDebug::emitAccelObjC() { for (SmallVectorImpl::const_iterator I = getUnits().begin(), E = getUnits().end(); I != E; ++I) { - Unit *TheCU = *I; - const StringMap > &Names = TheCU->getAccelObjC(); + Unit *TheU = *I; + const StringMap > &Names = TheU->getAccelObjC(); for (StringMap >::const_iterator GI = Names.begin(), GE = Names.end(); @@ -2297,9 +2308,9 @@ void DwarfDebug::emitAccelNamespaces() { for (SmallVectorImpl::const_iterator I = getUnits().begin(), E = getUnits().end(); I != E; ++I) { - Unit *TheCU = *I; + Unit *TheU = *I; const StringMap > &Names = - TheCU->getAccelNamespace(); + TheU->getAccelNamespace(); for (StringMap >::const_iterator GI = Names.begin(), GE = Names.end(); @@ -2336,9 +2347,9 @@ void DwarfDebug::emitAccelTypes() { for (SmallVectorImpl::const_iterator I = getUnits().begin(), E = getUnits().end(); I != E; ++I) { - Unit *TheCU = *I; + Unit *TheU = *I; const StringMap > > &Names = - TheCU->getAccelTypes(); + TheU->getAccelTypes(); for (StringMap< std::vector > >::const_iterator GI = Names.begin(), @@ -2433,8 +2444,8 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { for (SmallVectorImpl::const_iterator I = getUnits().begin(), E = getUnits().end(); I != E; ++I) { - Unit *TheCU = *I; - unsigned ID = TheCU->getUniqueID(); + Unit *TheU = *I; + unsigned ID = TheU->getUniqueID(); // Start the dwarf pubnames section. Asm->OutStreamer.SwitchSection(PSec); @@ -2442,7 +2453,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { // Emit a label so we can reference the beginning of this pubname section. if (GnuStyle) Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("gnu_pubnames", TheCU->getUniqueID())); + Asm->GetTempSymbol("gnu_pubnames", TheU->getUniqueID())); // Emit the header. Asm->OutStreamer.AddComment("Length of Public Names Info"); @@ -2464,7 +2475,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { 4); // Emit the pubnames for this compilation unit. - const StringMap &Globals = TheCU->getGlobalNames(); + const StringMap &Globals = TheU->getGlobalNames(); for (StringMap::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { @@ -2475,7 +2486,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { Asm->EmitInt32(Entity->getOffset()); if (GnuStyle) { - dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheCU, Entity); + dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); Asm->OutStreamer.AddComment( Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); @@ -2502,23 +2513,23 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { for (SmallVectorImpl::const_iterator I = getUnits().begin(), E = getUnits().end(); I != E; ++I) { - Unit *TheCU = *I; + Unit *TheU = *I; // Start the dwarf pubtypes section. Asm->OutStreamer.SwitchSection(PSec); // Emit a label so we can reference the beginning of this pubtype section. if (GnuStyle) Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("gnu_pubtypes", TheCU->getUniqueID())); + Asm->GetTempSymbol("gnu_pubtypes", TheU->getUniqueID())); // Emit the header. Asm->OutStreamer.AddComment("Length of Public Types Info"); Asm->EmitLabelDifference( - Asm->GetTempSymbol("pubtypes_end", TheCU->getUniqueID()), - Asm->GetTempSymbol("pubtypes_begin", TheCU->getUniqueID()), 4); + Asm->GetTempSymbol("pubtypes_end", TheU->getUniqueID()), + Asm->GetTempSymbol("pubtypes_begin", TheU->getUniqueID()), 4); Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("pubtypes_begin", TheCU->getUniqueID())); + Asm->GetTempSymbol("pubtypes_begin", TheU->getUniqueID())); if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version"); @@ -2526,16 +2537,16 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { Asm->OutStreamer.AddComment("Offset of Compilation Unit Info"); Asm->EmitSectionOffset( - Asm->GetTempSymbol(ISec->getLabelBeginName(), TheCU->getUniqueID()), + Asm->GetTempSymbol(ISec->getLabelBeginName(), TheU->getUniqueID()), DwarfInfoSectionSym); Asm->OutStreamer.AddComment("Compilation Unit Length"); Asm->EmitLabelDifference( - Asm->GetTempSymbol(ISec->getLabelEndName(), TheCU->getUniqueID()), - Asm->GetTempSymbol(ISec->getLabelBeginName(), TheCU->getUniqueID()), 4); + Asm->GetTempSymbol(ISec->getLabelEndName(), TheU->getUniqueID()), + Asm->GetTempSymbol(ISec->getLabelBeginName(), TheU->getUniqueID()), 4); // Emit the pubtypes. - const StringMap &Globals = TheCU->getGlobalTypes(); + const StringMap &Globals = TheU->getGlobalTypes(); for (StringMap::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { @@ -2547,7 +2558,7 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { Asm->EmitInt32(Entity->getOffset()); if (GnuStyle) { - dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheCU, Entity); + dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); Asm->OutStreamer.AddComment( Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); @@ -2564,7 +2575,7 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { Asm->OutStreamer.AddComment("End Mark"); Asm->EmitInt32(0); Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("pubtypes_end", TheCU->getUniqueID())); + Asm->GetTempSymbol("pubtypes_end", TheU->getUniqueID())); } } @@ -2922,18 +2933,51 @@ void DwarfDebug::emitDebugRanges() { // Start the dwarf ranges section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfRangesSection()); + + // Size for our labels. unsigned char Size = Asm->getDataLayout().getPointerSize(); - for (uint32_t i = 0, e = DebugRangeSymbols.size(); i < e; ++i) { - // Only emit a symbol for every range pair for now. - // FIXME: Make this per range list. - if ((i % 2) == 0) - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_ranges", i)); - - const MCSymbol *I = DebugRangeSymbols[i]; - if (I) - Asm->OutStreamer.EmitSymbolValue(I, Size); - else + + // Grab the specific ranges for the compile units in the module. + for (DenseMap::iterator I = CUMap.begin(), + E = CUMap.end(); + I != E; ++I) { + CompileUnit *TheCU = I->second; + unsigned ID = TheCU->getUniqueID(); + + // Emit a symbol so we can find the beginning of our ranges. + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("gnu_ranges", ID)); + + // Iterate over the misc ranges for the compile units in the module. + const SmallVectorImpl &RangeLists = TheCU->getRangeLists(); + for (SmallVectorImpl::const_iterator + I = RangeLists.begin(), + E = RangeLists.end(); + I != E; ++I) { + RangeSpanList *List = *I; + + // Emit a symbol so we can find the beginning of the range. + Asm->OutStreamer.EmitLabel( + Asm->GetTempSymbol("debug_ranges", List->getIndex())); + + for (SmallVectorImpl::const_iterator + I = List->getRanges().begin(), + E = List->getRanges().end(); + I != E; ++I) { + RangeSpan Range = *I; + // We occasionally have ranges without begin/end labels. + // FIXME: Verify and fix. + const MCSymbol *Begin = Range.getStart(); + const MCSymbol *End = Range.getEnd(); + Begin ? Asm->OutStreamer.EmitSymbolValue(Begin, Size) + : Asm->OutStreamer.EmitIntValue(0, Size); + End ? Asm->OutStreamer.EmitSymbolValue(End, Size) + : Asm->OutStreamer.EmitIntValue(0, Size); + } + + // And terminate the list with two 0 values. + Asm->OutStreamer.EmitIntValue(0, Size); Asm->OutStreamer.EmitIntValue(0, Size); + } } } @@ -3007,14 +3051,17 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { DwarfGnuPubTypesSectionSym); } - // Flag if we've emitted any ranges and their location for the compile unit. - if (DebugRangeSymbols.size()) { + // Attribute if we've emitted any ranges and their location for the compile unit. + if (CU->getRangeLists().size()) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base, - DwarfDebugRangeSectionSym); + NewCU->addSectionLabel( + Die, dwarf::DW_AT_GNU_ranges_base, + Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID())); else - NewCU->addUInt(Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4, - 0); + NewCU->addSectionDelta( + Die, dwarf::DW_AT_GNU_ranges_base, + Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID()), + DwarfDebugRangeSectionSym); } SkeletonHolder.addUnit(NewCU);