void Symtab::InitAddressIndexes() { // Protected function, no need to lock mutex... if (!m_file_addr_to_index_computed && !m_symbols.empty()) { m_file_addr_to_index_computed = true; FileRangeToIndexMap::Entry entry; const_iterator begin = m_symbols.begin(); const_iterator end = m_symbols.end(); for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) { if (pos->ValueIsAddress()) { entry.SetRangeBase(pos->GetAddressRef().GetFileAddress()); entry.SetByteSize(pos->GetByteSize()); entry.data = std::distance(begin, pos); m_file_addr_to_index.Append(entry); } } const size_t num_entries = m_file_addr_to_index.GetSize(); 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) { 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) { 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) { Symbol &symbol = m_symbols[entry.data]; symbol.SetByteSize(end_section_file_addr - symbol_file_addr); symbol.SetSizeIsSynthesized(true); } } } // Sort again in case the range size changes the ordering m_file_addr_to_index.Sort(); } } }
void Symtab::InitAddressIndexes() { // Protected function, no need to lock mutex... if (!m_file_addr_to_index_computed && !m_symbols.empty()) { m_file_addr_to_index_computed = true; FileRangeToIndexMap::Entry entry; const_iterator begin = m_symbols.begin(); const_iterator end = m_symbols.end(); for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) { if (pos->ValueIsAddress()) { entry.SetRangeBase(pos->GetAddressRef().GetFileAddress()); entry.SetByteSize(pos->GetByteSize()); entry.data = std::distance(begin, pos); m_file_addr_to_index.Append(entry); } } const size_t num_entries = m_file_addr_to_index.GetSize(); if (num_entries > 0) { m_file_addr_to_index.Sort(); // 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++) { FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.GetMutableEntryAtIndex(i); if (entry->GetByteSize() == 0) { 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) { 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; // 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(); } } }