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:
parent
8978a9dd0a
commit
3046e66830
|
@ -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:
|
||||
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 §_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;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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
|
@ -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 ();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue