diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 5 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h | 7 | ||||
-rw-r--r-- | lldb/source/Symbol/Symbol.cpp | 93 |
3 files changed, 77 insertions, 28 deletions
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 4f491ce67b0..6866a068ef7 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1838,6 +1838,11 @@ ObjectFileMachO::ParseSymtab () // Strip the path if there is @rpath, @executanble, etc so we just use the basename if (path[0] == '@') file_spec.GetDirectory().Clear(); + + if (lc.cmd == LC_REEXPORT_DYLIB) + { + m_reexported_dylibs.AppendIfUnique(file_spec); + } dylib_files.Append(file_spec); } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index c565ac63e4e..dff0b21be80 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -13,6 +13,7 @@ #include "lldb/Utility/SafeMachO.h" #include "lldb/Core/Address.h" +#include "lldb/Core/FileSpecList.h" #include "lldb/Core/RangeMap.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Mutex.h" @@ -127,6 +128,11 @@ public: virtual uint32_t GetDependentModules (lldb_private::FileSpecList& files); + virtual lldb_private::FileSpecList + GetReExportedLibraries () + { + return m_reexported_dylibs; + } //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -208,6 +214,7 @@ protected: lldb_private::Address m_entry_point_address; FileRangeArray m_thread_context_offsets; bool m_thread_context_offsets_valid; + lldb_private::FileSpecList m_reexported_dylibs; size_t ParseSymtab (); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 9bda7b20ecb..98b5a320580 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -536,47 +536,84 @@ Symbol::GetByteSize () const return m_addr_range.GetByteSize(); } + Symbol * -Symbol::ResolveReExportedSymbol (Target &target) +Symbol::ResolveReExportedSymbolInModuleSpec (Target &target, + ConstString &reexport_name, + ModuleSpec &module_spec, + ModuleList &seen_modules) { - ConstString reexport_name (GetReExportedSymbolName()); - if (reexport_name) + ModuleSP module_sp; + if (module_spec.GetFileSpec()) { - ModuleSpec module_spec; - ModuleSP module_sp; - module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary(); - if (module_spec.GetFileSpec()) + // Try searching for the module file spec first using the full path + module_sp = target.GetImages().FindFirstModule(module_spec); + if (!module_sp) { - // Try searching for the module file spec first using the full path + // Next try and find the module by basename in case environment + // variables or other runtime trickery causes shared libraries + // to be loaded from alternate paths + module_spec.GetFileSpec().GetDirectory().Clear(); module_sp = target.GetImages().FindFirstModule(module_spec); - if (!module_sp) - { - // Next try and find the module by basename in case environment - // variables or other runtime trickery causes shared libraries - // to be loaded from alternate paths - module_spec.GetFileSpec().GetDirectory().Clear(); - module_sp = target.GetImages().FindFirstModule(module_spec); - } } + } + + if (module_sp) + { + // There should not be cycles in the reexport list, but we don't want to crash if there are so make sure + // we haven't seen this before: + if (!seen_modules.AppendIfNeeded(module_sp)) + return nullptr; - if (module_sp) + lldb_private::SymbolContextList sc_list; + module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list); + const size_t num_scs = sc_list.GetSize(); + if (num_scs > 0) { - lldb_private::SymbolContextList sc_list; - module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list); - const size_t num_scs = sc_list.GetSize(); - if (num_scs > 0) + for (size_t i=0; i<num_scs; ++i) { - for (size_t i=0; i<num_scs; ++i) + lldb_private::SymbolContext sc; + if (sc_list.GetContextAtIndex(i, sc)) { - lldb_private::SymbolContext sc; - if (sc_list.GetContextAtIndex(i, sc)) - { - if (sc.symbol->IsExternal()) - return sc.symbol; - } + if (sc.symbol->IsExternal()) + return sc.symbol; } } } + // If we didn't find the symbol in this module, it may be because this module re-exports some + // whole other library. We have to search those as well: + seen_modules.Append(module_sp); + + FileSpecList reexported_libraries = module_sp->GetObjectFile()->GetReExportedLibraries(); + size_t num_reexported_libraries = reexported_libraries.GetSize(); + for (size_t idx = 0; idx < num_reexported_libraries; idx++) + { + ModuleSpec reexported_module_spec; + reexported_module_spec.GetFileSpec() = reexported_libraries.GetFileSpecAtIndex(idx); + Symbol *result_symbol = ResolveReExportedSymbolInModuleSpec(target, + reexport_name, + reexported_module_spec, + seen_modules); + if (result_symbol) + return result_symbol; + } + } + return nullptr; +} + +Symbol * +Symbol::ResolveReExportedSymbol (Target &target) +{ + ConstString reexport_name (GetReExportedSymbolName()); + if (reexport_name) + { + ModuleSpec module_spec; + ModuleList seen_modules; + module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary(); + if (module_spec.GetFileSpec()) + { + return ResolveReExportedSymbolInModuleSpec(target, reexport_name, module_spec, seen_modules); + } } return nullptr; } |