X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.cpp;h=fde3604e04f37d663ef0394eaea93d500194d77c;hb=b7b9bf458b2230a977ad5572b8435bb4a2d0cb13;hp=5fb603c143b6c1bb3b5af268afc10bd70b9a394c;hpb=e1ea4faca159ff8e6fba39d00fee8ea5b4b5efe8;p=oota-llvm.git diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 5fb603c143b..fde3604e04f 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -178,7 +178,7 @@ static unsigned getDwarfVersionFromModule(const Module *M) { DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), FirstCU(0), PrevLabel(NULL), GlobalRangeCount(0), - InfoHolder(A, "info_string", DIEValueAllocator), HasCURanges(false), + InfoHolder(A, "info_string", DIEValueAllocator), UsedNonDefaultText(false), SkeletonHolder(A, "skel_string", DIEValueAllocator) { @@ -456,8 +456,15 @@ void DwarfDebug::addScopeRangeList(DwarfCompileUnit *TheCU, DIE *ScopeDIE, // Emit offset in .debug_range as a relocatable label. emitDIE will handle // emitting it appropriately. MCSymbol *RangeSym = Asm->GetTempSymbol("debug_ranges", GlobalRangeCount++); - addSectionLabel(Asm, TheCU, ScopeDIE, dwarf::DW_AT_ranges, RangeSym, - DwarfDebugRangeSectionSym); + + // Under fission, ranges are specified by constant offsets relative to the + // CU's DW_AT_GNU_ranges_base. + if (useSplitDwarf()) + TheCU->addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, RangeSym, + DwarfDebugRangeSectionSym); + else + addSectionLabel(Asm, TheCU, ScopeDIE, dwarf::DW_AT_ranges, RangeSym, + DwarfDebugRangeSectionSym); RangeSpanList List(RangeSym); for (const InsnRange &R : Range) { @@ -603,8 +610,7 @@ DIE *DwarfDebug::constructScopeDIE(DwarfCompileUnit *TheCU, if (!Scope || !Scope->getScopeNode()) return NULL; - // Unique scope where applicable. - DIScope DS(resolve(DIScope(Scope->getScopeNode()).getRef())); + DIScope DS(Scope->getScopeNode()); SmallVector Children; DIE *ObjectPointer = NULL; @@ -680,8 +686,7 @@ void DwarfDebug::addGnuPubAttributes(DwarfUnit *U, DIE *D) const { // Create new DwarfCompileUnit for the given metadata node with tag // DW_TAG_compile_unit. -DwarfCompileUnit *DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit, - bool Singular) { +DwarfCompileUnit *DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) { StringRef FN = DIUnit.getFilename(); CompilationDir = DIUnit.getDirectory(); @@ -689,7 +694,12 @@ DwarfCompileUnit *DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit, DwarfCompileUnit *NewCU = new DwarfCompileUnit( InfoHolder.getUnits().size(), Die, DIUnit, Asm, this, &InfoHolder); InfoHolder.addUnit(NewCU); - if (!Asm->OutStreamer.hasRawTextSupport() || Singular) + + // LTO with assembly output shares a single line table amongst multiple CUs. + // To avoid the compilation directory being ambiguous, let the line table + // explicitly describe the directory of all files, never relying on the + // compilation directory. + if (!Asm->OutStreamer.hasRawTextSupport() || SingleCU) Asm->OutStreamer.getContext().setMCLineTableCompilationDir( NewCU->getUniqueID(), CompilationDir); @@ -784,7 +794,7 @@ void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU, DIE *IMDie = new DIE(Module.getTag()); TheCU->insertDIE(Module, IMDie); DIE *EntityDie; - DIDescriptor Entity = Module.getEntity(); + DIDescriptor Entity = resolve(Module.getEntity()); if (Entity.isNameSpace()) EntityDie = TheCU->getOrCreateNameSpace(DINameSpace(Entity)); else if (Entity.isSubprogram()) @@ -822,13 +832,11 @@ void DwarfDebug::beginModule() { // Emit initial sections so we can reference labels later. emitSectionLabels(); - auto Operands = CU_Nodes->operands(); - - bool SingleCU = std::next(Operands.begin()) == Operands.end(); + SingleCU = CU_Nodes->getNumOperands() == 1; - for (MDNode *N : Operands) { + for (MDNode *N : CU_Nodes->operands()) { DICompileUnit CUNode(N); - DwarfCompileUnit *CU = constructDwarfCompileUnit(CUNode, SingleCU); + DwarfCompileUnit *CU = constructDwarfCompileUnit(CUNode); DIArray ImportedEntities = CUNode.getImportedEntities(); for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i) ScopesWithImportedEntities.push_back(std::make_pair( @@ -948,28 +956,47 @@ void DwarfDebug::finalizeModuleInfo() { dwarf::DW_FORM_data8, ID); SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8, ID); + + // We don't keep track of which addresses are used in which CU so this + // is a bit pessimistic under LTO. + if (!InfoHolder.getAddrPool()->empty()) + addSectionLabel(Asm, SkCU, SkCU->getUnitDie(), + dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym, + DwarfAddrSectionSym); + if (!TheU->getRangeLists().empty()) + addSectionLabel(Asm, SkCU, SkCU->getUnitDie(), + dwarf::DW_AT_GNU_ranges_base, + DwarfDebugRangeSectionSym, DwarfDebugRangeSectionSym); } - // 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. + // If we have code split among multiple sections or non-contiguous + // ranges of code 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: We should use ranges allow reordering of code ala + // .subsections_via_symbols in mach-o. This would mean turning on + // ranges for all subprogram DIEs for 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); + unsigned NumRanges = TheU->getRanges().size(); + if (NumRanges) { + if (NumRanges > 1) { + 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 { + RangeSpan &Range = TheU->getRanges().back(); + U->addLocalLabelAddress(U->getUnitDie(), dwarf::DW_AT_low_pc, + Range.getStart()); + U->addLabelDelta(U->getUnitDie(), dwarf::DW_AT_high_pc, + Range.getEnd(), Range.getStart()); + } + } } } @@ -1024,14 +1051,6 @@ void DwarfDebug::endSections() { // Insert a final terminator. SectionMap[Section].push_back(SymbolCU(NULL, Sym)); } - - // For now only turn on CU ranges if 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 = UsedNonDefaultText || (CUMap.size() > 1) || - TargetMachine::getFunctionSections(); } // Emit all Dwarf sections that should come after the content. @@ -1057,9 +1076,6 @@ void DwarfDebug::endModule() { // Corresponding abbreviations into a abbrev section. emitAbbreviations(); - // Emit info into a debug loc section. - emitDebugLoc(); - // Emit info into a debug aranges section. if (GenerateARangeSection) emitDebugARanges(); @@ -1074,7 +1090,10 @@ void DwarfDebug::endModule() { emitDebugLineDWO(); // Emit DWO addresses. InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection()); - } + emitDebugLocDWO(); + } else + // Emit info into a debug loc section. + emitDebugLoc(); // Emit info into the dwarf accelerator table sections. if (useDwarfAccelTables()) { @@ -1175,10 +1194,11 @@ static bool isDbgValueInDefinedReg(const MachineInstr *MI) { // Get .debug_loc entry for the instruction range starting at MI. static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm, - const MCSymbol *FLabel, - const MCSymbol *SLabel, - const MachineInstr *MI) { - const MDNode *Var = MI->getOperand(MI->getNumOperands() - 1).getMetadata(); + const MCSymbol *FLabel, + const MCSymbol *SLabel, + const MachineInstr *MI, + DwarfCompileUnit *Unit) { + const MDNode *Var = MI->getDebugVariable(); assert(MI->getNumOperands() == 3); if (MI->getOperand(0).isReg()) { @@ -1189,14 +1209,14 @@ static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm, MLoc.set(MI->getOperand(0).getReg()); else MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); - return DebugLocEntry(FLabel, SLabel, MLoc, Var); + return DebugLocEntry(FLabel, SLabel, MLoc, Var, Unit); } if (MI->getOperand(0).isImm()) - return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getImm()); + return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getImm(), Unit); if (MI->getOperand(0).isFPImm()) - return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getFPImm()); + return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getFPImm(), Unit); if (MI->getOperand(0).isCImm()) - return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getCImm()); + return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getCImm(), Unit); llvm_unreachable("Unexpected 3 operand DBG_VALUE instruction!"); } @@ -1251,6 +1271,11 @@ DwarfDebug::collectVariableInfo(SmallPtrSet &Processed) { // Handle multiple DBG_VALUE instructions describing one variable. RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); + DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1); + DebugLocList &LocList = DotDebugLocEntries.back(); + LocList.Label = + Asm->GetTempSymbol("debug_loc", DotDebugLocEntries.size() - 1); + SmallVector &DebugLoc = LocList.List; for (SmallVectorImpl::const_iterator HI = History.begin(), HE = History.end(); @@ -1286,10 +1311,12 @@ DwarfDebug::collectVariableInfo(SmallPtrSet &Processed) { } // The value is valid until the next DBG_VALUE or clobber. - DotDebugLocEntries.push_back( - getDebugLocEntry(Asm, FLabel, SLabel, Begin)); + LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); + DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); + DebugLocEntry Loc = getDebugLocEntry(Asm, FLabel, SLabel, Begin, TheCU); + if (DebugLoc.empty() || !DebugLoc.back().Merge(Loc)) + DebugLoc.push_back(std::move(Loc)); } - DotDebugLocEntries.push_back(DebugLocEntry()); } // Collect info for variables that were optimized out. @@ -1426,12 +1453,8 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // Grab the lexical scopes for the function, if we don't have any of those // then we're not going to be able to do anything. LScopes.initialize(*MF); - if (LScopes.empty()) { - // If we don't have a lexical scope for this function then there will - // be a hole in the range information. Keep note of this. - UsedNonDefaultText = true; + if (LScopes.empty()) return; - } assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned"); @@ -1450,12 +1473,6 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { 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. @@ -1476,8 +1493,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { assert(MI->getNumOperands() > 1 && "Invalid machine instruction!"); // Keep track of user variables. - const MDNode *Var = - MI->getOperand(MI->getNumOperands() - 1).getMetadata(); + const MDNode *Var = MI->getDebugVariable(); // Variable is in a register, we need to check for clobbers. if (isDbgValueInDefinedReg(MI)) @@ -1661,6 +1677,11 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { assert(CurFn != 0); if (!MMI->hasDebugInfo() || LScopes.empty()) { + // If we don't have a lexical scope for this function then there will + // be a hole in the range information. Keep note of this by setting the + // previously used section to nullptr. + PrevSection = nullptr; + PrevCU = nullptr; CurFn = 0; return; } @@ -1711,6 +1732,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // Add the range of this function to the list of ranges for the CU. RangeSpan Span(FunctionBeginSym, FunctionEndSym); TheCU->addRange(std::move(Span)); + PrevSection = Asm->getCurrentSection(); + PrevCU = TheCU; // Clear debug info for (auto &I : ScopeVariables) @@ -1855,7 +1878,6 @@ void DwarfDebug::emitSectionLabels() { DwarfLineSectionSym = emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line"); - emitSectionSym(Asm, TLOF.getDwarfLocSection()); if (GenerateGnuPubSections) { DwarfGnuPubNamesSectionSym = emitSectionSym(Asm, TLOF.getDwarfGnuPubNamesSection()); @@ -1873,12 +1895,13 @@ void DwarfDebug::emitSectionLabels() { emitSectionSym(Asm, TLOF.getDwarfStrDWOSection(), "skel_string"); DwarfAddrSectionSym = emitSectionSym(Asm, TLOF.getDwarfAddrSection(), "addr_sec"); - } + DwarfDebugLocSectionSym = + emitSectionSym(Asm, TLOF.getDwarfLocDWOSection(), "skel_loc"); + } else + DwarfDebugLocSectionSym = + emitSectionSym(Asm, TLOF.getDwarfLocSection(), "section_debug_loc"); DwarfDebugRangeSectionSym = emitSectionSym(Asm, TLOF.getDwarfRangesSection(), "debug_range"); - - DwarfDebugLocSectionSym = - emitSectionSym(Asm, TLOF.getDwarfLocSection(), "section_debug_loc"); } // Recursively emits a debug information entry. @@ -1928,8 +1951,7 @@ void DwarfDebug::emitDIE(DIE *Die) { // Emit the various dwarf units to the unit section USection with // the abbreviations going into ASection. -void DwarfFile::emitUnits(DwarfDebug *DD, const MCSection *ASection, - const MCSymbol *ASectionSym) { +void DwarfFile::emitUnits(DwarfDebug *DD, const MCSymbol *ASectionSym) { for (DwarfUnit *TheU : CUs) { DIE *Die = TheU->getUnitDie(); const MCSection *USection = TheU->getSection(); @@ -1942,7 +1964,7 @@ void DwarfFile::emitUnits(DwarfDebug *DD, const MCSection *ASection, Asm->OutStreamer.AddComment("Length of Unit"); Asm->EmitInt32(TheU->getHeaderSize() + Die->getSize()); - TheU->emitHeader(ASection, ASectionSym); + TheU->emitHeader(ASectionSym); DD->emitDIE(Die); Asm->OutStreamer.EmitLabel(TheU->getLabelEnd()); @@ -1953,8 +1975,7 @@ void DwarfFile::emitUnits(DwarfDebug *DD, const MCSection *ASection, void DwarfDebug::emitDebugInfo() { DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; - Holder.emitUnits(this, Asm->getObjFileLowering().getDwarfAbbrevSection(), - DwarfAbbrevSectionSym); + Holder.emitUnits(this, DwarfAbbrevSectionSym); } // Emit the abbreviation section. @@ -2367,53 +2388,67 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer, // FIXME: ^ } +void DwarfDebug::emitDebugLocEntryLocation(const DebugLocEntry &Entry) { + 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); + // Emit the entry. + APByteStreamer Streamer(*Asm); + emitDebugLocEntry(Streamer, Entry); + // Close the range. + Asm->OutStreamer.EmitLabel(end); +} + // Emit locations into the debug loc section. void DwarfDebug::emitDebugLoc() { - if (DotDebugLocEntries.empty()) - return; - - for (SmallVectorImpl::iterator - I = DotDebugLocEntries.begin(), - E = DotDebugLocEntries.end(); - I != E; ++I) { - DebugLocEntry &Entry = *I; - if (I + 1 != DotDebugLocEntries.end()) - Entry.Merge(I + 1); - } - // Start the dwarf loc section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfLocSection()); unsigned char Size = Asm->getDataLayout().getPointerSize(); - Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", 0)); - unsigned index = 1; - for (SmallVectorImpl::const_iterator - I = DotDebugLocEntries.begin(), - E = DotDebugLocEntries.end(); - I != E; ++I, ++index) { - const DebugLocEntry &Entry = *I; - if (Entry.isMerged()) - continue; + for (const auto &DebugLoc : DotDebugLocEntries) { + Asm->OutStreamer.EmitLabel(DebugLoc.Label); + for (const auto &Entry : DebugLoc.List) { + // Set up the range. This range is relative to the entry point of the + // compile unit. This is a hard coded 0 for low_pc when we're emitting + // ranges, or the DW_AT_low_pc on the compile unit otherwise. + const DwarfCompileUnit *CU = Entry.getCU(); + if (CU->getRanges().size() == 1) { + // Grab the begin symbol from the first range as our base. + const MCSymbol *Base = CU->getRanges()[0].getStart(); + Asm->EmitLabelDifference(Entry.getBeginSym(), Base, Size); + Asm->EmitLabelDifference(Entry.getEndSym(), Base, Size); + } else { + Asm->OutStreamer.EmitSymbolValue(Entry.getBeginSym(), Size); + Asm->OutStreamer.EmitSymbolValue(Entry.getEndSym(), Size); + } - 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); - 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); - // Emit the entry. - APByteStreamer Streamer(*Asm); - emitDebugLocEntry(Streamer, Entry); - // Close the range. - Asm->OutStreamer.EmitLabel(end); + emitDebugLocEntryLocation(Entry); } + Asm->OutStreamer.EmitIntValue(0, Size); + Asm->OutStreamer.EmitIntValue(0, Size); + } +} + +void DwarfDebug::emitDebugLocDWO() { + Asm->OutStreamer.SwitchSection( + Asm->getObjFileLowering().getDwarfLocDWOSection()); + for (const auto &DebugLoc : DotDebugLocEntries) { + Asm->OutStreamer.EmitLabel(DebugLoc.Label); + for (const auto &Entry : DebugLoc.List) { + // Just always use start_length for now - at least that's one address + // rather than two. We could get fancier and try to, say, reuse an + // address we know we've emitted elsewhere (the start of the function? + // The start of the CU or CU subrange that encloses this range?) + Asm->EmitInt8(dwarf::DW_LLE_start_length_entry); + unsigned idx = InfoHolder.getAddrPoolIndex(Entry.getBeginSym()); + Asm->EmitULEB128(idx); + Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4); + + emitDebugLocEntryLocation(Entry); + } + Asm->EmitInt8(dwarf::DW_LLE_end_of_list_entry); } } @@ -2600,7 +2635,7 @@ void DwarfDebug::emitDebugRanges() { } // Now emit a range for the CU itself. - if (useCURanges() && TheCU->getRanges().size()) { + if (TheCU->getRanges().size() > 1) { Asm->OutStreamer.EmitLabel( Asm->GetTempSymbol("cu_ranges", TheCU->getUniqueID())); for (const RangeSpan &Range : TheCU->getRanges()) { @@ -2625,13 +2660,6 @@ void DwarfDebug::initSkeletonUnit(const DwarfUnit *U, DIE *Die, 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()) - NewU->addSectionLabel(Die, dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym); - else - NewU->addSectionOffset(Die, dwarf::DW_AT_GNU_addr_base, 0); - if (!CompilationDir.empty()) NewU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir); @@ -2642,8 +2670,7 @@ void DwarfDebug::initSkeletonUnit(const DwarfUnit *U, DIE *Die, // This DIE has the following attributes: DW_AT_comp_dir, DW_AT_stmt_list, // DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_dwo_name, DW_AT_dwo_id, -// DW_AT_ranges_base, DW_AT_addr_base. -// TODO: Implement DW_AT_ranges_base. +// DW_AT_addr_base, DW_AT_ranges_base. DwarfCompileUnit *DwarfDebug::constructSkeletonCU(const DwarfCompileUnit *CU) { DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); @@ -2681,9 +2708,9 @@ DwarfTypeUnit *DwarfDebug::constructSkeletonTU(DwarfTypeUnit *TU) { // compile units that would normally be in debug_info. void DwarfDebug::emitDebugInfoDWO() { assert(useSplitDwarf() && "No split dwarf debug info?"); - InfoHolder.emitUnits(this, - Asm->getObjFileLowering().getDwarfAbbrevDWOSection(), - DwarfAbbrevDWOSectionSym); + // Don't pass an abbrev symbol, using a constant zero instead so as not to + // emit relocations into the dwo file. + InfoHolder.emitUnits(this, /* AbbrevSymbol */nullptr); } // Emit the .debug_abbrev.dwo section for separated dwarf. This contains the @@ -2712,6 +2739,14 @@ void DwarfDebug::emitDebugStrDWO() { OffSec, StrSym); } +MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) { + if (!useSplitDwarf()) + return nullptr; + if (SingleCU) + SplitTypeUnitFileTable.setCompilationDir(CU.getCUNode().getDirectory()); + return &SplitTypeUnitFileTable; +} + void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE *RefDie, DICompositeType CTy) { @@ -2728,9 +2763,9 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, } DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit); - DwarfTypeUnit *NewTU = new DwarfTypeUnit( - InfoHolder.getUnits().size(), UnitDie, CU, Asm, this, &InfoHolder, - useSplitDwarf() ? &SplitTypeUnitFileTable : nullptr); + DwarfTypeUnit *NewTU = + new DwarfTypeUnit(InfoHolder.getUnits().size(), UnitDie, CU, Asm, this, + &InfoHolder, getDwoLineTable(CU)); TU = NewTU; InfoHolder.addUnit(NewTU);