Cleanup on the unified section list changes. Main changes are:

- ObjectFile::GetSymtab() and ObjectFile::ClearSymtab() no longer takes any flags
- Module coordinates with the object files and contain a unified section list so that object file and symbol file can share sections when they need to, yet contain their own sections.

Other cleanups:
- Fixed Symbol::GetByteSize() to not have the symbol table compute the byte sizes on the fly
- Modified the ObjectFileMachO class to compute symbol sizes all at once efficiently
- Modified the Symtab class to store a file address lookup table for more efficient lookups
- Removed Section::Finalize() and SectionList::Finalize() as they did nothing
- Improved performance of the detection of symbol files that have debug maps by excluding stripped files and core files, debug files, object files and stubs
- Added the ability to tell if an ObjectFile has been stripped with ObjectFile::IsStripped() (used this for the above performance improvement)

llvm-svn: 185990
This commit is contained in:
Greg Clayton 2013-07-10 01:23:25 +00:00
parent 8978a9dd0a
commit 3046e66830
30 changed files with 988 additions and 1073 deletions

View File

@ -651,8 +651,8 @@ public:
/// Unified module section list.
//------------------------------------------------------------------
virtual SectionList *
GetUnifiedSectionList ();
GetSectionList ();
uint32_t
GetVersion (uint32_t *versions, uint32_t num_versions);
@ -1000,7 +1000,7 @@ protected:
std::unique_ptr<SymbolVendor> m_symfile_ap; ///< A pointer to the symbol vendor for this module.
ClangASTContext m_ast; ///< The AST context for this module.
PathMappingList m_source_mappings; ///< Module specific source remappings for when you have debug info for a module that doesn't match where the sources currently are
std::unique_ptr<lldb_private::SectionList> m_unified_sections_ap; ///< Unified section list for module.
std::unique_ptr<lldb_private::SectionList> m_sections_ap; ///< Unified section list for module that is used by the ObjectFile and and ObjectFile instances for the debug info
bool m_did_load_objfile:1,
m_did_load_symbol_vendor:1,
@ -1059,9 +1059,12 @@ protected:
bool
SetArchitecture (const ArchSpec &new_arch);
SectionList *
GetUnifiedSectionList();
friend class ModuleList;
friend class ObjectFile;
friend class SymbolFile;
private:

View File

@ -1138,6 +1138,39 @@ namespace lldb_private {
}
}
// Calculate the byte size of ranges with zero byte sizes by finding
// the next entry with a base address > the current base address
void
CalculateSizesOfZeroByteSizeRanges ()
{
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert (IsSorted());
#endif
typename Collection::iterator pos;
typename Collection::iterator end;
typename Collection::iterator next;
for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos)
{
if (pos->GetByteSize() == 0)
{
// Watch out for multiple entries with same address and make sure
// we find an entry that is greater than the current base address
// before we use that for the size
auto curr_base = pos->GetRangeBase();
for (next = pos + 1; next != end; ++next)
{
auto next_base = next->GetRangeBase();
if (next_base > curr_base)
{
pos->SetByteSize (next_base - curr_base);
break;
}
}
}
}
}
void
Clear ()
{

View File

@ -34,8 +34,8 @@ public:
~SectionList();
bool
Copy (SectionList* dest_section_list);
SectionList &
operator =(const SectionList& rhs);
size_t
AddSection (const lldb::SectionSP& section_sp);
@ -91,17 +91,6 @@ public:
size_t
Slide (lldb::addr_t slide_amount, bool slide_children);
// Update all section lookup caches
void
Finalize ();
// Each time Finalize() is called with changes, revision id increments.
uint32_t
GetRevisionID() const
{
return m_revision_id;
}
void
Clear ()
{
@ -109,8 +98,6 @@ public:
}
protected:
bool m_changed;
uint32_t m_revision_id;
collection m_sections;
};
@ -283,13 +270,6 @@ public:
m_thread_specific = b;
}
// Update all section lookup caches
void
Finalize ()
{
m_children.Finalize();
}
ObjectFile *
GetObjectFile ()
{

View File

@ -80,11 +80,6 @@ public:
eStrataRawImage
} Strata;
typedef enum
{
eSymtabFromUnifiedSectionList = 0x0001 /// Return symbol table from unified module section list
} SymtabFlags;
//------------------------------------------------------------------
/// Construct with a parent module, offset, and header data.
///
@ -353,7 +348,10 @@ public:
/// The list of sections contained in this object file.
//------------------------------------------------------------------
virtual SectionList *
GetSectionList () = 0;
GetSectionList ();
virtual void
CreateSections (SectionList &unified_section_list) = 0;
//------------------------------------------------------------------
/// Gets the symbol table for the currently selected architecture
@ -362,15 +360,21 @@ public:
/// Symbol table parsing can be deferred by ObjectFile instances
/// until this accessor is called the first time.
///
/// @param[in] flags
/// eSymtabFromUnifiedSectionList: Whether to get symbol table
/// for unified module section list, or object file.
///
/// @return
/// The symbol table for this object file.
//------------------------------------------------------------------
virtual Symtab *
GetSymtab (uint32_t flags = 0) = 0;
GetSymtab () = 0;
//------------------------------------------------------------------
/// Detect if this object file has been stripped of local symbols.
///
/// @return
/// Return \b true if the object file has been stripped of local
/// symbols.
//------------------------------------------------------------------
virtual bool
IsStripped () = 0;
//------------------------------------------------------------------
/// Frees the symbol table.
@ -385,7 +389,7 @@ public:
/// The symbol table for this object file.
//------------------------------------------------------------------
virtual void
ClearSymtab (uint32_t flags = 0);
ClearSymtab ();
//------------------------------------------------------------------
/// Gets the UUID for this object file.
@ -676,8 +680,6 @@ protected:
const lldb::addr_t m_memory_addr;
std::unique_ptr<lldb_private::SectionList> m_sections_ap;
std::unique_ptr<lldb_private::Symtab> m_symtab_ap;
std::unique_ptr<lldb_private::Symtab> m_symtab_unified_ap; ///< Unified section list symbol table.
uint32_t m_symtab_unified_revisionid; ///< Unified section list symbol table revision id for when m_symtab_unified_ap was last modified.
//------------------------------------------------------------------
/// Sets the architecture for a module. At present the architecture

View File

@ -210,13 +210,19 @@ public:
bool
IsIndirect () const;
bool
GetByteSizeIsValid () const
{
return m_size_is_valid;
}
lldb::addr_t
GetByteSize () const;
void
SetByteSize (lldb::addr_t size)
{
m_calculated_size = size > 0;
m_size_is_valid = size > 0;
m_addr_range.SetByteSize(size);
}
@ -298,7 +304,7 @@ protected:
m_is_external:1, // non-zero if this symbol is globally visible
m_size_is_sibling:1, // m_size contains the index of this symbol's sibling
m_size_is_synthesized:1,// non-zero if this symbol's size was calculated using a delta between this symbol and the next
m_calculated_size:1,
m_size_is_valid:1,
m_demangled_is_synthesized:1, // The demangled name was created should not be used for expressions or other lookups
m_type:8;
Mangled m_mangled; // uniqued symbol name/mangled name pair

View File

@ -38,7 +38,7 @@ class SymbolVendor :
public:
static SymbolVendor*
FindPlugin (const lldb::ModuleSP &module_sp,
lldb_private::Stream *feedback_strm);
Stream *feedback_strm);
//------------------------------------------------------------------
// Constructors and Destructors
@ -126,7 +126,7 @@ public:
size_t max_matches,
TypeList& types);
virtual lldb_private::ClangNamespaceDecl
virtual ClangNamespaceDecl
FindNamespace (const SymbolContext& sc,
const ConstString &name,
const ClangNamespaceDecl *parent_namespace_decl);
@ -154,9 +154,9 @@ public:
}
virtual size_t
GetTypes (lldb_private::SymbolContextScope *sc_scope,
GetTypes (SymbolContextScope *sc_scope,
uint32_t type_mask,
lldb_private::TypeList &type_list);
TypeList &type_list);
SymbolFile *
GetSymbolFile()
@ -175,7 +175,7 @@ public:
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
virtual lldb_private::ConstString
virtual ConstString
GetPluginName();
virtual uint32_t

View File

@ -14,6 +14,7 @@
#include <vector>
#include "lldb/lldb-private.h"
#include "lldb/Core/RangeMap.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/Symbol.h"
@ -72,7 +73,7 @@ public:
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
size_t CalculateSymbolSize (Symbol *symbol);
void CalculateSymbolSizes ();
void SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const;
@ -98,19 +99,19 @@ protected:
typedef std::vector<Symbol> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
typedef RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> FileRangeToIndexMap;
void InitNameIndexes ();
void InitAddressIndexes ();
ObjectFile * m_objfile;
collection m_symbols;
std::vector<uint32_t> m_addr_indexes;
FileRangeToIndexMap m_file_addr_to_index;
UniqueCStringMap<uint32_t> m_name_to_index;
UniqueCStringMap<uint32_t> m_basename_to_index;
UniqueCStringMap<uint32_t> m_method_to_index;
UniqueCStringMap<uint32_t> m_selector_to_index;
mutable Mutex m_mutex; // Provide thread safety for this symbol table
bool m_addr_indexes_computed:1,
bool m_file_addr_to_index_computed:1,
m_name_indexes_computed:1;
private:

View File

@ -406,7 +406,7 @@ SBModule::GetNumSections ()
{
// Give the symbol vendor a chance to add to the unified section list.
module_sp->GetSymbolVendor();
SectionList *section_list = module_sp->GetUnifiedSectionList();
SectionList *section_list = module_sp->GetSectionList();
if (section_list)
return section_list->GetSize();
}
@ -422,7 +422,7 @@ SBModule::GetSectionAtIndex (size_t idx)
{
// Give the symbol vendor a chance to add to the unified section list.
module_sp->GetSymbolVendor();
SectionList *section_list = module_sp->GetUnifiedSectionList ();
SectionList *section_list = module_sp->GetSectionList ();
if (section_list)
sb_section.SetSP(section_list->GetSectionAtIndex (idx));
@ -587,7 +587,7 @@ SBModule::FindSection (const char *sect_name)
{
// Give the symbol vendor a chance to add to the unified section list.
module_sp->GetSymbolVendor();
SectionList *section_list = module_sp->GetUnifiedSectionList();
SectionList *section_list = module_sp->GetSectionList();
if (section_list)
{
ConstString const_sect_name(sect_name);

View File

@ -1453,7 +1453,7 @@ DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *modul
{
if (module)
{
SectionList *section_list = module->GetUnifiedSectionList();
SectionList *section_list = module->GetSectionList();
if (section_list)
{
strm.Printf ("Sections for '%s' (%s):\n",
@ -2804,7 +2804,7 @@ protected:
ObjectFile *objfile = module->GetObjectFile();
if (objfile)
{
SectionList *section_list = objfile->GetSectionList();
SectionList *section_list = module->GetSectionList();
if (section_list)
{
bool changed = false;

View File

@ -245,7 +245,7 @@ Module::~Module()
// function calls back into this module object. The ordering is important
// here because symbol files can require the module object file. So we tear
// down the symbol file first, then the object file.
m_unified_sections_ap.reset();
m_sections_ap.reset();
m_symfile_ap.reset();
m_objfile_sp.reset();
}
@ -441,9 +441,9 @@ Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
{
Mutex::Locker locker (m_mutex);
Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")", vm_addr);
ObjectFile* ofile = GetObjectFile();
if (ofile)
return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList());
SectionList *section_list = GetSectionList();
if (section_list)
return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
return false;
}
@ -1114,24 +1114,31 @@ Module::GetObjectFile()
// architecture since it might differ in vendor/os if some parts were
// unknown.
m_objfile_sp->GetArchitecture (m_arch);
// Populate m_unified_sections_ap with sections from objfile.
SectionList *section_list = m_objfile_sp->GetSectionList();
if (section_list)
{
m_unified_sections_ap.reset(new SectionList());
section_list->Copy (m_unified_sections_ap.get());
m_unified_sections_ap->Finalize();
}
}
}
return m_objfile_sp.get();
}
SectionList *
Module::GetSectionList()
{
// Populate m_unified_sections_ap with sections from objfile.
if (m_sections_ap.get() == NULL)
{
ObjectFile *obj_file = GetObjectFile();
if (obj_file)
obj_file->CreateSections(*GetUnifiedSectionList());
}
return m_sections_ap.get();
}
SectionList *
Module::GetUnifiedSectionList()
{
return m_unified_sections_ap.get();
// Populate m_unified_sections_ap with sections from objfile.
if (m_sections_ap.get() == NULL)
m_sections_ap.reset(new SectionList());
return m_sections_ap.get();
}
const Symbol *
@ -1246,7 +1253,7 @@ Module::SetSymbolFileFileSpec (const FileSpec &file)
// Remove any sections in the unified section list that come from the current symbol vendor.
if (m_symfile_ap)
{
SectionList *section_list = GetUnifiedSectionList();
SectionList *section_list = GetSectionList();
SymbolFile *symbol_file = m_symfile_ap->GetSymbolFile();
if (section_list && symbol_file)
{
@ -1259,10 +1266,9 @@ Module::SetSymbolFileFileSpec (const FileSpec &file)
lldb::SectionSP section_sp (section_list->GetSectionAtIndex (idx - 1));
if (section_sp->GetObjectFile() == obj_file)
{
m_unified_sections_ap->DeleteSection (idx - 1);
section_list->DeleteSection (idx - 1);
}
}
m_unified_sections_ap->Finalize();
}
}
}
@ -1287,7 +1293,7 @@ Module::IsLoadedInTarget (Target *target)
ObjectFile *obj_file = GetObjectFile();
if (obj_file)
{
SectionList *sections = obj_file->GetSectionList();
SectionList *sections = GetSectionList();
if (sections != NULL)
{
size_t num_sections = sections->GetSize();
@ -1394,26 +1400,22 @@ bool
Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed)
{
size_t num_loaded_sections = 0;
ObjectFile *objfile = GetObjectFile();
if (objfile)
SectionList *section_list = GetSectionList ();
if (section_list)
{
SectionList *section_list = objfile->GetSectionList ();
if (section_list)
const size_t num_sections = section_list->GetSize();
size_t sect_idx = 0;
for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
{
const size_t num_sections = section_list->GetSize();
size_t sect_idx = 0;
for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
// Iterate through the object file sections to find the
// first section that starts of file offset zero and that
// has bytes in the file...
SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
// Only load non-thread specific sections when given a slide
if (section_sp && !section_sp->IsThreadSpecific())
{
// Iterate through the object file sections to find the
// first section that starts of file offset zero and that
// has bytes in the file...
SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
// Only load non-thread specific sections when given a slide
if (section_sp && !section_sp->IsThreadSpecific())
{
if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + offset))
++num_loaded_sections;
}
if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + offset))
++num_loaded_sections;
}
}
}

View File

@ -292,8 +292,6 @@ Section::Slide (addr_t slide_amount, bool slide_children)
#pragma mark SectionList
SectionList::SectionList () :
m_changed(false),
m_revision_id(0),
m_sections()
{
}
@ -303,22 +301,17 @@ SectionList::~SectionList ()
{
}
bool
SectionList::Copy (SectionList *dest_section_list)
SectionList &
SectionList::operator = (const SectionList& rhs)
{
if (dest_section_list)
{
dest_section_list->m_sections = m_sections;
dest_section_list->m_changed = true;
return true;
}
return false;
if (this != &rhs)
m_sections = rhs.m_sections;
return *this;
}
size_t
SectionList::AddSection (const lldb::SectionSP& section_sp)
{
m_changed = true;
assert (section_sp.get());
size_t section_index = m_sections.size();
m_sections.push_back(section_sp);
@ -331,7 +324,6 @@ SectionList::DeleteSection (size_t idx)
{
if (idx < m_sections.size())
{
m_changed = true;
m_sections.erase (m_sections.begin() + idx);
return true;
}
@ -361,7 +353,6 @@ SectionList::AddUniqueSection (const lldb::SectionSP& sect_sp)
size_t sect_idx = FindSectionIndex (sect_sp.get());
if (sect_idx == UINT32_MAX)
{
m_changed = true;
sect_idx = AddSection (sect_sp);
}
return sect_idx;
@ -375,7 +366,6 @@ SectionList::ReplaceSection (user_id_t sect_id, const lldb::SectionSP& sect_sp,
{
if ((*sect_iter)->GetID() == sect_id)
{
m_changed = true;
*sect_iter = sect_sp;
return true;
}
@ -552,22 +542,3 @@ SectionList::Slide (addr_t slide_amount, bool slide_children)
}
return count;
}
void
SectionList::Finalize ()
{
for (const_iterator si = m_sections.begin(), se = m_sections.end();
si != se;
++si)
{
Section *sect = si->get();
sect->GetChildren().Finalize();
}
if (m_changed)
{
m_revision_id++;
m_changed = false;
}
}

View File

@ -1524,13 +1524,8 @@ ClangExpressionDeclMap::GetVariableValue
if (!var_sc.module_sp)
return NULL;
ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
if (!object_file)
return NULL;
Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
Address so_addr(var_location->GetScalar().ULongLong(), var_sc.module_sp->GetSectionList());
lldb::addr_t load_addr = so_addr.GetLoadAddress(target);

View File

@ -312,7 +312,7 @@ AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp)
if (!ofile)
return eObjC_VersionUnknown;
SectionList *sections = ofile->GetSectionList();
SectionList *sections = module_sp->GetSectionList();
if (!sections)
return eObjC_VersionUnknown;
SectionSP v1_telltale_section_sp = sections->FindSectionByName(ConstString ("__OBJC"));

View File

@ -2189,7 +2189,7 @@ AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress()
if (objc_object)
{
SectionList *section_list = objc_object->GetSectionList();
SectionList *section_list = objc_module_sp->GetSectionList();
if (section_list)
{

View File

@ -513,22 +513,6 @@ ObjectFileELF::GetDependentModules(FileSpecList &files)
return num_specs;
}
user_id_t
ObjectFileELF::GetSectionIndexByType(unsigned type)
{
if (!ParseSectionHeaders())
return 0;
for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
sh_pos != m_section_headers.end(); ++sh_pos)
{
if (sh_pos->sh_type == type)
return SectionIndex(sh_pos);
}
return 0;
}
Address
ObjectFileELF::GetImageInfoAddress()
{
@ -539,28 +523,27 @@ ObjectFileELF::GetImageInfoAddress()
if (!section_list)
return Address();
user_id_t dynsym_id = GetSectionIndexByType(SHT_DYNAMIC);
if (!dynsym_id)
// Find the SHT_DYNAMIC (.dynamic) section.
SectionSP dynsym_section_sp (section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true));
if (!dynsym_section_sp)
return Address();
assert (dynsym_section_sp->GetObjectFile() == this);
user_id_t dynsym_id = dynsym_section_sp->GetID();
const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
if (!dynsym_hdr)
return Address();
SectionSP dynsym_section_sp (section_list->FindSectionByID(dynsym_id));
if (dynsym_section_sp)
for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
{
for (size_t i = 0; i < m_dynamic_symbols.size(); ++i)
{
ELFDynamic &symbol = m_dynamic_symbols[i];
ELFDynamic &symbol = m_dynamic_symbols[i];
if (symbol.d_tag == DT_DEBUG)
{
// Compute the offset as the number of previous entries plus the
// size of d_tag.
addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
return Address(dynsym_section_sp, offset);
}
if (symbol.d_tag == DT_DEBUG)
{
// Compute the offset as the number of previous entries plus the
// size of d_tag.
addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
return Address(dynsym_section_sp, offset);
}
}
@ -570,26 +553,19 @@ ObjectFileELF::GetImageInfoAddress()
lldb_private::Address
ObjectFileELF::GetEntryPointAddress ()
{
SectionList *sections;
addr_t offset;
if (m_entry_point_address.IsValid())
return m_entry_point_address;
if (!ParseHeader() || !IsExecutable())
return m_entry_point_address;
sections = GetSectionList();
offset = m_header.e_entry;
SectionList *section_list = GetSectionList();
addr_t offset = m_header.e_entry;
if (!sections)
{
if (!section_list)
m_entry_point_address.SetOffset(offset);
return m_entry_point_address;
}
m_entry_point_address.ResolveAddressUsingFileSections(offset, sections);
else
m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
return m_entry_point_address;
}
@ -607,32 +583,22 @@ ObjectFileELF::ParseDependentModules()
if (!ParseSectionHeaders())
return 0;
// Locate the dynamic table.
user_id_t dynsym_id = 0;
user_id_t dynstr_id = 0;
for (SectionHeaderCollIter sh_pos = m_section_headers.begin();
sh_pos != m_section_headers.end(); ++sh_pos)
{
if (sh_pos->sh_type == SHT_DYNAMIC)
{
dynsym_id = SectionIndex(sh_pos);
dynstr_id = sh_pos->sh_link + 1; // Section ID's are 1 based.
break;
}
}
if (!(dynsym_id && dynstr_id))
return 0;
SectionList *section_list = GetSectionList();
if (!section_list)
return 0;
// Resolve and load the dynamic table entries and corresponding string
// table.
Section *dynsym = section_list->FindSectionByID(dynsym_id).get();
Section *dynstr = section_list->FindSectionByID(dynstr_id).get();
if (!(dynsym && dynstr))
// Find the SHT_DYNAMIC section.
Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
if (!dynsym)
return 0;
assert (dynsym->GetObjectFile() == this);
const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex (dynsym->GetID());
if (!header)
return 0;
// sh_link: section header index of string table used by entries in the section.
Section *dynstr = section_list->FindSectionByID (header->sh_link + 1).get();
if (!dynstr)
return 0;
DataExtractor dynsym_data;
@ -844,30 +810,6 @@ ObjectFileELF::ParseSectionHeaders()
return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc);
}
lldb::user_id_t
ObjectFileELF::GetSectionIndexByName(const char *name)
{
if (!ParseSectionHeaders())
return 0;
// Search the collection of section headers for one with a matching name.
for (SectionHeaderCollIter I = m_section_headers.begin();
I != m_section_headers.end(); ++I)
{
const char *sectionName = I->section_name.AsCString();
if (!sectionName)
return 0;
if (strcmp(name, sectionName) != 0)
continue;
return SectionIndex(I);
}
return 0;
}
const ObjectFileELF::ELFSectionHeaderInfo *
ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
{
@ -880,14 +822,10 @@ ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
return NULL;
}
SectionList *
ObjectFileELF::GetSectionList()
void
ObjectFileELF::CreateSections(SectionList &unified_section_list)
{
if (m_sections_ap.get())
return m_sections_ap.get();
if (ParseSectionHeaders())
if (!m_sections_ap.get() && ParseSectionHeaders())
{
m_sections_ap.reset(new SectionList());
@ -982,40 +920,75 @@ ObjectFileELF::GetSectionList()
break;
}
SectionSP section_sp(new Section(
GetModule(), // Module to which this section belongs.
this, // ObjectFile to which this section belongs and should read section data from.
SectionIndex(I), // Section ID.
name, // Section name.
sect_type, // Section type.
header.sh_addr, // VM address.
vm_size, // VM size in bytes of this section.
header.sh_offset, // Offset of this section in the file.
file_size, // Size of the section as found in the file.
header.sh_flags)); // Flags for this section.
SectionSP section_sp (new Section(GetModule(), // Module to which this section belongs.
this, // ObjectFile to which this section belongs and should read section data from.
SectionIndex(I), // Section ID.
name, // Section name.
sect_type, // Section type.
header.sh_addr, // VM address.
vm_size, // VM size in bytes of this section.
header.sh_offset, // Offset of this section in the file.
file_size, // Size of the section as found in the file.
header.sh_flags)); // Flags for this section.
if (is_thread_specific)
section_sp->SetIsThreadSpecific (is_thread_specific);
m_sections_ap->AddSection(section_sp);
}
m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
}
return m_sections_ap.get();
if (m_sections_ap.get())
{
if (GetType() == eTypeDebugInfo)
{
static const SectionType g_sections[] =
{
eSectionTypeDWARFDebugAranges,
eSectionTypeDWARFDebugInfo,
eSectionTypeDWARFDebugAbbrev,
eSectionTypeDWARFDebugFrame,
eSectionTypeDWARFDebugLine,
eSectionTypeDWARFDebugStr,
eSectionTypeDWARFDebugLoc,
eSectionTypeDWARFDebugMacInfo,
eSectionTypeDWARFDebugPubNames,
eSectionTypeDWARFDebugPubTypes,
eSectionTypeDWARFDebugRanges,
eSectionTypeELFSymbolTable,
};
SectionList *elf_section_list = m_sections_ap.get();
for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
{
SectionType section_type = g_sections[idx];
SectionSP section_sp (elf_section_list->FindSectionByType (section_type, true));
if (section_sp)
{
SectionSP module_section_sp (unified_section_list.FindSectionByType (section_type, true));
if (module_section_sp)
unified_section_list.ReplaceSection (module_section_sp->GetID(), section_sp);
else
unified_section_list.AddSection (section_sp);
}
}
}
else
{
unified_section_list = *m_sections_ap;
}
}
}
// private
unsigned
ObjectFileELF::ParseSymbols(Symtab *symtab,
user_id_t start_id,
SectionList *section_list,
const ELFSectionHeaderInfo *symtab_shdr,
const DataExtractor &symtab_data,
const DataExtractor &strtab_data)
ObjectFileELF::ParseSymbols (Symtab *symtab,
user_id_t start_id,
SectionList *section_list,
const size_t num_symbols,
const DataExtractor &symtab_data,
const DataExtractor &strtab_data)
{
ELFSymbol symbol;
lldb::offset_t offset = 0;
const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
static ConstString text_section_name(".text");
static ConstString init_section_name(".init");
@ -1128,21 +1101,18 @@ ObjectFileELF::ParseSymbols(Symtab *symtab,
}
}
// If the symbol section we've found has no data (SHT_NOBITS), then check the module
// for the main object file and use the section there if it has data. This can happen
// if we're parsing the debug file and the it has no .text section, for example.
// If the symbol section we've found has no data (SHT_NOBITS), then check the module section
// list. This can happen if we're parsing the debug file and it has no .text section, for example.
if (symbol_section_sp && (symbol_section_sp->GetFileSize() == 0))
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
ObjectFile *obj_file = module_sp->GetObjectFile();
// Check if we've got a different object file than ourselves.
if (obj_file && (obj_file != this))
SectionList *module_section_list = module_sp->GetSectionList();
if (module_section_list && module_section_list != section_list)
{
const ConstString &sect_name = symbol_section_sp->GetName();
SectionList *obj_file_section_list = obj_file->GetSectionList();
lldb::SectionSP section_sp (obj_file_section_list->FindSectionByName (sect_name));
lldb::SectionSP section_sp (module_section_list->FindSectionByName (sect_name));
if (section_sp && section_sp->GetFileSize())
{
symbol_section_sp = section_sp;
@ -1178,32 +1148,46 @@ ObjectFileELF::ParseSymbols(Symtab *symtab,
}
unsigned
ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, user_id_t symtab_id)
ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id, lldb_private::Section *symtab)
{
// Parse in the section list if needed.
SectionList *section_list = GetSectionList();
if (symtab->GetObjectFile() != this)
{
// If the symbol table section is owned by a different object file, have it do the
// parsing.
ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(symtab->GetObjectFile());
return obj_file_elf->ParseSymbolTable (symbol_table, start_id, symtab);
}
// Get section list for this object file.
SectionList *section_list = m_sections_ap.get();
if (!section_list)
return 0;
const ELFSectionHeaderInfo *symtab_hdr = &m_section_headers[symtab_id - 1];
user_id_t symtab_id = symtab->GetID();
const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
assert(symtab_hdr->sh_type == SHT_SYMTAB ||
symtab_hdr->sh_type == SHT_DYNSYM);
// sh_link: section header index of associated string table.
// Section ID's are ones based.
user_id_t strtab_id = symtab_hdr->sh_link + 1;
Section *symtab = section_list->FindSectionByID(symtab_id).get();
Section *strtab = section_list->FindSectionByID(strtab_id).get();
unsigned num_symbols = 0;
if (symtab && strtab)
{
assert (symtab->GetObjectFile() == this);
assert (strtab->GetObjectFile() == this);
DataExtractor symtab_data;
DataExtractor strtab_data;
if (ReadSectionData(symtab, symtab_data) &&
ReadSectionData(strtab, strtab_data))
{
size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
num_symbols = ParseSymbols(symbol_table, start_id,
section_list, symtab_hdr,
section_list, num_symbols,
symtab_data, strtab_data);
}
}
@ -1217,17 +1201,15 @@ ObjectFileELF::ParseDynamicSymbols()
if (m_dynamic_symbols.size())
return m_dynamic_symbols.size();
user_id_t dyn_id = GetSectionIndexByType(SHT_DYNAMIC);
if (!dyn_id)
return 0;
SectionList *section_list = GetSectionList();
if (!section_list)
return 0;
Section *dynsym = section_list->FindSectionByID(dyn_id).get();
// Find the SHT_DYNAMIC section.
Section *dynsym = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
if (!dynsym)
return 0;
assert (dynsym->GetObjectFile() == this);
ELFDynamic symbol;
DataExtractor dynsym_data;
@ -1360,7 +1342,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
{
assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
// The link field points to the associated symbol table. The info field
// The link field points to the associated symbol table. The info field
// points to the section holding the plt.
user_id_t symtab_id = rel_hdr->sh_link;
user_id_t plt_id = rel_hdr->sh_info;
@ -1380,7 +1362,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
if (!sym_hdr)
return 0;
SectionList *section_list = GetSectionList();
SectionList *section_list = m_sections_ap.get();
if (!section_list)
return 0;
@ -1396,6 +1378,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
if (!symtab)
return 0;
// sh_link points to associated string table.
Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
if (!strtab)
return 0;
@ -1430,82 +1413,68 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table,
}
Symtab *
ObjectFileELF::GetSymtab(uint32_t flags)
ObjectFileELF::GetSymtab()
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
if (!module_sp)
return NULL;
bool from_unified_section_list = !!(flags & eSymtabFromUnifiedSectionList);
SectionList *section_list = from_unified_section_list ? module_sp->GetUnifiedSectionList() : GetSectionList();
// We always want to use the main object file so we (hopefully) only have one cached copy
// of our symtab, dynamic sections, etc.
ObjectFile *module_obj_file = module_sp->GetObjectFile();
if (module_obj_file && module_obj_file != this)
return module_obj_file->GetSymtab();
if (m_symtab_ap.get() == NULL)
{
SectionList *section_list = GetSectionList();
if (!section_list)
return NULL;
// If we're doing the unified section list and it has been modified, then clear our
// cache and reload the symbols. If needed, we could check on only the sections that
// we use to create the symbol table...
std::unique_ptr<lldb_private::Symtab> &symtab_ap = from_unified_section_list ? m_symtab_unified_ap : m_symtab_ap;
if (from_unified_section_list && (m_symtab_unified_revisionid != section_list->GetRevisionID()))
{
symtab_ap.reset();
m_symtab_unified_revisionid = section_list->GetRevisionID();
}
else if (symtab_ap.get())
{
return symtab_ap.get();
}
uint64_t symbol_id = 0;
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
Symtab *symbol_table = new Symtab(this);
symtab_ap.reset(symbol_table);
m_symtab_ap.reset(new Symtab(this));
// Sharable objects and dynamic executables usually have 2 distinct symbol
// tables, one named ".symtab", and the other ".dynsym". The dynsym is a smaller
// version of the symtab that only contains global symbols. The information found
// in the dynsym is therefore also found in the symtab, while the reverse is not
// necessarily true.
Section *section_sym = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
if (!section_sym)
Section *symtab = section_list->FindSectionByType (eSectionTypeELFSymbolTable, true).get();
if (!symtab)
{
// The symtab section is non-allocable and can be stripped, so if it doesn't exist
// then use the dynsym section which should always be there.
section_sym = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
symtab = section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true).get();
}
if (symtab)
symbol_id += ParseSymbolTable (m_symtab_ap.get(), symbol_id, symtab);
uint64_t symbol_id = 0;
if (section_sym)
// Synthesize trampoline symbols to help navigate the PLT.
const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
if (symbol)
{
user_id_t section_id = section_sym->GetID();
ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section_sym->GetObjectFile());
symbol_id += obj_file_elf->ParseSymbolTable (symbol_table, symbol_id, section_id);
}
Section *section = section_list->FindSectionByType (eSectionTypeELFDynamicLinkInfo, true).get();
if (section)
{
ObjectFileELF *obj_file_elf = static_cast<ObjectFileELF *>(section->GetObjectFile());
// Synthesize trampoline symbols to help navigate the PLT.
const ELFDynamic *symbol = obj_file_elf->FindDynamicSymbol(DT_JMPREL);
if (symbol)
addr_t addr = symbol->d_ptr;
Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
if (reloc_section)
{
addr_t addr = symbol->d_ptr;
Section *reloc_section = section_list->FindSectionContainingFileAddress(addr).get();
if (reloc_section)
{
user_id_t reloc_id = reloc_section->GetID();
const ELFSectionHeaderInfo *reloc_header = obj_file_elf->GetSectionHeaderByIndex(reloc_id);
assert(reloc_header);
user_id_t reloc_id = reloc_section->GetID();
const ELFSectionHeaderInfo *reloc_header = GetSectionHeaderByIndex(reloc_id);
assert(reloc_header);
obj_file_elf->ParseTrampolineSymbols(symbol_table, symbol_id, reloc_header, reloc_id);
}
ParseTrampolineSymbols (m_symtab_ap.get(), symbol_id, reloc_header, reloc_id);
}
}
return symbol_table;
}
return NULL;
return m_symtab_ap.get();
}
bool
ObjectFileELF::IsStripped ()
{
// TODO: determine this for ELF
return false;
}
//===----------------------------------------------------------------------===//

View File

@ -100,10 +100,13 @@ public:
GetAddressByteSize() const;
virtual lldb_private::Symtab *
GetSymtab(uint32_t flags = 0);
GetSymtab();
virtual lldb_private::SectionList *
GetSectionList();
virtual bool
IsStripped ();
virtual void
CreateSections (lldb_private::SectionList &unified_section_list);
virtual void
Dump(lldb_private::Stream *s);
@ -232,14 +235,14 @@ private:
unsigned
ParseSymbolTable(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
lldb::user_id_t symtab_id);
lldb_private::Section *symtab);
/// Helper routine for ParseSymbolTable().
unsigned
ParseSymbols(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
lldb_private::SectionList *section_list,
const ELFSectionHeaderInfo *symtab_shdr,
const size_t num_symbols,
const lldb_private::DataExtractor &symtab_data,
const lldb_private::DataExtractor &strtab_data);
@ -252,17 +255,6 @@ private:
const ELFSectionHeaderInfo *rela_hdr,
lldb::user_id_t section_id);
/// Utility method for looking up a section given its name. Returns the
/// index of the corresponding section or zero if no section with the given
/// name can be found (note that section indices are always 1 based, and so
/// section index 0 is never valid).
lldb::user_id_t
GetSectionIndexByName(const char *name);
// Returns the ID of the first section that has the given type.
lldb::user_id_t
GetSectionIndexByType(unsigned type);
/// Returns the section header with the given id or NULL.
const ELFSectionHeaderInfo *
GetSectionHeaderByIndex(lldb::user_id_t id);

File diff suppressed because it is too large Load Diff

View File

@ -102,10 +102,13 @@ public:
GetAddressClass (lldb::addr_t file_addr);
virtual lldb_private::Symtab *
GetSymtab(uint32_t flags = 0);
GetSymtab();
virtual lldb_private::SectionList *
GetSectionList();
virtual bool
IsStripped ();
virtual void
CreateSections (lldb_private::SectionList &unified_section_list);
virtual void
Dump (lldb_private::Stream *s);
@ -195,10 +198,7 @@ protected:
bool m_thread_context_offsets_valid;
size_t
ParseSections ();
size_t
ParseSymtab (bool minimize);
ParseSymtab ();
};

View File

@ -511,7 +511,7 @@ ObjectFilePECOFF::GetSectionName(std::string& sect_name, const section_header_t&
// GetNListSymtab
//----------------------------------------------------------------------
Symtab *
ObjectFilePECOFF::GetSymtab(uint32_t flags)
ObjectFilePECOFF::GetSymtab()
{
ModuleSP module_sp(GetModule());
if (module_sp)
@ -597,16 +597,26 @@ ObjectFilePECOFF::GetSymtab(uint32_t flags)
}
SectionList *
ObjectFilePECOFF::GetSectionList()
bool
ObjectFilePECOFF::IsStripped ()
{
ModuleSP module_sp(GetModule());
if (module_sp)
// TODO: determine this for COFF
return false;
}
void
ObjectFilePECOFF::CreateSections (SectionList &unified_section_list)
{
if (!m_sections_ap.get())
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
if (m_sections_ap.get() == NULL)
m_sections_ap.reset(new SectionList());
ModuleSP module_sp(GetModule());
if (module_sp)
{
m_sections_ap.reset(new SectionList());
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
const uint32_t nsects = m_sect_headers.size();
ModuleSP module_sp (GetModule());
for (uint32_t idx = 0; idx<nsects; ++idx)
@ -710,13 +720,11 @@ ObjectFilePECOFF::GetSectionList()
//section_sp->SetIsEncrypted (segment_is_encrypted);
m_sections_ap->AddSection(section_sp);
unified_section_list.AddSection(section_sp);
m_sections_ap->AddSection (section_sp);
}
m_sections_ap->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
}
}
return m_sections_ap.get();
}
bool
@ -754,8 +762,9 @@ ObjectFilePECOFF::Dump(Stream *s)
*s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n";
if (m_sections_ap.get())
m_sections_ap->Dump(s, NULL, true, UINT32_MAX);
SectionList *sections = GetSectionList();
if (sections)
sections->Dump(s, NULL, true, UINT32_MAX);
if (m_symtab_ap.get())
m_symtab_ap->Dump(s, NULL, eSortOrderNone);

View File

@ -86,10 +86,13 @@ public:
// GetAddressClass (lldb::addr_t file_addr);
//
virtual lldb_private::Symtab *
GetSymtab(uint32_t flags = 0);
GetSymtab ();
virtual lldb_private::SectionList *
GetSectionList();
virtual bool
IsStripped ();
virtual void
CreateSections (lldb_private::SectionList &unified_section_list);
virtual void
Dump (lldb_private::Stream *s);

View File

@ -543,7 +543,7 @@ SymbolFileDWARF::InitializeObject()
ModuleSP module_sp (m_obj_file->GetModule());
if (module_sp)
{
const SectionList *section_list = module_sp->GetUnifiedSectionList();
const SectionList *section_list = module_sp->GetSectionList();
const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
@ -706,7 +706,7 @@ SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type,
{
ModuleSP module_sp (m_obj_file->GetModule());
m_flags.Set (got_flag);
const SectionList *section_list = module_sp->GetUnifiedSectionList();
const SectionList *section_list = module_sp->GetSectionList();
if (section_list)
{
SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
@ -1056,7 +1056,7 @@ SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompile
if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
{
ModuleSP module_sp (m_obj_file->GetModule());
func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetUnifiedSectionList());
func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetSectionList());
if (func_range.GetBaseAddress().IsValid())
func_range.SetByteSize(highest_func_addr - lowest_func_addr);
}
@ -4723,7 +4723,7 @@ SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
Symbol *objc_class_symbol = NULL;
if (m_obj_file)
{
Symtab *symtab = m_obj_file->GetSymtab (ObjectFile::eSymtabFromUnifiedSectionList);
Symtab *symtab = m_obj_file->GetSymtab ();
if (symtab)
{
objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
@ -7437,7 +7437,7 @@ SymbolFileDWARF::ParseVariableDIE
ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
if (debug_map_objfile)
{
Symtab *debug_map_symtab = debug_map_objfile->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
if (debug_map_symtab)
{
Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,

View File

@ -75,9 +75,9 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa
{
for (auto comp_unit_info : cu_infos)
{
Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
ModuleSP oso_module_sp (oso_objfile->GetModule());
Symtab *oso_symtab = oso_objfile->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
Symtab *oso_symtab = oso_objfile->GetSymtab();
///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
//SectionList *oso_sections = oso_objfile->Sections();
@ -169,7 +169,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa
exe_symfile->FinalizeOSOFileRanges (this);
// We don't need the symbols anymore for the .o files
oso_objfile->ClearSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
oso_objfile->ClearSymtab();
}
}
return file_range_map;
@ -325,12 +325,36 @@ SymbolFileDWARFDebugMap::InitOSO()
return;
m_flags.set(kHaveInitializedOSOs);
// If the object file has been stripped, there is no sense in looking further
// as all of the debug symbols for the debug map will not be available
if (m_obj_file->IsStripped())
return;
// Also make sure the file type is some sort of executable. Core files, debug
// info files (dSYM), object files (.o files), and stub libraries all can
switch (m_obj_file->GetType())
{
case ObjectFile::eTypeInvalid:
case ObjectFile::eTypeCoreFile:
case ObjectFile::eTypeDebugInfo:
case ObjectFile::eTypeObjectFile:
case ObjectFile::eTypeStubLibrary:
case ObjectFile::eTypeUnknown:
return;
case ObjectFile::eTypeExecutable:
case ObjectFile::eTypeDynamicLinker:
case ObjectFile::eTypeSharedLibrary:
break;
}
// In order to get the abilities of this plug-in, we look at the list of
// N_OSO entries (object files) from the symbol table and make sure that
// these files exist and also contain valid DWARF. If we get any of that
// then we return the abilities of the first N_OSO's DWARF.
Symtab* symtab = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
Symtab* symtab = m_obj_file->GetSymtab();
if (symtab)
{
Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
@ -367,13 +391,7 @@ SymbolFileDWARFDebugMap::InitOSO()
{
const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
// The N_GSYM and N_STSYM symbols have a byte size and calling
// symbol->GetByteSize() can cause an infinite loop where
// InitOSO() gets called over and over if we are in the process
// of getting the symbol vendor (module->SymbolVendor()). So
// use a safer call for now until we can fix this. This is related
// to the unified section/symtab changes that just went in.
lldb::addr_t byte_size = symtab->CalculateSymbolSize(const_cast<Symbol *>(symbol));
lldb::addr_t byte_size = symbol->GetByteSize();
DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
m_debug_map.Append(debug_map_entry);
}
@ -599,27 +617,17 @@ SymbolFileDWARFDebugMap::CalculateAbilities ()
const uint32_t oso_index_count = GetNumCompileUnits();
if (oso_index_count > 0)
{
const uint32_t dwarf_abilities = SymbolFile::CompileUnits |
SymbolFile::Functions |
SymbolFile::Blocks |
SymbolFile::GlobalVariables |
SymbolFile::LocalVariables |
SymbolFile::VariableTypes |
SymbolFile::LineTables;
InitOSO();
if (!m_compile_unit_infos.empty())
return dwarf_abilities;
// for (uint32_t oso_idx=0; oso_idx<oso_index_count; ++oso_idx)
// {
// SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
// if (oso_dwarf)
// {
// uint32_t oso_abilities = oso_dwarf->GetAbilities();
// if ((oso_abilities & dwarf_abilities) == dwarf_abilities)
// return oso_abilities;
// }
// }
{
return SymbolFile::CompileUnits |
SymbolFile::Functions |
SymbolFile::Blocks |
SymbolFile::GlobalVariables |
SymbolFile::LocalVariables |
SymbolFile::VariableTypes |
SymbolFile::LineTables ;
}
}
return 0;
}
@ -783,7 +791,7 @@ uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
uint32_t resolved_flags = 0;
Symtab* symtab = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
Symtab* symtab = m_obj_file->GetSymtab();
if (symtab)
{
const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
@ -1460,12 +1468,10 @@ SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
lldb::addr_t oso_file_addr,
lldb::addr_t oso_byte_size)
{
assert (cu_info);// REMOVE THIS PRIOR TO CHECKIN
const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
if (debug_map_idx != UINT32_MAX)
{
DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
assert (debug_map_entry);// REMOVE THIS PRIOR TO CHECKIN
debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
return true;

View File

@ -93,7 +93,7 @@ SymbolFileSymtab::CalculateAbilities ()
uint32_t abilities = 0;
if (m_obj_file)
{
const Symtab *symtab = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
const Symtab *symtab = m_obj_file->GetSymtab();
if (symtab)
{
//----------------------------------------------------------------------
@ -159,7 +159,7 @@ SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
// the entire object file
if (idx < m_source_indexes.size())
{
const Symbol *cu_symbol = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList)->SymbolAtIndex(m_source_indexes[idx]);
const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown));
}
@ -179,7 +179,7 @@ SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
size_t num_added = 0;
// We must at least have a valid compile unit
assert (sc.comp_unit != NULL);
const Symtab *symtab = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
const Symtab *symtab = m_obj_file->GetSymtab();
const Symbol *curr_symbol = NULL;
const Symbol *next_symbol = NULL;
// const char *prefix = m_obj_file->SymbolPrefix();
@ -307,13 +307,13 @@ SymbolFileSymtab::FindNamespace (const SymbolContext& sc, const ConstString &nam
uint32_t
SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
if (m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList) == NULL)
if (m_obj_file->GetSymtab() == NULL)
return 0;
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextSymbol)
{
sc.symbol = m_obj_file->GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList)->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
if (sc.symbol)
resolved_flags |= eSymbolContextSymbol;
}

View File

@ -141,7 +141,7 @@ SymbolVendorELF::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::
if (symbol_vendor)
{
// Get the module unified section list and add our debug sections to that.
SectionList *module_section_list = module_sp->GetUnifiedSectionList();
SectionList *module_section_list = module_sp->GetSectionList();
SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
static const SectionType g_sections[] =
@ -172,7 +172,6 @@ SymbolVendorELF::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::
module_section_list->AddSection (section_sp);
}
}
module_section_list->Finalize();
symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp);
return symbol_vendor;

View File

@ -83,51 +83,6 @@ UUIDsMatch(Module *module, ObjectFile *ofile, lldb_private::Stream *feedback_str
return false;
}
static bool
ReplaceDSYMSectionsWithExecutableSections (ObjectFile *exec_objfile, ObjectFile *dsym_objfile)
{
// We need both the executable and the dSYM to live off of the
// same section lists. So we take all of the sections from the
// executable, and replace them in the dSYM. This allows section
// offset addresses that come from the dSYM to automatically
// get updated as images (shared libraries) get loaded and
// unloaded.
SectionList *exec_section_list = exec_objfile->GetSectionList();
SectionList *dsym_section_list = dsym_objfile->GetSectionList();
if (exec_section_list && dsym_section_list)
{
const uint32_t num_exec_sections = dsym_section_list->GetSize();
uint32_t exec_sect_idx;
for (exec_sect_idx = 0; exec_sect_idx < num_exec_sections; ++exec_sect_idx)
{
SectionSP exec_sect_sp(exec_section_list->GetSectionAtIndex(exec_sect_idx));
if (exec_sect_sp.get())
{
// Try and replace any sections that exist in both the executable
// and in the dSYM with those from the executable. If we fail to
// replace the one in the dSYM, then add the executable section to
// the dSYM.
SectionSP dsym_sect_sp(dsym_section_list->FindSectionByID(exec_sect_sp->GetID()));
if (dsym_sect_sp.get() && dsym_sect_sp->GetName() != exec_sect_sp->GetName())
{
// The sections in a dSYM are normally a superset of the sections in an executable.
// If we find a section # in the exectuable & dSYM that don't have the same name,
// something has changed since the dSYM was written. The mach_kernel DSTROOT binary
// has a CTF segment added, for instance, and it's easiest to simply not add that to
// the dSYM - none of the nlist entries are going to have references to that section.
continue;
}
if (dsym_section_list->ReplaceSection(exec_sect_sp->GetID(), exec_sect_sp, 0) == false)
dsym_section_list->AddSection(exec_sect_sp);
}
}
dsym_section_list->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
return true;
}
return false;
}
void
SymbolVendorMacOSX::Initialize()
{
@ -321,16 +276,6 @@ SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_privat
}
}
if (ReplaceDSYMSectionsWithExecutableSections (obj_file, dsym_objfile_sp.get()))
{
SectionList *section_list = dsym_objfile_sp.get()->GetSectionList();
if (section_list)
{
section_list->Copy (module_sp->GetUnifiedSectionList());
section_list->Finalize ();
}
}
symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
return symbol_vendor;
}

View File

@ -243,10 +243,8 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_unwind_table (*this),
m_process_wp(),
m_memory_addr (LLDB_INVALID_ADDRESS),
m_sections_ap (),
m_symtab_ap (),
m_symtab_unified_ap (),
m_symtab_unified_revisionid (0)
m_sections_ap(),
m_symtab_ap ()
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
@ -292,10 +290,8 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_unwind_table (*this),
m_process_wp (process_sp),
m_memory_addr (header_addr),
m_sections_ap (),
m_symtab_ap (),
m_symtab_unified_ap (),
m_symtab_unified_revisionid (0)
m_sections_ap(),
m_symtab_ap ()
{
if (header_data_sp)
m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
@ -331,7 +327,7 @@ ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
AddressClass
ObjectFile::GetAddressClass (addr_t file_addr)
{
Symtab *symtab = GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
Symtab *symtab = GetSymtab();
if (symtab)
{
Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
@ -586,29 +582,31 @@ ObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &
}
void
ObjectFile::ClearSymtab (uint32_t flags)
ObjectFile::ClearSymtab ()
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
bool unified_section_list = !!(flags & ObjectFile::eSymtabFromUnifiedSectionList);
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
log->Printf ("%p ObjectFile::ClearSymtab (%s) symtab = %p",
log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
this,
unified_section_list ? "unified" : "",
unified_section_list ? m_symtab_unified_ap.get() : m_symtab_ap.get());
}
if (unified_section_list)
{
m_symtab_unified_ap.reset();
m_symtab_unified_revisionid = 0;
}
else
{
m_symtab_ap.reset();
m_symtab_ap.get());
}
m_symtab_ap.reset();
}
}
SectionList *
ObjectFile::GetSectionList()
{
if (m_sections_ap.get() == NULL)
{
ModuleSP module_sp(GetModule());
if (module_sp)
CreateSections(*module_sp->GetUnifiedSectionList());
}
return m_sections_ap.get();
}

View File

@ -33,7 +33,7 @@ Symbol::Symbol() :
m_is_external (false),
m_size_is_sibling (false),
m_size_is_synthesized (false),
m_calculated_size (false),
m_size_is_valid (false),
m_demangled_is_synthesized (false),
m_type (eSymbolTypeInvalid),
m_mangled (),
@ -67,7 +67,7 @@ Symbol::Symbol
m_is_external (external),
m_size_is_sibling (false),
m_size_is_synthesized (false),
m_calculated_size (size_is_valid || size > 0),
m_size_is_valid (size_is_valid || size > 0),
m_demangled_is_synthesized (false),
m_type (type),
m_mangled (ConstString(name), name_is_mangled),
@ -99,7 +99,7 @@ Symbol::Symbol
m_is_external (external),
m_size_is_sibling (false),
m_size_is_synthesized (false),
m_calculated_size (size_is_valid || range.GetByteSize() > 0),
m_size_is_valid (size_is_valid || range.GetByteSize() > 0),
m_demangled_is_synthesized (false),
m_type (type),
m_mangled (ConstString(name), name_is_mangled),
@ -118,7 +118,7 @@ Symbol::Symbol(const Symbol& rhs):
m_is_external (rhs.m_is_external),
m_size_is_sibling (rhs.m_size_is_sibling),
m_size_is_synthesized (false),
m_calculated_size (rhs.m_calculated_size),
m_size_is_valid (rhs.m_size_is_valid),
m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
m_type (rhs.m_type),
m_mangled (rhs.m_mangled),
@ -141,7 +141,7 @@ Symbol::operator= (const Symbol& rhs)
m_is_external = rhs.m_is_external;
m_size_is_sibling = rhs.m_size_is_sibling;
m_size_is_synthesized = rhs.m_size_is_sibling;
m_calculated_size = rhs.m_calculated_size;
m_size_is_valid = rhs.m_size_is_valid;
m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
m_type = rhs.m_type;
m_mangled = rhs.m_mangled;
@ -163,7 +163,7 @@ Symbol::Clear()
m_is_external = false;
m_size_is_sibling = false;
m_size_is_synthesized = false;
m_calculated_size = false;
m_size_is_valid = false;
m_demangled_is_synthesized = false;
m_type = eSymbolTypeInvalid;
m_flags = 0;
@ -410,7 +410,6 @@ Symbol::GetTypeAsString() const
return "<unknown SymbolType>";
}
void
Symbol::CalculateSymbolContext (SymbolContext *sc)
{
@ -436,7 +435,6 @@ Symbol::CalculateSymbolContextSymbol ()
return this;
}
void
Symbol::DumpSymbolContext (Stream *s)
{
@ -456,32 +454,9 @@ Symbol::DumpSymbolContext (Stream *s)
s->Printf("Symbol{0x%8.8x}", GetID());
}
lldb::addr_t
Symbol::GetByteSize () const
{
addr_t byte_size = m_addr_range.GetByteSize();
if (byte_size == 0 && !m_calculated_size)
{
const_cast<Symbol*>(this)->m_calculated_size = true;
if (ValueIsAddress())
{
ModuleSP module_sp (GetAddress().GetModule());
if (module_sp)
{
SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
if (sym_vendor)
{
Symtab *symtab = sym_vendor->GetSymtab();
if (symtab)
{
const_cast<Symbol*>(this)->SetByteSize (symtab->CalculateSymbolSize (const_cast<Symbol *>(this)));
byte_size = m_addr_range.GetByteSize();
}
}
}
}
}
return byte_size;
return m_addr_range.GetByteSize();
}

View File

@ -24,6 +24,22 @@ SymbolFile::FindPlugin (ObjectFile* obj_file)
std::unique_ptr<SymbolFile> best_symfile_ap;
if (obj_file != NULL)
{
// We need to test the abilities of this section list. So create what it would
// be with this new obj_file.
lldb::ModuleSP module_sp(obj_file->GetModule());
if (module_sp)
{
// Default to the main module section list.
ObjectFile *module_obj_file = module_sp->GetObjectFile();
if (module_obj_file != obj_file)
{
// Make sure the main object file's sections are created
module_obj_file->GetSectionList();
obj_file->CreateSections (*module_sp->GetUnifiedSectionList());
}
}
// TODO: Load any plug-ins in the appropriate plug-in search paths and
// iterate over all of them to find the best one for the job.

View File

@ -447,7 +447,7 @@ SymbolVendor::GetSymtab ()
if (objfile)
{
// Get symbol table from unified section list.
return objfile->GetSymtab (ObjectFile::eSymtabFromUnifiedSectionList);
return objfile->GetSymtab ();
}
}
return NULL;
@ -463,7 +463,7 @@ SymbolVendor::ClearSymtab()
if (objfile)
{
// Clear symbol table from unified section list.
objfile->ClearSymtab (ObjectFile::eSymtabFromUnifiedSectionList);
objfile->ClearSymtab ();
}
}
}

View File

@ -27,10 +27,10 @@ using namespace lldb_private;
Symtab::Symtab(ObjectFile *objfile) :
m_objfile (objfile),
m_symbols (),
m_addr_indexes (),
m_file_addr_to_index (),
m_name_to_index (),
m_mutex (Mutex::eMutexTypeRecursive),
m_addr_indexes_computed (false),
m_file_addr_to_index_computed (false),
m_name_indexes_computed (false)
{
}
@ -63,9 +63,9 @@ Symtab::AddSymbol(const Symbol& symbol)
// when calling this function to avoid performance issues.
uint32_t symbol_idx = m_symbols.size();
m_name_to_index.Clear();
m_addr_indexes.clear();
m_file_addr_to_index.Clear();
m_symbols.push_back(symbol);
m_addr_indexes_computed = false;
m_file_addr_to_index_computed = false;
m_name_indexes_computed = false;
return symbol_idx;
}
@ -144,19 +144,14 @@ Symtab::Dump (Stream *s, Target *target, SortOrder sort_order)
case eSortOrderByAddress:
s->PutCString (" (sorted by address):\n");
DumpSymbolHeader (s);
if (!m_addr_indexes_computed)
if (!m_file_addr_to_index_computed)
InitAddressIndexes();
const size_t num_symbols = GetNumSymbols();
std::vector<uint32_t>::const_iterator pos;
std::vector<uint32_t>::const_iterator end = m_addr_indexes.end();
for (pos = m_addr_indexes.begin(); pos != end; ++pos)
const size_t num_entries = m_file_addr_to_index.GetSize();
for (size_t i=0; i<num_entries; ++i)
{
size_t idx = *pos;
if (idx < num_symbols)
{
s->Indent();
m_symbols[idx].Dump(s, target, idx);
}
s->Indent();
const uint32_t symbol_idx = m_file_addr_to_index.GetEntryRef(i).data;
m_symbols[symbol_idx].Dump(s, target, symbol_idx);
}
break;
}
@ -943,92 +938,94 @@ void
Symtab::InitAddressIndexes()
{
// Protected function, no need to lock mutex...
if (!m_addr_indexes_computed && !m_symbols.empty())
if (!m_file_addr_to_index_computed && !m_symbols.empty())
{
m_addr_indexes_computed = true;
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())
m_addr_indexes.push_back (std::distance(begin, pos));
}
SortSymbolIndexesByValue (m_addr_indexes, false);
m_addr_indexes.push_back (UINT32_MAX); // Terminator for bsearch since we might need to look at the next symbol
}
}
size_t
Symtab::CalculateSymbolSize (Symbol *symbol)
{
Mutex::Locker locker (m_mutex);
if (m_symbols.empty())
return 0;
// Make sure this symbol is from this symbol table...
if (symbol < &m_symbols.front() || symbol > &m_symbols.back())
return 0;
size_t byte_size = 0;
// Else if this is an address based symbol, figure out the delta between
// it and the next address based symbol
if (symbol->ValueIsAddress())
{
if (!m_addr_indexes_computed)
InitAddressIndexes();
const size_t num_addr_indexes = m_addr_indexes.size();
const lldb::addr_t symbol_file_addr = symbol->GetAddress().GetFileAddress();
SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress (this,
symbol_file_addr,
&m_addr_indexes.front(),
num_addr_indexes);
if (info.match_index_ptr != NULL)
{
// We can figure out the address range of all symbols except the
// last one by taking the delta between the current symbol and
// the next symbol
for (uint32_t addr_index = info.match_index_ptr - &m_addr_indexes.front() + 1;
addr_index < num_addr_indexes;
++addr_index)
{
Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]);
if (next_symbol == NULL)
entry.SetRangeBase(pos->GetAddress().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)
{
// No next symbol take the size to be the remaining bytes in the section
// in which the symbol resides
SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (symbol_file_addr));
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)
{
const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
if (end_section_file_addr > symbol_file_addr)
{
byte_size = end_section_file_addr - symbol_file_addr;
symbol->SetByteSize(byte_size);
symbol->SetSizeIsSynthesized(true);
break;
}
}
}
else
{
const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
if (next_file_addr > symbol_file_addr)
{
byte_size = next_file_addr - symbol_file_addr;
symbol->SetByteSize(byte_size);
symbol->SetSizeIsSynthesized(true);
break;
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::CalculateSymbolSizes ()
{
Mutex::Locker locker (m_mutex);
if (!m_symbols.empty())
{
if (!m_file_addr_to_index_computed)
InitAddressIndexes();
const size_t num_entries = m_file_addr_to_index.GetSize();
for (size_t i = 0; i < num_entries; ++i)
{
// The entries in the m_file_addr_to_index have calculated the sizes already
// so we will use this size if we need to.
const FileRangeToIndexMap::Entry &entry = m_file_addr_to_index.GetEntryRef(i);
Symbol &symbol = m_symbols[entry.data];
// If the symbol size is already valid, no need to do anything
if (symbol.GetByteSizeIsValid())
continue;
const addr_t range_size = entry.GetByteSize();
if (range_size > 0)
{
symbol.SetByteSize(range_size);
symbol.SetSizeIsSynthesized(true);
}
}
}
return byte_size;
}
Symbol *
@ -1036,6 +1033,7 @@ Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* index
{
Mutex::Locker locker (m_mutex);
SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 };
::bsearch (&info,
@ -1074,10 +1072,13 @@ Symtab::FindSymbolContainingFileAddress (addr_t file_addr)
{
Mutex::Locker locker (m_mutex);
if (!m_addr_indexes_computed)
if (!m_file_addr_to_index_computed)
InitAddressIndexes();
return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size());
const FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.FindEntryThatContains(file_addr);
if (entry)
return SymbolAtIndex(entry->data);
return NULL;
}
void