summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp170
1 files changed, 85 insertions, 85 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index ebc3fdcd4f3..01b6017b32a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -14,9 +14,11 @@
#include <algorithm>
+#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"
#include "DWARFDebugInfo.h"
#include "DWARFCompileUnit.h"
@@ -73,7 +75,7 @@ public:
for (uint32_t i=0; (arange_desc_ptr = set.GetDescriptor(i)) != NULL; ++i)
{
range.lo_pc = arange_desc_ptr->address;
- range.hi_pc = arange_desc_ptr->address + arange_desc_ptr->length;
+ range.length = arange_desc_ptr->length;
// Insert each item in increasing address order so binary searching
// can later be done!
@@ -90,7 +92,7 @@ public:
static void PrintRange(const DWARFDebugAranges::Range& range)
{
// Cast the address values in case the address type is compiled as 32 bit
- printf("0x%8.8x: [0x%8.8llx - 0x%8.8llx)\n", range.offset, (long long)range.lo_pc, (long long)range.hi_pc);
+ printf("0x%8.8x: [0x%8.8llx - 0x%8.8llx)\n", range.offset, (long long)range.lo_pc, (long long)range.hi_pc());
}
//----------------------------------------------------------------------
@@ -139,13 +141,14 @@ DWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data)
DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
if (debug_info)
{
+ const bool clear_dies_if_already_not_parsed = true;
uint32_t cu_idx = 0;
const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
{
DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
if (cu)
- cu->DIE()->BuildAddressRangeTable(dwarf2Data, cu, this);
+ cu->BuildAddressRangeTable(dwarf2Data, this, clear_dies_if_already_not_parsed);
}
}
return !IsEmpty();
@@ -153,17 +156,23 @@ DWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data)
void
-DWARFDebugAranges::Print() const
+DWARFDebugAranges::Dump (Log *log) const
{
- puts("\n\nDWARFDebugAranges address range list is:\n");
- for_each(m_aranges.begin(), m_aranges.end(), PrintRange);
+ if (log == NULL)
+ return;
+ const uint32_t num_ranges = NumRanges();
+ for (uint32_t i = 0; i < num_ranges; ++i)
+ {
+ const Range &range = m_aranges[i];
+ log->Printf ("0x%8.8x: [0x%8.8llx - 0x%8.8llx)", range.offset, (uint64_t)range.lo_pc, (uint64_t)range.hi_pc());
+ }
}
void
DWARFDebugAranges::Range::Dump(Stream *s) const
{
- s->Printf("{0x%8.8x}: [0x%8.8llx - 0x%8.8llx)\n", offset, lo_pc, hi_pc);
+ s->Printf("{0x%8.8x}: [0x%8.8llx - 0x%8.8llx)\n", offset, lo_pc, hi_pc());
}
//----------------------------------------------------------------------
@@ -232,57 +241,14 @@ DWARFDebugAranges::Range::Dump(Stream *s) const
// debug_ranges.AppendMax64(0, addr_size);
//
//}
-//
-//----------------------------------------------------------------------
-// ArangeSetContainsAddress
-//----------------------------------------------------------------------
-class ArangeSetContainsAddress
-{
-public:
- ArangeSetContainsAddress (dw_addr_t the_address) : address(the_address), offset(DW_INVALID_OFFSET) {}
- bool operator() (const DWARFDebugArangeSet& set)
- {
- offset = set.FindAddress(address);
- return (offset != DW_INVALID_OFFSET);
- }
- const dw_addr_t address;
- dw_offset_t offset;
-};
-
-
-//----------------------------------------------------------------------
-// InsertRange
-//----------------------------------------------------------------------
-void
-DWARFDebugAranges::InsertRange(dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc)
-{
- // Insert each item in increasing address order so binary searching
- // can later be done!
- DWARFDebugAranges::Range range(low_pc, high_pc, offset);
- InsertRange(range);
-}
-
-//----------------------------------------------------------------------
-// InsertRange
-//----------------------------------------------------------------------
-void
-DWARFDebugAranges::InsertRange(const DWARFDebugAranges::Range& range)
-{
- // Insert each item in increasing address order so binary searching
- // can later be done!
- RangeColl::iterator insert_pos = lower_bound(m_aranges.begin(), m_aranges.end(), range, RangeLessThan);
- m_aranges.insert(insert_pos, range);
-}
-
-
void
DWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc)
{
if (!m_aranges.empty())
{
- if (m_aranges.back().offset == offset && m_aranges.back().hi_pc == low_pc)
+ if (m_aranges.back().offset == offset && m_aranges.back().hi_pc() == low_pc)
{
- m_aranges.back().hi_pc = high_pc;
+ m_aranges.back().set_hi_pc(high_pc);
return;
}
}
@@ -290,49 +256,83 @@ DWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t
}
void
-DWARFDebugAranges::Sort()
+DWARFDebugAranges::Sort (bool minimize, uint32_t n)
{
Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
__PRETTY_FUNCTION__, this);
+ Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES);
+ const size_t orig_arange_size = m_aranges.size();
+ if (log)
+ {
+ log->Printf ("DWARFDebugAranges::Sort(minimize = %u, n = %u) with %zu entries", minimize, n, orig_arange_size);
+ Dump (log);
+ }
+
+ // Size of one? If so, no sorting is needed
+ if (orig_arange_size <= 1)
+ return;
// Sort our address range entries
std::stable_sort (m_aranges.begin(), m_aranges.end(), RangeLessThan);
- // Merge all neighbouring ranges into a single range and remember the
- // indices of all ranges merged.
- const size_t old_size = m_aranges.size();
- std::vector<size_t> merged;
- for (size_t merge, cursor = 1; cursor < old_size; ++cursor)
- {
- merge = cursor - 1;
- Range &r1 = m_aranges[merge];
- Range &r2 = m_aranges[cursor];
+
+ if (!minimize)
+ return;
- if (r1.hi_pc == r2.lo_pc && r1.offset == r2.offset)
- {
- r2.lo_pc = r1.lo_pc;
- merged.push_back(merge);
- }
+ // Most address ranges are contiguous from function to function
+ // so our new ranges will likely be smaller. We calculate the size
+ // of the new ranges since although std::vector objects can be resized,
+ // the will never reduce their allocated block size and free any excesss
+ // memory, so we might as well start a brand new collection so it is as
+ // small as possible.
+
+ // First calculate the size of the new minimal arange vector
+ // so we don't have to do a bunch of re-allocations as we
+ // copy the new minimal stuff over to the new collection
+ size_t minimal_size = 1;
+ size_t i;
+ for (i=1; i<orig_arange_size; ++i)
+ {
+ if (!DWARFDebugAranges::Range::SortedOverlapCheck (m_aranges[i-1], m_aranges[i], n))
+ ++minimal_size;
}
- if (merged.empty())
+ // If the sizes are the same, then no consecutive aranges can be
+ // combined, we are done
+ if (minimal_size == orig_arange_size)
return;
- // Remove the merged ranges by shifting down all the keepers...
- const size_t new_size = old_size - merged.size();
- for (size_t i = 0, src = 0, dst = 0; dst < new_size; ++src, ++dst)
+ // Else, make a new RangeColl that _only_ contains what we need.
+ RangeColl minimal_aranges;
+ minimal_aranges.resize(minimal_size);
+ uint32_t j=0;
+ minimal_aranges[j] = m_aranges[0];
+ for (i=1; i<orig_arange_size; ++i)
{
- while (src == merged[i]) {
- ++src;
- ++i;
+ if (DWARFDebugAranges::Range::SortedOverlapCheck (minimal_aranges[j], m_aranges[i], n))
+ {
+ minimal_aranges[j].set_hi_pc (m_aranges[i].hi_pc());
+ }
+ else
+ {
+ // Only increment j if we aren't merging
+ minimal_aranges[++j] = m_aranges[i];
}
- if (src == dst)
- continue;
- m_aranges[dst] = m_aranges[src];
}
-
- // ...and drop the extra elements.
- m_aranges.resize(new_size);
+ assert (j+1 == minimal_size);
+
+ // Now swap our new minimal aranges into place. The local
+ // minimal_aranges will then contian the old big collection
+ // which will get freed.
+ minimal_aranges.swap(m_aranges);
+
+ if (log)
+ {
+ size_t delta = orig_arange_size - m_aranges.size();
+ log->Printf ("DWARFDebugAranges::Sort() %zu entries after minimizing (%zu entries combined for %zu bytes saved)",
+ m_aranges.size(), delta, delta * sizeof(Range));
+ Dump (log);
+ }
}
//----------------------------------------------------------------------
@@ -348,7 +348,7 @@ DWARFDebugAranges::FindAddress(dw_addr_t address) const
DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
DWARFDebugAranges::RangeCollIterator pos = lower_bound(begin, end, range, RangeLessThan);
- if ((pos != end) && (pos->lo_pc <= address && address < pos->hi_pc))
+ if ((pos != end) && (pos->lo_pc <= address && address < pos->hi_pc()))
{
// printf("FindAddress(1) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
return pos->offset;
@@ -356,7 +356,7 @@ DWARFDebugAranges::FindAddress(dw_addr_t address) const
else if (pos != begin)
{
--pos;
- if ((pos->lo_pc <= address) && (address < pos->hi_pc))
+ if ((pos->lo_pc <= address) && (address < pos->hi_pc()))
{
// printf("FindAddress(2) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
return (*pos).offset;
@@ -384,10 +384,10 @@ DWARFDebugAranges::AllRangesAreContiguous(dw_addr_t& lo_pc, dw_addr_t& hi_pc) co
{
if ((pos != begin) && (pos->lo_pc != next_addr))
return false;
- next_addr = pos->hi_pc;
+ next_addr = pos->hi_pc();
}
lo_pc = m_aranges.front().lo_pc; // We checked for empty at the start of function so front() will be valid
- hi_pc = m_aranges.back().hi_pc; // We checked for empty at the start of function so back() will be valid
+ hi_pc = m_aranges.back().hi_pc(); // We checked for empty at the start of function so back() will be valid
return true;
}
@@ -398,7 +398,7 @@ DWARFDebugAranges::GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
return false;
lo_pc = m_aranges.front().lo_pc; // We checked for empty at the start of function so front() will be valid
- hi_pc = m_aranges.back().hi_pc; // We checked for empty at the start of function so back() will be valid
+ hi_pc = m_aranges.back().hi_pc(); // We checked for empty at the start of function so back() will be valid
return true;
}
OpenPOWER on IntegriCloud