[Lldb-commits] [lldb] r209270 - ReExported symbols can point to a library that doesn't actually

Jim Ingham jingham at apple.com
Tue May 20 20:58:03 PDT 2014


Author: jingham
Date: Tue May 20 22:58:03 2014
New Revision: 209270

URL: http://llvm.org/viewvc/llvm-project?rev=209270&view=rev
Log:
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>

Modified:
    lldb/trunk/include/lldb/Symbol/ObjectFile.h
    lldb/trunk/include/lldb/Symbol/Symbol.h
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
    lldb/trunk/source/Symbol/Symbol.cpp

Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=209270&r1=209269&r2=209270&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Tue May 20 22:58:03 2014
@@ -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.
     ///

Modified: lldb/trunk/include/lldb/Symbol/Symbol.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Symbol.h?rev=209270&r1=209269&r2=209270&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Symbol.h (original)
+++ lldb/trunk/include/lldb/Symbol/Symbol.h Tue May 20 22:58:03 2014
@@ -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

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=209270&r1=209269&r2=209270&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Tue May 20 22:58:03 2014
@@ -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);
                 }

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=209270&r1=209269&r2=209270&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Tue May 20 22:58:03 2014
@@ -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 ();

Modified: lldb/trunk/source/Symbol/Symbol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symbol.cpp?rev=209270&r1=209269&r2=209270&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symbol.cpp (original)
+++ lldb/trunk/source/Symbol/Symbol.cpp Tue May 20 22:58:03 2014
@@ -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;
 }





More information about the lldb-commits mailing list