X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp;h=1c6d1a760d377e0c1d6bcb567cd43159c73f7716;hb=ef953d6399f396b129417e1cdadcd6dc53b9a0ec;hp=04bdfe7ae8dfd7037d148156510a52b8d435d5b2;hpb=c6a2cbbacb5c95efb1171636bba849d99937366e;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 04bdfe7ae8d..45a90dc12d7 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "dwarfdebug" +#include "ByteStreamer.h" #include "DwarfDebug.h" #include "DIE.h" #include "DIEHash.h" @@ -23,12 +24,13 @@ #include "llvm/ADT/Triple.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/DIBuilder.h" -#include "llvm/DebugInfo.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" @@ -38,10 +40,10 @@ #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" #include "llvm/Support/Path.h" #include "llvm/Support/Timer.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" @@ -58,11 +60,6 @@ static cl::opt UnknownLocations( cl::desc("Make an absence of debug location information explicit."), cl::init(false)); -static cl::opt -GenerateODRHash("generate-odr-hash", cl::Hidden, - cl::desc("Add an ODR hash to external type DIEs."), - cl::init(false)); - static cl::opt GenerateCUHash("generate-cu-hash", cl::Hidden, cl::desc("Add the CU hash as the dwo_id."), cl::init(false)); @@ -72,12 +69,13 @@ GenerateGnuPubSections("generate-gnu-dwarf-pub-sections", cl::Hidden, cl::desc("Generate GNU-style pubnames and pubtypes"), cl::init(false)); +static cl::opt GenerateARangeSection("generate-arange-section", + cl::Hidden, + cl::desc("Generate dwarf aranges"), + cl::init(false)); + namespace { -enum DefaultOnOff { - Default, - Enable, - Disable -}; +enum DefaultOnOff { Default, Enable, Disable }; } static cl::opt @@ -90,7 +88,7 @@ DwarfAccelTables("dwarf-accel-tables", cl::Hidden, static cl::opt SplitDwarf("split-dwarf", cl::Hidden, - cl::desc("Output prototype dwarf split debug info."), + cl::desc("Output DWARF5 split debug info."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled"), clEnumValEnd), @@ -106,18 +104,18 @@ DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden, static cl::opt DwarfVersionNumber("dwarf-version", cl::Hidden, - cl::desc("Generate DWARF for dwarf version."), - cl::init(0)); + cl::desc("Generate DWARF for dwarf version."), cl::init(0)); + +static cl::opt +DwarfCURanges("generate-dwarf-cu-ranges", cl::Hidden, + cl::desc("Generate DW_AT_ranges for compile units"), + cl::init(false)); static const char *const DWARFGroupName = "DWARF Emission"; static const char *const DbgTimerName = "DWARF Debug Writer"; //===----------------------------------------------------------------------===// -// Configuration values for initial hash set sizes (log2). -// -static const unsigned InitAbbreviationsSetSize = 9; // log2(512) - namespace llvm { /// resolve - Look in the DwarfDebug map for the MDNode that @@ -182,22 +180,19 @@ static unsigned getDwarfVersionFromModule(const Module *M) { } DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) - : Asm(A), MMI(Asm->MMI), FirstCU(0), - AbbreviationsSet(InitAbbreviationsSetSize), - SourceIdMap(DIEValueAllocator), PrevLabel(NULL), GlobalCUIndexCount(0), - GlobalRangeCount(0), InfoHolder(A, &AbbreviationsSet, Abbreviations, - "info_string", DIEValueAllocator), - SkeletonAbbrevSet(InitAbbreviationsSetSize), - SkeletonHolder(A, &SkeletonAbbrevSet, SkeletonAbbrevs, "skel_string", - DIEValueAllocator) { - - DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; - DwarfStrSectionSym = TextSectionSym = 0; + : Asm(A), MMI(Asm->MMI), FirstCU(0), SourceIdMap(DIEValueAllocator), + PrevLabel(NULL), GlobalRangeCount(0), + InfoHolder(A, "info_string", DIEValueAllocator), HasCURanges(false), + UsedNonDefaultText(false), + SkeletonHolder(A, "skel_string", DIEValueAllocator) { + + DwarfInfoSectionSym = DwarfAbbrevSectionSym = DwarfStrSectionSym = 0; DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = DwarfLineSectionSym = 0; DwarfAddrSectionSym = 0; DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0; FunctionBeginSym = FunctionEndSym = 0; - CurFn = 0; CurMI = 0; + CurFn = 0; + CurMI = 0; // Turn on accelerator tables for Darwin by default, pubnames by // default for non-Darwin, and handle split dwarf. @@ -241,17 +236,16 @@ static MCSymbol *emitSectionSym(AsmPrinter *Asm, const MCSection *Section, return TmpSym; } -DwarfUnits::~DwarfUnits() { - for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); I != E; - ++I) - delete *I; +DwarfFile::~DwarfFile() { + for (DwarfUnit *DU : CUs) + delete DU; } -MCSymbol *DwarfUnits::getStringPoolSym() { +MCSymbol *DwarfFile::getStringPoolSym() { return Asm->GetTempSymbol(StringPref); } -MCSymbol *DwarfUnits::getStringPoolEntry(StringRef Str) { +MCSymbol *DwarfFile::getStringPoolEntry(StringRef Str) { std::pair &Entry = StringPool.GetOrCreateValue(Str).getValue(); if (Entry.first) @@ -261,7 +255,7 @@ MCSymbol *DwarfUnits::getStringPoolEntry(StringRef Str) { return Entry.first = Asm->GetTempSymbol(StringPref, Entry.second); } -unsigned DwarfUnits::getStringPoolIndex(StringRef Str) { +unsigned DwarfFile::getStringPoolIndex(StringRef Str) { std::pair &Entry = StringPool.GetOrCreateValue(Str).getValue(); if (Entry.first) @@ -272,23 +266,19 @@ unsigned DwarfUnits::getStringPoolIndex(StringRef Str) { return Entry.second; } -unsigned DwarfUnits::getAddrPoolIndex(const MCSymbol *Sym) { - return getAddrPoolIndex(MCSymbolRefExpr::Create(Sym, Asm->OutContext)); -} - -unsigned DwarfUnits::getAddrPoolIndex(const MCExpr *Sym) { - std::pair::iterator, bool> P = - AddressPool.insert(std::make_pair(Sym, NextAddrPoolNumber)); +unsigned DwarfFile::getAddrPoolIndex(const MCSymbol *Sym, bool TLS) { + std::pair P = AddressPool.insert( + std::make_pair(Sym, AddressPoolEntry(NextAddrPoolNumber, TLS))); if (P.second) ++NextAddrPoolNumber; - return P.first->second; + return P.first->second.Number; } // Define a unique number for the abbreviation. // -void DwarfUnits::assignAbbrevNumber(DIEAbbrev &Abbrev) { +void DwarfFile::assignAbbrevNumber(DIEAbbrev &Abbrev) { // Check the set for priors. - DIEAbbrev *InSet = AbbreviationsSet->GetOrInsertNode(&Abbrev); + DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev); // If it's newly added. if (InSet == &Abbrev) { @@ -342,7 +332,7 @@ 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 *TheU, DISubprogram SP, DIE *Die) { +static void addSubprogramNames(DwarfUnit *TheU, DISubprogram SP, DIE *Die) { if (!SP.isDefinition()) return; TheU->addAccelName(SP.getName(), Die); @@ -381,7 +371,8 @@ bool DwarfDebug::isSubprogramContext(const MDNode *Context) { // Find DIE for the given subprogram and attach appropriate DW_AT_low_pc // and DW_AT_high_pc attributes. If there are global variables in this // scope then create and insert DIEs for these variables. -DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { +DIE *DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit *SPCU, + DISubprogram SP) { DIE *SPDie = SPCU->getDIE(SP); assert(SPDie && "Unable to find subprogram DIE!"); @@ -412,16 +403,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { DIArray Args = SPTy.getTypeArray(); uint16_t SPTag = SPTy.getTag(); if (SPTag == dwarf::DW_TAG_subroutine_type) - for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { - DIE *Arg = - SPCU->createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie); - DIType ATy(Args.getElement(i)); - SPCU->addType(Arg, ATy); - if (ATy.isArtificial()) - SPCU->addFlag(Arg, dwarf::DW_AT_artificial); - if (ATy.isObjectPointer()) - SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg); - } + SPCU->constructSubprogramArguments(*SPDie, Args); DIE *SPDeclDie = SPDie; SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getUnitDie()); @@ -430,11 +412,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) { } } - 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); + attachLowHighPC(SPCU, SPDie, FunctionBeginSym, FunctionEndSym); const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); MachineLocation Location(RI->getFrameRegister(*Asm->MF)); @@ -468,28 +446,36 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { return !End; } -void DwarfDebug::addScopeRangeList(CompileUnit *TheCU, DIE *ScopeDIE, +static void addSectionLabel(AsmPrinter *Asm, DwarfUnit *U, DIE *D, + dwarf::Attribute A, const MCSymbol *L, + const MCSymbol *Sec) { + if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) + U->addSectionLabel(D, A, L); + else + U->addSectionDelta(D, A, L, Sec); +} + +void DwarfDebug::addScopeRangeList(DwarfCompileUnit *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); + MCSymbol *RangeSym = Asm->GetTempSymbol("debug_ranges", GlobalRangeCount++); + addSectionLabel(Asm, TheCU, ScopeDIE, dwarf::DW_AT_ranges, RangeSym, + DwarfDebugRangeSectionSym); + + RangeSpanList List(RangeSym); + for (const InsnRange &R : Range) { + RangeSpan Span(getLabelBeforeInsn(R.first), getLabelAfterInsn(R.second)); + List.addRange(std::move(Span)); } // Add the range list to the set of ranges to be emitted. - TheCU->addRangeList(List); + TheCU->addRangeList(std::move(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, +DIE *DwarfDebug::constructLexicalScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope) { if (isLexicalScopeDIENull(Scope)) return 0; @@ -515,18 +501,17 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, assert(Start->isDefined() && "Invalid starting label for an inlined scope!"); assert(End->isDefined() && "Invalid end label for an inlined scope!"); - TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_low_pc, Start); - TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_high_pc, End); + attachLowHighPC(TheCU, ScopeDIE, Start, End); return ScopeDIE; } // This scope represents inlined body of a function. Construct DIE to // represent this concrete inlined copy of the function. -DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, +DIE *DwarfDebug::constructInlinedScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope) { const SmallVectorImpl &ScopeRanges = Scope->getRanges(); - assert(ScopeRanges.empty() == false && + assert(!ScopeRanges.empty() && "LexicalScope does not have instruction markers!"); if (!Scope->getScopeNode()) @@ -557,8 +542,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, "Invalid starting label for an inlined scope!"); assert(EndLabel->isDefined() && "Invalid end label for an inlined scope!"); - TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_low_pc, StartLabel); - TheCU->addLabelAddress(ScopeDIE, dwarf::DW_AT_high_pc, EndLabel); + attachLowHighPC(TheCU, ScopeDIE, StartLabel, EndLabel); } InlinedSubprogramDIEs.insert(OriginDIE); @@ -577,14 +561,15 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, return ScopeDIE; } -DIE *DwarfDebug::createScopeChildrenDIE(CompileUnit *TheCU, LexicalScope *Scope, +DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit *TheCU, + LexicalScope *Scope, SmallVectorImpl &Children) { DIE *ObjectPointer = NULL; // Collect arguments for current function. - if (LScopes.isCurrentFunctionScope(Scope)) - for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i) - if (DbgVariable *ArgDV = CurrentFnArguments[i]) + if (LScopes.isCurrentFunctionScope(Scope)) { + for (DbgVariable *ArgDV : CurrentFnArguments) + if (ArgDV) if (DIE *Arg = TheCU->constructVariableDIE(*ArgDV, Scope->isAbstractScope())) { Children.push_back(Arg); @@ -592,25 +577,33 @@ DIE *DwarfDebug::createScopeChildrenDIE(CompileUnit *TheCU, LexicalScope *Scope, ObjectPointer = Arg; } + // If this is a variadic function, add an unspecified parameter. + DISubprogram SP(Scope->getScopeNode()); + DIArray FnArgs = SP.getType().getTypeArray(); + if (FnArgs.getElement(FnArgs.getNumElements() - 1) + .isUnspecifiedParameter()) { + DIE *Ellipsis = new DIE(dwarf::DW_TAG_unspecified_parameters); + Children.push_back(Ellipsis); + } + } + // Collect lexical scope children first. - const SmallVectorImpl &Variables = - ScopeVariables.lookup(Scope); - for (unsigned i = 0, N = Variables.size(); i < N; ++i) - if (DIE *Variable = TheCU->constructVariableDIE(*Variables[i], + for (DbgVariable *DV : ScopeVariables.lookup(Scope)) + if (DIE *Variable = TheCU->constructVariableDIE(*DV, Scope->isAbstractScope())) { Children.push_back(Variable); - if (Variables[i]->isObjectPointer()) + if (DV->isObjectPointer()) ObjectPointer = Variable; } - const SmallVectorImpl &Scopes = Scope->getChildren(); - for (unsigned j = 0, M = Scopes.size(); j < M; ++j) - if (DIE *Nested = constructScopeDIE(TheCU, Scopes[j])) + for (LexicalScope *LS : Scope->getChildren()) + if (DIE *Nested = constructScopeDIE(TheCU, LS)) Children.push_back(Nested); return ObjectPointer; } // Construct a DIE for this scope. -DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { +DIE *DwarfDebug::constructScopeDIE(DwarfCompileUnit *TheCU, + LexicalScope *Scope) { if (!Scope || !Scope->getScopeNode()) return NULL; @@ -672,10 +665,8 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children); // Add children - for (SmallVectorImpl::iterator I = Children.begin(), - E = Children.end(); - I != E; ++I) - ScopeDIE->addChild(*I); + for (DIE *I : Children) + ScopeDIE->addChild(I); if (DS.isSubprogram() && ObjectPointer != NULL) TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, ObjectPointer); @@ -689,12 +680,12 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { // as well. unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, StringRef DirName, unsigned CUID) { - // If we use .loc in assembly, we can't separate .file entries according to + // If we print assembly, we can't separate .file entries according to // compile units. Thus all files will belong to the default compile unit. // FIXME: add a better feature test than hasRawTextSupport. Even better, // extend .file to support this. - if (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport()) + if (Asm->OutStreamer.hasRawTextSupport()) CUID = 0; // If FE did not provide a file name, then assume stdin. @@ -727,88 +718,40 @@ unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, StringRef DirName, return SrcId; } -// Create new CompileUnit for the given metadata node with tag +void DwarfDebug::addGnuPubAttributes(DwarfUnit *U, DIE *D) const { + if (!GenerateGnuPubSections) + return; + + U->addFlag(D, dwarf::DW_AT_GNU_pubnames); +} + +// Create new DwarfCompileUnit for the given metadata node with tag // DW_TAG_compile_unit. -CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { +DwarfCompileUnit *DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) { StringRef FN = DIUnit.getFilename(); CompilationDir = DIUnit.getDirectory(); DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); - CompileUnit *NewCU = new CompileUnit(GlobalCUIndexCount++, Die, DIUnit, Asm, - this, &InfoHolder); + DwarfCompileUnit *NewCU = new DwarfCompileUnit( + InfoHolder.getUnits().size(), Die, DIUnit, Asm, this, &InfoHolder); + InfoHolder.addUnit(NewCU); FileIDCUMap[NewCU->getUniqueID()] = 0; - // Call this to emit a .file directive if it wasn't emitted for the source - // file this CU comes from yet. - getOrCreateSourceID(FN, CompilationDir, NewCU->getUniqueID()); NewCU->addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer()); NewCU->addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2, 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. We're using 0 (or a NULL label) for this. For - // split dwarf it's in the skeleton CU so omit it here. - if (!useSplitDwarf()) - 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()); - - // Use a single line table if we are using .loc and generating assembly. - bool UseTheFirstCU = - (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport()) || - (NewCU->getUniqueID() == 0); - if (!useSplitDwarf()) { - // DW_AT_stmt_list is a offset of line number information for this - // compile unit in debug_line section. For split dwarf this is - // left in the skeleton CU and so not included. - // 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->addSectionLabel( - Die, dwarf::DW_AT_stmt_list, - UseTheFirstCU ? Asm->GetTempSymbol("section_line") - : LineTableStartSym); - else if (UseTheFirstCU) - NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0); - else - NewCU->addSectionDelta(Die, dwarf::DW_AT_stmt_list, - LineTableStartSym, DwarfLineSectionSym); + NewCU->initStmtList(DwarfLineSectionSym); // If we're using split dwarf the compilation dir is going to be in the // skeleton CU and so we don't need to duplicate it here. if (!CompilationDir.empty()) NewCU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir); - // Flags to let the linker know we have emitted new style pubnames. Only - // emit it here if we don't have a skeleton CU for split dwarf. - if (GenerateGnuPubSections) { - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addSectionLabel( - Die, dwarf::DW_AT_GNU_pubnames, - Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID())); - else - NewCU->addSectionDelta( - Die, dwarf::DW_AT_GNU_pubnames, - Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()), - DwarfGnuPubNamesSectionSym); - - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addSectionLabel( - Die, dwarf::DW_AT_GNU_pubtypes, - Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID())); - else - NewCU->addSectionDelta( - Die, dwarf::DW_AT_GNU_pubtypes, - Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()), - DwarfGnuPubTypesSectionSym); - } + addGnuPubAttributes(NewCU, Die); } if (DIUnit.isOptimized()) @@ -825,7 +768,13 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { if (!FirstCU) FirstCU = NewCU; - InfoHolder.addUnit(NewCU); + if (useSplitDwarf()) { + NewCU->initSection(Asm->getObjFileLowering().getDwarfInfoDWOSection(), + DwarfInfoDWOSectionSym); + NewCU->setSkeleton(constructSkeletonCU(NewCU)); + } else + NewCU->initSection(Asm->getObjFileLowering().getDwarfInfoSection(), + DwarfInfoSectionSym); CUMap.insert(std::make_pair(DIUnit, NewCU)); CUDieMap.insert(std::make_pair(Die, NewCU)); @@ -833,12 +782,13 @@ CompileUnit *DwarfDebug::constructCompileUnit(DICompileUnit DIUnit) { } // Construct subprogram DIE. -void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N) { +void DwarfDebug::constructSubprogramDIE(DwarfCompileUnit *TheCU, + const MDNode *N) { // FIXME: We should only call this routine once, however, during LTO if a // program is defined in multiple CUs we could end up calling it out of // beginModule as we walk the CUs. - CompileUnit *&CURef = SPMap[N]; + DwarfCompileUnit *&CURef = SPMap[N]; if (CURef) return; CURef = TheCU; @@ -855,24 +805,22 @@ void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N) { TheCU->addGlobalName(SP.getName(), SubprogramDie, resolve(SP.getContext())); } -void DwarfDebug::constructImportedEntityDIE(CompileUnit *TheCU, +void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU, const MDNode *N) { DIImportedEntity Module(N); - if (!Module.Verify()) - return; + assert(Module.Verify()); if (DIE *D = TheCU->getOrCreateContextDIE(Module.getContext())) constructImportedEntityDIE(TheCU, Module, D); } -void DwarfDebug::constructImportedEntityDIE(CompileUnit *TheCU, const MDNode *N, - DIE *Context) { +void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU, + const MDNode *N, DIE *Context) { DIImportedEntity Module(N); - if (!Module.Verify()) - return; + assert(Module.Verify()); return constructImportedEntityDIE(TheCU, Module, Context); } -void DwarfDebug::constructImportedEntityDIE(CompileUnit *TheCU, +void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU, const DIImportedEntity &Module, DIE *Context) { assert(Module.Verify() && @@ -921,9 +869,9 @@ void DwarfDebug::beginModule() { // 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); + for (MDNode *N : CU_Nodes->operands()) { + DICompileUnit CUNode(N); + DwarfCompileUnit *CU = constructDwarfCompileUnit(CUNode); DIArray ImportedEntities = CUNode.getImportedEntities(); for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i) ScopesWithImportedEntities.push_back(std::make_pair( @@ -959,16 +907,11 @@ void DwarfDebug::beginModule() { // Attach DW_AT_inline attribute with inlined subprogram DIEs. void DwarfDebug::computeInlinedDIEs() { // Attach DW_AT_inline attribute with inlined subprogram DIEs. - for (SmallPtrSet::iterator AI = InlinedSubprogramDIEs.begin(), - AE = InlinedSubprogramDIEs.end(); - AI != AE; ++AI) { - DIE *ISP = *AI; + for (DIE *ISP : InlinedSubprogramDIEs) FirstCU->addUInt(ISP, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); - } - for (DenseMap::iterator AI = AbstractSPDies.begin(), - AE = AbstractSPDies.end(); - AI != AE; ++AI) { - DIE *ISP = AI->second; + + for (const auto &AI : AbstractSPDies) { + DIE *ISP = AI.second; if (InlinedSubprogramDIEs.count(ISP)) continue; FirstCU->addUInt(ISP, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); @@ -980,8 +923,8 @@ void DwarfDebug::collectDeadVariables() { const Module *M = MMI->getModule(); if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) { - for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { - DICompileUnit TheCU(CU_Nodes->getOperand(i)); + for (MDNode *N : CU_Nodes->operands()) { + DICompileUnit TheCU(N); DIArray Subprograms = TheCU.getSubprograms(); for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) { DISubprogram SP(Subprograms.getElement(i)); @@ -996,7 +939,8 @@ void DwarfDebug::collectDeadVariables() { continue; // Construct subprogram DIE and add variables DIEs. - CompileUnit *SPCU = static_cast(CUMap.lookup(TheCU)); + DwarfCompileUnit *SPCU = + static_cast(CUMap.lookup(TheCU)); assert(SPCU && "Unable to find Compile Unit!"); // FIXME: See the comment in constructSubprogramDIE about duplicate // subprogram DIEs. @@ -1015,41 +959,6 @@ void DwarfDebug::collectDeadVariables() { } } -// Type Signature [7.27] and ODR Hash code. - -/// \brief Grabs the string in whichever attribute is passed in and returns -/// a reference to it. Returns "" if the attribute doesn't exist. -static StringRef getDIEStringAttr(DIE *Die, unsigned Attr) { - DIEValue *V = Die->findAttribute(Attr); - - if (DIEString *S = dyn_cast_or_null(V)) - return S->getString(); - - return StringRef(""); -} - -/// Return true if the current DIE is contained within an anonymous namespace. -static bool isContainedInAnonNamespace(DIE *Die) { - DIE *Parent = Die->getParent(); - - while (Parent) { - if (Parent->getTag() == dwarf::DW_TAG_namespace && - getDIEStringAttr(Parent, dwarf::DW_AT_name) == "") - return true; - Parent = Parent->getParent(); - } - - return false; -} - -/// Test if the current CU language is C++ and that we have -/// a named type that is not contained in an anonymous namespace. -static bool shouldAddODRHash(TypeUnit *CU, DIE *Die) { - return CU->getLanguage() == dwarf::DW_LANG_C_plus_plus && - getDIEStringAttr(Die, dwarf::DW_AT_name) != "" && - !isContainedInAnonNamespace(Die); -} - void DwarfDebug::finalizeModuleInfo() { // Collect info for variables that were optimized out. collectDeadVariables(); @@ -1057,32 +966,52 @@ void DwarfDebug::finalizeModuleInfo() { // Attach DW_AT_inline attribute with inlined subprogram DIEs. computeInlinedDIEs(); - // Handle anything that needs to be done on a per-cu basis. - for (SmallVectorImpl::const_iterator I = getUnits().begin(), - E = getUnits().end(); - I != E; ++I) { - Unit *TheU = *I; + // Handle anything that needs to be done on a per-unit basis after + // all other generation. + for (DwarfUnit *TheU : getUnits()) { // Emit DW_AT_containing_type attribute to connect types with their // vtable holding type. 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() && - TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) { - uint64_t ID = 0; - if (GenerateCUHash) { - DIEHash CUHash; - ID = CUHash.computeCUSignature(*TheU->getUnitDie()); + // Add CU specific attributes if we need to add any. + if (TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) { + // If we're splitting the dwarf out now that we've got the entire + // CU then add the dwo id to it. + DwarfCompileUnit *SkCU = + static_cast(TheU->getSkeleton()); + if (useSplitDwarf()) { + // This should be a unique identifier when we want to build .dwp files. + uint64_t ID = 0; + if (GenerateCUHash) { + DIEHash CUHash(Asm); + ID = CUHash.computeCUSignature(*TheU->getUnitDie()); + } + TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); } - // This should be a unique identifier when we want to build .dwp files. - 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(TheU)); - // This should be a unique identifier when we want to build .dwp files. - SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, - dwarf::DW_FORM_data8, ID); + + // If we have code split among multiple sections or we've requested + // it then emit a DW_AT_ranges attribute on the unit that will remain + // in the .o file, otherwise add a DW_AT_low_pc. + // FIXME: Also add a high pc if we can. + // FIXME: We should use ranges if we have multiple compile units or + // allow reordering of code ala .subsections_via_symbols in mach-o. + DwarfCompileUnit *U = SkCU ? SkCU : static_cast(TheU); + if (useCURanges() && TheU->getRanges().size()) { + addSectionLabel(Asm, U, U->getUnitDie(), dwarf::DW_AT_ranges, + Asm->GetTempSymbol("cu_ranges", U->getUniqueID()), + DwarfDebugRangeSectionSym); + + // A DW_AT_low_pc attribute may also be specified in combination with + // DW_AT_ranges to specify the default base address for use in location + // lists (see Section 2.6.2) and range lists (see Section 2.17.3). + U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + 0); + } else + U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + 0); } } @@ -1094,8 +1023,7 @@ void DwarfDebug::finalizeModuleInfo() { void DwarfDebug::endSections() { // Filter labels by section. - for (size_t n = 0; n < ArangeLabels.size(); n++) { - const SymbolCU &SCU = ArangeLabels[n]; + for (const SymbolCU &SCU : ArangeLabels) { if (SCU.Sym->isInSection()) { // Make a note of this symbol and it's section. const MCSection *Section = &SCU.Sym->getSection(); @@ -1111,9 +1039,8 @@ void DwarfDebug::endSections() { // Build a list of sections used. std::vector Sections; - for (SectionMapType::iterator it = SectionMap.begin(); it != SectionMap.end(); - it++) { - const MCSection *Section = it->first; + for (const auto &it : SectionMap) { + const MCSection *Section = it.first; Sections.push_back(Section); } @@ -1122,17 +1049,15 @@ void DwarfDebug::endSections() { std::sort(Sections.begin(), Sections.end(), SectionSort); // Add terminating symbols for each section. - for (unsigned ID = 0; ID < Sections.size(); ID++) { + for (unsigned ID = 0, E = Sections.size(); ID != E; ID++) { const MCSection *Section = Sections[ID]; MCSymbol *Sym = NULL; if (Section) { // We can't call MCSection::getLabelEndName, as it's only safe to do so // if we know the section name up-front. For user-created sections, the - // resulting - // label may not be valid to use as a label. (section names can use a - // greater - // set of characters on some systems) + // resulting label may not be valid to use as a label. (section names can + // use a greater set of characters on some systems) Sym = Asm->GetTempSymbol("debug_end", ID); Asm->OutStreamer.SwitchSection(Section); Asm->OutStreamer.EmitLabel(Sym); @@ -1141,11 +1066,21 @@ void DwarfDebug::endSections() { // Insert a final terminator. SectionMap[Section].push_back(SymbolCU(NULL, Sym)); } + + // For now only turn on CU ranges if we've explicitly asked for it, + // we have -ffunction-sections enabled, we've emitted a function + // into a unique section, or we're using LTO. If we're using LTO then + // we can't know that any particular function in the module is correlated + // to a particular CU and so we need to be conservative. At this point all + // sections should be finalized except for dwarf sections. + HasCURanges = DwarfCURanges || UsedNonDefaultText || (CUMap.size() > 1) || + TargetMachine::getFunctionSections(); } // Emit all Dwarf sections that should come after the content. void DwarfDebug::endModule() { assert(CurFn == 0); + assert(CurMI == 0); if (!FirstCU) return; @@ -1169,14 +1104,12 @@ void DwarfDebug::endModule() { emitDebugLoc(); // Emit info into a debug aranges section. - emitDebugARanges(); + if (GenerateARangeSection) + emitDebugARanges(); // Emit info into a debug ranges section. emitDebugRanges(); - // Emit info into a debug macinfo section. - emitDebugMacInfo(); - if (useSplitDwarf()) { emitDebugStrDWO(); emitDebugInfoDWO(); @@ -1251,30 +1184,24 @@ bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) { // Collect variable information from side table maintained by MMI. void DwarfDebug::collectVariableInfoFromMMITable( SmallPtrSet &Processed) { - MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo(); - for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(), - VE = VMap.end(); - VI != VE; ++VI) { - const MDNode *Var = VI->first; - if (!Var) + for (const auto &VI : MMI->getVariableDbgInfo()) { + if (!VI.Var) continue; - Processed.insert(Var); - DIVariable DV(Var); - const std::pair &VP = VI->second; - - LexicalScope *Scope = LScopes.findLexicalScope(VP.second); + Processed.insert(VI.Var); + DIVariable DV(VI.Var); + LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc); // If variable scope is not found then skip this variable. if (Scope == 0) continue; - DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second); + DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VI.Loc); DbgVariable *RegVar = new DbgVariable(DV, AbsDbgVariable, this); - RegVar->setFrameIndex(VP.first); + RegVar->setFrameIndex(VI.Slot); if (!addCurrentFnArgument(RegVar, Scope)) addScopeVariable(Scope, RegVar); if (AbsDbgVariable) - AbsDbgVariable->setFrameIndex(VP.first); + AbsDbgVariable->setFrameIndex(VI.Slot); } } @@ -1323,11 +1250,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSet &Processed) { // Grab the variable info that was squirreled away in the MMI side-table. collectVariableInfoFromMMITable(Processed); - for (SmallVectorImpl::const_iterator - UVI = UserVariables.begin(), - UVE = UserVariables.end(); - UVI != UVE; ++UVI) { - const MDNode *Var = *UVI; + for (const MDNode *Var : UserVariables) { if (Processed.count(Var)) continue; @@ -1519,53 +1442,20 @@ void DwarfDebug::identifyScopeMarkers() { const SmallVectorImpl &Children = S->getChildren(); if (!Children.empty()) - for (SmallVectorImpl::const_iterator - SI = Children.begin(), - SE = Children.end(); - SI != SE; ++SI) - WorkList.push_back(*SI); + WorkList.append(Children.begin(), Children.end()); if (S->isAbstractScope()) continue; - const SmallVectorImpl &Ranges = S->getRanges(); - if (Ranges.empty()) - continue; - for (SmallVectorImpl::const_iterator RI = Ranges.begin(), - RE = Ranges.end(); - RI != RE; ++RI) { - assert(RI->first && "InsnRange does not have first instruction!"); - assert(RI->second && "InsnRange does not have second instruction!"); - requestLabelBeforeInsn(RI->first); - requestLabelAfterInsn(RI->second); + for (const InsnRange &R : S->getRanges()) { + assert(R.first && "InsnRange does not have first instruction!"); + assert(R.second && "InsnRange does not have second instruction!"); + requestLabelBeforeInsn(R.first); + requestLabelAfterInsn(R.second); } } } -// Get MDNode for DebugLoc's scope. -static MDNode *getScopeNode(DebugLoc DL, const LLVMContext &Ctx) { - if (MDNode *InlinedAt = DL.getInlinedAt(Ctx)) - return getScopeNode(DebugLoc::getFromDILocation(InlinedAt), Ctx); - return DL.getScope(Ctx); -} - -// Walk up the scope chain of given debug loc and find line number info -// for the function. -static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) { - const MDNode *Scope = getScopeNode(DL, Ctx); - DISubprogram SP = getDISubprogram(Scope); - if (SP.isSubprogram()) { - // Check for number of operands since the compatibility is - // cheap here. - if (SP->getNumOperands() > 19) - return DebugLoc::get(SP.getScopeLineNumber(), 0, SP); - else - return DebugLoc::get(SP.getLineNumber(), 0, SP); - } - - return DebugLoc(); -} - // Gather pre-function debug information. Assumes being called immediately // after the function entry point has been emitted. void DwarfDebug::beginFunction(const MachineFunction *MF) { @@ -1586,18 +1476,24 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // Make sure that each lexical scope will have a begin/end label. identifyScopeMarkers(); - // Set DwarfCompileUnitID in MCContext to the Compile Unit this function + // Set DwarfDwarfCompileUnitID in MCContext to the Compile Unit this function // belongs to so that we add to the correct per-cu line table in the // non-asm case. LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); - CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); + DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); assert(TheCU && "Unable to find compile unit!"); - if (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport()) - // Use a single line table if we are using .loc and generating assembly. + if (Asm->OutStreamer.hasRawTextSupport()) + // Use a single line table if we are generating assembly. Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); else Asm->OutStreamer.getContext().setDwarfCompileUnitID(TheCU->getUniqueID()); + // Check the current section against the standard text section. If different + // keep track so that we will know when we're emitting functions into multiple + // sections. + if (Asm->getObjFileLowering().getTextSection() != Asm->getCurrentSection()) + UsedNonDefaultText = true; + // Emit a label for the function so that we have a beginning address. FunctionBeginSym = Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()); // Assumes in correct section after the entry point. @@ -1650,7 +1546,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // Terminate old register assignments that don't reach MI; MachineFunction::const_iterator PrevMBB = Prev->getParent(); - if (PrevMBB != I && (!AtBlockEntry || llvm::next(PrevMBB) != I) && + if (PrevMBB != I && (!AtBlockEntry || std::next(PrevMBB) != I) && isDbgValueInDefinedReg(Prev)) { // Previous register assignment needs to terminate at the end of // its basic block. @@ -1661,7 +1557,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { DEBUG(dbgs() << "Dropping DBG_VALUE for empty range:\n" << "\t" << *Prev << "\n"); History.pop_back(); - } else if (llvm::next(PrevMBB) != PrevMBB->getParent()->end()) + } else if (std::next(PrevMBB) != PrevMBB->getParent()->end()) // Terminate after LastMI. History.push_back(LastMI); } @@ -1670,7 +1566,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { History.push_back(MI); } else { // Not a DBG_VALUE instruction. - if (!MI->isLabel()) + if (!MI->isPosition()) AtBlockEntry = false; // First known non-DBG_VALUE and non-frame setup location marks @@ -1680,12 +1576,10 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { PrologEndLoc = MI->getDebugLoc(); // Check if the instruction clobbers any registers with debug vars. - for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(), - MOE = MI->operands_end(); - MOI != MOE; ++MOI) { - if (!MOI->isReg() || !MOI->isDef() || !MOI->getReg()) + for (const MachineOperand &MO : MI->operands()) { + if (!MO.isReg() || !MO.isDef() || !MO.getReg()) continue; - for (MCRegAliasIterator AI(MOI->getReg(), TRI, true); AI.isValid(); + for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI) { unsigned Reg = *AI; const MDNode *Var = LiveUserVar[Reg]; @@ -1718,9 +1612,8 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { } } - for (DbgValueHistoryMap::iterator I = DbgValues.begin(), E = DbgValues.end(); - I != E; ++I) { - SmallVectorImpl &History = I->second; + for (auto &I : DbgValues) { + SmallVectorImpl &History = I.second; if (History.empty()) continue; @@ -1739,8 +1632,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { } } // Request labels for the full history. - for (unsigned i = 0, e = History.size(); i != e; ++i) { - const MachineInstr *MI = History[i]; + for (const MachineInstr *MI : History) { if (MI->isDebugValue()) requestLabelBeforeInsn(MI); else @@ -1754,7 +1646,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // Record beginning of function. if (!PrologEndLoc.isUnknown()) { DebugLoc FnStartDL = - getFnDebugLoc(PrologEndLoc, MF->getFunction()->getContext()); + PrologEndLoc.getFnDebugLoc(MF->getFunction()->getContext()); recordSourceLine( FnStartDL.getLine(), FnStartDL.getCol(), FnStartDL.getScope(MF->getFunction()->getContext()), @@ -1796,7 +1688,14 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { } // Gather and emit post-function debug information. -void DwarfDebug::endFunction() { +void DwarfDebug::endFunction(const MachineFunction *MF) { + // 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()) { @@ -1808,20 +1707,19 @@ void DwarfDebug::endFunction() { FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()); // Assumes in correct section after the entry point. Asm->OutStreamer.EmitLabel(FunctionEndSym); - // Set DwarfCompileUnitID in MCContext to default value. + + // Set DwarfDwarfCompileUnitID in MCContext to default value. Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); SmallPtrSet ProcessedVars; collectVariableInfo(ProcessedVars); LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); - CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); + DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); assert(TheCU && "Unable to find compile unit!"); // Construct abstract scopes. - ArrayRef AList = LScopes.getAbstractScopesList(); - for (unsigned i = 0, e = AList.size(); i != e; ++i) { - LexicalScope *AScope = AList[i]; + for (LexicalScope *AScope : LScopes.getAbstractScopesList()) { DISubprogram SP(AScope->getScopeNode()); if (SP.isSubprogram()) { // Collect info for variables that were optimized out. @@ -1845,15 +1743,16 @@ void DwarfDebug::endFunction() { } DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope); - if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn)) TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr); + // Add the range of this function to the list of ranges for the CU. + RangeSpan Span(FunctionBeginSym, FunctionEndSym); + TheCU->addRange(std::move(Span)); + // Clear debug info - for (ScopeVariablesMap::iterator I = ScopeVariables.begin(), - E = ScopeVariables.end(); - I != E; ++I) - DeleteContainerPointers(I->second); + for (auto &I : ScopeVariables) + DeleteContainerPointers(I.second); ScopeVariables.clear(); DeleteContainerPointers(CurrentFnArguments); UserVariables.clear(); @@ -1872,6 +1771,7 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, StringRef Fn; StringRef Dir; unsigned Src = 1; + unsigned Discriminator = 0; if (S) { DIDescriptor Scope(S); @@ -1895,13 +1795,15 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, DILexicalBlock DB(S); Fn = DB.getFilename(); Dir = DB.getDirectory(); + Discriminator = DB.getDiscriminator(); } else llvm_unreachable("Unexpected scope info"); Src = getOrCreateSourceID( Fn, Dir, Asm->OutStreamer.getContext().getDwarfCompileUnitID()); } - Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, Flags, 0, 0, Fn); + Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, Flags, 0, + Discriminator, Fn); } //===----------------------------------------------------------------------===// @@ -1910,38 +1812,36 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, // Compute the size and offset of a DIE. The offset is relative to start of the // CU. It returns the offset after laying out the DIE. -unsigned DwarfUnits::computeSizeAndOffset(DIE *Die, unsigned Offset) { - // Get the children. - const std::vector &Children = Die->getChildren(); - +unsigned DwarfFile::computeSizeAndOffset(DIE *Die, unsigned Offset) { // Record the abbreviation. assignAbbrevNumber(Die->getAbbrev()); // Get the abbreviation for this DIE. - unsigned AbbrevNumber = Die->getAbbrevNumber(); - const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1]; + const DIEAbbrev &Abbrev = Die->getAbbrev(); // Set DIE offset Die->setOffset(Offset); // Start the size with the size of abbreviation code. - Offset += MCAsmInfo::getULEB128Size(AbbrevNumber); + Offset += getULEB128Size(Die->getAbbrevNumber()); const SmallVectorImpl &Values = Die->getValues(); - const SmallVectorImpl &AbbrevData = Abbrev->getData(); + const SmallVectorImpl &AbbrevData = Abbrev.getData(); // Size the DIE attribute values. for (unsigned i = 0, N = Values.size(); i < N; ++i) // Size attribute value. Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm()); + // Get the children. + const std::vector &Children = Die->getChildren(); + // Size the DIE children if any. if (!Children.empty()) { - assert(Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes && - "Children flag not set"); + assert(Abbrev.hasChildren() && "Children flag not set"); - for (unsigned j = 0, M = Children.size(); j < M; ++j) - Offset = computeSizeAndOffset(Children[j], Offset); + for (DIE *Child : Children) + Offset = computeSizeAndOffset(Child, Offset); // End of children marker. Offset += sizeof(int8_t); @@ -1952,23 +1852,22 @@ unsigned DwarfUnits::computeSizeAndOffset(DIE *Die, unsigned Offset) { } // Compute the size and offset for each DIE. -void DwarfUnits::computeSizeAndOffsets() { +void DwarfFile::computeSizeAndOffsets() { // Offset from the first CU in the debug info section is 0 initially. unsigned SecOffset = 0; // Iterate over each compile unit and set the size and offsets for each // DIE within each compile unit. All offsets are CU relative. - for (SmallVectorImpl::const_iterator I = CUs.begin(), E = CUs.end(); - I != E; ++I) { - (*I)->setDebugInfoOffset(SecOffset); + for (DwarfUnit *TheU : CUs) { + TheU->setDebugInfoOffset(SecOffset); // CU-relative offset is reset to 0 here. unsigned Offset = sizeof(int32_t) + // Length of Unit Info - (*I)->getHeaderSize(); // Unit-specific headers + TheU->getHeaderSize(); // Unit-specific headers // EndOffset here is CU-relative, after laying out // all of the CU DIE. - unsigned EndOffset = computeSizeAndOffset((*I)->getUnitDie(), Offset); + unsigned EndOffset = computeSizeAndOffset(TheU->getUnitDie(), Offset); SecOffset += EndOffset; } } @@ -1980,15 +1879,16 @@ void DwarfDebug::emitSectionLabels() { // Dwarf sections base addresses. DwarfInfoSectionSym = emitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info"); + if (useSplitDwarf()) + DwarfInfoDWOSectionSym = + emitSectionSym(Asm, TLOF.getDwarfInfoDWOSection(), "section_info_dwo"); DwarfAbbrevSectionSym = emitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev"); if (useSplitDwarf()) DwarfAbbrevDWOSectionSym = emitSectionSym( Asm, TLOF.getDwarfAbbrevDWOSection(), "section_abbrev_dwo"); - emitSectionSym(Asm, TLOF.getDwarfARangesSection()); - - if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection()) - emitSectionSym(Asm, MacroInfo); + if (GenerateARangeSection) + emitSectionSym(Asm, TLOF.getDwarfARangesSection()); DwarfLineSectionSym = emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line"); @@ -2016,27 +1916,23 @@ void DwarfDebug::emitSectionLabels() { DwarfDebugLocSectionSym = emitSectionSym(Asm, TLOF.getDwarfLocSection(), "section_debug_loc"); - - TextSectionSym = emitSectionSym(Asm, TLOF.getTextSection(), "text_begin"); - emitSectionSym(Asm, TLOF.getDataSection()); } // Recursively emits a debug information entry. -void DwarfDebug::emitDIE(DIE *Die, ArrayRef Abbrevs) { +void DwarfDebug::emitDIE(DIE *Die) { // Get the abbreviation for this DIE. - unsigned AbbrevNumber = Die->getAbbrevNumber(); - const DIEAbbrev *Abbrev = Abbrevs[AbbrevNumber - 1]; + const DIEAbbrev &Abbrev = Die->getAbbrev(); // Emit the code (index) for the abbreviation. if (Asm->isVerbose()) - Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" + - Twine::utohexstr(Die->getOffset()) + ":0x" + - Twine::utohexstr(Die->getSize()) + " " + - dwarf::TagString(Abbrev->getTag())); - Asm->EmitULEB128(AbbrevNumber); + Asm->OutStreamer.AddComment("Abbrev [" + Twine(Abbrev.getNumber()) + + "] 0x" + Twine::utohexstr(Die->getOffset()) + + ":0x" + Twine::utohexstr(Die->getSize()) + " " + + dwarf::TagString(Abbrev.getTag())); + Asm->EmitULEB128(Abbrev.getNumber()); const SmallVectorImpl &Values = Die->getValues(); - const SmallVectorImpl &AbbrevData = Abbrev->getData(); + const SmallVectorImpl &AbbrevData = Abbrev.getData(); // Emit the DIE attribute values. for (unsigned i = 0, N = Values.size(); i < N; ++i) { @@ -2044,105 +1940,40 @@ void DwarfDebug::emitDIE(DIE *Die, ArrayRef Abbrevs) { dwarf::Form Form = AbbrevData[i].getForm(); assert(Form && "Too many attributes for DIE (check abbreviation)"); - if (Asm->isVerbose()) + if (Asm->isVerbose()) { Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr)); - - switch (Attr) { - case dwarf::DW_AT_abstract_origin: - case dwarf::DW_AT_type: - case dwarf::DW_AT_friend: - case dwarf::DW_AT_specification: - case dwarf::DW_AT_import: - case dwarf::DW_AT_containing_type: { - DIEEntry *E = cast(Values[i]); - DIE *Origin = E->getEntry(); - unsigned Addr = Origin->getOffset(); - if (Form == dwarf::DW_FORM_ref_addr) { - assert(!useSplitDwarf() && "TODO: dwo files can't have relocations."); - // For DW_FORM_ref_addr, output the offset from beginning of debug info - // section. Origin->getOffset() returns the offset from start of the - // compile unit. - CompileUnit *CU = CUDieMap.lookup(Origin->getUnit()); - assert(CU && "CUDie should belong to a CU."); - Addr += CU->getDebugInfoOffset(); - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - Asm->EmitLabelPlusOffset(DwarfInfoSectionSym, Addr, - DIEEntry::getRefAddrSize(Asm)); - else - Asm->EmitLabelOffsetDifference(DwarfInfoSectionSym, Addr, - DwarfInfoSectionSym, - DIEEntry::getRefAddrSize(Asm)); - } else { - // Make sure Origin belong to the same CU. - assert(Die->getUnit() == Origin->getUnit() && - "The referenced DIE should belong to the same CU in ref4"); - Asm->EmitInt32(Addr); - } - break; + if (Attr == dwarf::DW_AT_accessibility) + Asm->OutStreamer.AddComment(dwarf::AccessibilityString( + cast(Values[i])->getValue())); } - case dwarf::DW_AT_ranges: { - // DW_AT_range Value encodes offset in debug_range section. - DIELabel *V = cast(Values[i]); - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - Asm->EmitSectionOffset(V->getValue(), DwarfDebugRangeSectionSym); - else - Asm->EmitLabelDifference(V->getValue(), DwarfDebugRangeSectionSym, 4); - break; - } - case dwarf::DW_AT_location: { - if (DIELabel *L = dyn_cast(Values[i])) { - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - Asm->EmitSectionOffset(L->getValue(), DwarfDebugLocSectionSym); - else - Asm->EmitLabelDifference(L->getValue(), DwarfDebugLocSectionSym, 4); - } else { - Values[i]->EmitValue(Asm, Form); - } - break; - } - case dwarf::DW_AT_accessibility: { - if (Asm->isVerbose()) { - DIEInteger *V = cast(Values[i]); - Asm->OutStreamer.AddComment(dwarf::AccessibilityString(V->getValue())); - } - Values[i]->EmitValue(Asm, Form); - break; - } - default: - // Emit an attribute using the defined form. - Values[i]->EmitValue(Asm, Form); - break; - } + // Emit an attribute using the defined form. + Values[i]->EmitValue(Asm, Form); } // Emit the DIE children if any. - if (Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes) { + if (Abbrev.hasChildren()) { const std::vector &Children = Die->getChildren(); - for (unsigned j = 0, M = Children.size(); j < M; ++j) - emitDIE(Children[j], Abbrevs); + for (DIE *Child : Children) + emitDIE(Child); - if (Asm->isVerbose()) - Asm->OutStreamer.AddComment("End Of Children Mark"); + Asm->OutStreamer.AddComment("End Of Children Mark"); Asm->EmitInt8(0); } } // Emit the various dwarf units to the unit section USection with // the abbreviations going into ASection. -void DwarfUnits::emitUnits(DwarfDebug *DD, const MCSection *USection, - const MCSection *ASection, - const MCSymbol *ASectionSym) { - Asm->OutStreamer.SwitchSection(USection); - for (SmallVectorImpl::iterator I = CUs.begin(), E = CUs.end(); I != E; - ++I) { - Unit *TheU = *I; +void DwarfFile::emitUnits(DwarfDebug *DD, const MCSection *ASection, + const MCSymbol *ASectionSym) { + for (DwarfUnit *TheU : CUs) { DIE *Die = TheU->getUnitDie(); + const MCSection *USection = TheU->getSection(); + Asm->OutStreamer.SwitchSection(USection); // Emit the compile units header. - Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol(USection->getLabelBeginName(), TheU->getUniqueID())); + Asm->OutStreamer.EmitLabel(TheU->getLabelBegin()); // Emit size of content not including length itself Asm->OutStreamer.AddComment("Length of Unit"); @@ -2150,45 +1981,34 @@ void DwarfUnits::emitUnits(DwarfDebug *DD, const MCSection *USection, TheU->emitHeader(ASection, ASectionSym); - DD->emitDIE(Die, Abbreviations); - Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol(USection->getLabelEndName(), TheU->getUniqueID())); + DD->emitDIE(Die); + Asm->OutStreamer.EmitLabel(TheU->getLabelEnd()); } } // Emit the debug info section. void DwarfDebug::emitDebugInfo() { - DwarfUnits &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; + DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; - Holder.emitUnits(this, Asm->getObjFileLowering().getDwarfInfoSection(), - Asm->getObjFileLowering().getDwarfAbbrevSection(), + Holder.emitUnits(this, Asm->getObjFileLowering().getDwarfAbbrevSection(), DwarfAbbrevSectionSym); } // Emit the abbreviation section. void DwarfDebug::emitAbbreviations() { - if (!useSplitDwarf()) - emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection(), - &Abbreviations); - else - emitSkeletonAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection()); + DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; + + Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection()); } -void DwarfDebug::emitAbbrevs(const MCSection *Section, - std::vector *Abbrevs) { +void DwarfFile::emitAbbrevs(const MCSection *Section) { // Check to see if it is worth the effort. - if (!Abbrevs->empty()) { + if (!Abbreviations.empty()) { // Start the debug abbrev section. Asm->OutStreamer.SwitchSection(Section); - MCSymbol *Begin = Asm->GetTempSymbol(Section->getLabelBeginName()); - Asm->OutStreamer.EmitLabel(Begin); - // For each abbrevation. - for (unsigned i = 0, N = Abbrevs->size(); i < N; ++i) { - // Get abbreviation data - const DIEAbbrev *Abbrev = Abbrevs->at(i); - + for (const DIEAbbrev *Abbrev : Abbreviations) { // Emit the abbrevations code (base 1 index.) Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code"); @@ -2198,9 +2018,6 @@ void DwarfDebug::emitAbbrevs(const MCSection *Section, // Mark end of abbreviations. Asm->EmitULEB128(0, "EOM(3)"); - - MCSymbol *End = Asm->GetTempSymbol(Section->getLabelEndName()); - Asm->OutStreamer.EmitLabel(End); } } @@ -2232,21 +2049,11 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { void DwarfDebug::emitAccelNames() { DwarfAccelTable AT( DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); - for (SmallVectorImpl::const_iterator I = getUnits().begin(), - E = getUnits().end(); - I != E; ++I) { - Unit *TheU = *I; - const StringMap > &Names = TheU->getAccelNames(); - for (StringMap >::const_iterator - GI = Names.begin(), - GE = Names.end(); - GI != GE; ++GI) { - StringRef Name = GI->getKey(); - const std::vector &Entities = GI->second; - for (std::vector::const_iterator DI = Entities.begin(), - DE = Entities.end(); - DI != DE; ++DI) - AT.AddName(Name, *DI); + for (DwarfUnit *TheU : getUnits()) { + for (const auto &GI : TheU->getAccelNames()) { + StringRef Name = GI.getKey(); + for (const DIE *D : GI.second) + AT.AddName(Name, D); } } @@ -2265,21 +2072,11 @@ void DwarfDebug::emitAccelNames() { void DwarfDebug::emitAccelObjC() { DwarfAccelTable AT( DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); - for (SmallVectorImpl::const_iterator I = getUnits().begin(), - E = getUnits().end(); - I != E; ++I) { - Unit *TheU = *I; - const StringMap > &Names = TheU->getAccelObjC(); - for (StringMap >::const_iterator - GI = Names.begin(), - GE = Names.end(); - GI != GE; ++GI) { - StringRef Name = GI->getKey(); - const std::vector &Entities = GI->second; - for (std::vector::const_iterator DI = Entities.begin(), - DE = Entities.end(); - DI != DE; ++DI) - AT.AddName(Name, *DI); + for (DwarfUnit *TheU : getUnits()) { + for (const auto &GI : TheU->getAccelObjC()) { + StringRef Name = GI.getKey(); + for (const DIE *D : GI.second) + AT.AddName(Name, D); } } @@ -2297,22 +2094,11 @@ void DwarfDebug::emitAccelObjC() { void DwarfDebug::emitAccelNamespaces() { DwarfAccelTable AT( DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)); - for (SmallVectorImpl::const_iterator I = getUnits().begin(), - E = getUnits().end(); - I != E; ++I) { - Unit *TheU = *I; - const StringMap > &Names = - TheU->getAccelNamespace(); - for (StringMap >::const_iterator - GI = Names.begin(), - GE = Names.end(); - GI != GE; ++GI) { - StringRef Name = GI->getKey(); - const std::vector &Entities = GI->second; - for (std::vector::const_iterator DI = Entities.begin(), - DE = Entities.end(); - DI != DE; ++DI) - AT.AddName(Name, *DI); + for (DwarfUnit *TheU : getUnits()) { + for (const auto &GI : TheU->getAccelNamespace()) { + StringRef Name = GI.getKey(); + for (const DIE *D : GI.second) + AT.AddName(Name, D); } } @@ -2336,25 +2122,11 @@ void DwarfDebug::emitAccelTypes() { Atoms.push_back( DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)); DwarfAccelTable AT(Atoms); - for (SmallVectorImpl::const_iterator I = getUnits().begin(), - E = getUnits().end(); - I != E; ++I) { - Unit *TheU = *I; - const StringMap > > &Names = - TheU->getAccelTypes(); - for (StringMap< - std::vector > >::const_iterator - GI = Names.begin(), - GE = Names.end(); - GI != GE; ++GI) { - StringRef Name = GI->getKey(); - const std::vector > &Entities = - GI->second; - for (std::vector >::const_iterator - DI = Entities.begin(), - DE = Entities.end(); - DI != DE; ++DI) - AT.AddName(Name, DI->first, DI->second); + for (DwarfUnit *TheU : getUnits()) { + for (const auto &GI : TheU->getAccelTypes()) { + StringRef Name = GI.getKey(); + for (const auto &DI : GI.second) + AT.AddName(Name, DI.first, DI.second); } } @@ -2383,7 +2155,7 @@ void DwarfDebug::emitAccelTypes() { // reference in the pubname header doesn't change. /// computeIndexValue - Compute the gdb index value for the DIE and CU. -static dwarf::PubIndexEntryDescriptor computeIndexValue(Unit *CU, +static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die) { dwarf::GDBIndexEntryLinkage Linkage = dwarf::GIEL_STATIC; @@ -2428,51 +2200,49 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(Unit *CU, /// emitDebugPubNames - Emit visible names into a debug pubnames section. /// void DwarfDebug::emitDebugPubNames(bool GnuStyle) { - const MCSection *ISec = Asm->getObjFileLowering().getDwarfInfoSection(); const MCSection *PSec = GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() : Asm->getObjFileLowering().getDwarfPubNamesSection(); - for (SmallVectorImpl::const_iterator I = getUnits().begin(), - E = getUnits().end(); - I != E; ++I) { - Unit *TheU = *I; + emitDebugPubSection(GnuStyle, PSec, "Names", &DwarfUnit::getGlobalNames); +} + +void DwarfDebug::emitDebugPubSection( + bool GnuStyle, const MCSection *PSec, StringRef Name, + const StringMap &(DwarfUnit::*Accessor)() const) { + for (const auto &NU : CUMap) { + DwarfCompileUnit *TheU = NU.second; + + const auto &Globals = (TheU->*Accessor)(); + + if (auto Skeleton = static_cast(TheU->getSkeleton())) + TheU = Skeleton; unsigned ID = TheU->getUniqueID(); // Start the dwarf pubnames section. Asm->OutStreamer.SwitchSection(PSec); - // Emit a label so we can reference the beginning of this pubname section. - if (GnuStyle) - Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("gnu_pubnames", TheU->getUniqueID())); - // Emit the header. - Asm->OutStreamer.AddComment("Length of Public Names Info"); - Asm->EmitLabelDifference(Asm->GetTempSymbol("pubnames_end", ID), - Asm->GetTempSymbol("pubnames_begin", ID), 4); + Asm->OutStreamer.AddComment("Length of Public " + Name + " Info"); + MCSymbol *BeginLabel = Asm->GetTempSymbol("pub" + Name + "_begin", ID); + MCSymbol *EndLabel = Asm->GetTempSymbol("pub" + Name + "_end", ID); + Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin", ID)); + Asm->OutStreamer.EmitLabel(BeginLabel); Asm->OutStreamer.AddComment("DWARF Version"); Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); Asm->OutStreamer.AddComment("Offset of Compilation Unit Info"); - Asm->EmitSectionOffset(Asm->GetTempSymbol(ISec->getLabelBeginName(), ID), - DwarfInfoSectionSym); + Asm->EmitSectionOffset(TheU->getLabelBegin(), TheU->getSectionSym()); Asm->OutStreamer.AddComment("Compilation Unit Length"); - Asm->EmitLabelDifference(Asm->GetTempSymbol(ISec->getLabelEndName(), ID), - Asm->GetTempSymbol(ISec->getLabelBeginName(), ID), - 4); + Asm->EmitLabelDifference(TheU->getLabelEnd(), TheU->getLabelBegin(), 4); // Emit the pubnames for this compilation unit. - const StringMap &Globals = TheU->getGlobalNames(); - for (StringMap::const_iterator GI = Globals.begin(), - GE = Globals.end(); - GI != GE; ++GI) { - const char *Name = GI->getKeyData(); - const DIE *Entity = GI->second; + for (const auto &GI : Globals) { + const char *Name = GI.getKeyData(); + const DIE *Entity = GI.second; Asm->OutStreamer.AddComment("DIE offset"); Asm->EmitInt32(Entity->getOffset()); @@ -2485,96 +2255,28 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) { Asm->EmitInt8(Desc.toBits()); } - if (Asm->isVerbose()) - Asm->OutStreamer.AddComment("External Name"); - Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength() + 1)); + Asm->OutStreamer.AddComment("External Name"); + Asm->OutStreamer.EmitBytes(StringRef(Name, GI.getKeyLength() + 1)); } Asm->OutStreamer.AddComment("End Mark"); Asm->EmitInt32(0); - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end", ID)); + Asm->OutStreamer.EmitLabel(EndLabel); } } void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { - const MCSection *ISec = Asm->getObjFileLowering().getDwarfInfoSection(); const MCSection *PSec = GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() : Asm->getObjFileLowering().getDwarfPubTypesSection(); - for (SmallVectorImpl::const_iterator I = getUnits().begin(), - E = getUnits().end(); - I != E; ++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", TheU->getUniqueID())); - - // Emit the header. - Asm->OutStreamer.AddComment("Length of Public Types Info"); - Asm->EmitLabelDifference( - Asm->GetTempSymbol("pubtypes_end", TheU->getUniqueID()), - Asm->GetTempSymbol("pubtypes_begin", TheU->getUniqueID()), 4); - - Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("pubtypes_begin", TheU->getUniqueID())); - - if (Asm->isVerbose()) - Asm->OutStreamer.AddComment("DWARF Version"); - Asm->EmitInt16(dwarf::DW_PUBTYPES_VERSION); - - Asm->OutStreamer.AddComment("Offset of Compilation Unit Info"); - Asm->EmitSectionOffset( - Asm->GetTempSymbol(ISec->getLabelBeginName(), TheU->getUniqueID()), - DwarfInfoSectionSym); - - Asm->OutStreamer.AddComment("Compilation Unit Length"); - Asm->EmitLabelDifference( - Asm->GetTempSymbol(ISec->getLabelEndName(), TheU->getUniqueID()), - Asm->GetTempSymbol(ISec->getLabelBeginName(), TheU->getUniqueID()), 4); - - // Emit the pubtypes. - const StringMap &Globals = TheU->getGlobalTypes(); - for (StringMap::const_iterator GI = Globals.begin(), - GE = Globals.end(); - GI != GE; ++GI) { - const char *Name = GI->getKeyData(); - const DIE *Entity = GI->second; - - if (Asm->isVerbose()) - Asm->OutStreamer.AddComment("DIE offset"); - Asm->EmitInt32(Entity->getOffset()); - - if (GnuStyle) { - dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); - Asm->OutStreamer.AddComment( - Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + - dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); - Asm->EmitInt8(Desc.toBits()); - } - - if (Asm->isVerbose()) - Asm->OutStreamer.AddComment("External Name"); - - // Emit the name with a terminating null byte. - Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength() + 1)); - } - - Asm->OutStreamer.AddComment("End Mark"); - Asm->EmitInt32(0); - Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("pubtypes_end", TheU->getUniqueID())); - } + emitDebugPubSection(GnuStyle, PSec, "Types", &DwarfUnit::getGlobalTypes); } // Emit strings into a string section. -void DwarfUnits::emitStrings(const MCSection *StrSection, - const MCSection *OffsetSection = NULL, - const MCSymbol *StrSecSym = NULL) { +void DwarfFile::emitStrings(const MCSection *StrSection, + const MCSection *OffsetSection = NULL, + const MCSymbol *StrSecSym = NULL) { if (StringPool.empty()) return; @@ -2584,26 +2286,20 @@ void DwarfUnits::emitStrings(const MCSection *StrSection, // Get all of the string pool entries and put them in an array by their ID so // we can sort them. - SmallVector< - std::pair > *>, - 64> Entries; + SmallVector, 64 > Entries; - for (StringMap >::iterator - I = StringPool.begin(), - E = StringPool.end(); - I != E; ++I) - Entries.push_back(std::make_pair(I->second.second, &*I)); + for (const auto &I : StringPool) + Entries.push_back(std::make_pair(I.second.second, &I)); array_pod_sort(Entries.begin(), Entries.end()); - for (unsigned i = 0, e = Entries.size(); i != e; ++i) { + for (const auto &Entry : Entries) { // Emit a label for reference from debug information entries. - Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first); + Asm->OutStreamer.EmitLabel(Entry.second->getValue().first); // Emit the string itself with a terminating null byte. - Asm->OutStreamer.EmitBytes( - StringRef(Entries[i].second->getKeyData(), - Entries[i].second->getKeyLength() + 1)); + Asm->OutStreamer.EmitBytes(StringRef(Entry.second->getKeyData(), + Entry.second->getKeyLength() + 1)); } // If we've got an offset section go ahead and emit that now as well. @@ -2611,16 +2307,15 @@ void DwarfUnits::emitStrings(const MCSection *StrSection, Asm->OutStreamer.SwitchSection(OffsetSection); unsigned offset = 0; unsigned size = 4; // FIXME: DWARF64 is 8. - for (unsigned i = 0, e = Entries.size(); i != e; ++i) { + for (const auto &Entry : Entries) { Asm->OutStreamer.EmitIntValue(offset, size); - offset += Entries[i].second->getKeyLength() + 1; + offset += Entry.second->getKeyLength() + 1; } } } - // Emit addresses into the section given. -void DwarfUnits::emitAddresses(const MCSection *AddrSection) { +void DwarfFile::emitAddresses(const MCSection *AddrSection) { if (AddressPool.empty()) return; @@ -2631,26 +2326,81 @@ void DwarfUnits::emitAddresses(const MCSection *AddrSection) { // Order the address pool entries by ID SmallVector Entries(AddressPool.size()); - for (DenseMap::iterator I = AddressPool.begin(), - E = AddressPool.end(); - I != E; ++I) - Entries[I->second] = I->first; + for (const auto &I : AddressPool) + Entries[I.second.Number] = + I.second.TLS + ? Asm->getObjFileLowering().getDebugThreadLocalSymbol(I.first) + : MCSymbolRefExpr::Create(I.first, Asm->OutContext); - for (unsigned i = 0, e = Entries.size(); i != e; ++i) { - // Emit an expression for reference from debug information entries. - if (const MCExpr *Expr = Entries[i]) - Asm->OutStreamer.EmitValue(Expr, Asm->getDataLayout().getPointerSize()); - else - Asm->OutStreamer.EmitIntValue(0, Asm->getDataLayout().getPointerSize()); - } + for (const MCExpr *Entry : Entries) + Asm->OutStreamer.EmitValue(Entry, Asm->getDataLayout().getPointerSize()); } // Emit visible names into a debug str section. void DwarfDebug::emitDebugStr() { - DwarfUnits &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; + DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection()); } +void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer, + const DotDebugLocEntry &Entry) { + DIVariable DV(Entry.getVariable()); + if (Entry.isInt()) { + DIBasicType BTy(DV.getType()); + if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed || + BTy.getEncoding() == dwarf::DW_ATE_signed_char)) { + Streamer.EmitInt8(dwarf::DW_OP_consts, "DW_OP_consts"); + Streamer.EmitSLEB128(Entry.getInt()); + } else { + Streamer.EmitInt8(dwarf::DW_OP_constu, "DW_OP_constu"); + Streamer.EmitULEB128(Entry.getInt()); + } + } else if (Entry.isLocation()) { + MachineLocation Loc = Entry.getLoc(); + if (!DV.hasComplexAddress()) + // Regular entry. + Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect()); + else { + // Complex address entry. + unsigned N = DV.getNumAddrElements(); + unsigned i = 0; + if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { + if (Loc.getOffset()) { + i = 2; + Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect()); + Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref"); + Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst"); + Streamer.EmitSLEB128(DV.getAddrElement(1)); + } else { + // If first address element is OpPlus then emit + // DW_OP_breg + Offset instead of DW_OP_reg + Offset. + MachineLocation TLoc(Loc.getReg(), DV.getAddrElement(1)); + Asm->EmitDwarfRegOp(Streamer, TLoc, DV.isIndirect()); + i = 2; + } + } else { + Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect()); + } + + // Emit remaining complex address elements. + for (; i < N; ++i) { + uint64_t Element = DV.getAddrElement(i); + if (Element == DIBuilder::OpPlus) { + Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst"); + Streamer.EmitULEB128(DV.getAddrElement(++i)); + } else if (Element == DIBuilder::OpDeref) { + if (!Loc.isReg()) + Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref"); + } else + llvm_unreachable("unknown Opcode found in complex address"); + } + } + } + // else ... ignore constant fp. There is not any good way to + // to represent them here in dwarf. + // FIXME: ^ +} + // Emit locations into the debug loc section. void DwarfDebug::emitDebugLoc() { if (DotDebugLocEntries.empty()) @@ -2671,110 +2421,36 @@ void DwarfDebug::emitDebugLoc() { unsigned char Size = Asm->getDataLayout().getPointerSize(); Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", 0)); unsigned index = 1; - for (SmallVectorImpl::iterator + for (SmallVectorImpl::const_iterator I = DotDebugLocEntries.begin(), E = DotDebugLocEntries.end(); I != E; ++I, ++index) { - DotDebugLocEntry &Entry = *I; + const DotDebugLocEntry &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 { + // Set up the range. Asm->OutStreamer.EmitSymbolValue(Entry.getBeginSym(), Size); Asm->OutStreamer.EmitSymbolValue(Entry.getEndSym(), Size); - DIVariable DV(Entry.getVariable()); Asm->OutStreamer.AddComment("Loc expr size"); MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol(); MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol(); Asm->EmitLabelDifference(end, begin, 2); Asm->OutStreamer.EmitLabel(begin); - if (Entry.isInt()) { - DIBasicType BTy(DV.getType()); - if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed || - BTy.getEncoding() == dwarf::DW_ATE_signed_char)) { - Asm->OutStreamer.AddComment("DW_OP_consts"); - Asm->EmitInt8(dwarf::DW_OP_consts); - Asm->EmitSLEB128(Entry.getInt()); - } else { - Asm->OutStreamer.AddComment("DW_OP_constu"); - Asm->EmitInt8(dwarf::DW_OP_constu); - Asm->EmitULEB128(Entry.getInt()); - } - } else if (Entry.isLocation()) { - MachineLocation Loc = Entry.getLoc(); - if (!DV.hasComplexAddress()) - // Regular entry. - Asm->EmitDwarfRegOp(Loc, DV.isIndirect()); - else { - // Complex address entry. - unsigned N = DV.getNumAddrElements(); - unsigned i = 0; - if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { - if (Loc.getOffset()) { - i = 2; - Asm->EmitDwarfRegOp(Loc, DV.isIndirect()); - Asm->OutStreamer.AddComment("DW_OP_deref"); - Asm->EmitInt8(dwarf::DW_OP_deref); - Asm->OutStreamer.AddComment("DW_OP_plus_uconst"); - Asm->EmitInt8(dwarf::DW_OP_plus_uconst); - Asm->EmitSLEB128(DV.getAddrElement(1)); - } else { - // If first address element is OpPlus then emit - // DW_OP_breg + Offset instead of DW_OP_reg + Offset. - MachineLocation TLoc(Loc.getReg(), DV.getAddrElement(1)); - Asm->EmitDwarfRegOp(TLoc, DV.isIndirect()); - i = 2; - } - } else { - Asm->EmitDwarfRegOp(Loc, DV.isIndirect()); - } - - // Emit remaining complex address elements. - for (; i < N; ++i) { - uint64_t Element = DV.getAddrElement(i); - if (Element == DIBuilder::OpPlus) { - Asm->EmitInt8(dwarf::DW_OP_plus_uconst); - Asm->EmitULEB128(DV.getAddrElement(++i)); - } else if (Element == DIBuilder::OpDeref) { - if (!Loc.isReg()) - Asm->EmitInt8(dwarf::DW_OP_deref); - } else - llvm_unreachable("unknown Opcode found in complex address"); - } - } - } - // else ... ignore constant fp. There is not any good way to - // to represent them here in dwarf. + // Emit the entry. + APByteStreamer Streamer(*Asm); + emitDebugLocEntry(Streamer, Entry); + // Close the range. Asm->OutStreamer.EmitLabel(end); } } } -struct SymbolCUSorter { - SymbolCUSorter(const MCStreamer &s) : Streamer(s) {} - const MCStreamer &Streamer; - - bool operator()(const SymbolCU &A, const SymbolCU &B) { - unsigned IA = A.Sym ? Streamer.GetSymbolOrder(A.Sym) : 0; - unsigned IB = B.Sym ? Streamer.GetSymbolOrder(B.Sym) : 0; - - // Symbols with no order assigned should be placed at the end. - // (e.g. section end labels) - if (IA == 0) - IA = (unsigned)(-1); - if (IB == 0) - IB = (unsigned)(-1); - return IA < IB; - } -}; - -static bool CUSort(const Unit *A, const Unit *B) { - return (A->getUniqueID() < B->getUniqueID()); -} - struct ArangeSpan { const MCSymbol *Start, *End; }; @@ -2786,15 +2462,14 @@ void DwarfDebug::emitDebugARanges() { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfARangesSection()); - typedef DenseMap > SpansType; + typedef DenseMap > SpansType; SpansType Spans; // Build a list of sections used. std::vector Sections; - for (SectionMapType::iterator it = SectionMap.begin(); it != SectionMap.end(); - it++) { - const MCSection *Section = it->first; + for (const auto &it : SectionMap) { + const MCSection *Section = it.first; Sections.push_back(Section); } @@ -2803,22 +2478,30 @@ void DwarfDebug::emitDebugARanges() { std::sort(Sections.begin(), Sections.end(), SectionSort); // Build a set of address spans, sorted by CU. - for (size_t SecIdx = 0; SecIdx < Sections.size(); SecIdx++) { - const MCSection *Section = Sections[SecIdx]; + for (const MCSection *Section : Sections) { SmallVector &List = SectionMap[Section]; if (List.size() < 2) continue; // Sort the symbols by offset within the section. - SymbolCUSorter sorter(Asm->OutStreamer); - std::sort(List.begin(), List.end(), sorter); + std::sort(List.begin(), List.end(), + [&](const SymbolCU &A, const SymbolCU &B) { + unsigned IA = A.Sym ? Asm->OutStreamer.GetSymbolOrder(A.Sym) : 0; + unsigned IB = B.Sym ? Asm->OutStreamer.GetSymbolOrder(B.Sym) : 0; + + // Symbols with no order assigned should be placed at the end. + // (e.g. section end labels) + if (IA == 0) + return false; + if (IB == 0) + return true; + return IA < IB; + }); // If we have no section (e.g. common), just write out // individual spans for each symbol. if (Section == NULL) { - for (size_t n = 0; n < List.size(); n++) { - const SymbolCU &Cur = List[n]; - + for (const SymbolCU &Cur : List) { ArangeSpan Span; Span.Start = Cur.Sym; Span.End = NULL; @@ -2828,7 +2511,7 @@ void DwarfDebug::emitDebugARanges() { } else { // Build spans between each label. const MCSymbol *StartSym = List[0].Sym; - for (size_t n = 1; n < List.size(); n++) { + for (size_t n = 1, e = List.size(); n < e; n++) { const SymbolCU &Prev = List[n - 1]; const SymbolCU &Cur = List[n]; @@ -2844,22 +2527,22 @@ void DwarfDebug::emitDebugARanges() { } } - const MCSection *ISec = Asm->getObjFileLowering().getDwarfInfoSection(); unsigned PtrSize = Asm->getDataLayout().getPointerSize(); // Build a list of CUs used. - std::vector CUs; - for (SpansType::iterator it = Spans.begin(); it != Spans.end(); it++) { - CompileUnit *CU = it->first; + std::vector CUs; + for (const auto &it : Spans) { + DwarfCompileUnit *CU = it.first; CUs.push_back(CU); } // Sort the CU list (again, to ensure consistent output order). - std::sort(CUs.begin(), CUs.end(), CUSort); + std::sort(CUs.begin(), CUs.end(), [](const DwarfUnit *A, const DwarfUnit *B) { + return A->getUniqueID() < B->getUniqueID(); + }); // Emit an arange table for each CU we used. - for (size_t CUIdx = 0; CUIdx < CUs.size(); CUIdx++) { - CompileUnit *CU = CUs[CUIdx]; + for (DwarfCompileUnit *CU : CUs) { std::vector &List = Spans[CU]; // Emit size of content not including length itself. @@ -2872,9 +2555,8 @@ void DwarfDebug::emitDebugARanges() { unsigned TupleSize = PtrSize * 2; // 7.20 in the Dwarf specs requires the table to be aligned to a tuple. - unsigned Padding = 0; - while (((sizeof(int32_t) + ContentSize + Padding) % TupleSize) != 0) - Padding++; + unsigned Padding = + OffsetToAlignment(sizeof(int32_t) + ContentSize, TupleSize); ContentSize += Padding; ContentSize += (List.size() + 1) * TupleSize; @@ -2885,19 +2567,15 @@ void DwarfDebug::emitDebugARanges() { Asm->OutStreamer.AddComment("DWARF Arange version number"); Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); Asm->OutStreamer.AddComment("Offset Into Debug Info Section"); - Asm->EmitSectionOffset( - Asm->GetTempSymbol(ISec->getLabelBeginName(), CU->getUniqueID()), - DwarfInfoSectionSym); + Asm->EmitSectionOffset(CU->getLocalLabelBegin(), CU->getLocalSectionSym()); Asm->OutStreamer.AddComment("Address Size (in bytes)"); Asm->EmitInt8(PtrSize); Asm->OutStreamer.AddComment("Segment Size (in bytes)"); Asm->EmitInt8(0); - for (unsigned n = 0; n < Padding; n++) - Asm->EmitInt8(0xff); + Asm->OutStreamer.EmitFill(Padding, 0xff); - for (unsigned n = 0; n < List.size(); n++) { - const ArangeSpan &Span = List[n]; + for (const ArangeSpan &Span : List) { Asm->EmitLabelReference(Span.Start, PtrSize); // Calculate the size as being from the span start to it's end. @@ -2930,147 +2608,115 @@ void DwarfDebug::emitDebugRanges() { unsigned char Size = Asm->getDataLayout().getPointerSize(); // 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(); + for (const auto &I : CUMap) { + DwarfCompileUnit *TheCU = I.second; // Emit a symbol so we can find the beginning of our ranges. - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("gnu_ranges", ID)); + Asm->OutStreamer.EmitLabel(TheCU->getLabelRange()); // 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. + for (const RangeSpanList &List : TheCU->getRangeLists()) { + // Emit our symbol so we can find the beginning of the range. + Asm->OutStreamer.EmitLabel(List.getSym()); + + for (const RangeSpan &Range : List.getRanges()) { 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); + assert(Begin && "Range without a begin symbol?"); + assert(End && "Range without an end symbol?"); + Asm->OutStreamer.EmitSymbolValue(Begin, Size); + Asm->OutStreamer.EmitSymbolValue(End, Size); } // And terminate the list with two 0 values. Asm->OutStreamer.EmitIntValue(0, Size); Asm->OutStreamer.EmitIntValue(0, Size); } - } -} -// Emit visible names into a debug macinfo section. -void DwarfDebug::emitDebugMacInfo() { - if (const MCSection *LineInfo = - Asm->getObjFileLowering().getDwarfMacroInfoSection()) { - // Start the dwarf macinfo section. - Asm->OutStreamer.SwitchSection(LineInfo); + // Now emit a range for the CU itself. + if (useCURanges() && TheCU->getRanges().size()) { + Asm->OutStreamer.EmitLabel( + Asm->GetTempSymbol("cu_ranges", TheCU->getUniqueID())); + for (const RangeSpan &Range : TheCU->getRanges()) { + const MCSymbol *Begin = Range.getStart(); + const MCSymbol *End = Range.getEnd(); + assert(Begin && "Range without a begin symbol?"); + assert(End && "Range without an end symbol?"); + Asm->OutStreamer.EmitSymbolValue(Begin, Size); + Asm->OutStreamer.EmitSymbolValue(End, Size); + } + // And terminate the list with two 0 values. + Asm->OutStreamer.EmitIntValue(0, Size); + Asm->OutStreamer.EmitIntValue(0, Size); + } } } // DWARF5 Experimental Separate Dwarf emitters. -// 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. -CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) { - - DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); - CompileUnit *NewCU = new CompileUnit(CU->getUniqueID(), Die, CU->getNode(), - Asm, this, &SkeletonHolder); - - NewCU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name, - CU->getNode().getSplitDebugFilename()); +void DwarfDebug::initSkeletonUnit(const DwarfUnit *U, DIE *Die, + DwarfUnit *NewU) { + NewU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name, + U->getCUNode().getSplitDebugFilename()); // 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()) - NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base, - DwarfAddrSectionSym); + NewU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym); else - NewCU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0); + NewU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0); - // 2.17.1 requires that we use DW_AT_low_pc for a single entry point - // 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); + if (!CompilationDir.empty()) + NewU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir); - // DW_AT_stmt_list is a offset of line number information for this - // compile unit in debug_line section. - // FIXME: Should handle multiple compile units. - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addSectionLabel(Die, dwarf::DW_AT_stmt_list, - DwarfLineSectionSym); - else - NewCU->addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0); + addGnuPubAttributes(NewU, Die); - if (!CompilationDir.empty()) - NewCU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir); + SkeletonHolder.addUnit(NewU); +} - // Flags to let the linker know we have emitted new style pubnames. - if (GenerateGnuPubSections) { - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addSectionLabel( - Die, dwarf::DW_AT_GNU_pubnames, - Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID())); - else - NewCU->addSectionDelta( - Die, dwarf::DW_AT_GNU_pubnames, - Asm->GetTempSymbol("gnu_pubnames", NewCU->getUniqueID()), - DwarfGnuPubNamesSectionSym); - - if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) - NewCU->addSectionLabel( - Die, dwarf::DW_AT_GNU_pubtypes, - Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID())); - else - NewCU->addSectionDelta( - Die, dwarf::DW_AT_GNU_pubtypes, - Asm->GetTempSymbol("gnu_pubtypes", NewCU->getUniqueID()), - DwarfGnuPubTypesSectionSym); - } - - // 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, - Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID())); - else - NewCU->addSectionDelta( - Die, dwarf::DW_AT_GNU_ranges_base, - Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID()), - DwarfDebugRangeSectionSym); - } +// 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. +DwarfCompileUnit *DwarfDebug::constructSkeletonCU(const DwarfCompileUnit *CU) { + + DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); + DwarfCompileUnit *NewCU = new DwarfCompileUnit( + CU->getUniqueID(), Die, CU->getCUNode(), Asm, this, &SkeletonHolder); + NewCU->initSection(Asm->getObjFileLowering().getDwarfInfoSection(), + DwarfInfoSectionSym); - SkeletonHolder.addUnit(NewCU); + NewCU->initStmtList(DwarfLineSectionSym); + + initSkeletonUnit(CU, Die, NewCU); return NewCU; } -void DwarfDebug::emitSkeletonAbbrevs(const MCSection *Section) { - assert(useSplitDwarf() && "No split dwarf debug info?"); - emitAbbrevs(Section, &SkeletonAbbrevs); +// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_dwo_name, +// DW_AT_addr_base. +DwarfTypeUnit *DwarfDebug::constructSkeletonTU(DwarfTypeUnit *TU) { + DwarfCompileUnit &CU = static_cast( + *SkeletonHolder.getUnits()[TU->getCU().getUniqueID()]); + + DIE *Die = new DIE(dwarf::DW_TAG_type_unit); + DwarfTypeUnit *NewTU = + new DwarfTypeUnit(TU->getUniqueID(), Die, CU, Asm, this, &SkeletonHolder); + NewTU->setTypeSignature(TU->getTypeSignature()); + NewTU->setType(NULL); + NewTU->initSection( + Asm->getObjFileLowering().getDwarfTypesSection(TU->getTypeSignature())); + CU.applyStmtList(*Die); + + initSkeletonUnit(TU, Die, NewTU); + return NewTU; } // Emit the .debug_info.dwo section for separated dwarf. This contains the // compile units that would normally be in debug_info. void DwarfDebug::emitDebugInfoDWO() { assert(useSplitDwarf() && "No split dwarf debug info?"); - InfoHolder.emitUnits(this, Asm->getObjFileLowering().getDwarfInfoDWOSection(), + InfoHolder.emitUnits(this, Asm->getObjFileLowering().getDwarfAbbrevDWOSection(), DwarfAbbrevDWOSectionSym); } @@ -3079,8 +2725,7 @@ void DwarfDebug::emitDebugInfoDWO() { // abbreviations for the .debug_info.dwo section. void DwarfDebug::emitDebugAbbrevDWO() { assert(useSplitDwarf() && "No split dwarf?"); - emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevDWOSection(), - &Abbreviations); + InfoHolder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevDWOSection()); } // Emit the .debug_str.dwo section for separated dwarf. This contains the @@ -3095,56 +2740,59 @@ void DwarfDebug::emitDebugStrDWO() { OffSec, StrSym); } -void DwarfDebug::addTypeUnitType(uint16_t Language, DIE *RefDie, - DICompositeType CTy) { - DenseMap *> >::iterator I = - TypeUnits.find(CTy); - SmallVector References; - References.push_back(RefDie); - if (I != TypeUnits.end()) { - if (I->second.second) { - I->second.second->push_back(RefDie); - return; - } - } else { - DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit); - TypeUnit *NewTU = new TypeUnit(GlobalCUIndexCount++, UnitDie, Language, Asm, - this, &InfoHolder); - NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2, - Language); - - // Register the type in the TypeUnits map with a vector of references to be - // populated whenever a reference is required. - I = TypeUnits.insert(std::make_pair(CTy, std::make_pair(0, &References))) - .first; - - // Construct the type, this may, recursively, require more type units that - // may in turn require this type again - in which case they will add DIEs to - // the References vector. - DIE *Die = NewTU->createTypeDIE(CTy); - - if (GenerateODRHash && shouldAddODRHash(NewTU, Die)) - NewTU->addUInt(UnitDie, dwarf::DW_AT_GNU_odr_signature, - dwarf::DW_FORM_data8, - DIEHash().computeDIEODRSignature(*Die)); - // FIXME: This won't handle circularly referential structures, as the DIE - // may have references to other DIEs still under construction and missing - // their signature. Hashing should walk through the signatures to their - // referenced type, or possibly walk the precomputed hashes of related types - // at the end. - uint64_t Signature = DIEHash().computeTypeSignature(*Die); - - // Remove the References vector and add the type hash. - I->second.first = Signature; - I->second.second = NULL; - - InfoHolder.addUnit(NewTU); - } - - // Populate all the signatures. - for (unsigned i = 0, e = References.size(); i != e; ++i) { - CUMap.begin()->second->addUInt(References[i], dwarf::DW_AT_signature, - dwarf::DW_FORM_ref_sig8, I->second.first); +void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, + StringRef Identifier, DIE *RefDie, + DICompositeType CTy) { + // Flag the type unit reference as a declaration so that if it contains + // members (implicit special members, static data member definitions, member + // declarations for definitions in this CU, etc) consumers don't get confused + // and think this is a full definition. + CU.addFlag(RefDie, dwarf::DW_AT_declaration); + + const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy]; + if (TU) { + CU.addDIETypeSignature(RefDie, *TU); + return; } + + DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit); + DwarfTypeUnit *NewTU = new DwarfTypeUnit(InfoHolder.getUnits().size(), + UnitDie, CU, Asm, this, &InfoHolder); + TU = NewTU; + InfoHolder.addUnit(NewTU); + + NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2, + CU.getLanguage()); + + MD5 Hash; + Hash.update(Identifier); + // ... take the least significant 8 bytes and return those. Our MD5 + // implementation always returns its results in little endian, swap bytes + // appropriately. + MD5::MD5Result Result; + Hash.final(Result); + uint64_t Signature = *reinterpret_cast(Result + 8); + NewTU->setTypeSignature(Signature); + if (useSplitDwarf()) + NewTU->setSkeleton(constructSkeletonTU(NewTU)); + else + CU.applyStmtList(*UnitDie); + + NewTU->setType(NewTU->createTypeDIE(CTy)); + + NewTU->initSection( + useSplitDwarf() + ? Asm->getObjFileLowering().getDwarfTypesDWOSection(Signature) + : Asm->getObjFileLowering().getDwarfTypesSection(Signature)); + + CU.addDIETypeSignature(RefDie, *NewTU); +} + +void DwarfDebug::attachLowHighPC(DwarfCompileUnit *Unit, DIE *D, + MCSymbol *Begin, MCSymbol *End) { + Unit->addLabelAddress(D, dwarf::DW_AT_low_pc, Begin); + if (DwarfVersion < 4) + Unit->addLabelAddress(D, dwarf::DW_AT_high_pc, End); + else + Unit->addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin); }