diff options
author | Eric Christopher <echristo@gmail.com> | 2013-12-20 04:16:18 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gmail.com> | 2013-12-20 04:16:18 +0000 |
commit | ff37ddf185761005c89f625a7a9897e8129114a8 (patch) | |
tree | c3aabb5a2f162e75ab90629be72ee0f4f391e01c /lib/CodeGen | |
parent | e899f2516316aa432d9ce553a63fdc7e0da7f3a8 (diff) | |
download | llvm-ff37ddf185761005c89f625a7a9897e8129114a8.tar.gz llvm-ff37ddf185761005c89f625a7a9897e8129114a8.tar.bz2 llvm-ff37ddf185761005c89f625a7a9897e8129114a8.tar.xz |
Add support for a CU to output a set of ranges for the CU. This is useful
when you want to have the full list of addresses for a particular CU or
when you have multiple modules linked together and can't depend upon the
ordering of a single CU for begin/end ranges.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197776 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 84 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfUnit.h | 10 |
2 files changed, 74 insertions, 20 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 06ad162438..1c6d1a760d 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -108,6 +108,11 @@ static cl::opt<unsigned> DwarfVersionNumber("dwarf-version", cl::Hidden, cl::desc("Generate DWARF for dwarf version."), cl::init(0)); +static cl::opt<bool> +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"; @@ -426,6 +431,10 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit *SPCU, SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc, FunctionBeginSym); SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc, FunctionEndSym); + // Add this range to the list of ranges for the CU. + RangeSpan Span(FunctionBeginSym, FunctionEndSym); + SPCU->addRange(llvm_move(Span)); + const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); MachineLocation Location(RI->getFrameRegister(*Asm->MF)); SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location); @@ -1070,24 +1079,32 @@ void DwarfDebug::finalizeModuleInfo() { // 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 construct a skeleton CU based upon it. + if (useSplitDwarf()) { + // This should be a unique identifier when we want to build .dwp files. + uint64_t ID = 0; + if (GenerateCUHash) { + DIEHash CUHash; + ID = CUHash.computeCUSignature(*TheU->getUnitDie()); + } + TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + // Now construct the skeleton CU associated. + DwarfCompileUnit *SkCU = + constructSkeletonCU(static_cast<DwarfCompileUnit *>(TheU)); + SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, + dwarf::DW_FORM_data8, ID); + } else { + // Attribute if we've emitted a range list for the compile unit, this + // will get constructed for the skeleton CU separately if we have one. + if (DwarfCURanges && TheU->getRanges().size()) + addSectionLabel(Asm, TheU, TheU->getUnitDie(), dwarf::DW_AT_ranges, + Asm->GetTempSymbol("cu_ranges", TheU->getUniqueID()), + DwarfDebugRangeSectionSym); } - // 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. - DwarfCompileUnit *SkCU = - constructSkeletonCU(static_cast<DwarfCompileUnit *>(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); } } @@ -2935,6 +2952,28 @@ void DwarfDebug::emitDebugRanges() { Asm->OutStreamer.EmitIntValue(0, Size); Asm->OutStreamer.EmitIntValue(0, Size); } + + // Now emit a range for the CU itself. + if (DwarfCURanges) { + Asm->OutStreamer.EmitLabel( + Asm->GetTempSymbol("cu_ranges", TheCU->getUniqueID())); + const SmallVectorImpl<RangeSpan> &Ranges = TheCU->getRanges(); + for (uint32_t i = 0, e = Ranges.size(); i != e; ++i) { + RangeSpan Range = Ranges[i]; + + // We occasionally have ranges without begin/end labels. + // FIXME: Verify and fix. + const MCSymbol *Begin = Range.getStart(); + const MCSymbol *End = Range.getEnd(); + Begin ? Asm->OutStreamer.EmitSymbolValue(Begin, Size) + : Asm->OutStreamer.EmitIntValue(0, Size); + End ? Asm->OutStreamer.EmitSymbolValue(End, Size) + : Asm->OutStreamer.EmitIntValue(0, Size); + } + // And terminate the list with two 0 values. + Asm->OutStreamer.EmitIntValue(0, Size); + Asm->OutStreamer.EmitIntValue(0, Size); + } } } @@ -2963,9 +3002,14 @@ DwarfCompileUnit *DwarfDebug::constructSkeletonCU(const DwarfCompileUnit *CU) { else NewCU->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); + // Attribute if we've emitted a range list for the compile unit, this + // will get constructed for the skeleton CU separately if we have one. + if (DwarfCURanges && CU->getRanges().size()) + addSectionLabel(Asm, NewCU, Die, dwarf::DW_AT_ranges, + Asm->GetTempSymbol("cu_ranges", CU->getUniqueID()), + DwarfDebugRangeSectionSym); + else + NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0); // DW_AT_stmt_list is a offset of line number information for this // compile unit in debug_line section. diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h index 5f9d483796..7d7b351b9b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -118,6 +118,9 @@ protected: /// corresponds to the MDNode mapped with the subprogram DIE. DenseMap<DIE *, const MDNode *> ContainingTypeMap; + // List of ranges for a given compile unit. + SmallVector<RangeSpan, 1> CURanges; + // List of range lists for a given compile unit, separate from the ranges for // the CU itself. SmallVector<RangeSpanList, 1> CURangeLists; @@ -216,6 +219,13 @@ public: /// hasContent - Return true if this compile unit has something to write out. bool hasContent() const { return !UnitDie->getChildren().empty(); } + /// addRange - Add an address range to the list of ranges for this unit. + void addRange(RangeSpan Range) { CURanges.push_back(Range); } + + /// getRanges - Get the list of ranges for this unit. + const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; } + SmallVectorImpl<RangeSpan> &getRanges() { return CURanges; } + /// addRangeList - Add an address range list to the list of range lists. void addRangeList(RangeSpanList Ranges) { CURangeLists.push_back(Ranges); } |