diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 706ea100e0c..714043d0be6 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -19,7 +19,7 @@ DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DICompileUnit Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) : DwarfUnit(UID, dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), - Skeleton(nullptr), LabelBegin(nullptr) { + Skeleton(nullptr), LabelBegin(nullptr), BaseAddress(nullptr) { insertDIE(Node, &getUnitDie()); } diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 787ac23eb03..27cfdcdaa48 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -55,6 +55,10 @@ class DwarfCompileUnit : public DwarfUnit { // List of ranges for a given compile unit. SmallVector CURanges; + // The base address of this unit, if any. Used for relative references in + // ranges/locs. + const MCSymbol *BaseAddress; + /// \brief Construct a DIE for the given DbgVariable without initializing the /// DbgVariable's DIE reference. std::unique_ptr constructVariableDIEImpl(const DbgVariable &DV, @@ -233,6 +237,9 @@ public: /// getRanges - Get the list of ranges for this unit. const SmallVectorImpl &getRanges() const { return CURanges; } + + void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; } + const MCSymbol *getBaseAddress() const { return BaseAddress; } }; } // end llvm namespace diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 2b432c035cb..95dedb5549b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -592,6 +592,7 @@ void DwarfDebug::finalizeModuleInfo() { U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0); } else { const RangeSpan &Range = TheCU.getRanges().back(); + TheCU.setBaseAddress(Range.getStart()); U.attachLowHighPC(U.getUnitDie(), Range.getStart(), Range.getEnd()); } } @@ -1791,9 +1792,7 @@ void DwarfDebug::emitDebugLoc() { // 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. - if (CU->getRanges().size() == 1) { - // Grab the begin symbol from the first range as our base. - const MCSymbol *Base = CU->getRanges()[0].getStart(); + if (auto *Base = CU->getBaseAddress()) { Asm->EmitLabelDifference(Entry.getBeginSym(), Base, Size); Asm->EmitLabelDifference(Entry.getEndSym(), Base, Size); } else { @@ -2003,9 +2002,7 @@ void DwarfDebug::emitDebugRanges() { const MCSymbol *End = Range.getEnd(); assert(Begin && "Range without a begin symbol?"); assert(End && "Range without an end symbol?"); - if (TheCU->getRanges().size() == 1) { - // Grab the begin symbol from the first range as our base. - const MCSymbol *Base = TheCU->getRanges()[0].getStart(); + if (auto *Base = TheCU->getBaseAddress()) { Asm->EmitLabelDifference(Begin, Base, Size); Asm->EmitLabelDifference(End, Base, Size); } else {