diff options
5 files changed, 151 insertions, 31 deletions
diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp index 37054d4afa7..60547c6bd78 100644 --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -167,13 +167,15 @@ BreakpointResolverName::SearchCallback case Breakpoint::Exact: if (context.module_sp) { - if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull)) - context.module_sp->FindSymbolsWithNameAndType (m_func_name, eSymbolTypeCode, sym_list); - context.module_sp->FindFunctions (m_func_name, - m_func_name_type_mask, - include_symbols, - append, - func_list); + if (context.module_sp->FindFunctions (m_func_name, + m_func_name_type_mask, + include_symbols, + append, + func_list) == 0) + { + if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull)) + context.module_sp->FindSymbolsWithNameAndType (m_func_name, eSymbolTypeCode, sym_list); + } } break; case Breakpoint::Regexp: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index 6eb249bfc34..3ee478ebc56 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -38,16 +38,23 @@ HashedNameToDIE::HashedNameToDIE (SymbolFileDWARF *dwarf, const DataExtractor &d m_data (data), m_header () { +} + +void +HashedNameToDIE::Initialize() +{ uint32_t offset = 0; m_header.version = m_data.GetU16(&offset); - m_header.hash_type = m_data.GetU8(&offset); - m_header.hash_index_bitsize = m_data.GetU8(&offset); - m_header.num_buckets = m_data.GetU32(&offset); - m_header.num_hashes = m_data.GetU32(&offset); - m_header.die_offset_base = m_data.GetU32(&offset); + if (m_header.version) + { + m_header.hash_type = m_data.GetU8(&offset); + m_header.hash_index_bitsize = m_data.GetU8(&offset); + m_header.num_buckets = m_data.GetU32(&offset); + m_header.num_hashes = m_data.GetU32(&offset); + m_header.die_offset_base = m_data.GetU32(&offset); + } } - size_t HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const { @@ -62,7 +69,7 @@ HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const const uint32_t bucket_idx = name_hash % m_header.num_buckets; // Calculate the offset for the bucket entry for the bucket index - uint32_t offset = GetOffsetForBucket (bucket_idx); + uint32_t offset = GetOffsetOfBucketEntry (bucket_idx); // Extract the bucket entry. const uint32_t bucket_entry = m_data.GetU32 (&offset); @@ -77,7 +84,7 @@ HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const const uint32_t hash_count = bucket_entry >> m_header.hash_index_bitsize; const uint32_t hash_end_idx = hash_idx + hash_count; // Figure out the offset to the hash value by index - uint32_t hash_offset = GetOffsetForHash (hash_idx); + uint32_t hash_offset = GetOffsetOfHashValue (hash_idx); for (uint32_t idx = hash_idx; idx < hash_end_idx; ++idx) { // Extract the hash value and see if it matches our string @@ -87,20 +94,24 @@ HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const // The hash matches, but we still need to verify that the // C string matches in case we have a hash collision. Figure // out the offset for the data associated with this hash entry - offset = GetOffsetForOffset (hash_idx); + offset = GetOffsetOfHashDataOffset (idx); // Extract the first 32 bit value which is the .debug_str offset // of the string we need - const uint32_t str_offset = m_data.GetU32 (&offset); + uint32_t hash_data_offset = m_data.GetU32 (&offset); + const uint32_t str_offset = m_data.GetU32 (&hash_data_offset); // Extract the C string and comapare it const char *cstr_name = m_dwarf->get_debug_str_data().PeekCStr(str_offset); - if (strcmp(name_cstr, cstr_name) == 0) + if (cstr_name) { - // We have a match, now extract the DIE count - const uint32_t die_count = m_data.GetU32 (&offset); - // Now extract "die_count" DIE offsets and put them into the - // results - for (uint32_t die_idx = 0; die_idx < die_count; ++die_idx) - die_ofsets.push_back(m_data.GetU32 (&offset)); + if (strcmp(name_cstr, cstr_name) == 0) + { + // We have a match, now extract the DIE count + const uint32_t die_count = m_data.GetU32 (&hash_data_offset); + // Now extract "die_count" DIE offsets and put them into the + // results + for (uint32_t die_idx = 0; die_idx < die_count; ++die_idx) + die_ofsets.push_back(m_data.GetU32 (&hash_data_offset)); + } } } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h index d84bf223ccd..96b4426ffd5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -31,7 +31,7 @@ public: uint32_t die_offset_base; Header() : - version(1), + version(0), hash_type (0), hash_index_bitsize (0), num_buckets(0), @@ -49,6 +49,12 @@ public: { } + bool + IsValid () const + { + return m_header.version > 0; + } + uint32_t GetHashIndexMask () const { @@ -56,7 +62,7 @@ public: } uint32_t - GetOffsetForBucket (uint32_t idx) const + GetOffsetOfBucketEntry (uint32_t idx) const { if (idx < m_header.num_buckets) return sizeof(Header) + 4 * idx; @@ -64,18 +70,25 @@ public: } uint32_t - GetOffsetForHash (uint32_t idx) const + GetOffsetOfHashValue (uint32_t idx) const { if (idx < m_header.num_hashes) - return sizeof(Header) + 4 * m_header.num_buckets + 4 * idx; + return sizeof(Header) + + 4 * m_header.num_buckets + + 4 * idx; return UINT32_MAX; } uint32_t - GetOffsetForOffset (uint32_t idx) const + GetOffsetOfHashDataOffset (uint32_t idx) const { if (idx < m_header.num_hashes) - return sizeof(Header) + 4 * m_header.num_buckets + 4 * m_header.num_hashes + 4 * idx; + { + return sizeof(Header) + + 4 * m_header.num_buckets + + 4 * m_header.num_hashes + + 4 * idx; + } return UINT32_MAX; } @@ -90,6 +103,9 @@ public: Find (const lldb_private::RegularExpression& regex, DIEArray &die_ofsets) const; + void + Initialize(); + protected: SymbolFileDWARF *m_dwarf; const lldb_private::DataExtractor &m_data; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index dedd1115eee..43ccbbdfe04 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -174,6 +174,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : m_aranges(), m_info(), m_line(), + m_debug_names (this, m_data_debug_names), m_function_basename_index(), m_function_fullname_index(), m_function_method_index(), @@ -187,6 +188,8 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : m_ranges(), m_unique_ast_type_map () { + get_debug_names_data(); + m_debug_names.Initialize(); } SymbolFileDWARF::~SymbolFileDWARF() @@ -2075,6 +2078,76 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append } +uint32_t +SymbolFileDWARF::ResolveFunctions (const DIEArray &die_offsets, + SymbolContextList& sc_list) +{ + DWARFDebugInfo* info = DebugInfo(); + if (info == NULL) + return 0; + + const uint32_t sc_list_initial_size = sc_list.GetSize(); + SymbolContext sc; + sc.module_sp = m_obj_file->GetModule()->GetSP(); + assert (sc.module_sp); + + DWARFCompileUnit* dwarf_cu = NULL; + const size_t num_matches = die_offsets.size(); + for (size_t i=0; i<num_matches; ++i) + { + const dw_offset_t die_offset = die_offsets[i]; + const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); + + 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 (dwarf_cu, die, sc)) + { + 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 + { + sc.block = NULL; + addr = sc.function->GetAddressRange().GetBaseAddress(); + } + + 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); + } + } + } + return sc_list.GetSize() - sc_list_initial_size; +} + void SymbolFileDWARF::FindFunctions ( @@ -2253,7 +2326,19 @@ SymbolFileDWARF::FindFunctions // Remember how many sc_list are in the list before we search in case // we are appending the results to a variable list. - uint32_t original_size = sc_list.GetSize(); + + if (m_debug_names.IsValid()) + { + DIEArray die_offsets; + const uint32_t num_matches = m_debug_names.Find(name, die_offsets); + if (num_matches > 0) + { + return ResolveFunctions (die_offsets, sc_list); + } + return 0; + } + + const uint32_t original_size = sc_list.GetSize(); // Index the DWARF if we haven't already if (!m_indexed) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 364d0991945..16f36aae4bf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -32,6 +32,7 @@ // Project includes #include "DWARFDefines.h" +#include "HashedNameToDIE.h" #include "NameToDIE.h" #include "UniqueDWARFASTType.h" @@ -308,6 +309,10 @@ protected: uint32_t& byte_stride, uint32_t& bit_stride); + uint32_t ResolveFunctions ( + const DIEArray &die_offsets, + lldb_private::SymbolContextList& sc_list); + void FindFunctions( const lldb_private::ConstString &name, const NameToDIE &name_to_die, @@ -384,6 +389,7 @@ protected: std::auto_ptr<DWARFDebugAranges> m_aranges; std::auto_ptr<DWARFDebugInfo> m_info; std::auto_ptr<DWARFDebugLine> m_line; + HashedNameToDIE m_debug_names; NameToDIE m_function_basename_index; // All concrete functions NameToDIE m_function_fullname_index; // All concrete functions NameToDIE m_function_method_index; // All inlined functions |

