diff options
Diffstat (limited to 'lldb/source')
13 files changed, 580 insertions, 874 deletions
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index 9f7609293e3..1a81c24efc0 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -79,6 +79,8 @@ ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough) void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx) { + m_target = exe_ctx.target; + if (!exe_ctx.frame) return; @@ -87,8 +89,6 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx) if (!sym_ctx.function) return; - m_target = &exe_ctx.GetProcess()->GetTarget(); - clang::DeclContext *decl_context; if (sym_ctx.block && sym_ctx.block->GetInlinedFunctionInfo()) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index fb34d4d5651..bbb284bd13e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -30,16 +30,16 @@ using namespace std; extern int g_verbose; DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) : - m_dwarf2Data ( dwarf2Data ), - m_offset ( DW_INVALID_OFFSET ), - m_length ( 0 ), - m_version ( 0 ), - m_abbrevs ( NULL ), - m_addr_size ( DWARFCompileUnit::GetDefaultAddressSize() ), - m_base_addr ( 0 ), + m_dwarf2Data (dwarf2Data), + m_abbrevs (NULL), + m_user_data (NULL), m_die_array (), - m_aranges_ap (), - m_user_data ( NULL ) + m_func_aranges_ap (), + m_base_addr (0), + m_offset (DW_INVALID_OFFSET), + m_length (0), + m_version (0), + m_addr_size (DWARFCompileUnit::GetDefaultAddressSize()) { } @@ -53,7 +53,7 @@ DWARFCompileUnit::Clear() m_addr_size = DWARFCompileUnit::GetDefaultAddressSize(); m_base_addr = 0; m_die_array.clear(); - m_aranges_ap.reset(); + m_func_aranges_ap.reset(); m_user_data = NULL; } @@ -324,6 +324,50 @@ DWARFCompileUnit::SetDefaultAddressSize(uint8_t addr_size) g_default_addr_size = addr_size; } +void +DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, + DWARFDebugAranges* debug_aranges, + bool clear_dies_if_already_not_parsed) +{ + // This function is usually called if there in no .debug_aranges section + // in order to produce a compile unit level set of address ranges that + // is accurate. If the DIEs weren't parsed, then we don't want all dies for + // all compile units to stay loaded when they weren't needed. So we can end + // up parsing the DWARF and then throwing them all away to keep memory usage + // down. + const bool clear_dies = ExtractDIEsIfNeeded (false) > 1; + + DIE()->BuildAddressRangeTable(dwarf2Data, this, debug_aranges); + + // Keep memory down by clearing DIEs if this generate function + // caused them to be parsed + if (clear_dies) + ClearDIEs (true); + +} + + +const DWARFDebugAranges & +DWARFCompileUnit::GetFunctionAranges () +{ + if (m_func_aranges_ap.get() == NULL) + { + m_func_aranges_ap.reset (new DWARFDebugAranges()); + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES); + + if (log) + log->Printf ("DWARFCompileUnit::GetFunctionAranges() for \"%s/%s\" compile unit at 0x%8.8x", + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetDirectory().GetCString(), + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetFilename().GetCString(), + m_offset); + DIE()->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get()); + const bool minimize = false; + const uint32_t fudge_size = 0; + m_func_aranges_ap->Sort(minimize, fudge_size); + } + return *m_func_aranges_ap.get(); +} + bool DWARFCompileUnit::LookupAddress ( @@ -336,16 +380,13 @@ DWARFCompileUnit::LookupAddress if (function_die_handle != NULL && DIE()) { - if (m_aranges_ap.get() == NULL) - { - m_aranges_ap.reset(new DWARFDebugAranges()); - m_die_array.front().BuildFunctionAddressRangeTable(m_dwarf2Data, this, m_aranges_ap.get()); - } + + const DWARFDebugAranges &func_aranges = GetFunctionAranges (); // Re-check the aranges auto pointer contents in case it was created above - if (m_aranges_ap.get() != NULL) + if (!func_aranges.IsEmpty()) { - *function_die_handle = GetDIEPtr(m_aranges_ap->FindAddress(address)); + *function_die_handle = GetDIEPtr(func_aranges.FindAddress(address)); if (*function_die_handle != NULL) { success = true; @@ -581,26 +622,20 @@ DWARFCompileUnit::AppendDIEsWithTag (const dw_tag_t tag, DWARFDIECollection& die void -DWARFCompileUnit::Index -( - const uint32_t cu_idx, - NameToDIE& func_basenames, - NameToDIE& func_fullnames, - NameToDIE& func_methods, - NameToDIE& func_selectors, - NameToDIE& objc_class_selectors, - NameToDIE& globals, - NameToDIE& types, - NameToDIE& namespaces, - const DWARFDebugRanges *debug_ranges, - DWARFDebugAranges *aranges -) +DWARFCompileUnit::Index (const uint32_t cu_idx, + NameToDIE& func_basenames, + NameToDIE& func_fullnames, + NameToDIE& func_methods, + NameToDIE& func_selectors, + NameToDIE& objc_class_selectors, + NameToDIE& globals, + NameToDIE& types, + NameToDIE& namespaces) { const DataExtractor* debug_str = &m_dwarf2Data->get_debug_str_data(); const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize()); - NameToDIE::Info die_info = { cu_idx, 0 }; DWARFDebugInfoEntry::const_iterator pos; DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin(); DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); @@ -640,9 +675,6 @@ DWARFCompileUnit::Index bool has_address = false; bool has_location = false; bool is_global_or_static_variable = false; - dw_addr_t lo_pc = DW_INVALID_ADDRESS; - dw_addr_t hi_pc = DW_INVALID_ADDRESS; - DWARFDebugRanges::RangeList ranges; dw_offset_t specification_die_offset = DW_INVALID_OFFSET; const size_t num_attributes = die.GetAttributes(m_dwarf2Data, this, fixed_form_sizes, attributes); @@ -677,33 +709,8 @@ DWARFCompileUnit::Index break; case DW_AT_low_pc: - has_address = true; - if (tag == DW_TAG_subprogram && attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) - { - lo_pc = form_value.Unsigned(); - } - break; - case DW_AT_high_pc: - has_address = true; - if (tag == DW_TAG_subprogram && attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) - { - hi_pc = form_value.Unsigned(); - } - break; - case DW_AT_ranges: - if (tag == DW_TAG_subprogram && attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value)) - { - if (debug_ranges) - { - debug_ranges->FindRanges(form_value.Unsigned(), ranges); - // 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(GetBaseAddress()); - } - } has_address = true; break; @@ -765,26 +772,8 @@ DWARFCompileUnit::Index break; } } - - if (tag == DW_TAG_subprogram) - { - if (lo_pc != DW_INVALID_ADDRESS && hi_pc != DW_INVALID_ADDRESS) - { - aranges->AppendRange (m_offset, lo_pc, hi_pc); - } - else - { - for (uint32_t i=0, num_ranges = ranges.Size(); i<num_ranges; ++i) - { - const DWARFDebugRanges::Range *range = ranges.RangeAtIndex (i); - aranges->AppendRange (m_offset, range->begin_offset, range->end_offset); - } - } - } } - die_info.die_idx = std::distance (begin, pos); - switch (tag) { case DW_TAG_subprogram: @@ -804,14 +793,14 @@ DWARFCompileUnit::Index &objc_method_name, &objc_base_name)) { - objc_class_selectors.Insert(objc_class_name, die_info); + objc_class_selectors.Insert(objc_class_name, die.GetOffset()); - func_selectors.Insert (objc_method_name, die_info); + func_selectors.Insert (objc_method_name, die.GetOffset()); if (!objc_base_name.IsEmpty()) { - func_basenames.Insert (objc_base_name, die_info); - func_fullnames.Insert (objc_base_name, die_info); + func_basenames.Insert (objc_base_name, die.GetOffset()); + func_fullnames.Insert (objc_base_name, die.GetOffset()); } } } @@ -849,9 +838,9 @@ DWARFCompileUnit::Index if (is_method) - func_methods.Insert (ConstString(name), die_info); + func_methods.Insert (ConstString(name), die.GetOffset()); else - func_basenames.Insert (ConstString(name), die_info); + func_basenames.Insert (ConstString(name), die.GetOffset()); } if (mangled_cstr) { @@ -862,9 +851,9 @@ DWARFCompileUnit::Index if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { Mangled mangled (mangled_cstr, true); - func_fullnames.Insert (mangled.GetMangledName(), die_info); + func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); if (mangled.GetDemangledName()) - func_fullnames.Insert (mangled.GetDemangledName(), die_info); + func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); } } } @@ -874,7 +863,7 @@ DWARFCompileUnit::Index if (has_address) { if (name) - func_basenames.Insert (ConstString(name), die_info); + func_basenames.Insert (ConstString(name), die.GetOffset()); if (mangled_cstr) { // Make sure our mangled name isn't the same string table entry @@ -884,9 +873,9 @@ DWARFCompileUnit::Index if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { Mangled mangled (mangled_cstr, true); - func_fullnames.Insert (mangled.GetMangledName(), die_info); + func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); if (mangled.GetDemangledName()) - func_fullnames.Insert (mangled.GetDemangledName(), die_info); + func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); } } } @@ -903,19 +892,19 @@ DWARFCompileUnit::Index case DW_TAG_typedef: if (name && is_declaration == false) { - types.Insert (ConstString(name), die_info); + types.Insert (ConstString(name), die.GetOffset()); } break; case DW_TAG_namespace: if (name) - namespaces.Insert (ConstString(name), die_info); + namespaces.Insert (ConstString(name), die.GetOffset()); break; case DW_TAG_variable: if (name && has_location && is_global_or_static_variable) { - globals.Insert (ConstString(name), die_info); + globals.Insert (ConstString(name), die.GetOffset()); // Be sure to include variables by their mangled and demangled // names if they have any since a variable can have a basename // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled @@ -928,9 +917,9 @@ DWARFCompileUnit::Index if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { Mangled mangled (mangled_cstr, true); - globals.Insert (mangled.GetMangledName(), die_info); + globals.Insert (mangled.GetMangledName(), die.GetOffset()); if (mangled.GetDemangledName()) - globals.Insert (mangled.GetDemangledName(), die_info); + globals.Insert (mangled.GetDemangledName(), die.GetOffset()); } } break; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 52aaf3f1b99..e54c6bc68f7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFCompileUnit_h_ +#ifndef SymbolFileDWARF_DWARFCompileUnit_h_ #define SymbolFileDWARF_DWARFCompileUnit_h_ -#include "SymbolFileDWARF.h" #include "DWARFDebugInfoEntry.h" +#include "SymbolFileDWARF.h" class NameToDIE; @@ -45,6 +45,9 @@ public: uint8_t GetAddressByteSize() const { return m_addr_size; } dw_addr_t GetBaseAddress() const { return m_base_addr; } void ClearDIEs(bool keep_compile_unit_die); + void BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, + DWARFDebugAranges* debug_aranges, + bool clear_dies_if_already_not_parsed); void SetBaseAddress(dw_addr_t base_addr) @@ -141,24 +144,22 @@ public: NameToDIE& objc_class_selectors, NameToDIE& globals, NameToDIE& types, - NameToDIE& namespaces, - const DWARFDebugRanges* debug_ranges, - DWARFDebugAranges *aranges); + NameToDIE& namespaces); + const DWARFDebugAranges & + GetFunctionAranges (); protected: SymbolFileDWARF* m_dwarf2Data; + const DWARFAbbreviationDeclarationSet *m_abbrevs; + void * m_user_data; + DWARFDebugInfoEntry::collection m_die_array; // The compile unit debug information entry item + std::auto_ptr<DWARFDebugAranges> m_func_aranges_ap; // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs + dw_addr_t m_base_addr; dw_offset_t m_offset; uint32_t m_length; uint16_t m_version; - const DWARFAbbreviationDeclarationSet* - m_abbrevs; uint8_t m_addr_size; - dw_addr_t m_base_addr; - DWARFDebugInfoEntry::collection - m_die_array; // The compile unit debug information entry item - std::auto_ptr<DWARFDebugAranges> m_aranges_ap; // A table similar to the .debug_aranges table, but this one points to the exact DW_TAG_subprogram DIEs - void * m_user_data; private: DISALLOW_COPY_AND_ASSIGN (DWARFCompileUnit); }; 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; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index dd8ec8b742a..b6fe1439a9b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugAranges_h_ +#ifndef SymbolFileDWARF_DWARFDebugAranges_h_ #define SymbolFileDWARF_DWARFDebugAranges_h_ #include "DWARFDebugArangeSet.h" @@ -20,35 +20,60 @@ class DWARFDebugAranges public: struct Range { - Range( - dw_addr_t _lo_pc = DW_INVALID_ADDRESS, - dw_addr_t _hi_pc = DW_INVALID_ADDRESS, - dw_offset_t _offset = DW_INVALID_OFFSET) : - lo_pc(_lo_pc), - hi_pc(_hi_pc), - offset(_offset) + explicit + Range (dw_addr_t lo = DW_INVALID_ADDRESS, + dw_addr_t hi = DW_INVALID_ADDRESS, + dw_offset_t off = DW_INVALID_OFFSET) : + lo_pc (lo), + length (hi-lo), + offset (off) { } void Clear() { - lo_pc = hi_pc = DW_INVALID_ADDRESS; + lo_pc = DW_INVALID_ADDRESS; + length = 0; offset = DW_INVALID_OFFSET; } - bool ValidRange() const + void + set_hi_pc (dw_addr_t hi_pc) { - return hi_pc > lo_pc; + if (hi_pc == DW_INVALID_ADDRESS || hi_pc <= lo_pc) + length = 0; + else + length = hi_pc - lo_pc; + } + dw_addr_t + hi_pc() const + { + if (length) + return lo_pc + length; + return DW_INVALID_ADDRESS; + } + bool + ValidRange() const + { + return length > 0; + } + + static bool + SortedOverlapCheck (const Range& curr_range, const Range& next_range, uint32_t n) + { + if (curr_range.offset != next_range.offset) + return false; + return curr_range.hi_pc() + n >= next_range.lo_pc; } bool Contains(const Range& range) const { - return lo_pc <= range.lo_pc && range.hi_pc <= hi_pc; + return lo_pc <= range.lo_pc && range.hi_pc() <= hi_pc(); } void Dump(lldb_private::Stream *s) const; dw_addr_t lo_pc; // Start of address range - dw_addr_t hi_pc; // End of address range (not including this address) + uint32_t length; // End of address range (not including this address) dw_offset_t offset; // Offset of the compile unit or die }; @@ -59,12 +84,10 @@ public: bool GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const; bool Extract(const lldb_private::DataExtractor &debug_aranges_data); bool Generate(SymbolFileDWARF* dwarf2Data); - void InsertRange (dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc); - void InsertRange (const DWARFDebugAranges::Range& range); // Use append range multiple times and then call sort void AppendRange (dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc); - void Sort(); + void Sort (bool minimize, uint32_t n); const Range* RangeAtIndex(uint32_t idx) const { @@ -72,7 +95,7 @@ public: return &m_aranges[idx]; return NULL; } - void Print() const; + void Dump (lldb_private::Log *log) const; dw_offset_t FindAddress(dw_addr_t address) const; bool IsEmpty() const { return m_aranges.empty(); } // void Dump(lldb_private::Stream *s); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index c138f7f9255..29db0a7a647 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -14,12 +14,15 @@ #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Stream.h" +#include "lldb/Symbol/ObjectFile.h" +#include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" #include "DWARFCompileUnit.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfoEntry.h" #include "DWARFFormValue.h" +#include "LogChannelDWARF.h" using namespace lldb_private; using namespace std; @@ -29,7 +32,8 @@ using namespace std; //---------------------------------------------------------------------- DWARFDebugInfo::DWARFDebugInfo() : m_dwarf2Data(NULL), - m_compile_units() + m_compile_units(), + m_cu_aranges_ap () { } @@ -43,25 +47,60 @@ DWARFDebugInfo::SetDwarfData(SymbolFileDWARF* dwarf2Data) m_compile_units.clear(); } -//---------------------------------------------------------------------- -// BuildDIEAddressRangeTable -//---------------------------------------------------------------------- -bool -DWARFDebugInfo::BuildFunctionAddressRangeTable(DWARFDebugAranges* debug_aranges) + +DWARFDebugAranges & +DWARFDebugInfo::GetCompileUnitAranges () { - const uint32_t num_compile_units = GetNumCompileUnits(); - uint32_t idx; - for (idx = 0; idx < num_compile_units; ++idx) + if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data) { - DWARFCompileUnit* cu = GetCompileUnitAtIndex (idx); - if (cu) + Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES); + + m_cu_aranges_ap.reset (new DWARFDebugAranges()); + const DataExtractor &debug_aranges_data = m_dwarf2Data->get_debug_aranges_data(); + if (debug_aranges_data.GetByteSize() > 0) { - cu->DIE()->BuildFunctionAddressRangeTable(m_dwarf2Data, cu, debug_aranges); + if (log) + log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s/%s\" from .debug_aranges", + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetDirectory().GetCString(), + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetFilename().GetCString()); + m_cu_aranges_ap->Extract (debug_aranges_data); + + } + else + { + if (log) + log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s/%s\" by parsing", + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetDirectory().GetCString(), + m_dwarf2Data->GetObjectFile()->GetFileSpec().GetFilename().GetCString()); + const uint32_t num_compile_units = GetNumCompileUnits(); + uint32_t idx; + const bool clear_dies_if_already_not_parsed = true; + for (idx = 0; idx < num_compile_units; ++idx) + { + DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx); + if (cu) + cu->BuildAddressRangeTable (m_dwarf2Data, m_cu_aranges_ap.get(), clear_dies_if_already_not_parsed); + } } + + // Sort with a fudge factor of 16 to make sure if we have a lot + // of functions in the compile unit whose end address if followed + // a start address that is "fudge_size" bytes close, it will combine + // the arange entries. This currently happens a lot on x86_64. This + // will help reduce the size of the aranges since sort will sort all + // of them and combine aranges that are consecutive for ranges in the + // same compile unit and we really don't need it to be all that + // accurate since we will get exact accuracy when we search the + // actual compile unit aranges which point to the exact range and + // the exact DIE offset of the function. + const bool minimize = true; + const uint32_t fudge_factor = 16; + m_cu_aranges_ap->Sort (minimize, fudge_factor); } - return !debug_aranges->IsEmpty(); + return *m_cu_aranges_ap.get(); } + //---------------------------------------------------------------------- // LookupAddress //---------------------------------------------------------------------- @@ -80,28 +119,9 @@ DWARFDebugInfo::LookupAddress cu_sp = GetCompileUnit(hint_die_offset); else { - // Get a non const version of the address ranges - DWARFDebugAranges* debug_aranges = ((SymbolFileDWARF*)m_dwarf2Data)->DebugAranges(); - - if (debug_aranges != NULL) - { - // If we have an empty address ranges section, lets build a sorted - // table ourselves by going through all of the debug information so we - // can do quick subsequent searches. - - if (debug_aranges->IsEmpty()) - { - const uint32_t num_compile_units = GetNumCompileUnits(); - uint32_t idx; - for (idx = 0; idx < num_compile_units; ++idx) - { - DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx); - if (cu) - cu->DIE()->BuildAddressRangeTable(m_dwarf2Data, cu, debug_aranges); - } - } - cu_sp = GetCompileUnit(debug_aranges->FindAddress(address)); - } + DWARFDebugAranges &cu_aranges = GetCompileUnitAranges (); + const dw_offset_t cu_offset = cu_aranges.FindAddress (address); + cu_sp = GetCompileUnit(cu_offset); } if (cu_sp.get()) @@ -613,7 +633,7 @@ VerifyCallback range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS); if (range.lo_pc != DW_INVALID_ADDRESS) { - range.hi_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS); + range.set_hi_pc (die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS)); if (s->GetVerbose()) { s->Printf("\n CU "); @@ -636,8 +656,8 @@ VerifyCallback range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS); if (range.lo_pc != DW_INVALID_ADDRESS) { - range.hi_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS); - if (range.hi_pc != DW_INVALID_ADDRESS) + range.set_hi_pc (die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS)); + if (range.hi_pc() != DW_INVALID_ADDRESS) { range.offset = die->GetOffset(); bool valid = range.ValidRange(); @@ -651,10 +671,6 @@ VerifyCallback s->Printf(" ERROR: Invalid address range for function."); } } - - // Only add to our subroutine ranges if our compile unit has a valid address range - // if (valid && verifyInfo->die_ranges.size() >= 2 && verifyInfo->die_ranges[1].range.ValidRange()) - // verifyInfo->subroutine_ranges.InsertRange(range); } } break; @@ -665,8 +681,8 @@ VerifyCallback range.lo_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS); if (range.lo_pc != DW_INVALID_ADDRESS) { - range.hi_pc = die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS); - if (range.hi_pc != DW_INVALID_ADDRESS) + range.set_hi_pc (die->GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS)); + if (range.hi_pc() != DW_INVALID_ADDRESS) { range.offset = die->GetOffset(); bool valid = range.ValidRange(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index bf4f80bd23a..e71d31963da 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugInfo_h_ +#ifndef SymbolFileDWARF_DWARFDebugInfo_h_ #define SymbolFileDWARF_DWARFDebugInfo_h_ #include <vector> @@ -36,7 +36,6 @@ public: DWARFDebugInfo(); void SetDwarfData(SymbolFileDWARF* dwarf2Data); - bool BuildFunctionAddressRangeTable(DWARFDebugAranges* debug_aranges); bool LookupAddress( const dw_addr_t address, @@ -70,12 +69,14 @@ public: eDumpFlag_ShowAncestors = (1<<2) // Show all parent DIEs when dumping single DIEs }; + DWARFDebugAranges & + GetCompileUnitAranges (); protected: SymbolFileDWARF* m_dwarf2Data; typedef std::vector<DWARFCompileUnitSP> CompileUnitColl; - CompileUnitColl m_compile_units; + std::auto_ptr<DWARFDebugAranges> m_cu_aranges_ap; // A quick address to compile unit table private: // All parsing needs to be done partially any managed by this class as accessors are called. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 5b1e899de97..22d0d22b657 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1843,7 +1843,7 @@ DWARFDebugInfoEntry::BuildAddressRangeTable if (hi_pc != DW_INVALID_ADDRESS) { /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); - debug_aranges->InsertRange(cu->GetOffset(), lo_pc, hi_pc); + debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc); } } @@ -1885,7 +1885,7 @@ DWARFDebugInfoEntry::BuildFunctionAddressRangeTable if (hi_pc != DW_INVALID_ADDRESS) { // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16llx - 0x%16.16llx)\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY - debug_aranges->InsertRange(GetOffset(), lo_pc, hi_pc); + debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc); } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index 5d25ccb5cf7..069009e62f3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -23,335 +23,53 @@ using namespace lldb; using namespace lldb_private; void -NameToDIE::Insert (const ConstString& name, const Info &info) +NameToDIE::Finalize() { - m_collection.insert (std::make_pair(name.AsCString(), info)); + m_map.Sort (); + m_map.SizeToFit (); } -size_t -NameToDIE::Find (const ConstString &name, std::vector<Info> &info_array) const +void +NameToDIE::Insert (const ConstString& name, uint32_t die_offset) { - const char *name_cstr = name.AsCString(); - const size_t initial_info_array_size = info_array.size(); - collection::const_iterator pos, end = m_collection.end(); - for (pos = m_collection.lower_bound (name_cstr); pos != end && pos->first == name_cstr; ++pos) - { - info_array.push_back (pos->second); - } - return info_array.size() - initial_info_array_size; + m_map.Append(name.GetCString(), die_offset); } size_t -NameToDIE::Find (const RegularExpression& regex, std::vector<Info> &info_array) const +NameToDIE::Find (const ConstString &name, DIEArray &info_array) const { - const size_t initial_info_array_size = info_array.size(); - collection::const_iterator pos, end = m_collection.end(); - for (pos = m_collection.begin(); pos != end; ++pos) - { - if (regex.Execute(pos->first)) - info_array.push_back (pos->second); - } - return info_array.size() - initial_info_array_size; + return m_map.GetValues (name.GetCString(), info_array); } size_t -NameToDIE::FindAllEntriesForCompileUnitWithIndex (const uint32_t cu_idx, std::vector<Info> &info_array) const +NameToDIE::Find (const RegularExpression& regex, DIEArray &info_array) const { - const size_t initial_info_array_size = info_array.size(); - collection::const_iterator pos, end = m_collection.end(); - for (pos = m_collection.begin(); pos != end; ++pos) - { - if (cu_idx == pos->second.cu_idx) - info_array.push_back (pos->second); - } - return info_array.size() - initial_info_array_size; + return m_map.GetValues (regex, info_array); } -void -NameToDIE::Dump (Stream *s) +size_t +NameToDIE::FindAllEntriesForCompileUnit (uint32_t cu_offset, + uint32_t cu_end_offset, + DIEArray &info_array) const { - collection::const_iterator pos, end = m_collection.end(); - for (pos = m_collection.begin(); pos != end; ++pos) + const size_t initial_size = info_array.size(); + const uint32_t size = m_map.GetSize(); + for (uint32_t i=0; i<size; ++i) { - s->Printf("%p: 0x%8.8x 0x%8.8x \"%s\"\n", pos->first, pos->second.cu_idx, pos->second.die_idx, pos->first); + const uint32_t die_offset = m_map.GetValueAtIndexUnchecked(i); + if (cu_offset < die_offset && die_offset < cu_end_offset) + info_array.push_back (die_offset); } + return info_array.size() - initial_size; } - -static uint32_t -dl_new_hash (const char *s) -{ - uint32_t h = 5381; - - for (unsigned char c = *s; c; c = *++s) - h = ((h << 5) + h) + c; - - return h; -} - -struct HashEntry -{ - uint32_t hash; - uint32_t cu_idx; - uint32_t die_idx; - const char *name; - - bool - operator < (const HashEntry &rhs) const - { - return hash < rhs.hash; - } -}; - -struct HashHeader -{ - uint32_t version; - uint32_t bucket_info_size; // The fixed data associated with this bucket - uint32_t bucket_count; - uint32_t flags; -}; - -struct HashBucketInfo -{ - uint32_t offset; // Offset to the data for each bucket -}; - -struct HashBucketEntryStrp -{ - HashBucketEntryStrp () : - str_offset (0) - { - } - - HashBucketEntryStrp (uint32_t s, uint32_t d) : - str_offset (s) - { - } - - uint32_t - GetByteSize () - { - return sizeof(uint32_t) + // String offset in .debug_str - sizeof(uint32_t) + // Number of dies - die_array.size() * sizeof(uint32_t); - } - - uint32_t str_offset; - std::vector<dw_offset_t> die_array; -}; - -typedef std::vector<dw_offset_t> DIEArray; -typedef std::map<const char *, DIEArray> NameToDIEArrayMap; - -struct HashBucketEntryCStr +void +NameToDIE::Dump (Stream *s) { - uint32_t - GetByteSize () const + const uint32_t size = m_map.GetSize(); + for (uint32_t i=0; i<size; ++i) { - uint32_t byte_size = 0; - NameToDIEArrayMap::const_iterator pos, end = name_to_die.end(); - for (pos = name_to_die.begin(); pos != end; ++pos) - { - // Include the size of the and a length for the dies, and all dies - byte_size += sizeof(uint32_t) + sizeof(uint32_t) * (pos->second.size() + 1); - } - return byte_size; + const char *cstr = m_map.GetCStringAtIndex(i); + s->Printf("%p: {0x%8.8x} \"%s\"\n", cstr, m_map.GetValueAtIndexUnchecked(i), cstr); } - - NameToDIEArrayMap name_to_die; -}; - -static uint32_t -closest_power_2_less_than_n (uint32_t n) -{ - if (n) - return 0x80000000u >> __builtin_clz (n); - return 0; -} - -typedef struct HashEntry HashEntryType; - -void -NameToDIE::Hash (Stream *s, SymbolFileDWARF *dwarf) -{ -// if (m_collection.empty()) -// return; -// -// typedef std::vector<HashEntryType> hash_collection; -// hash_collection hash_entries; -// collection::const_iterator pos, end = m_collection.end(); -// for (pos = m_collection.begin(); pos != end; ++pos) -// { -// HashEntry entry = { dl_new_hash (pos->first), pos->second.cu_idx, pos->second.die_idx, pos->first }; -// hash_entries.push_back (entry); -// } -// -//// const DataExtractor &debug_str_data = dwarf->get_debug_str_data(); -// -//// uint32_t collisions = 0; -//// for (i=1; i<hash_entries_size; ++i) -//// { -//// if (hash_entries[i-1].hash == hash_entries[i].hash && -//// hash_entries[i-1].name != hash_entries[i].name) -//// ++collisions; -//// } -//// s->Printf("count = %u, collisions = %u\n", hash_entries_size, collisions); -// -//// for (i=0; i<hash_entries_size; ++i) -//// s->Printf("0x%8.8x: cu = %8u, die = %8u, name = '%s'\n", -//// hash_entries[i].hash, -//// hash_entries[i].cu_idx, -//// hash_entries[i].die_idx, -//// hash_entries[i].name); -// DWARFDebugInfo *debug_info = dwarf->DebugInfo(); -// -// uint32_t num_buckets; -// if (hash_entries_size > 1024) -// num_buckets = closest_power_2_less_than_n (hash_entries_size/16); -// else if (hash_entries_size > 128) -// num_buckets = closest_power_2_less_than_n (hash_entries_size/8); -// else -// num_buckets = closest_power_2_less_than_n (hash_entries_size/4); -// if (num_buckets == 0) -// num_buckets = 1; -// -// //for (uint32_t power_2 = 0x10; power_2 <= hash_entries_size; power_2 <<= 1) -// { -//// if (num_buckets > 0x10 && num_buckets > hash_entries_size) -//// break; -// -// typedef std::vector<uint32_t> uint32_array; -// typedef std::map<uint32_t, HashBucketEntryCStr> HashBucketEntryMap; -// std::vector<HashBucketEntryMap> hash_buckets; -// hash_buckets.resize(num_buckets); -// -// uint32_t bucket_entry_empties = 0; -// uint32_t bucket_entry_single = 0; -// uint32_t bucket_entry_collisions = 0; -// uint32_t names_entry_single = 0; -// uint32_t names_entry_collisions = 0; -// //StreamString hash_file_data(Stream::eBinary, dwarf->GetObjectFile()->GetAddressByteSize(), dwarf->GetObjectFile()->GetByteSize()); -// -// // Write hash table header -//// hash_file_data.PutHex32 (1); // Version -//// hash_file_data.PutHex32 (4); // Sizeof bucket data -//// hash_file_data.PutHex32 (num_buckets); -//// hash_file_data.PutHex32 (0); // Flags -// -// s->Printf("HashHeader = { version = %u, bucket_info_size = %u, bucket_count = %u, flags = 0x%8.8x }\n", 1, (uint32_t)sizeof(HashBucketInfo), num_buckets, 0); -// -// for (i=0; i<hash_entries_size; ++i) -// { -// uint32_t hash = hash_entries[i].hash; -// uint32_t bucket_idx = hash_entries[i].hash % num_buckets; -// DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex (hash_entries[i].cu_idx); -// cu->ExtractDIEsIfNeeded(false); -// DWARFDebugInfoEntry *die = cu->GetDIEAtIndexUnchecked(hash_entries[i].die_idx); -// hash_buckets[bucket_idx][hash].name_to_die[hash_entries[i].name].push_back(die->GetOffset()); -// } -// uint32_t byte_size = sizeof(HashHeader); // Header -// uint32_t data_offset = 0; -// uint32_t num_bucket_entries; -// uint32_t bucket_data_size; -// // Now for each bucket we write the offset to the data for each bucket -// // The offset is currently a zero based offset from the end of this table -// // which is header.num_buckets * sizeof(uint32_t) long. -// for (i=0; i<num_buckets; ++i) -// { -// byte_size += sizeof(HashBucketInfo); -// HashBucketEntryMap &bucket_entry = hash_buckets[i]; -// bucket_data_size = 0; -// HashBucketEntryMap::const_iterator pos, end = bucket_entry.end(); -// for (pos = bucket_entry.begin(); pos != end; ++pos) -// { -// bucket_data_size += sizeof(pos->first) + pos->second.GetByteSize(); -// } -// if (bucket_data_size > 0) -// { -// // Offset to bucket data -//// hash_file_data.PutHex32 (data_offset); -// s->Printf("bucket[%u] {0x%8.8x}\n", i, data_offset); -// data_offset += bucket_data_size; -// } -// else -// { -// // Invalid offset that indicates an empty bucket -//// hash_file_data.PutHex32 (UINT32_MAX); -// s->Printf("bucket[%u] {0xFFFFFFFF}\n", i); -// ++bucket_entry_empties; -// } -// } -// -// // Now we write the bucket data for each bucket that corresponds to each bucket -// // offset from above. -// data_offset = 0; -// uint32_t total_num_name_entries = 0; -// uint32_t total_num_bucket_entries = 0; -// uint32_t total_non_empty_buckets = 0; -// for (i=0; i<num_buckets; ++i) -// { -// HashBucketEntryMap &bucket_entry = hash_buckets[i]; -// bucket_data_size = 0; -// if (bucket_entry.empty()) -// continue; -// -// ++total_non_empty_buckets; -// -// s->Printf("0x%8.8x: BucketEntry:\n", data_offset, num_bucket_entries); -// bucket_data_size = 0; -// uint32_t num_bucket_entries = 0; -// HashBucketEntryMap::const_iterator pos, end = bucket_entry.end(); -// for (pos = bucket_entry.begin(); pos != end; ++pos) -// { -// ++num_bucket_entries; -// uint32_t hash_data_len = pos->second.GetByteSize(); -// s->Printf(" hash = 0x%8.8x, length = 0x%8.8x:\n", pos->first, hash_data_len); -//// hash_file_data.PutHex32 (pos->first); // Write the hash -//// hash_file_data.PutHex32 (hash_data_len); // The length of the data for this hash not including the length itself -// -// const HashBucketEntryCStr &hash_entry = pos->second; -// uint32_t num_name_entries = 0; -// NameToDIEArrayMap::const_iterator name_pos, name_end = hash_entry.name_to_die.end(); -// for (name_pos = hash_entry.name_to_die.begin(); name_pos != name_end; ++name_pos) -// { -// ++num_name_entries; -// ++total_num_name_entries; -// s->Printf(" name = %p '%s'\n", name_pos->first, name_pos->first); -//// hash_file_data.PutHex32 (pos->first); // Write the hash -//// hash_file_data.PutHex32 (hash_data_len); // The length of the data for this hash not including the length itself -// -// -// const uint32_t num_dies = name_pos->second.size(); -// s->Printf(" dies[%u] = { ", num_dies); -// for (uint32_t j=0; j < num_dies; ++j) -// s->Printf("0x%8.8x ", name_pos->second[j]); -// s->PutCString("}\n"); -// } -// if (num_name_entries == 1) -// ++names_entry_single; -// else if (num_name_entries > 1) -// ++names_entry_collisions; -// bucket_data_size += sizeof(pos->first) + hash_data_len; -// } -// data_offset += bucket_data_size; -// byte_size += bucket_data_size; -// total_num_bucket_entries += num_bucket_entries; -// if (num_bucket_entries == 1) -// ++bucket_entry_single; -// else if (num_bucket_entries > 1) -// ++bucket_entry_collisions; -// } -// -// s->Printf ("Trying size of %u buckets, %u items:\n", num_buckets, hash_entries_size); -// s->Printf ("buckets: empty = %u (%%%f)\n", bucket_entry_empties, ((float)bucket_entry_empties/(float)num_buckets) * 100.0f); -// s->Printf ("buckets: single = %u\n", bucket_entry_single); -// s->Printf ("buckets: multiple = %u (avg = %f entries/bucket, avg = %f entries/non-empty bucket)\n", -// bucket_entry_collisions, -// (float)total_num_bucket_entries / (float)num_buckets, -// (float)total_num_bucket_entries / (float)total_non_empty_buckets); -// s->Printf ("names : single = %u of %u\n", names_entry_single, total_num_name_entries); -// s->Printf ("names : multiple = %u of %u\n", names_entry_collisions, total_num_name_entries); -// s->Printf ("total byte size = %u\n", byte_size); -// s->PutCString ("\n----------------------------------------------------------------------\n\n"); -// } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index 2fcd34a1b5c..43fb8a54ce9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -10,24 +10,18 @@ #ifndef SymbolFileDWARF_NameToDIE_h_ #define SymbolFileDWARF_NameToDIE_h_ -#include <map> -#include <vector> +#include "lldb/Core/UniqueCStringMap.h" #include "lldb/lldb-defines.h" class SymbolFileDWARF; +typedef std::vector<uint32_t> DIEArray; + class NameToDIE { public: - typedef struct Info - { - uint32_t cu_idx; - uint32_t die_idx; - } Info; - - - NameToDIE () : - m_collection () + NameToDIE () : + m_map() { } @@ -39,27 +33,27 @@ public: Dump (lldb_private::Stream *s); void - Insert (const lldb_private::ConstString& name, const Info &info); - + Insert (const lldb_private::ConstString& name, uint32_t die_offset); + + void + Finalize(); + size_t Find (const lldb_private::ConstString &name, - std::vector<Info> &info_array) const; + DIEArray &info_array) const; size_t Find (const lldb_private::RegularExpression& regex, - std::vector<Info> &info_array) const; + DIEArray &info_array) const; size_t - FindAllEntriesForCompileUnitWithIndex (const uint32_t cu_idx, - std::vector<Info> &info_array) const; - - void - Hash (lldb_private::Stream *s, SymbolFileDWARF *dwarf); + FindAllEntriesForCompileUnit (uint32_t cu_offset, + uint32_t cu_end_offset, + DIEArray &info_array) const; protected: - typedef std::multimap<const char *, Info> collection; + lldb_private::UniqueCStringMap<uint32_t> m_map; - collection m_collection; }; #endif // SymbolFileDWARF_NameToDIE_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 353c00b23f1..2e0b956e708 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -108,7 +108,7 @@ SymbolFileDWARF::Terminate() const char * SymbolFileDWARF::GetPluginNameStatic() { - return "symbol-file.dwarf2"; + return "dwarf"; } const char * @@ -163,17 +163,17 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : m_debug_map_symfile (NULL), m_clang_tu_decl (NULL), m_flags(), - m_data_debug_abbrev(), - m_data_debug_frame(), - m_data_debug_info(), - m_data_debug_line(), - m_data_debug_loc(), - m_data_debug_ranges(), - m_data_debug_str(), + m_data_debug_abbrev (), + m_data_debug_aranges (), + m_data_debug_frame (), + m_data_debug_info (), + m_data_debug_line (), + m_data_debug_loc (), + m_data_debug_ranges (), + m_data_debug_str (), m_data_debug_names (), m_data_debug_types (), m_abbr(), - m_aranges(), m_info(), m_line(), m_debug_names (this, m_data_debug_names), @@ -413,6 +413,12 @@ SymbolFileDWARF::get_debug_abbrev_data() } const DataExtractor& +SymbolFileDWARF::get_debug_aranges_data() +{ + return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges); +} + +const DataExtractor& SymbolFileDWARF::get_debug_frame_data() { return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame); @@ -483,41 +489,6 @@ SymbolFileDWARF::DebugAbbrev() const return m_abbr.get(); } -DWARFDebugAranges* -SymbolFileDWARF::DebugAranges() -{ - // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files - // and we are already parsing all of the DWARF because the .debug_pubnames - // is useless (it only mentions symbols that are externally visible), so - // don't use the .debug_aranges section, we should be using a debug aranges - // we got from SymbolFileDWARF::Index(). - - if (!m_indexed) - Index(); - - -// if (m_aranges.get() == NULL) -// { -// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); -// m_aranges.reset(new DWARFDebugAranges()); -// if (m_aranges.get()) -// { -// const DataExtractor &debug_aranges_data = get_debug_aranges_data(); -// if (debug_aranges_data.GetByteSize() > 0) -// m_aranges->Extract(debug_aranges_data); -// else -// m_aranges->Generate(this); -// } -// } - return m_aranges.get(); -} - -const DWARFDebugAranges* -SymbolFileDWARF::DebugAranges() const -{ - return m_aranges.get(); -} - DWARFDebugInfo* SymbolFileDWARF::DebugInfo() @@ -1569,20 +1540,17 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type { ConstString class_name (class_str.c_str()); - std::vector<NameToDIE::Info> method_die_infos; - if (m_objc_class_selectors_index.Find (class_name, method_die_infos)) + DIEArray method_die_offsets; + if (m_objc_class_selectors_index.Find (class_name, method_die_offsets)) { + DWARFDebugInfo* debug_info = DebugInfo(); + DWARFCompileUnit* method_cu = NULL; - DWARFCompileUnit* prev_method_cu = NULL; - const size_t num_objc_methods = method_die_infos.size(); - for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu) + const size_t num_matches = method_die_offsets.size(); + for (size_t i=0; i<num_matches; ++i) { - method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx); - - if (method_cu != prev_method_cu) - method_cu->ExtractDIEsIfNeeded (false); - - DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx); + const dw_offset_t die_offset = method_die_offsets[i]; + DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu); ResolveType (method_cu, method_die); } @@ -1722,11 +1690,10 @@ SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_ { lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); - DWARFDebugAranges* debug_aranges = DebugAranges(); DWARFDebugInfo* debug_info = DebugInfo(); - if (debug_aranges) + if (debug_info) { - dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr); + dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr); if (cu_offset != DW_INVALID_OFFSET) { uint32_t cu_idx; @@ -1932,8 +1899,6 @@ SymbolFileDWARF::Index () DWARFDebugInfo* debug_info = DebugInfo(); if (debug_info) { - m_aranges.reset(new DWARFDebugAranges()); - uint32_t cu_idx = 0; const uint32_t num_compile_units = GetNumCompileUnits(); for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) @@ -1950,9 +1915,7 @@ SymbolFileDWARF::Index () m_objc_class_selectors_index, m_global_index, m_type_index, - m_namespace_index, - DebugRanges(), - m_aranges.get()); + m_namespace_index); // Keep memory down by clearing DIEs if this generate function // caused them to be parsed @@ -1960,7 +1923,14 @@ SymbolFileDWARF::Index () curr_cu->ClearDIEs (true); } - m_aranges->Sort(); + m_function_basename_index.Finalize(); + m_function_fullname_index.Finalize(); + m_function_method_index.Finalize(); + m_function_selector_index.Finalize(); + m_objc_class_selectors_index.Finalize(); + m_global_index.Finalize(); + m_type_index.Finalize(); + m_namespace_index.Finalize(); #if defined (ENABLE_DEBUG_PRINTF) StreamFile s(stdout, false); @@ -2002,27 +1972,26 @@ SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint sc.module_sp = m_obj_file->GetModule()->GetSP(); assert (sc.module_sp); - DWARFCompileUnit* curr_cu = NULL; - DWARFCompileUnit* prev_cu = NULL; + DWARFCompileUnit* dwarf_cu = NULL; const DWARFDebugInfoEntry* die = NULL; - std::vector<NameToDIE::Info> die_info_array; - const size_t num_matches = m_global_index.Find(name, die_info_array); - for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) + DIEArray die_offsets; + const size_t num_matches = m_global_index.Find (name, die_offsets); + if (num_matches) { - curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); - - if (curr_cu != prev_cu) - curr_cu->ExtractDIEsIfNeeded (false); - - die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_matches; ++i) + { + const dw_offset_t die_offset = die_offsets[i]; + die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); - sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); - assert(sc.comp_unit != NULL); + sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); + assert(sc.comp_unit != NULL); - ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); + ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); - if (variables.GetSize() - original_size >= max_matches) - break; + if (variables.GetSize() - original_size >= max_matches) + break; + } } // Return the number of variable that were appended to the list @@ -2052,27 +2021,25 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append sc.module_sp = m_obj_file->GetModule()->GetSP(); assert (sc.module_sp); - DWARFCompileUnit* curr_cu = NULL; - DWARFCompileUnit* prev_cu = NULL; + DWARFCompileUnit* dwarf_cu = NULL; const DWARFDebugInfoEntry* die = NULL; - std::vector<NameToDIE::Info> die_info_array; - const size_t num_matches = m_global_index.Find(regex, die_info_array); - for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) + DIEArray die_offsets; + const size_t num_matches = m_global_index.Find (regex, die_offsets); + if (num_matches) { - curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); - - if (curr_cu != prev_cu) - curr_cu->ExtractDIEsIfNeeded (false); - - die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); - - sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); - assert(sc.comp_unit != NULL); + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_matches; ++i) + { + const dw_offset_t die_offset = die_offsets[i]; + die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); + sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); + assert(sc.comp_unit != NULL); - ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); + ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); - if (variables.GetSize() - original_size >= max_matches) - break; + if (variables.GetSize() - original_size >= max_matches) + break; + } } // Return the number of variable that were appended to the list @@ -2166,64 +2133,62 @@ SymbolFileDWARF::FindFunctions sc.module_sp = m_obj_file->GetModule()->GetSP(); assert (sc.module_sp); - DWARFCompileUnit* curr_cu = NULL; - DWARFCompileUnit* prev_cu = NULL; + DWARFCompileUnit* dwarf_cu = NULL; const DWARFDebugInfoEntry* die = NULL; - std::vector<NameToDIE::Info> die_info_array; - const size_t num_matches = name_to_die.Find (name, die_info_array); - for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) + DIEArray die_offsets; + const size_t num_matches = name_to_die.Find (name, die_offsets); + if (num_matches) { - curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); - - if (curr_cu != prev_cu) - curr_cu->ExtractDIEsIfNeeded (false); - - die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); - - const DWARFDebugInfoEntry* inlined_die = NULL; - if (die->Tag() == DW_TAG_inlined_subroutine) - { - inlined_die = die; - - while ((die = die->GetParent()) != NULL) - { - if (die->Tag() == DW_TAG_subprogram) - break; - } - } - assert (die->Tag() == DW_TAG_subprogram); - if (GetFunction (curr_cu, die, sc)) + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_matches; ++i) { - Address addr; - // Parse all blocks if needed - if (inlined_die) - { - sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); - assert (sc.block != NULL); - if (sc.block->GetStartAddress (addr) == false) - addr.Clear(); - } - else + const dw_offset_t die_offset = die_offsets[i]; + die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); + const DWARFDebugInfoEntry* inlined_die = NULL; + if (die->Tag() == DW_TAG_inlined_subroutine) { - sc.block = NULL; - addr = sc.function->GetAddressRange().GetBaseAddress(); + inlined_die = die; + + while ((die = die->GetParent()) != NULL) + { + if (die->Tag() == DW_TAG_subprogram) + break; + } } - - if (addr.IsValid()) + assert (die->Tag() == DW_TAG_subprogram); + if (GetFunction (dwarf_cu, die, sc)) { - - // We found the function, so we should find the line table - // and line table entry as well - LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table == NULL) + Address addr; + // Parse all blocks if needed + if (inlined_die) { - if (ParseCompileUnitLineTable(sc)) - line_table = sc.comp_unit->GetLineTable(); + sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); + assert (sc.block != NULL); + if (sc.block->GetStartAddress (addr) == false) + addr.Clear(); + } + else + { + sc.block = NULL; + addr = sc.function->GetAddressRange().GetBaseAddress(); } - if (line_table != NULL) - line_table->FindLineEntryByAddress (addr, sc.line_entry); - sc_list.Append(sc); + if (addr.IsValid()) + { + + // We found the function, so we should find the line table + // and line table entry as well + LineTable *line_table = sc.comp_unit->GetLineTable(); + if (line_table == NULL) + { + if (ParseCompileUnitLineTable(sc)) + line_table = sc.comp_unit->GetLineTable(); + } + if (line_table != NULL) + line_table->FindLineEntryByAddress (addr, sc.line_entry); + + sc_list.Append(sc); + } } } } @@ -2246,64 +2211,63 @@ SymbolFileDWARF::FindFunctions sc.module_sp = m_obj_file->GetModule()->GetSP(); assert (sc.module_sp); - DWARFCompileUnit* curr_cu = NULL; - DWARFCompileUnit* prev_cu = NULL; + DWARFCompileUnit* dwarf_cu = NULL; const DWARFDebugInfoEntry* die = NULL; - std::vector<NameToDIE::Info> die_info_array; - const size_t num_matches = name_to_die.Find(regex, die_info_array); - for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) + DIEArray die_offsets; + const size_t num_matches = name_to_die.Find (regex, die_offsets); + if (num_matches) { - curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); - - if (curr_cu != prev_cu) - curr_cu->ExtractDIEsIfNeeded (false); - - die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); - - const DWARFDebugInfoEntry* inlined_die = NULL; - if (die->Tag() == DW_TAG_inlined_subroutine) - { - inlined_die = die; - - while ((die = die->GetParent()) != NULL) - { - if (die->Tag() == DW_TAG_subprogram) - break; - } - } - assert (die->Tag() == DW_TAG_subprogram); - if (GetFunction (curr_cu, die, sc)) + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_matches; ++i) { - Address addr; - // Parse all blocks if needed - if (inlined_die) - { - sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); - assert (sc.block != NULL); - if (sc.block->GetStartAddress (addr) == false) - addr.Clear(); - } - else + const dw_offset_t die_offset = die_offsets[i]; + die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); + + const DWARFDebugInfoEntry* inlined_die = NULL; + if (die->Tag() == DW_TAG_inlined_subroutine) { - sc.block = NULL; - addr = sc.function->GetAddressRange().GetBaseAddress(); + inlined_die = die; + + while ((die = die->GetParent()) != NULL) + { + if (die->Tag() == DW_TAG_subprogram) + break; + } } - - if (addr.IsValid()) + assert (die->Tag() == DW_TAG_subprogram); + if (GetFunction (dwarf_cu, die, sc)) { - - // We found the function, so we should find the line table - // and line table entry as well - LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table == NULL) + Address addr; + // Parse all blocks if needed + if (inlined_die) { - if (ParseCompileUnitLineTable(sc)) - line_table = sc.comp_unit->GetLineTable(); + sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); + assert (sc.block != NULL); + if (sc.block->GetStartAddress (addr) == false) + addr.Clear(); + } + else + { + sc.block = NULL; + addr = sc.function->GetAddressRange().GetBaseAddress(); } - if (line_table != NULL) - line_table->FindLineEntryByAddress (addr, sc.line_entry); - sc_list.Append(sc); + if (addr.IsValid()) + { + + // We found the function, so we should find the line table + // and line table entry as well + LineTable *line_table = sc.comp_unit->GetLineTable(); + if (line_table == NULL) + { + if (ParseCompileUnitLineTable(sc)) + line_table = sc.comp_unit->GetLineTable(); + } + if (line_table != NULL) + line_table->FindLineEntryByAddress (addr, sc.line_entry); + + sc_list.Append(sc); + } } } } @@ -2421,34 +2385,33 @@ SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, boo Index (); const uint32_t initial_types_size = types.GetSize(); - DWARFCompileUnit* curr_cu = NULL; - DWARFCompileUnit* prev_cu = NULL; + DWARFCompileUnit* dwarf_cu = NULL; const DWARFDebugInfoEntry* die = NULL; - std::vector<NameToDIE::Info> die_info_array; - const size_t num_matches = m_type_index.Find (name, die_info_array); - for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) + DIEArray die_offsets; + const size_t num_matches = m_type_index.Find (name, die_offsets); + if (num_matches) { - curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); - - if (curr_cu != prev_cu) - curr_cu->ExtractDIEsIfNeeded (false); - - die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); - - Type *matching_type = ResolveType (curr_cu, die); - if (matching_type) + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_matches; ++i) { - // We found a type pointer, now find the shared pointer form our type list - TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); - if (type_sp) - { - types.InsertUnique (type_sp); - if (types.GetSize() >= max_matches) - break; - } - else + const dw_offset_t die_offset = die_offsets[i]; + die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); + + Type *matching_type = ResolveType (dwarf_cu, die); + if (matching_type) { - fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID()); + // We found a type pointer, now find the shared pointer form our type list + TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); + if (type_sp) + { + types.InsertUnique (type_sp); + if (types.GetSize() >= max_matches) + break; + } + else + { + fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID()); + } } } } @@ -2469,25 +2432,25 @@ SymbolFileDWARF::FindNamespace (const SymbolContext& sc, if (!m_indexed) Index (); - DWARFCompileUnit* curr_cu = NULL; - DWARFCompileUnit* prev_cu = NULL; + + DWARFCompileUnit* dwarf_cu = NULL; const DWARFDebugInfoEntry* die = NULL; - std::vector<NameToDIE::Info> die_info_array; - const size_t num_matches = m_namespace_index.Find (name, die_info_array); - for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) + DIEArray die_offsets; + const size_t num_matches = m_namespace_index.Find (name, die_offsets); + if (num_matches) { - curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); - - if (curr_cu != prev_cu) - curr_cu->ExtractDIEsIfNeeded (false); - - die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); - - clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die); - if (clang_namespace_decl) + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_matches; ++i) { - namespace_decl.SetASTContext (GetClangASTContext().getASTContext()); - namespace_decl.SetNamespaceDecl (clang_namespace_decl); + const dw_offset_t die_offset = die_offsets[i]; + die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); + + clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die); + if (clang_namespace_decl) + { + namespace_decl.SetASTContext (GetClangASTContext().getASTContext()); + namespace_decl.SetNamespaceDecl (clang_namespace_decl); + } } } } @@ -3110,24 +3073,18 @@ SymbolFileDWARF::FindDefinitionTypeForDIE ( Index (); const dw_tag_t type_tag = die->Tag(); - std::vector<NameToDIE::Info> die_info_array; - const size_t num_matches = m_type_index.Find (type_name, die_info_array); - if (num_matches > 0) + + DWARFCompileUnit* type_cu = NULL; + const DWARFDebugInfoEntry* type_die = NULL; + DIEArray die_offsets; + const size_t num_matches = m_type_index.Find (type_name, die_offsets); + if (num_matches) { - DWARFCompileUnit* type_cu = NULL; - DWARFCompileUnit* curr_cu = cu; - DWARFDebugInfo *info = DebugInfo(); + DWARFDebugInfo* debug_info = DebugInfo(); for (size_t i=0; i<num_matches; ++i) { - type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx); - - if (type_cu != curr_cu) - { - type_cu->ExtractDIEsIfNeeded (false); - curr_cu = type_cu; - } - - DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx); + const dw_offset_t die_offset = die_offsets[i]; + type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu); if (type_die != die && type_die->Tag() == type_tag) { @@ -4254,15 +4211,25 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) if (!m_indexed) Index (); - std::vector<NameToDIE::Info> global_die_info_array; - const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array); - for (size_t idx=0; idx<num_globals; ++idx) + DWARFCompileUnit* match_dwarf_cu = NULL; + const DWARFDebugInfoEntry* die = NULL; + DIEArray die_offsets; + const size_t num_matches = m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(), + dwarf_cu->GetNextCompileUnitOffset(), + die_offsets); + if (num_matches) { - VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS)); - if (var_sp) + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_matches; ++i) { - variables->AddVariableIfUnique (var_sp); - ++vars_added; + const dw_offset_t die_offset = die_offsets[i]; + die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu); + VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS)); + if (var_sp) + { + variables->AddVariableIfUnique (var_sp); + ++vars_added; + } } } } @@ -4694,24 +4661,23 @@ SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context, DWARFDebugInfo* info = DebugInfo(); - std::vector<NameToDIE::Info> die_info_array; + DIEArray die_offsets; - size_t num_matches = m_type_index.Find (ConstString(name), die_info_array); + DWARFCompileUnit* dwarf_cu = NULL; + const DWARFDebugInfoEntry* die = NULL; + size_t num_matches = m_type_index.Find (ConstString(name), die_offsets); if (num_matches) { - for (int i = 0; - i < num_matches; - ++i) + for (size_t i = 0; i < num_matches; ++i) { - DWARFCompileUnit* compile_unit = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); - compile_unit->ExtractDIEsIfNeeded (false); - const DWARFDebugInfoEntry *die = compile_unit->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); - + const dw_offset_t die_offset = die_offsets[i]; + die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); + if (die->GetParent() != context_die) continue; - Type *matching_type = ResolveType (compile_unit, die); + Type *matching_type = ResolveType (dwarf_cu, die); lldb::clang_type_t type = matching_type->GetClangFullType(); clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 2c596bf3b09..3a0026a8983 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolFileDWARF_h_ -#define liblldb_SymbolFileDWARF_h_ +#ifndef SymbolFileDWARF_SymbolFileDWARF_h_ +#define SymbolFileDWARF_SymbolFileDWARF_h_ // C Includes // C++ Includes @@ -156,22 +156,20 @@ public: //virtual size_t GetCompUnitCount() = 0; //virtual CompUnitSP GetCompUnitAtIndex(size_t cu_idx) = 0; - const lldb_private::DataExtractor& get_debug_abbrev_data(); - const lldb_private::DataExtractor& get_debug_frame_data(); - const lldb_private::DataExtractor& get_debug_info_data(); - const lldb_private::DataExtractor& get_debug_line_data(); - const lldb_private::DataExtractor& get_debug_loc_data(); - const lldb_private::DataExtractor& get_debug_ranges_data(); - const lldb_private::DataExtractor& get_debug_str_data(); - const lldb_private::DataExtractor& get_debug_names_data(); - const lldb_private::DataExtractor& get_debug_types_data(); + const lldb_private::DataExtractor& get_debug_abbrev_data (); + const lldb_private::DataExtractor& get_debug_aranges_data (); + const lldb_private::DataExtractor& get_debug_frame_data (); + const lldb_private::DataExtractor& get_debug_info_data (); + const lldb_private::DataExtractor& get_debug_line_data (); + const lldb_private::DataExtractor& get_debug_loc_data (); + const lldb_private::DataExtractor& get_debug_ranges_data (); + const lldb_private::DataExtractor& get_debug_str_data (); + const lldb_private::DataExtractor& get_debug_names_data (); + const lldb_private::DataExtractor& get_debug_types_data (); DWARFDebugAbbrev* DebugAbbrev(); const DWARFDebugAbbrev* DebugAbbrev() const; - DWARFDebugAranges* DebugAranges(); - const DWARFDebugAranges*DebugAranges() const; - DWARFDebugInfo* DebugInfo(); const DWARFDebugInfo* DebugInfo() const; @@ -374,6 +372,7 @@ protected: lldb_private::Flags m_flags; lldb_private::DataExtractor m_dwarf_data; lldb_private::DataExtractor m_data_debug_abbrev; + lldb_private::DataExtractor m_data_debug_aranges; lldb_private::DataExtractor m_data_debug_frame; lldb_private::DataExtractor m_data_debug_info; lldb_private::DataExtractor m_data_debug_line; @@ -386,7 +385,6 @@ protected: // The auto_ptr items below are generated on demand if and when someone accesses // them through a non const version of this class. std::auto_ptr<DWARFDebugAbbrev> m_abbr; - std::auto_ptr<DWARFDebugAranges> m_aranges; std::auto_ptr<DWARFDebugInfo> m_info; std::auto_ptr<DWARFDebugLine> m_line; HashedNameToDIE m_debug_names; @@ -417,4 +415,4 @@ protected: ClangTypeToDIE m_forward_decl_clang_type_to_die; }; -#endif // liblldb_SymbolFileDWARF_h_ +#endif // SymbolFileDWARF_SymbolFileDWARF_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index b6480cc9ac9..cc7ff1b0f27 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -44,7 +44,7 @@ SymbolFileDWARFDebugMap::Terminate() const char * SymbolFileDWARFDebugMap::GetPluginNameStatic() { - return "symbol-file.dwarf2-debugmap"; + return "dwarf-debugmap"; } const char * |