diff --git a/lldb/include/lldb/Core/RangeMap.h b/lldb/include/lldb/Core/RangeMap.h index dc7c7cb8ba67..476f4eafe51d 100644 --- a/lldb/include/lldb/Core/RangeMap.h +++ b/lldb/include/lldb/Core/RangeMap.h @@ -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 class RangeArray { + public: + typedef B BaseType; + typedef S SizeType; typedef Range Entry; - RangeArray () + RangeArray () : + m_entries () { } @@ -163,41 +191,75 @@ namespace lldb_private { } void - CombineConsecutiveEntriesWithEqualData () + CombineConsecutiveRanges () { - typename std::vector::iterator pos; - typename std::vector::iterator end; - typename std::vector::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 minimal_ranges; + // The list should be sorted prior to calling this function + typename std::vector::iterator pos; + typename std::vector::iterator end; + typename std::vector::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 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(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::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::const_iterator begin = m_entries.begin(); + typename std::vector::const_iterator end = m_entries.end(); + typename std::vector::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::const_iterator begin = m_entries.begin(); + typename std::vector::const_iterator end = m_entries.end(); + typename std::vector::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 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::const_iterator begin = m_entries.begin(); + typename std::vector::const_iterator end = m_entries.end(); + typename std::vector::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::const_iterator begin = m_entries.begin(); + typename std::vector::const_iterator end = m_entries.end(); + typename std::vector::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 m_entries; }; diff --git a/lldb/include/lldb/Symbol/Block.h b/lldb/include/lldb/Symbol/Block.h index 34465ebc788d..f2c243f9470a 100644 --- a/lldb/include/lldb/Symbol/Block.h +++ b/lldb/include/lldb/Symbol/Block.h @@ -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 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 diff --git a/lldb/source/API/SBBlock.cpp b/lldb/source/API/SBBlock.cpp index bc7392c11f9f..5374a7f86ba7 100644 --- a/lldb/source/API/SBBlock.cpp +++ b/lldb/source/API/SBBlock.cpp @@ -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; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp index 8c269b9f2da1..ab2f9c4f16e6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -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; iPrintf ("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)); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index 90dc4fc43c15..78e1dfddc3f9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -69,7 +69,7 @@ public: uint32_t GetNumRanges() const { - return m_aranges.GetNumEntries(); + return m_aranges.GetSize(); } dw_offset_t diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 152867a54675..bcce74c60c93 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -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::const_iterator pos; std::vector::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***"); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index 3502d56a82e4..f69b370b515b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -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) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h index 362b99dc7662..9145cc126486 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -11,66 +11,17 @@ #define SymbolFileDWARF_DWARFDebugRanges_h_ #include "SymbolFileDWARF.h" + #include #include +#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 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 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 range_map; typedef range_map::iterator range_map_iterator; typedef range_map::const_iterator range_map_const_iterator; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 5204d070ff5e..bcbb448807e7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -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; ibegin_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); } } diff --git a/lldb/source/Symbol/Block.cpp b/lldb/source/Symbol/Block.cpp index 2b00cf8e4b27..a65eb78f47d3 100644 --- a/lldb/source/Symbol/Block.cpp +++ b/lldb/source/Symbol/Block.cpp @@ -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::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; iAddressRange(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::const_iterator pos; - std::vector::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; iContains(*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::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; iAddressRange(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()) diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index c069bd2e818f..04c8b44cec5e 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -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; diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index deb88e23add0..40d049652a67 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -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;