Added more functionality to Range template classes in RangeMap.h and converted remaining DWARF areas that were using ranges over to this class. Also converted lldb_private::Block to use it.

llvm-svn: 141460
This commit is contained in:
Greg Clayton 2011-10-08 00:49:15 +00:00
parent 0ad4caa263
commit ea3e7d5ccf
12 changed files with 455 additions and 317 deletions

View File

@ -46,6 +46,13 @@ namespace lldb_private {
{
}
void
Clear (BaseType b = 0)
{
base = b;
size = 0;
}
// Set the start value for the range, and keep the same size
BaseType
GetRangeBase () const
@ -59,6 +66,12 @@ namespace lldb_private {
base = b;
}
void
Slide (BaseType slide)
{
base += slide;
}
BaseType
GetRangeEnd () const
{
@ -111,7 +124,18 @@ namespace lldb_private {
}
bool
operator < (const Range &rhs)
Overlap (const Range &rhs) const
{
const BaseType lhs_base = this->GetRangeBase();
const BaseType rhs_base = rhs.GetRangeBase();
const BaseType lhs_end = this->GetRangeEnd();
const BaseType rhs_end = rhs.GetRangeEnd();
bool result = (lhs_base <= rhs_end) && (lhs_end >= rhs_base);
return result;
}
bool
operator < (const Range &rhs) const
{
if (base == rhs.base)
return size < rhs.size;
@ -119,13 +143,13 @@ namespace lldb_private {
}
bool
operator == (const Range &rhs)
operator == (const Range &rhs) const
{
return base == rhs.base && size == rhs.size;
}
bool
operator != (const Range &rhs)
operator != (const Range &rhs) const
{
return base != rhs.base || size != rhs.size;
}
@ -139,9 +163,13 @@ namespace lldb_private {
template <typename B, typename S>
class RangeArray
{
public:
typedef B BaseType;
typedef S SizeType;
typedef Range<B,S> Entry;
RangeArray ()
RangeArray () :
m_entries ()
{
}
@ -163,41 +191,75 @@ namespace lldb_private {
}
void
CombineConsecutiveEntriesWithEqualData ()
CombineConsecutiveRanges ()
{
typename std::vector<Entry>::iterator pos;
typename std::vector<Entry>::iterator end;
typename std::vector<Entry>::iterator prev;
bool can_combine = false;
// First we determine if we can combine any of the Entry objects so we
// don't end up allocating and making a new collection for no reason
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
// Can't combine if ranges if we have zero or one range
if (m_entries.size() > 1)
{
if (prev != end && prev->data == pos->data)
{
can_combine = true;
break;
}
}
// We we can combine at least one entry, then we make a new collection
// and populate it accordingly, and then swap it into place.
if (can_combine)
{
std::vector<Entry> minimal_ranges;
// The list should be sorted prior to calling this function
typename std::vector<Entry>::iterator pos;
typename std::vector<Entry>::iterator end;
typename std::vector<Entry>::iterator prev;
bool can_combine = false;
// First we determine if we can combine any of the Entry objects so we
// don't end up allocating and making a new collection for no reason
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
{
if (prev != end && prev->data == pos->data)
minimal_ranges.back().range.SetEnd (pos->range.GetRangeEnd());
else
minimal_ranges.push_back (*pos);
if (prev != end && prev->Overlap(*pos))
{
can_combine = true;
break;
}
}
// We we can combine at least one entry, then we make a new collection
// and populate it accordingly, and then swap it into place.
if (can_combine)
{
std::vector<Entry> minimal_ranges;
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
{
if (prev != end && prev->Overlap(*pos))
minimal_ranges.back().SetRangeEnd (std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
else
minimal_ranges.push_back (*pos);
}
// Use the swap technique in case our new vector is much smaller.
// We must swap when using the STL because std::vector objects never
// release or reduce the memory once it has been allocated/reserved.
m_entries.swap (minimal_ranges);
}
// Use the swap technique in case our new vector is much smaller.
// We must swap when using the STL because std::vector objects never
// release or reduce the memory once it has been allocated/reserved.
m_entries.swap (minimal_ranges);
}
}
BaseType
GetMinRangeBase (BaseType fail_value) const
{
if (m_entries.empty())
return fail_value;
// m_entries must be sorted, so if we aren't empty, we grab the
// first range's base
return m_entries.front().GetRangeBase();
}
BaseType
GetMaxRangeEnd (BaseType fail_value) const
{
if (m_entries.empty())
return fail_value;
// m_entries must be sorted, so if we aren't empty, we grab the
// last range's end
return m_entries.back().GetRangeEnd();
}
void
Slide (BaseType slide)
{
typename std::vector<Entry>::iterator pos, end;
for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos)
pos->Slide (slide);
}
void
Clear ()
@ -212,25 +274,56 @@ namespace lldb_private {
}
size_t
GetNumEntries () const
GetSize () const
{
return m_entries.size();
}
const Entry *
GetEntryAtIndex (uint32_t i) const
GetEntryAtIndex (size_t i) const
{
if (i<m_entries.size())
return &m_entries[i];
return NULL;
}
// Clients must ensure that "i" is a valid index prior to calling this function
const Entry &
GetEntryRef (size_t i) const
{
return m_entries[i];
}
static bool
BaseLessThan (const Entry& lhs, const Entry& rhs)
{
return lhs.GetRangeBase() < rhs.GetRangeBase();
}
uint32_t
FindEntryIndexThatContains (B addr) const
{
if ( !m_entries.empty() )
{
Entry entry (addr, 1);
typename std::vector<Entry>::const_iterator begin = m_entries.begin();
typename std::vector<Entry>::const_iterator end = m_entries.end();
typename std::vector<Entry>::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
if (pos != end && pos->Contains(addr))
{
return std::distance (begin, pos);
}
else if (pos != begin)
{
--pos;
if (pos->Contains(addr))
return std::distance (begin, pos);
}
}
return UINT32_MAX;
}
const Entry *
FindEntryThatContains (B addr) const
{
@ -256,7 +349,32 @@ namespace lldb_private {
}
return NULL;
}
const Entry *
FindEntryThatContains (const Entry &range) const
{
if ( !m_entries.empty() )
{
typename std::vector<Entry>::const_iterator begin = m_entries.begin();
typename std::vector<Entry>::const_iterator end = m_entries.end();
typename std::vector<Entry>::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
if (pos != end && pos->Contains(range))
{
return &(*pos);
}
else if (pos != begin)
{
--pos;
if (pos->Contains(range))
{
return &(*pos);
}
}
}
return NULL;
}
protected:
std::vector<Entry> m_entries;
};
@ -392,25 +510,56 @@ namespace lldb_private {
}
size_t
GetNumEntries () const
GetSize () const
{
return m_entries.size();
}
const Entry *
GetEntryAtIndex (uint32_t i) const
GetEntryAtIndex (size_t i) const
{
if (i<m_entries.size())
return &m_entries[i];
return NULL;
}
// Clients must ensure that "i" is a valid index prior to calling this function
const Entry &
GetEntryRef (size_t i) const
{
return m_entries[i];
}
static bool
BaseLessThan (const Entry& lhs, const Entry& rhs)
{
return lhs.GetRangeBase() < rhs.GetRangeBase();
}
uint32_t
FindEntryIndexThatContains (B addr) const
{
if ( !m_entries.empty() )
{
Entry entry (addr, 1);
typename std::vector<Entry>::const_iterator begin = m_entries.begin();
typename std::vector<Entry>::const_iterator end = m_entries.end();
typename std::vector<Entry>::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
if (pos != end && pos->Contains(addr))
{
return std::distance (begin, pos);
}
else if (pos != begin)
{
--pos;
if (pos->Contains(addr))
return std::distance (begin, pos);
}
}
return UINT32_MAX;
}
const Entry *
FindEntryThatContains (B addr) const
{
@ -439,6 +588,32 @@ namespace lldb_private {
return NULL;
}
const Entry *
FindEntryThatContains (const Entry &range) const
{
if ( !m_entries.empty() )
{
typename std::vector<Entry>::const_iterator begin = m_entries.begin();
typename std::vector<Entry>::const_iterator end = m_entries.end();
typename std::vector<Entry>::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
if (pos != end && pos->Contains(range))
{
return &(*pos);
}
else if (pos != begin)
{
--pos;
if (pos->Contains(range))
{
return &(*pos);
}
}
}
return NULL;
}
protected:
std::vector<Entry> m_entries;
};

View File

@ -12,9 +12,9 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/UserID.h"
#include "lldb/Core/VMRange.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Symbol/SymbolContext.h"
@ -43,6 +43,8 @@ class Block :
public SymbolContextScope
{
public:
typedef RangeArray<uint32_t, uint32_t> RangeArray;
typedef RangeArray::Entry Range;
//------------------------------------------------------------------
/// Construct with a User ID \a uid, \a depth.
@ -97,7 +99,10 @@ public:
/// describes the end address of a range for this block.
//------------------------------------------------------------------
void
AddRange (const VMRange& range);
AddRange (const Range& range);
void
FinalizeRanges ();
//------------------------------------------------------------------
/// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
@ -143,7 +148,7 @@ public:
/// block's ranges, \b false otherwise.
//------------------------------------------------------------------
bool
Contains (const VMRange& range) const;
Contains (const Range& range) const;
//------------------------------------------------------------------
/// Check if this object contains "block" as a child block at any
@ -421,14 +426,17 @@ public:
uint32_t
GetNumRanges () const
{
return m_ranges.size();
return m_ranges.GetSize();
}
bool
GetRangeContainingOffset (const lldb::addr_t offset, VMRange &range);
GetRangeContainingOffset (const lldb::addr_t offset, Range &range);
bool
GetRangeContainingAddress (const Address& addr, AddressRange &range, uint32_t *range_idx_ptr = NULL);
GetRangeContainingAddress (const Address& addr, AddressRange &range);
uint32_t
GetRangeIndexContainingAddress (const Address& addr);
//------------------------------------------------------------------
// Since blocks might have multiple discontiguous addresss ranges,
@ -451,7 +459,7 @@ protected:
//------------------------------------------------------------------
SymbolContextScope *m_parent_scope;
collection m_children;
VMRange::collection m_ranges; ///< A list of address offset ranges relative to the function's section/offset address.
RangeArray m_ranges;
lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information.
lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and paramter variables scoped to this block.
bool m_parsed_block_info:1, ///< Set to true if this block and it's children have all been parsed

View File

@ -237,12 +237,7 @@ SBBlock::GetRangeIndexForBlockAddress (lldb::SBAddress block_addr)
{
if (m_opaque_ptr && block_addr.IsValid())
{
uint32_t range_idx = UINT32_MAX;
AddressRange range;
if (m_opaque_ptr->GetRangeContainingAddress (block_addr.ref(), range, &range_idx))
{
return range_idx;
}
return m_opaque_ptr->GetRangeIndexContainingAddress (block_addr.ref());
}
return UINT32_MAX;

View File

@ -113,7 +113,7 @@ DWARFDebugAranges::Dump (Log *log) const
if (log == NULL)
return;
const size_t num_entries = m_aranges.GetNumEntries();
const size_t num_entries = m_aranges.GetSize();
for (size_t i=0; i<num_entries; ++i)
{
const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
@ -141,7 +141,7 @@ DWARFDebugAranges::Sort (bool minimize)
size_t orig_arange_size = 0;
if (log)
{
orig_arange_size = m_aranges.GetNumEntries();
orig_arange_size = m_aranges.GetSize();
log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %zu entries", minimize, orig_arange_size);
}
@ -152,7 +152,7 @@ DWARFDebugAranges::Sort (bool minimize)
{
if (minimize)
{
const size_t new_arange_size = m_aranges.GetNumEntries();
const size_t new_arange_size = m_aranges.GetSize();
const size_t delta = orig_arange_size - new_arange_size;
log->Printf ("DWARFDebugAranges::Sort() %zu entries after minimizing (%zu entries combined for %zu bytes saved)",
new_arange_size, delta, delta * sizeof(Range));

View File

@ -69,7 +69,7 @@ public:
uint32_t
GetNumRanges() const
{
return m_aranges.GetNumEntries();
return m_aranges.GetSize();
}
dw_offset_t

View File

@ -933,7 +933,7 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
// All DW_AT_ranges are relative to the base address of the
// compile unit. We add the compile unit base address to make
// sure all the addresses are properly fixed up.
ranges.AddOffset(cu->GetBaseAddress());
ranges.Slide(cu->GetBaseAddress());
}
break;
@ -1024,26 +1024,25 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
}
}
size_t numRanges = ranges.Size();
if (numRanges == 0)
if (ranges.IsEmpty())
{
if (lo_pc != DW_INVALID_ADDRESS)
{
if (hi_pc != DW_INVALID_ADDRESS)
ranges.AddRange(lo_pc, hi_pc);
if (hi_pc != DW_INVALID_ADDRESS && hi_pc > lo_pc)
ranges.Append(DWARFDebugRanges::Range (lo_pc, hi_pc - lo_pc));
else
ranges.AddRange(lo_pc, lo_pc);
ranges.Append(DWARFDebugRanges::Range (lo_pc, 0));
}
}
if (set_frame_base_loclist_addr)
{
assert (ranges.LowestAddress(0) >= cu->GetBaseAddress());
frame_base->SetLocationListSlide(ranges.LowestAddress(0) - cu->GetBaseAddress());
dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
assert (lowest_range_pc >= cu->GetBaseAddress());
frame_base->SetLocationListSlide (lowest_range_pc - cu->GetBaseAddress());
}
if (ranges.Size() == 0 || (name == NULL) || (mangled == NULL))
if (ranges.IsEmpty() || name == NULL || mangled == NULL)
{
std::vector<dw_offset_t>::const_iterator pos;
std::vector<dw_offset_t>::const_iterator end = die_offsets.end();
@ -1060,7 +1059,7 @@ DWARFDebugInfoEntry::GetDIENamesAndRanges
}
}
}
return ranges.Size() > 0;
return !ranges.IsEmpty();
}
//----------------------------------------------------------------------
@ -2038,8 +2037,8 @@ DWARFDebugInfoEntry::LookupAddress
// All DW_AT_ranges are relative to the base address of the
// compile unit. We add the compile unit base address to make
// sure all the addresses are properly fixed up.
ranges.AddOffset(cu->GetBaseAddress());
if (ranges.Lookup(address))
ranges.Slide (cu->GetBaseAddress());
if (ranges.FindEntryThatContains(address))
{
found_address = true;
// puts("***MATCH***");

View File

@ -30,94 +30,62 @@ DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data)
RangeList range_list;
dw_offset_t offset = 0;
dw_offset_t debug_ranges_offset = offset;
while (range_list.Extract(dwarf2Data, &offset))
while (Extract(dwarf2Data, &offset, range_list))
{
m_range_map[debug_ranges_offset] = range_list;
debug_ranges_offset = offset;
}
}
bool
DWARFDebugRanges::RangeList::AddRange(dw_addr_t lo_addr, dw_addr_t hi_addr)
{
if (lo_addr <= hi_addr)
{
Range range(lo_addr, hi_addr);
ranges.push_back(range);
return true;
}
return false;
}
const DWARFDebugRanges::Range*
DWARFDebugRanges::RangeList::Lookup(dw_addr_t offset) const
{
Range::const_iterator pos = ranges.begin();
Range::const_iterator end_pos = ranges.end();
for (pos = ranges.begin(); pos != end_pos; ++pos)
{
if (pos->begin_offset <= offset && offset < pos->end_offset)
{
return &(*pos);
}
}
return NULL;
}
size_t
DWARFDebugRanges::RangeList::Size() const
{
return ranges.size();
}
void
DWARFDebugRanges::RangeList::AddOffset(dw_addr_t offset)
{
if (!ranges.empty())
{
Range::iterator pos = ranges.begin();
Range::iterator end_pos = ranges.end();
for (pos = ranges.begin(); pos != end_pos; ++pos)
{
// assert for unsigned overflows
assert (~pos->begin_offset >= offset);
assert (~pos->end_offset >= offset);
pos->begin_offset += offset;
pos->end_offset += offset;
}
}
}
void
DWARFDebugRanges::RangeList::SubtractOffset(dw_addr_t offset)
{
if (!ranges.empty())
{
Range::iterator pos = ranges.begin();
Range::iterator end_pos = ranges.end();
for (pos = ranges.begin(); pos != end_pos; ++pos)
{
assert (pos->begin_offset >= offset);
assert (pos->end_offset >= offset);
pos->begin_offset -= offset;
pos->end_offset -= offset;
}
}
}
const DWARFDebugRanges::Range*
DWARFDebugRanges::RangeList::RangeAtIndex(size_t i) const
{
if (i < ranges.size())
return &ranges[i];
return NULL;
}
//void
//DWARFDebugRanges::RangeList::AddOffset(dw_addr_t offset)
//{
// if (!ranges.empty())
// {
// Range::iterator pos = ranges.begin();
// Range::iterator end_pos = ranges.end();
// for (pos = ranges.begin(); pos != end_pos; ++pos)
// {
// // assert for unsigned overflows
// assert (~pos->begin_offset >= offset);
// assert (~pos->end_offset >= offset);
// pos->begin_offset += offset;
// pos->end_offset += offset;
// }
// }
//}
//
//void
//DWARFDebugRanges::RangeList::SubtractOffset(dw_addr_t offset)
//{
// if (!ranges.empty())
// {
// Range::iterator pos = ranges.begin();
// Range::iterator end_pos = ranges.end();
// for (pos = ranges.begin(); pos != end_pos; ++pos)
// {
// assert (pos->begin_offset >= offset);
// assert (pos->end_offset >= offset);
// pos->begin_offset -= offset;
// pos->end_offset -= offset;
// }
// }
//}
//
//
//const DWARFDebugRanges::Range*
//DWARFDebugRanges::RangeList::RangeAtIndex(size_t i) const
//{
// if (i < ranges.size())
// return &ranges[i];
// return NULL;
//}
bool
DWARFDebugRanges::RangeList::Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr)
DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr, RangeList &range_list)
{
Clear();
range_list.Clear();
uint32_t range_offset = *offset_ptr;
const DataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data();
uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
@ -154,65 +122,65 @@ DWARFDebugRanges::RangeList::Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offs
}
// Filter out empty ranges
if (begin != end)
ranges.push_back(Range(begin, end));
if (begin < end)
range_list.Append(Range(begin, end - begin));
}
// Make sure we consumed at least something
return range_offset != *offset_ptr;
}
dw_addr_t
DWARFDebugRanges::RangeList::LowestAddress(const dw_addr_t cu_base_addr) const
{
dw_addr_t addr = DW_INVALID_ADDRESS;
dw_addr_t curr_base_addr = cu_base_addr;
if (!ranges.empty())
{
Range::const_iterator pos = ranges.begin();
Range::const_iterator end_pos = ranges.end();
for (pos = ranges.begin(); pos != end_pos; ++pos)
{
if (pos->begin_offset == DW_INVALID_ADDRESS)
curr_base_addr = pos->end_offset;
else if (curr_base_addr != DW_INVALID_ADDRESS)
{
dw_addr_t curr_addr = curr_base_addr + pos->begin_offset;
if (addr > curr_addr)
addr = curr_addr;
}
}
}
return addr;
}
dw_addr_t
DWARFDebugRanges::RangeList::HighestAddress(const dw_addr_t cu_base_addr) const
{
dw_addr_t addr = 0;
dw_addr_t curr_base_addr = cu_base_addr;
if (!ranges.empty())
{
Range::const_iterator pos = ranges.begin();
Range::const_iterator end_pos = ranges.end();
for (pos = ranges.begin(); pos != end_pos; ++pos)
{
if (pos->begin_offset == DW_INVALID_ADDRESS)
curr_base_addr = pos->end_offset;
else if (curr_base_addr != DW_INVALID_ADDRESS)
{
dw_addr_t curr_addr = curr_base_addr + pos->end_offset;
if (addr < curr_addr)
addr = curr_addr;
}
}
}
if (addr != 0)
return addr;
return DW_INVALID_ADDRESS;
}
//
//dw_addr_t
//DWARFDebugRanges::RangeList::LowestAddress(const dw_addr_t cu_base_addr) const
//{
// dw_addr_t addr = DW_INVALID_ADDRESS;
// dw_addr_t curr_base_addr = cu_base_addr;
// if (!ranges.empty())
// {
// Range::const_iterator pos = ranges.begin();
// Range::const_iterator end_pos = ranges.end();
// for (pos = ranges.begin(); pos != end_pos; ++pos)
// {
// if (pos->begin_offset == DW_INVALID_ADDRESS)
// curr_base_addr = pos->end_offset;
// else if (curr_base_addr != DW_INVALID_ADDRESS)
// {
// dw_addr_t curr_addr = curr_base_addr + pos->begin_offset;
// if (addr > curr_addr)
// addr = curr_addr;
// }
// }
// }
// return addr;
//}
//
//dw_addr_t
//DWARFDebugRanges::RangeList::HighestAddress(const dw_addr_t cu_base_addr) const
//{
// dw_addr_t addr = 0;
// dw_addr_t curr_base_addr = cu_base_addr;
// if (!ranges.empty())
// {
// Range::const_iterator pos = ranges.begin();
// Range::const_iterator end_pos = ranges.end();
// for (pos = ranges.begin(); pos != end_pos; ++pos)
// {
// if (pos->begin_offset == DW_INVALID_ADDRESS)
// curr_base_addr = pos->end_offset;
// else if (curr_base_addr != DW_INVALID_ADDRESS)
// {
// dw_addr_t curr_addr = curr_base_addr + pos->end_offset;
// if (addr < curr_addr)
// addr = curr_addr;
// }
// }
// }
// if (addr != 0)
// return addr;
// return DW_INVALID_ADDRESS;
//}
//
void
DWARFDebugRanges::Dump(Stream &s, const DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr)

View File

@ -11,66 +11,17 @@
#define SymbolFileDWARF_DWARFDebugRanges_h_
#include "SymbolFileDWARF.h"
#include <map>
#include <vector>
#include "lldb/Core/RangeMap.h"
class DWARFDebugRanges
{
public:
//------------------------------------------------------------------
// Address range
//------------------------------------------------------------------
struct Range
{
Range(dw_addr_t begin = DW_INVALID_ADDRESS, dw_addr_t end = DW_INVALID_ADDRESS) :
begin_offset(begin),
end_offset(end)
{
}
void Clear()
{
begin_offset = DW_INVALID_ADDRESS;
end_offset = DW_INVALID_ADDRESS;
}
dw_addr_t begin_offset;
dw_addr_t end_offset;
typedef std::vector<Range> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
};
//------------------------------------------------------------------
// Collection of ranges
//------------------------------------------------------------------
struct RangeList
{
RangeList() :
ranges()
{
}
bool Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr);
bool AddRange(dw_addr_t lo_addr, dw_addr_t hi_addr);
void Clear()
{
ranges.clear();
}
dw_addr_t LowestAddress(const dw_addr_t base_addr) const;
dw_addr_t HighestAddress(const dw_addr_t base_addr) const;
void AddOffset(dw_addr_t offset);
void SubtractOffset(dw_addr_t offset);
size_t Size() const;
const Range* RangeAtIndex(size_t i) const;
const Range* Lookup(dw_addr_t offset) const;
Range::collection ranges;
};
typedef lldb_private::RangeArray<dw_addr_t, dw_addr_t> RangeList;
typedef RangeList::Entry Range;
DWARFDebugRanges();
~DWARFDebugRanges();
@ -79,6 +30,12 @@ public:
bool FindRanges(dw_offset_t debug_ranges_offset, DWARFDebugRanges::RangeList& range_list) const;
protected:
bool
Extract (SymbolFileDWARF* dwarf2Data,
uint32_t* offset_ptr,
RangeList &range_list);
typedef std::map<dw_offset_t, RangeList> range_map;
typedef range_map::iterator range_map_iterator;
typedef range_map::const_iterator range_map_const_iterator;

View File

@ -650,20 +650,19 @@ SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
}
static void
AddRangesToBlock
(
Block& block,
DWARFDebugRanges::RangeList& ranges,
addr_t block_base_addr
)
AddRangesToBlock (Block& block,
DWARFDebugRanges::RangeList& ranges,
addr_t block_base_addr)
{
ranges.SubtractOffset (block_base_addr);
size_t range_idx = 0;
const DWARFDebugRanges::Range *debug_range;
for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
const size_t num_ranges = ranges.GetSize();
for (size_t i = 0; i<num_ranges; ++i)
{
block.AddRange(VMRange (debug_range->begin_offset, debug_range->end_offset));
const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
const addr_t range_base = range.GetRangeBase();
assert (range_base >= block_base_addr);
block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
}
block.FinalizeRanges ();
}
@ -690,8 +689,8 @@ SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompile
{
// Union of all ranges in the function DIE (if the function is discontiguous)
AddressRange func_range;
lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
{
func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
@ -1054,7 +1053,7 @@ SymbolFileDWARF::ParseFunctionBlocks
if (tag == DW_TAG_subprogram)
{
assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
subprogram_low_pc = ranges.LowestAddress(0);
subprogram_low_pc = ranges.GetMinRangeBase(0);
}
else if (tag == DW_TAG_inlined_subroutine)
{
@ -1068,7 +1067,7 @@ SymbolFileDWARF::ParseFunctionBlocks
// function the offset will be for that function.
if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
{
subprogram_low_pc = ranges.LowestAddress(0);
subprogram_low_pc = ranges.GetMinRangeBase(0);
}
}

View File

@ -44,8 +44,8 @@ Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel leve
{
*s << "id = " << ((const UserID&)*this);
size_t num_ranges = m_ranges.size();
if (num_ranges)
size_t num_ranges = m_ranges.GetSize();
if (num_ranges > 0)
{
addr_t base_addr = LLDB_INVALID_ADDRESS;
@ -55,9 +55,11 @@ Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel leve
base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
s->Printf(", range%s = ", num_ranges > 1 ? "s" : "");
std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
for (pos = m_ranges.begin(); pos != end; ++pos)
pos->Dump(s, base_addr, 4);
for (size_t i=0; i<num_ranges; ++i)
{
const Range &range = m_ranges.GetEntryRef(i);
s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
}
}
if (m_inlineInfoSP.get() != NULL)
@ -95,18 +97,19 @@ Block::Dump(Stream *s, addr_t base_addr, int32_t depth, bool show_context) const
m_inlineInfoSP->Dump(s, show_fullpaths);
}
if (!m_ranges.empty())
if (!m_ranges.IsEmpty())
{
*s << ", ranges =";
std::vector<VMRange>::const_iterator pos;
std::vector<VMRange>::const_iterator end = m_ranges.end();
for (pos = m_ranges.begin(); pos != end; ++pos)
size_t num_ranges = m_ranges.GetSize();
for (size_t i=0; i<num_ranges; ++i)
{
if (parent_block != NULL && parent_block->Contains(*pos) == false)
const Range &range = m_ranges.GetEntryRef(i);
if (parent_block != NULL && parent_block->Contains(range) == false)
*s << '!';
else
*s << ' ';
pos->Dump(s, base_addr);
s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
}
}
s->EOL();
@ -197,18 +200,21 @@ Block::DumpSymbolContext(Stream *s)
void
Block::DumpAddressRanges (Stream *s, lldb::addr_t base_addr)
{
if (!m_ranges.empty())
if (!m_ranges.IsEmpty())
{
std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
for (pos = m_ranges.begin(); pos != end; ++pos)
pos->Dump (s, base_addr);
size_t num_ranges = m_ranges.GetSize();
for (size_t i=0; i<num_ranges; ++i)
{
const Range &range = m_ranges.GetEntryRef(i);
s->AddressRange(base_addr + range.GetRangeBase(), base_addr + range.GetRangeEnd(), 4);
}
}
}
bool
Block::Contains (addr_t range_offset) const
{
return VMRange::ContainsValue(m_ranges, range_offset);
return m_ranges.FindEntryThatContains(range_offset) != NULL;
}
bool
@ -230,9 +236,9 @@ Block::Contains (const Block *block) const
}
bool
Block::Contains (const VMRange& range) const
Block::Contains (const Range& range) const
{
return VMRange::ContainsRange(m_ranges, range);
return m_ranges.FindEntryThatContains (range) != NULL;
}
Block *
@ -267,12 +273,12 @@ Block::GetInlinedParent ()
bool
Block::GetRangeContainingOffset (const addr_t offset, VMRange &range)
Block::GetRangeContainingOffset (const addr_t offset, Range &range)
{
uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset);
if (range_idx < m_ranges.size())
const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
if (range_ptr)
{
range = m_ranges[range_idx];
range = *range_ptr;
return true;
}
range.Clear();
@ -281,7 +287,7 @@ Block::GetRangeContainingOffset (const addr_t offset, VMRange &range)
bool
Block::GetRangeContainingAddress (const Address& addr, AddressRange &range, uint32_t *range_idx_ptr)
Block::GetRangeContainingAddress (const Address& addr, AddressRange &range)
{
Function *function = CalculateSymbolContextFunction();
if (function)
@ -295,36 +301,55 @@ Block::GetRangeContainingAddress (const Address& addr, AddressRange &range, uint
{
addr_t offset = addr_offset - func_offset;
uint32_t range_idx = VMRange::FindRangeIndexThatContainsValue (m_ranges, offset);
if (range_idx < m_ranges.size())
const Range *range_ptr = m_ranges.FindEntryThatContains (offset);
if (range_ptr)
{
range.GetBaseAddress() = func_range.GetBaseAddress();
range.GetBaseAddress().SetOffset(func_offset + m_ranges[range_idx].GetBaseAddress());
range.SetByteSize(m_ranges[range_idx].GetByteSize());
if (range_idx_ptr)
*range_idx_ptr = range_idx;
range.GetBaseAddress().SetOffset(func_offset + range_ptr->GetRangeBase());
range.SetByteSize(range_ptr->GetByteSize());
return true;
}
}
}
}
if (range_idx_ptr)
*range_idx_ptr = UINT32_MAX;
range.Clear();
return false;
}
uint32_t
Block::GetRangeIndexContainingAddress (const Address& addr)
{
Function *function = CalculateSymbolContextFunction();
if (function)
{
const AddressRange &func_range = function->GetAddressRange();
if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
{
const addr_t addr_offset = addr.GetOffset();
const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
{
addr_t offset = addr_offset - func_offset;
return m_ranges.FindEntryIndexThatContains (offset);
}
}
}
return UINT32_MAX;
}
bool
Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
{
if (range_idx < m_ranges.size())
if (range_idx < m_ranges.GetSize())
{
Function *function = CalculateSymbolContextFunction();
if (function)
{
const Range &vm_range = m_ranges.GetEntryRef(range_idx);
range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
range.GetBaseAddress().Slide(m_ranges[range_idx].GetBaseAddress ());
range.SetByteSize (m_ranges[range_idx].GetByteSize());
range.GetBaseAddress().Slide(vm_range.GetRangeBase ());
range.SetByteSize (vm_range.GetByteSize());
return true;
}
}
@ -334,24 +359,31 @@ Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
bool
Block::GetStartAddress (Address &addr)
{
if (m_ranges.empty())
if (m_ranges.IsEmpty())
return false;
Function *function = CalculateSymbolContextFunction();
if (function)
{
addr = function->GetAddressRange().GetBaseAddress();
addr.Slide(m_ranges.front().GetBaseAddress ());
addr.Slide(m_ranges.GetEntryRef(0).GetRangeBase ());
return true;
}
return false;
}
void
Block::AddRange (const VMRange& new_range)
Block::FinalizeRanges ()
{
m_ranges.Sort();
m_ranges.CombineConsecutiveRanges ();
}
void
Block::AddRange (const Range& range)
{
Block *parent_block = GetParent ();
if (parent_block && !parent_block->Contains(new_range))
if (parent_block && !parent_block->Contains(range))
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
if (log)
@ -359,8 +391,8 @@ Block::AddRange (const VMRange& new_range)
Module *module = m_parent_scope->CalculateSymbolContextModule();
Function *function = m_parent_scope->CalculateSymbolContextFunction();
const addr_t function_file_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
const addr_t block_start_addr = function_file_addr + new_range.GetBaseAddress ();
const addr_t block_end_addr = function_file_addr + new_range.GetEndAddress ();
const addr_t block_start_addr = function_file_addr + range.GetRangeBase ();
const addr_t block_end_addr = function_file_addr + range.GetRangeEnd ();
Type *func_type = function->GetType();
const Declaration &func_decl = func_type->GetDeclaration();
@ -371,7 +403,7 @@ Block::AddRange (const VMRange& new_range)
func_decl.GetFile().GetFilename().GetCString(),
func_decl.GetLine(),
GetID(),
(uint32_t)m_ranges.size(),
(uint32_t)m_ranges.GetSize(),
block_start_addr,
block_end_addr,
parent_block->GetID(),
@ -383,7 +415,7 @@ Block::AddRange (const VMRange& new_range)
{
log->Printf ("warning: block {0x%8.8x} has range[%u] [0x%llx - 0x%llx) which is not contained in parent block {0x%8.8x} in function {0x%8.8x} from %s/%s",
GetID(),
(uint32_t)m_ranges.size(),
(uint32_t)m_ranges.GetSize(),
block_start_addr,
block_end_addr,
parent_block->GetID(),
@ -392,16 +424,16 @@ Block::AddRange (const VMRange& new_range)
module->GetFileSpec().GetFilename().GetCString());
}
}
parent_block->AddRange (new_range);
parent_block->AddRange (range);
}
m_ranges.push_back(new_range);
m_ranges.Append(range);
}
// Return the current number of bytes that this object occupies in memory
size_t
Block::MemorySize() const
{
size_t mem_size = sizeof(Block) + m_ranges.size() * sizeof(VMRange);
size_t mem_size = sizeof(Block) + m_ranges.GetSize() * sizeof(Range);
if (m_inlineInfoSP.get())
mem_size += m_inlineInfoSP->MemorySize();
if (m_variable_list_sp.get())

View File

@ -4106,6 +4106,7 @@ ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
case clang::Type::Auto: break;
case clang::Type::InjectedClassName: break;
case clang::Type::DependentName: break;
case clang::Type::Atomic: break;
}
// No DeclContext in this type...
return NULL;

View File

@ -281,6 +281,7 @@ ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t c
case clang::Type::TypeOf: break;
case clang::Type::Decltype: break;
case clang::Type::TemplateSpecialization: break;
case clang::Type::Atomic: break;
}
// We don't know hot to display this type...
return lldb::eTypeClassOther;
@ -492,8 +493,10 @@ ClangASTType::GetEncoding (clang_type_t clang_type, uint32_t &count)
case clang::Type::TypeOfExpr:
case clang::Type::TypeOf:
case clang::Type::Decltype:
// case clang::Type::QualifiedName:
case clang::Type::TemplateSpecialization: break;
case clang::Type::TemplateSpecialization:
case clang::Type::Atomic:
break;
}
count = 0;
return lldb::eEncodingInvalid;
@ -607,8 +610,9 @@ ClangASTType::GetFormat (clang_type_t clang_type)
case clang::Type::TypeOfExpr:
case clang::Type::TypeOf:
case clang::Type::Decltype:
// case clang::Type::QualifiedName:
case clang::Type::TemplateSpecialization: break;
case clang::Type::TemplateSpecialization:
case clang::Type::Atomic:
break;
}
// We don't know hot to display this type...
return lldb::eFormatBytes;