diff options
Diffstat (limited to 'source/Symbol/Symtab.cpp')
-rw-r--r-- | source/Symbol/Symtab.cpp | 256 |
1 files changed, 140 insertions, 116 deletions
diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp index 709d899075a4..b11b731014d8 100644 --- a/source/Symbol/Symtab.cpp +++ b/source/Symbol/Symtab.cpp @@ -25,16 +25,14 @@ using namespace lldb; using namespace lldb_private; - - -Symtab::Symtab(ObjectFile *objfile) : - m_objfile (objfile), - m_symbols (), - m_file_addr_to_index (), - m_name_to_index (), - m_mutex (Mutex::eMutexTypeRecursive), - m_file_addr_to_index_computed (false), - m_name_indexes_computed (false) +Symtab::Symtab(ObjectFile *objfile) + : m_objfile(objfile), + m_symbols(), + m_file_addr_to_index(), + m_name_to_index(), + m_mutex(), + m_file_addr_to_index_computed(false), + m_name_indexes_computed(false) { } @@ -56,7 +54,7 @@ Symtab::Resize(size_t count) // Clients should grab the mutex from this symbol table and lock it manually // when calling this function to avoid performance issues. m_symbols.resize (count); - return &m_symbols[0]; + return m_symbols.empty() ? nullptr : &m_symbols[0]; } uint32_t @@ -76,7 +74,7 @@ Symtab::AddSymbol(const Symbol& symbol) size_t Symtab::GetNumSymbols() const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_symbols.size(); } @@ -90,9 +88,9 @@ Symtab::SectionFileAddressesChanged () void Symtab::Dump (Stream *s, Target *target, SortOrder sort_order) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); -// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); + // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); s->Indent(); const FileSpec &file_spec = m_objfile->GetFileSpec(); const char * object_name = nullptr; @@ -171,7 +169,7 @@ Symtab::Dump (Stream *s, Target *target, SortOrder sort_order) void Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const size_t num_symbols = GetNumSymbols(); //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); @@ -224,7 +222,7 @@ CompareSymbolID (const void *key, const void *p) Symbol * Symtab::FindSymbolByID (lldb::user_id_t symbol_uid) const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); Symbol *symbol = (Symbol*)::bsearch (&symbol_uid, &m_symbols[0], @@ -474,7 +472,7 @@ Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes, if (add_demangled || add_mangled) { Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); // Create the name index vector to be able to quickly search by name NameToIndexMap::Entry entry; @@ -506,7 +504,7 @@ Symtab::AppendSymbolNamesToMap (const IndexCollection &indexes, uint32_t Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); uint32_t prev_size = indexes.size(); @@ -524,7 +522,7 @@ Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_ uint32_t Symtab::AppendSymbolIndexesWithTypeAndFlagsValue (SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); uint32_t prev_size = indexes.size(); @@ -542,7 +540,7 @@ Symtab::AppendSymbolIndexesWithTypeAndFlagsValue (SymbolType symbol_type, uint32 uint32_t Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); uint32_t prev_size = indexes.size(); @@ -632,7 +630,7 @@ namespace { void Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); Timer scoped_timer (__PRETTY_FUNCTION__,__PRETTY_FUNCTION__); // No need to sort if we have zero or one items... @@ -657,7 +655,7 @@ Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_du uint32_t Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); if (symbol_name) @@ -674,7 +672,7 @@ Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector uint32_t Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); if (symbol_name) @@ -700,7 +698,7 @@ Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbo uint32_t Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, std::vector<uint32_t>& indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0) { @@ -719,7 +717,7 @@ Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, Symb uint32_t Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type, symbol_visibility, indexes) > 0) { @@ -739,7 +737,7 @@ Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, Symb uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp, SymbolType symbol_type, std::vector<uint32_t>& indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); uint32_t prev_size = indexes.size(); uint32_t sym_end = m_symbols.size(); @@ -763,7 +761,7 @@ Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); uint32_t prev_size = indexes.size(); uint32_t sym_end = m_symbols.size(); @@ -790,7 +788,7 @@ Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp Symbol * Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t& start_idx) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const size_t count = m_symbols.size(); for (size_t idx = start_idx; idx < count; ++idx) @@ -810,7 +808,7 @@ Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Vis size_t Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); // Initialize all of the lookup by name indexes before converting NAME @@ -830,7 +828,7 @@ Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbo size_t Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); // Initialize all of the lookup by name indexes before converting NAME @@ -850,7 +848,7 @@ Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbo size_t Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression ®ex, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes); return symbol_indexes.size(); @@ -859,7 +857,7 @@ Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression ®ex, Symb Symbol * Symtab::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); if (!m_name_indexes_computed) @@ -894,33 +892,39 @@ typedef struct addr_t match_offset; } SymbolSearchInfo; -static int -SymbolWithClosestFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr) +// Add all the section file start address & size to the RangeVector, +// recusively adding any children sections. +static void +AddSectionsToRangeMap (SectionList *sectlist, RangeVector<addr_t, addr_t> §ion_ranges) { - const Symbol *symbol = info->symtab->SymbolAtIndex (index_ptr[0]); - if (symbol == nullptr) - return -1; - - const addr_t info_file_addr = info->file_addr; - if (symbol->ValueIsAddress()) + const int num_sections = sectlist->GetNumSections (0); + for (int i = 0; i < num_sections; i++) { - const addr_t curr_file_addr = symbol->GetAddressRef().GetFileAddress(); - if (info_file_addr < curr_file_addr) - return -1; - - // Since we are finding the closest symbol that is greater than or equal - // to 'info->file_addr' we set the symbol here. This will get set - // multiple times, but after the search is done it will contain the best - // symbol match - info->match_symbol = const_cast<Symbol *>(symbol); - info->match_index_ptr = index_ptr; - info->match_offset = info_file_addr - curr_file_addr; - - if (info_file_addr > curr_file_addr) - return +1; - return 0; + SectionSP sect_sp = sectlist->GetSectionAtIndex (i); + if (sect_sp) + { + SectionList &child_sectlist = sect_sp->GetChildren(); + + // If this section has children, add the children to the RangeVector. + // Else add this section to the RangeVector. + if (child_sectlist.GetNumSections (0) > 0) + { + AddSectionsToRangeMap (&child_sectlist, section_ranges); + } + else + { + size_t size = sect_sp->GetByteSize(); + if (size > 0) + { + addr_t base_addr = sect_sp->GetFileAddress(); + RangeVector<addr_t, addr_t>::Entry entry; + entry.SetRangeBase (base_addr); + entry.SetByteSize (size); + section_ranges.Append (entry); + } + } + } } - return -1; } void @@ -948,35 +952,69 @@ Symtab::InitAddressIndexes() if (num_entries > 0) { m_file_addr_to_index.Sort(); - m_file_addr_to_index.CalculateSizesOfZeroByteSizeRanges(); - - // Now our last symbols might not have had sizes because there - // was no subsequent symbol to calculate the size from. If this is - // the case, then calculate the size by capping it at the end of the - // section in which the symbol resides - for (int i = num_entries - 1; i >= 0; --i) + + // Create a RangeVector with the start & size of all the sections for + // this objfile. We'll need to check this for any FileRangeToIndexMap + // entries with an uninitialized size, which could potentially be a + // large number so reconstituting the weak pointer is busywork when it + // is invariant information. + SectionList *sectlist = m_objfile->GetSectionList(); + RangeVector<addr_t, addr_t> section_ranges; + if (sectlist) + { + AddSectionsToRangeMap (sectlist, section_ranges); + section_ranges.Sort(); + } + + // Iterate through the FileRangeToIndexMap and fill in the size for any + // entries that didn't already have a size from the Symbol (e.g. if we + // have a plain linker symbol with an address only, instead of debug info + // where we get an address and a size and a type, etc.) + for (size_t i = 0; i < num_entries; i++) { - const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i); - // As we iterate backwards, as soon as we find a symbol with a valid - // byte size, we are done - if (entry.GetByteSize() > 0) - break; - - // Cap the size to the end of the section in which the symbol resides - SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (entry.GetRangeBase())); - if (section_sp) + FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.GetMutableEntryAtIndex (i); + if (entry->GetByteSize() == 0) { - const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize(); - const lldb::addr_t symbol_file_addr = entry.GetRangeBase(); - if (end_section_file_addr > symbol_file_addr) + addr_t curr_base_addr = entry->GetRangeBase(); + const RangeVector<addr_t, addr_t>::Entry *containing_section = + section_ranges.FindEntryThatContains (curr_base_addr); + + // Use the end of the section as the default max size of the symbol + addr_t sym_size = 0; + if (containing_section) { - Symbol &symbol = m_symbols[entry.data]; + sym_size = containing_section->GetByteSize() - + (entry->GetRangeBase() - containing_section->GetRangeBase()); + } + + for (size_t j = i; j < num_entries; j++) + { + FileRangeToIndexMap::Entry *next_entry = m_file_addr_to_index.GetMutableEntryAtIndex (j); + addr_t next_base_addr = next_entry->GetRangeBase(); + if (next_base_addr > curr_base_addr) + { + addr_t size_to_next_symbol = next_base_addr - curr_base_addr; - symbol.SetByteSize(end_section_file_addr - symbol_file_addr); - symbol.SetSizeIsSynthesized(true); + // Take the difference between this symbol and the next one as its size, + // if it is less than the size of the section. + if (sym_size == 0 || size_to_next_symbol < sym_size) + { + sym_size = size_to_next_symbol; + } + break; + } + } + + if (sym_size > 0) + { + entry->SetByteSize (sym_size); + Symbol &symbol = m_symbols[entry->data]; + symbol.SetByteSize (sym_size); + symbol.SetSizeIsSynthesized (true); } } } + // Sort again in case the range size changes the ordering m_file_addr_to_index.Sort(); } @@ -986,7 +1024,7 @@ Symtab::InitAddressIndexes() void Symtab::CalculateSymbolSizes () { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_symbols.empty()) { @@ -1018,40 +1056,18 @@ Symtab::CalculateSymbolSizes () } Symbol * -Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes) +Symtab::FindSymbolAtFileAddress (addr_t file_addr) { - Mutex::Locker locker (m_mutex); - - - SymbolSearchInfo info = { this, file_addr, nullptr, nullptr, 0 }; - - ::bsearch (&info, - indexes, - num_indexes, - sizeof(uint32_t), - (ComparisonFunction)SymbolWithClosestFileAddress); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (!m_file_addr_to_index_computed) + InitAddressIndexes(); - if (info.match_symbol) + const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryStartsAt(file_addr); + if (entry) { - if (info.match_offset == 0) - { - // We found an exact match! - return info.match_symbol; - } - - const size_t symbol_byte_size = info.match_symbol->GetByteSize(); - - if (symbol_byte_size == 0) - { - // We weren't able to find the size of the symbol so lets just go - // with that match we found in our search... - return info.match_symbol; - } - - // We were able to figure out a symbol size so lets make sure our - // offset puts "file_addr" in the symbol's address range. - if (info.match_offset < symbol_byte_size) - return info.match_symbol; + Symbol* symbol = SymbolAtIndex(entry->data); + if (symbol->GetFileAddress() == file_addr) + return symbol; } return nullptr; } @@ -1059,21 +1075,25 @@ Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* index Symbol * Symtab::FindSymbolContainingFileAddress (addr_t file_addr) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_file_addr_to_index_computed) InitAddressIndexes(); const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryThatContains(file_addr); if (entry) - return SymbolAtIndex(entry->data); + { + Symbol* symbol = SymbolAtIndex(entry->data); + if (symbol->ContainsFileAddress(file_addr)) + return symbol; + } return nullptr; } void Symtab::ForEachSymbolContainingFileAddress(addr_t file_addr, std::function<bool(Symbol *)> const &callback) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_file_addr_to_index_computed) InitAddressIndexes(); @@ -1085,8 +1105,12 @@ Symtab::ForEachSymbolContainingFileAddress(addr_t file_addr, std::function<bool( for (size_t i = 0; i < addr_match_count; ++i) { - if (!callback(SymbolAtIndex(all_addr_indexes[i]))) - break; + Symbol* symbol = SymbolAtIndex(all_addr_indexes[i]); + if (symbol->ContainsFileAddress(file_addr)) + { + if (!callback(symbol)) + break; + } } } @@ -1133,7 +1157,7 @@ Symtab::FindFunctionSymbols (const ConstString &name, unsigned temp_symbol_indexes_size = temp_symbol_indexes.size(); if (temp_symbol_indexes_size > 0) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); for (unsigned i = 0; i < temp_symbol_indexes_size; i++) { SymbolContext sym_ctx; |