diff options
| author | Jim Ingham <jingham@apple.com> | 2014-05-21 03:58:03 +0000 |
|---|---|---|
| committer | Jim Ingham <jingham@apple.com> | 2014-05-21 03:58:03 +0000 |
| commit | fbe0b9abf99719834add56bfd7b84c913e17dad3 (patch) | |
| tree | afe4e3c55802e5541e6d3507413bf0a8845a4b68 | |
| parent | 56f9c191e1c41ab4fe61a9b9ad6bf4fc1c987837 (diff) | |
| download | bcm5719-llvm-fbe0b9abf99719834add56bfd7b84c913e17dad3.tar.gz bcm5719-llvm-fbe0b9abf99719834add56bfd7b84c913e17dad3.zip | |
ReExported symbols can point to a library that doesn't actually
contain the symbol, but just reexports wholesale from another
library. Handle this case.
<rdar://problem/16977589>
llvm-svn: 209270
| -rw-r--r-- | lldb/include/lldb/Symbol/ObjectFile.h | 17 | ||||
| -rw-r--r-- | lldb/include/lldb/Symbol/Symbol.h | 10 | ||||
| -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 |
5 files changed, 102 insertions, 30 deletions
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index cf17c3d5b15..4c0aa1bb86a 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -471,7 +471,7 @@ public: /// Gets the symbol file spec list for this object file. /// /// If the object file format contains a debug symbol file link, - /// the values will be return in the FileSpecList. + /// the values will be returned in the FileSpecList. /// /// @return /// Returns filespeclist. @@ -483,6 +483,21 @@ public: } //------------------------------------------------------------------ + /// Gets the file spec list of libraries re-exported by this object file. + /// + /// If the object file format has the notion of one library re-exporting the symbols from another, + /// the re-exported libraries will be returned in the FileSpecList. + /// + /// @return + /// Returns filespeclist. + //------------------------------------------------------------------ + virtual lldb_private::FileSpecList + GetReExportedLibraries () + { + return FileSpecList(); + } + + //------------------------------------------------------------------ /// Sets the load address for an entire module, assuming a rigid /// slide of sections, if possible in the implementation. /// diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h index db32ba373e4..cd10bf34e45 100644 --- a/lldb/include/lldb/Symbol/Symbol.h +++ b/lldb/include/lldb/Symbol/Symbol.h @@ -303,7 +303,15 @@ public: Stream &strm); protected: - + // This is the internal guts of ResolveReExportedSymbol, it assumes reexport_name is not null, and that module_spec + // is valid. We track the modules we've already seen to make sure we don't get caught in a cycle. + + Symbol * + ResolveReExportedSymbolInModuleSpec (Target &target, + ConstString &reexport_name, + lldb_private::ModuleSpec &module_spec, + lldb_private::ModuleList &seen_modules); + uint32_t m_uid; // User ID (usually the original symbol table index) uint16_t m_type_data; // data specific to m_type uint16_t m_type_data_resolved:1, // True if the data in m_type_data has already been calculated 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; } |

