From: Alexey Samsonov Date: Fri, 16 Nov 2012 08:36:25 +0000 (+0000) Subject: [DebugInfo] Generate address ranges for compile units even if .debug_aranges is prese... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=63a450a313a9b0a08622e97b53f5dd83f9266143;p=oota-llvm.git [DebugInfo] Generate address ranges for compile units even if .debug_aranges is present: it is often the case that .debug_aranges section contains ranges only for a small subset of compile units. Test cases will be added in separate commits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168144 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index af11eed90d3..5fa65340671 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -91,8 +91,10 @@ const DWARFDebugAranges *DWARFContext::getDebugAranges() { Aranges.reset(new DWARFDebugAranges()); Aranges->extract(arangesData); - if (Aranges->isEmpty()) // No aranges in file, generate them from the DIEs. - Aranges->generate(this); + // Generate aranges from DIEs: even if .debug_aranges section is present, + // it may describe only a small subset of compilation units, so we need to + // manually build aranges for the rest of them. + Aranges->generate(this); return Aranges.get(); } diff --git a/lib/DebugInfo/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARFDebugAranges.cpp index f9a34c908f1..b077eb5e38d 100644 --- a/lib/DebugInfo/DWARFDebugAranges.cpp +++ b/lib/DebugInfo/DWARFDebugAranges.cpp @@ -26,34 +26,40 @@ namespace { class CountArangeDescriptors { public: CountArangeDescriptors(uint32_t &count_ref) : Count(count_ref) {} - void operator()(const DWARFDebugArangeSet &set) { - Count += set.getNumDescriptors(); + void operator()(const DWARFDebugArangeSet &Set) { + Count += Set.getNumDescriptors(); } uint32_t &Count; }; class AddArangeDescriptors { public: - AddArangeDescriptors(DWARFDebugAranges::RangeColl &ranges) - : RangeCollection(ranges) {} - void operator()(const DWARFDebugArangeSet& set) { - const DWARFDebugArangeSet::Descriptor* arange_desc_ptr; - DWARFDebugAranges::Range range; - range.Offset = set.getCompileUnitDIEOffset(); - - for (uint32_t i=0; (arange_desc_ptr = set.getDescriptor(i)) != NULL; ++i){ - range.LoPC = arange_desc_ptr->Address; - range.Length = arange_desc_ptr->Length; + AddArangeDescriptors(DWARFDebugAranges::RangeColl &Ranges, + DWARFDebugAranges::ParsedCUOffsetColl &CUOffsets) + : RangeCollection(Ranges), + CUOffsetCollection(CUOffsets) {} + void operator()(const DWARFDebugArangeSet &Set) { + DWARFDebugAranges::Range Range; + Range.Offset = Set.getCompileUnitDIEOffset(); + CUOffsetCollection.insert(Range.Offset); + + for (uint32_t i = 0, n = Set.getNumDescriptors(); i < n; ++i) { + const DWARFDebugArangeSet::Descriptor *ArangeDescPtr = + Set.getDescriptor(i); + Range.LoPC = ArangeDescPtr->Address; + Range.Length = ArangeDescPtr->Length; // Insert each item in increasing address order so binary searching // can later be done! - DWARFDebugAranges::RangeColl::iterator insert_pos = + DWARFDebugAranges::RangeColl::iterator InsertPos = std::lower_bound(RangeCollection.begin(), RangeCollection.end(), - range, RangeLessThan); - RangeCollection.insert(insert_pos, range); + Range, RangeLessThan); + RangeCollection.insert(InsertPos, Range); } + } - DWARFDebugAranges::RangeColl& RangeCollection; + DWARFDebugAranges::RangeColl &RangeCollection; + DWARFDebugAranges::ParsedCUOffsetColl &CUOffsetCollection; }; } @@ -75,7 +81,7 @@ bool DWARFDebugAranges::extract(DataExtractor debug_aranges_data) { if (count > 0) { Aranges.reserve(count); - AddArangeDescriptors range_adder(Aranges); + AddArangeDescriptors range_adder(Aranges, ParsedCUOffsets); std::for_each(sets.begin(), sets.end(), range_adder); } } @@ -83,13 +89,14 @@ bool DWARFDebugAranges::extract(DataExtractor debug_aranges_data) { } bool DWARFDebugAranges::generate(DWARFContext *ctx) { - clear(); if (ctx) { const uint32_t num_compile_units = ctx->getNumCompileUnits(); for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { - DWARFCompileUnit *cu = ctx->getCompileUnitAtIndex(cu_idx); - if (cu) - cu->buildAddressRangeTable(this, true); + if (DWARFCompileUnit *cu = ctx->getCompileUnitAtIndex(cu_idx)) { + uint32_t CUOffset = cu->getOffset(); + if (ParsedCUOffsets.insert(CUOffset).second) + cu->buildAddressRangeTable(this, true); + } } } sort(true, /* overlap size */ 0); diff --git a/lib/DebugInfo/DWARFDebugAranges.h b/lib/DebugInfo/DWARFDebugAranges.h index 12afb60beb4..1509ffad41f 100644 --- a/lib/DebugInfo/DWARFDebugAranges.h +++ b/lib/DebugInfo/DWARFDebugAranges.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H #include "DWARFDebugArangeSet.h" +#include "llvm/ADT/DenseSet.h" #include namespace llvm { @@ -60,7 +61,10 @@ public: uint32_t Offset; // Offset of the compile unit or die }; - void clear() { Aranges.clear(); } + void clear() { + Aranges.clear(); + ParsedCUOffsets.clear(); + } bool allRangesAreContiguous(uint64_t& LoPC, uint64_t& HiPC) const; bool getMaxRange(uint64_t& LoPC, uint64_t& HiPC) const; bool extract(DataExtractor debug_aranges_data); @@ -88,9 +92,11 @@ public: typedef std::vector RangeColl; typedef RangeColl::const_iterator RangeCollIterator; + typedef DenseSet ParsedCUOffsetColl; private: RangeColl Aranges; + ParsedCUOffsetColl ParsedCUOffsets; }; }