[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
This commit is contained in:
Alexey Samsonov 2012-11-16 08:36:25 +00:00
parent 9bd4dd742e
commit 63a450a313
3 changed files with 38 additions and 23 deletions

View File

@ -91,7 +91,9 @@ const DWARFDebugAranges *DWARFContext::getDebugAranges() {
Aranges.reset(new DWARFDebugAranges()); Aranges.reset(new DWARFDebugAranges());
Aranges->extract(arangesData); Aranges->extract(arangesData);
if (Aranges->isEmpty()) // No aranges in file, generate them from the DIEs. // 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); Aranges->generate(this);
return Aranges.get(); return Aranges.get();
} }

View File

@ -26,34 +26,40 @@ namespace {
class CountArangeDescriptors { class CountArangeDescriptors {
public: public:
CountArangeDescriptors(uint32_t &count_ref) : Count(count_ref) {} CountArangeDescriptors(uint32_t &count_ref) : Count(count_ref) {}
void operator()(const DWARFDebugArangeSet &set) { void operator()(const DWARFDebugArangeSet &Set) {
Count += set.getNumDescriptors(); Count += Set.getNumDescriptors();
} }
uint32_t &Count; uint32_t &Count;
}; };
class AddArangeDescriptors { class AddArangeDescriptors {
public: public:
AddArangeDescriptors(DWARFDebugAranges::RangeColl &ranges) AddArangeDescriptors(DWARFDebugAranges::RangeColl &Ranges,
: RangeCollection(ranges) {} DWARFDebugAranges::ParsedCUOffsetColl &CUOffsets)
void operator()(const DWARFDebugArangeSet& set) { : RangeCollection(Ranges),
const DWARFDebugArangeSet::Descriptor* arange_desc_ptr; CUOffsetCollection(CUOffsets) {}
DWARFDebugAranges::Range range; void operator()(const DWARFDebugArangeSet &Set) {
range.Offset = set.getCompileUnitDIEOffset(); DWARFDebugAranges::Range Range;
Range.Offset = Set.getCompileUnitDIEOffset();
CUOffsetCollection.insert(Range.Offset);
for (uint32_t i=0; (arange_desc_ptr = set.getDescriptor(i)) != NULL; ++i){ for (uint32_t i = 0, n = Set.getNumDescriptors(); i < n; ++i) {
range.LoPC = arange_desc_ptr->Address; const DWARFDebugArangeSet::Descriptor *ArangeDescPtr =
range.Length = arange_desc_ptr->Length; Set.getDescriptor(i);
Range.LoPC = ArangeDescPtr->Address;
Range.Length = ArangeDescPtr->Length;
// Insert each item in increasing address order so binary searching // Insert each item in increasing address order so binary searching
// can later be done! // can later be done!
DWARFDebugAranges::RangeColl::iterator insert_pos = DWARFDebugAranges::RangeColl::iterator InsertPos =
std::lower_bound(RangeCollection.begin(), RangeCollection.end(), std::lower_bound(RangeCollection.begin(), RangeCollection.end(),
range, RangeLessThan); Range, RangeLessThan);
RangeCollection.insert(insert_pos, range); 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) { if (count > 0) {
Aranges.reserve(count); Aranges.reserve(count);
AddArangeDescriptors range_adder(Aranges); AddArangeDescriptors range_adder(Aranges, ParsedCUOffsets);
std::for_each(sets.begin(), sets.end(), range_adder); std::for_each(sets.begin(), sets.end(), range_adder);
} }
} }
@ -83,15 +89,16 @@ bool DWARFDebugAranges::extract(DataExtractor debug_aranges_data) {
} }
bool DWARFDebugAranges::generate(DWARFContext *ctx) { bool DWARFDebugAranges::generate(DWARFContext *ctx) {
clear();
if (ctx) { if (ctx) {
const uint32_t num_compile_units = ctx->getNumCompileUnits(); const uint32_t num_compile_units = ctx->getNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
DWARFCompileUnit *cu = ctx->getCompileUnitAtIndex(cu_idx); if (DWARFCompileUnit *cu = ctx->getCompileUnitAtIndex(cu_idx)) {
if (cu) uint32_t CUOffset = cu->getOffset();
if (ParsedCUOffsets.insert(CUOffset).second)
cu->buildAddressRangeTable(this, true); cu->buildAddressRangeTable(this, true);
} }
} }
}
sort(true, /* overlap size */ 0); sort(true, /* overlap size */ 0);
return !isEmpty(); return !isEmpty();
} }

View File

@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H #define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
#include "DWARFDebugArangeSet.h" #include "DWARFDebugArangeSet.h"
#include "llvm/ADT/DenseSet.h"
#include <list> #include <list>
namespace llvm { namespace llvm {
@ -60,7 +61,10 @@ public:
uint32_t Offset; // Offset of the compile unit or die 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 allRangesAreContiguous(uint64_t& LoPC, uint64_t& HiPC) const;
bool getMaxRange(uint64_t& LoPC, uint64_t& HiPC) const; bool getMaxRange(uint64_t& LoPC, uint64_t& HiPC) const;
bool extract(DataExtractor debug_aranges_data); bool extract(DataExtractor debug_aranges_data);
@ -88,9 +92,11 @@ public:
typedef std::vector<Range> RangeColl; typedef std::vector<Range> RangeColl;
typedef RangeColl::const_iterator RangeCollIterator; typedef RangeColl::const_iterator RangeCollIterator;
typedef DenseSet<uint32_t> ParsedCUOffsetColl;
private: private:
RangeColl Aranges; RangeColl Aranges;
ParsedCUOffsetColl ParsedCUOffsets;
}; };
} }