[Lldb-commits] [lldb] r193101 - <rdar://problem/14496092>

Greg Clayton gclayton at apple.com
Mon Oct 21 11:40:52 PDT 2013


Author: gclayton
Date: Mon Oct 21 13:40:51 2013
New Revision: 193101

URL: http://llvm.org/viewvc/llvm-project?rev=193101&view=rev
Log:
<rdar://problem/14496092>

Fixed an issue with reexported symbols on MacOSX by adding support for symbols re-exporting symbols. There is now a new symbol type eSymbolTypeReExported which contains a new name for the re-exported symbol and the new shared library. These symbols are only used when a symbol is re-exported as a symbol under a different name.

Modified the expression parser to be able to deal with finding the re-exported symbols and track down the actual symbol it refers to.


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

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=193101&r1=193100&r2=193101&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Mon Oct 21 13:40:51 2013
@@ -291,6 +291,9 @@ public:
     /// @param[in] name
     ///     The name of the symbol.  
     ///
+    /// @param[in] module
+    ///     The module to limit the search to. This can be NULL
+    ///
     /// @return
     ///     Valid load address for the symbol
     //------------------------------------------------------------------
@@ -298,7 +301,8 @@ public:
     GetSymbolAddress (Target &target,
                       Process *process,
                       const ConstString &name,
-                      lldb::SymbolType symbol_type);
+                      lldb::SymbolType symbol_type,
+                      Module *module = NULL);
     
     lldb::addr_t
     GetSymbolAddress (const ConstString &name,
@@ -504,12 +508,16 @@ private:
     /// @param[in] name
     ///     The name as a plain C string.
     ///
+    /// @param[in] module
+    ///     The module to limit the search to. This can be NULL
+    ///
     /// @return
     ///     The LLDB Symbol found, or NULL if none was found.
-    //---------------------------------------------------------
+    //------------------------------------------------------------------
     const Symbol *
     FindGlobalDataSymbol (Target &target,
-                          const ConstString &name);
+                          const ConstString &name,
+                          Module *module = NULL);
     
     //------------------------------------------------------------------
     /// Given a target, find a variable that matches the given name and 

Modified: lldb/trunk/include/lldb/Symbol/Symbol.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Symbol.h?rev=193101&r1=193100&r2=193101&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Symbol.h (original)
+++ lldb/trunk/include/lldb/Symbol/Symbol.h Mon Oct 21 13:40:51 2013
@@ -122,6 +122,21 @@ public:
         return m_mangled;
     }
 
+    ConstString
+    GetReExportedSymbolName() const;
+
+    FileSpec
+    GetReExportedSymbolSharedLibrary () const;
+    
+    bool
+    SetReExportedSymbolName(const ConstString &name);
+
+    bool
+    SetReExportedSymbolSharedLibrary (const FileSpec &fspec);
+    
+    Symbol *
+    ResolveReExportedSymbol (Target &target);
+
     uint32_t
     GetSiblingIndex () const;
 
@@ -238,24 +253,6 @@ public:
         m_size_is_sibling = b;
     }
 
-//    void
-//    SetValue (Address &value)
-//    {
-//        m_addr_range.GetBaseAddress() = value;
-//    }
-//
-//    void
-//    SetValue (const AddressRange &range)
-//    {
-//        m_addr_range = range;
-//    }
-//
-//    void
-//    SetValue (lldb::addr_t value);
-//    {
-//        m_addr_range.GetBaseAddress().SetRawAddress(value);
-//    }
-
     // If m_type is "Code" or "Function" then this will return the prologue size
     // in bytes, else it will return zero.
     uint32_t

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=193101&r1=193100&r2=193101&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Mon Oct 21 13:40:51 2013
@@ -484,7 +484,8 @@ namespace lldb {
         eSymbolTypeUndefined,
         eSymbolTypeObjCClass,
         eSymbolTypeObjCMetaClass,
-        eSymbolTypeObjCIVar
+        eSymbolTypeObjCIVar,
+        eSymbolTypeReExported
     } SymbolType;
     
     typedef enum SectionType

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=193101&r1=193100&r2=193101&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon Oct 21 13:40:51 2013
@@ -21,6 +21,7 @@
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/RegisterValue.h"
 #include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Core/ValueObjectVariable.h"
@@ -591,11 +592,18 @@ ClangExpressionDeclMap::GetFunctionAddre
 }
 
 addr_t
-ClangExpressionDeclMap::GetSymbolAddress (Target &target, Process *process, const ConstString &name, lldb::SymbolType symbol_type)
+ClangExpressionDeclMap::GetSymbolAddress (Target &target,
+                                          Process *process,
+                                          const ConstString &name,
+                                          lldb::SymbolType symbol_type,
+                                          Module *module)
 {
     SymbolContextList sc_list;
     
-    target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
+    if (module)
+        module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
+    else
+        target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
     
     const uint32_t num_matches = sc_list.GetSize();
     addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
@@ -623,6 +631,28 @@ ClangExpressionDeclMap::GetSymbolAddress
                     symbol_load_addr = sym_address->GetCallableLoadAddress (&target, true);
                     break;
 
+                case eSymbolTypeReExported:
+                    {
+                        ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
+                        if (reexport_name)
+                        {
+                            ModuleSP reexport_module_sp;
+                            ModuleSpec reexport_module_spec;
+                            reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
+                            if (reexport_module_spec.GetPlatformFileSpec())
+                            {
+                                reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
+                                if (!reexport_module_sp)
+                                {
+                                    reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
+                                    reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
+                                }
+                            }
+                            symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get());
+                        }
+                    }
+                    break;
+
                 case eSymbolTypeData:
                 case eSymbolTypeRuntime:
                 case eSymbolTypeVariable:
@@ -680,11 +710,15 @@ ClangExpressionDeclMap::GetSymbolAddress
 
 const Symbol *
 ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
-                                              const ConstString &name)
+                                              const ConstString &name,
+                                              Module *module)
 {
     SymbolContextList sc_list;
     
-    target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
+    if (module)
+        module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
+    else
+        target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
     
     const uint32_t matches = sc_list.GetSize();
     for (uint32_t i=0; i<matches; ++i)
@@ -716,6 +750,28 @@ ClangExpressionDeclMap::FindGlobalDataSy
                         }
                         return symbol;
 
+                    case eSymbolTypeReExported:
+                        {
+                            ConstString reexport_name = symbol->GetReExportedSymbolName();
+                            if (reexport_name)
+                            {
+                                ModuleSP reexport_module_sp;
+                                ModuleSpec reexport_module_spec;
+                                reexport_module_spec.GetPlatformFileSpec() = symbol->GetReExportedSymbolSharedLibrary();
+                                if (reexport_module_spec.GetPlatformFileSpec())
+                                {
+                                    reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
+                                    if (!reexport_module_sp)
+                                    {
+                                        reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
+                                        reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
+                                    }
+                                }
+                                return FindGlobalDataSymbol(target, symbol->GetReExportedSymbolName(), reexport_module_sp.get());
+                            }
+                        }
+                        break;
+                        
                     case eSymbolTypeCode: // We already lookup functions elsewhere
                     case eSymbolTypeVariable:
                     case eSymbolTypeLocal:
@@ -1286,8 +1342,7 @@ ClangExpressionDeclMap::FindExternalVisi
             
             if (sc_list.GetSize())
             {
-                Symbol *generic_symbol = NULL;
-                Symbol *non_extern_symbol = NULL;
+                Symbol *symbol = NULL;
                 
                 for (uint32_t index = 0, num_indices = sc_list.GetSize();
                      index < num_indices;
@@ -1315,23 +1370,18 @@ ClangExpressionDeclMap::FindExternalVisi
                     }
                     else if (sym_ctx.symbol)
                     {
-                        if (sym_ctx.symbol->IsExternal())
-                            generic_symbol = sym_ctx.symbol;
+                        if (sym_ctx.symbol->GetType() == eSymbolTypeReExported)
+                            symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
                         else
-                            non_extern_symbol = sym_ctx.symbol;
+                            symbol = sym_ctx.symbol;
                     }
                 }
                 
                 if (!context.m_found.function_with_type_info)
                 {
-                    if (generic_symbol)
-                    {
-                        AddOneFunction (context, NULL, generic_symbol, current_id);
-                        context.m_found.function = true;
-                    }
-                    else if (non_extern_symbol)
+                    if (symbol)
                     {
-                        AddOneFunction (context, NULL, non_extern_symbol, current_id);
+                        AddOneFunction (context, NULL, symbol, current_id);
                         context.m_found.function = true;
                     }
                 }

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=193101&r1=193100&r2=193101&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Oct 21 13:40:51 2013
@@ -894,6 +894,7 @@ ObjectFileMachO::GetAddressClass (lldb::
             case eSymbolTypeObjCClass:      return eAddressClassRuntime;
             case eSymbolTypeObjCMetaClass:  return eAddressClassRuntime;
             case eSymbolTypeObjCIVar:       return eAddressClassRuntime;
+            case eSymbolTypeReExported:     return eAddressClassRuntime;
             }
         }
     }
@@ -1481,6 +1482,138 @@ protected:
     std::vector<SectionInfo> m_section_infos;
 };
 
+struct TrieEntry
+{
+    TrieEntry () :
+        name(),
+        address(LLDB_INVALID_ADDRESS),
+        flags (0),
+        other(0),
+        import_name()
+    {
+    }
+    
+    void
+    Clear ()
+    {
+        name.Clear();
+        address = LLDB_INVALID_ADDRESS;
+        flags = 0;
+        other = 0;
+        import_name.Clear();
+    }
+    
+    void
+    Dump () const
+    {
+        printf ("0x%16.16llx 0x%16.16llx 0x%16.16llx \"%s\"", address, flags, other, name.GetCString());
+        if (import_name)
+            printf (" -> \"%s\"\n", import_name.GetCString());
+        else
+            printf ("\n");
+    }
+    ConstString		name;
+    uint64_t		address;
+    uint64_t		flags;
+    uint64_t		other;
+    ConstString		import_name;
+};
+
+struct TrieEntryWithOffset
+{
+	lldb::offset_t nodeOffset;
+	TrieEntry entry;
+	
+    TrieEntryWithOffset (lldb::offset_t offset) :
+        nodeOffset (offset),
+        entry()
+    {
+    }
+    
+    void
+    Dump (uint32_t idx) const
+    {
+        printf ("[%3u] 0x%16.16llx: ", idx, nodeOffset);
+        entry.Dump();
+    }
+
+	bool
+    operator<(const TrieEntryWithOffset& other) const
+    {
+        return ( nodeOffset < other.nodeOffset );
+    }
+};
+
+static void
+ParseTrieEntries (DataExtractor &data,
+                  lldb::offset_t offset,
+                  std::vector<llvm::StringRef> &nameSlices,
+                  std::set<lldb::addr_t> &resolver_addresses,
+                  std::vector<TrieEntryWithOffset>& output)
+{
+	if (!data.ValidOffset(offset))
+        return;
+
+	const uint64_t terminalSize = data.GetULEB128(&offset);
+	lldb::offset_t children_offset = offset + terminalSize;
+	if ( terminalSize != 0 ) {
+		TrieEntryWithOffset e (offset);
+		e.entry.flags = data.GetULEB128(&offset);
+        const char *import_name = NULL;
+		if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) {
+			e.entry.address = 0;
+			e.entry.other = data.GetULEB128(&offset); // dylib ordinal
+            import_name = data.GetCStr(&offset);
+		}
+		else {
+			e.entry.address = data.GetULEB128(&offset);
+			if ( e.entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER )
+            {
+                resolver_addresses.insert(e.entry.address);
+				e.entry.other = data.GetULEB128(&offset);
+            }
+			else
+				e.entry.other = 0;
+		}
+        // Only add symbols that are reexport symbols with a valid import name
+        if (EXPORT_SYMBOL_FLAGS_REEXPORT & e.entry.flags && import_name && import_name[0])
+        {
+            std::string name;
+            if (!nameSlices.empty())
+            {
+                for (auto name_slice: nameSlices)
+                    name.append(name_slice.data(), name_slice.size());
+            }
+            if (name.size() > 1)
+            {
+                // Skip the leading '_'
+                e.entry.name.SetCStringWithLength(name.c_str() + 1,name.size() - 1);
+            }
+            if (import_name)
+            {
+                // Skip the leading '_'
+                e.entry.import_name.SetCString(import_name+1);                
+            }
+            output.push_back(e);
+        }
+	}
+    
+	const uint8_t childrenCount = data.GetU8(&children_offset);
+	for (uint8_t i=0; i < childrenCount; ++i) {
+        nameSlices.push_back(data.GetCStr(&children_offset));
+        lldb::offset_t childNodeOffset = data.GetULEB128(&children_offset);
+		if (childNodeOffset)
+        {
+            ParseTrieEntries(data,
+                             childNodeOffset,
+                             nameSlices,
+                             resolver_addresses,
+                             output);
+        }
+        nameSlices.pop_back();
+	}
+}
+
 size_t
 ObjectFileMachO::ParseSymtab ()
 {
@@ -1493,11 +1626,12 @@ ObjectFileMachO::ParseSymtab ()
 
     struct symtab_command symtab_load_command = { 0, 0, 0, 0, 0, 0 };
     struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
+    struct dyld_info_command dyld_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
     typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
     FunctionStarts function_starts;
     lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
     uint32_t i;
-
+    FileSpecList dylib_files;
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
 
     for (i=0; i<m_header.ncmds; ++i)
@@ -1545,6 +1679,39 @@ ObjectFileMachO::ParseSymtab ()
             }
             break;
 
+        case LC_DYLD_INFO:
+        case LC_DYLD_INFO_ONLY:
+            if (m_data.GetU32(&offset, &dyld_info.rebase_off, 10))
+            {
+                dyld_info.cmd = lc.cmd;
+                dyld_info.cmdsize = lc.cmdsize;
+            }
+            else
+            {
+                memset (&dyld_info, 0, sizeof(dyld_info));
+            }
+            break;
+
+        case LC_LOAD_DYLIB:
+        case LC_LOAD_WEAK_DYLIB:
+        case LC_REEXPORT_DYLIB:
+        case LC_LOADFVMLIB:
+        case LC_LOAD_UPWARD_DYLIB:
+            {
+                uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
+                const char *path = m_data.PeekCStr(name_offset);
+                if (path)
+                {
+                    FileSpec file_spec(path, false);
+                    // Strip the path if there is @rpath, @executanble, etc so we just use the basename
+                    if (path[0] == '@')
+                        file_spec.GetDirectory().Clear();
+
+                    dylib_files.Append(file_spec);
+                }
+            }
+            break;
+
         case LC_FUNCTION_STARTS:
             function_starts_load_command.cmd = lc.cmd;
             function_starts_load_command.cmdsize = lc.cmdsize;
@@ -1574,6 +1741,7 @@ ObjectFileMachO::ParseSymtab ()
         DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
         DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
         DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
+        DataExtractor dyld_trie_data (NULL, 0, byte_order, addr_byte_size);
 
         const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
         const addr_t strtab_data_byte_size = symtab_load_command.strsize;
@@ -1689,6 +1857,14 @@ ObjectFileMachO::ParseSymtab ()
             strtab_data.SetData (m_data,
                                  symtab_load_command.stroff,
                                  strtab_data_byte_size);
+            
+            if (dyld_info.export_size > 0)
+            {
+                dyld_trie_data.SetData (m_data,
+                                        dyld_info.export_off,
+                                        dyld_info.export_size);
+            }
+
             if (m_dysymtab.nindirectsyms != 0)
             {
                 indirect_symbol_index_data.SetData (m_data,
@@ -2661,6 +2837,7 @@ ObjectFileMachO::ParseSymtab ()
                                                                 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                                                 // We just need the flags from the linker symbol, so put these flags
                                                                 // into the N_FUN flags to avoid duplicate symbols in the symbol table
+                                                                sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                                                                 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                                                 sym[sym_idx].Clear();
                                                                 continue;
@@ -2681,6 +2858,7 @@ ObjectFileMachO::ParseSymtab ()
                                                                 m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                                                 // We just need the flags from the linker symbol, so put these flags
                                                                 // into the N_STSYM flags to avoid duplicate symbols in the symbol table
+                                                                sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                                                                 sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                                                 sym[sym_idx].Clear();
                                                                 continue;
@@ -3404,6 +3582,7 @@ ObjectFileMachO::ParseSymtab ()
                                     m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                     // We just need the flags from the linker symbol, so put these flags
                                     // into the N_FUN flags to avoid duplicate symbols in the symbol table
+                                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                                     sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                     sym[sym_idx].Clear();
                                     continue;
@@ -3424,6 +3603,7 @@ ObjectFileMachO::ParseSymtab ()
                                     m_nlist_idx_to_sym_idx[nlist_idx] = pos->second;
                                     // We just need the flags from the linker symbol, so put these flags
                                     // into the N_STSYM flags to avoid duplicate symbols in the symbol table
+                                    sym[pos->second].SetExternal(sym[sym_idx].IsExternal());
                                     sym[pos->second].SetFlags (nlist.n_type << 16 | nlist.n_desc);
                                     sym[sym_idx].Clear();
                                     continue;
@@ -3469,38 +3649,6 @@ ObjectFileMachO::ParseSymtab ()
                 {
                     sym[sym_idx].Clear();
                 }
-
-            }
-
-            // STAB N_GSYM entries end up having a symbol type eSymbolTypeGlobal and when the symbol value
-            // is zero, the address of the global ends up being in a non-STAB entry. Try and fix up all
-            // such entries by figuring out what the address for the global is by looking up this non-STAB
-            // entry and copying the value into the debug symbol's value to save us the hassle in the
-            // debug symbol parser.
-
-            Symbol *global_symbol = NULL;
-            for (nlist_idx = 0;
-                 nlist_idx < symtab_load_command.nsyms && (global_symbol = symtab->FindSymbolWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, nlist_idx)) != NULL;
-                 nlist_idx++)
-            {
-                if (global_symbol->GetAddress().GetFileAddress() == 0)
-                {
-                    std::vector<uint32_t> indexes;
-                    if (symtab->AppendSymbolIndexesWithName (global_symbol->GetMangled().GetName(), indexes) > 0)
-                    {
-                        std::vector<uint32_t>::const_iterator pos;
-                        std::vector<uint32_t>::const_iterator end = indexes.end();
-                        for (pos = indexes.begin(); pos != end; ++pos)
-                        {
-                            symbol_ptr = symtab->SymbolAtIndex(*pos);
-                            if (symbol_ptr != global_symbol && symbol_ptr->IsDebug() == false)
-                            {
-                                global_symbol->GetAddress() = symbol_ptr->GetAddress();
-                                break;
-                            }
-                        }
-                    }
-                }
             }
         }
 
@@ -3588,6 +3736,31 @@ ObjectFileMachO::ParseSymtab ()
             sym = symtab->Resize (num_syms);
         }
 
+        std::vector<TrieEntryWithOffset> trie_entries;
+        std::set<lldb::addr_t> resolver_addresses;
+
+        if (dyld_trie_data.GetByteSize() > 0)
+        {
+            std::vector<llvm::StringRef> nameSlices;
+            ParseTrieEntries (dyld_trie_data,
+                              0,
+                              nameSlices,
+                              resolver_addresses,
+                              trie_entries);
+            
+            ConstString text_segment_name ("__TEXT");
+            SectionSP text_segment_sp = GetSectionList()->FindSectionByName(text_segment_name);
+            if (text_segment_sp)
+            {
+                const lldb::addr_t text_segment_file_addr = text_segment_sp->GetFileAddress();
+                if (text_segment_file_addr != LLDB_INVALID_ADDRESS)
+                {
+                    for (auto &e : trie_entries)
+                        e.entry.address += text_segment_file_addr;
+                }
+            }
+        }
+
         // Now synthesize indirect symbols
         if (m_dysymtab.nindirectsyms != 0)
         {
@@ -3646,7 +3819,10 @@ ObjectFileMachO::ParseSymtab ()
                                         // These symbols were N_UNDF N_EXT, and are useless to us, so we
                                         // can re-use them so we don't have to make up a synthetic symbol
                                         // for no good reason.
-                                        stub_symbol->SetType (eSymbolTypeTrampoline);
+                                        if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
+                                            stub_symbol->SetType (eSymbolTypeTrampoline);
+                                        else
+                                            stub_symbol->SetType (eSymbolTypeResolver);
                                         stub_symbol->SetExternal (false);
                                         stub_symbol->GetAddress() = so_addr;
                                         stub_symbol->SetByteSize (symbol_stub_byte_size);
@@ -3662,7 +3838,10 @@ ObjectFileMachO::ParseSymtab ()
                                         }
                                         sym[sym_idx].SetID (synthetic_sym_id++);
                                         sym[sym_idx].GetMangled() = stub_symbol_mangled_name;
-                                        sym[sym_idx].SetType (eSymbolTypeTrampoline);
+                                        if (resolver_addresses.find(symbol_stub_addr) == resolver_addresses.end())
+                                            sym[sym_idx].SetType (eSymbolTypeTrampoline);
+                                        else
+                                            sym[sym_idx].SetType (eSymbolTypeResolver);
                                         sym[sym_idx].SetIsSynthetic (true);
                                         sym[sym_idx].GetAddress() = so_addr;
                                         sym[sym_idx].SetByteSize (symbol_stub_byte_size);
@@ -3680,6 +3859,32 @@ ObjectFileMachO::ParseSymtab ()
                 }
             }
         }
+
+        
+        if (!trie_entries.empty())
+        {
+            for (const auto &e : trie_entries)
+            {
+                if (e.entry.import_name)
+                {
+                    // Make a synthetic symbol to describe re-exported symbol.
+                    if (sym_idx >= num_syms)
+                        sym = symtab->Resize (++num_syms);
+                    sym[sym_idx].SetID (synthetic_sym_id++);
+                    sym[sym_idx].GetMangled() = Mangled(e.entry.name);
+                    sym[sym_idx].SetType (eSymbolTypeReExported);
+                    sym[sym_idx].SetIsSynthetic (true);
+                    sym[sym_idx].SetReExportedSymbolName(e.entry.import_name);
+                    if (e.entry.other > 0 && e.entry.other <= dylib_files.GetSize())
+                    {
+                        sym[sym_idx].SetReExportedSymbolSharedLibrary(dylib_files.GetFileSpecAtIndex(e.entry.other-1));
+                    }
+                    ++sym_idx;
+                }
+            }
+        }
+
+
         
 //        StreamFile s(stdout, false);
 //        s.Printf ("Symbol table before CalculateSymbolSizes():\n");

Modified: lldb/trunk/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=193101&r1=193100&r2=193101&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ObjectFile.cpp (original)
+++ lldb/trunk/source/Symbol/ObjectFile.cpp Mon Oct 21 13:40:51 2013
@@ -423,6 +423,7 @@ ObjectFile::GetAddressClass (addr_t file
             case eSymbolTypeObjCClass:      return eAddressClassRuntime;
             case eSymbolTypeObjCMetaClass:  return eAddressClassRuntime;
             case eSymbolTypeObjCIVar:       return eAddressClassRuntime;
+            case eSymbolTypeReExported:     return eAddressClassRuntime;
             }
         }
     }

Modified: lldb/trunk/source/Symbol/Symbol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symbol.cpp?rev=193101&r1=193100&r2=193101&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symbol.cpp (original)
+++ lldb/trunk/source/Symbol/Symbol.cpp Mon Oct 21 13:40:51 2013
@@ -10,6 +10,7 @@
 #include "lldb/Symbol/Symbol.h"
 
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -176,6 +177,66 @@ Symbol::ValueIsAddress() const
     return m_addr_range.GetBaseAddress().GetSection().get() != NULL;
 }
 
+ConstString
+Symbol::GetReExportedSymbolName() const
+{
+    if (m_type == eSymbolTypeReExported)
+    {
+        // For eSymbolTypeReExported, the "const char *" from a ConstString
+        // is used as the offset in the address range base address. We can
+        // then make this back into a string that is the re-exported name.
+        intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset();
+        if (str_ptr != 0)
+            return ConstString((const char *)str_ptr);
+        else
+            return GetName();
+    }
+    return ConstString();
+}
+
+FileSpec
+Symbol::GetReExportedSymbolSharedLibrary() const
+{
+    if (m_type == eSymbolTypeReExported)
+    {
+        // For eSymbolTypeReExported, the "const char *" from a ConstString
+        // is used as the offset in the address range base address. We can
+        // then make this back into a string that is the re-exported name.
+        intptr_t str_ptr = m_addr_range.GetByteSize();
+        if (str_ptr != 0)
+            return FileSpec((const char *)str_ptr, false);
+    }
+    return FileSpec();
+}
+
+bool
+Symbol::SetReExportedSymbolName(const ConstString &name)
+{
+    if (m_type == eSymbolTypeReExported)
+    {
+        // For eSymbolTypeReExported, the "const char *" from a ConstString
+        // is used as the offset in the address range base address.
+        m_addr_range.GetBaseAddress().SetOffset((intptr_t)name.GetCString());
+        return true;
+    }
+    return false;
+    
+}
+
+bool
+Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
+{
+    if (m_type == eSymbolTypeReExported)
+    {
+        // For eSymbolTypeReExported, the "const char *" from a ConstString
+        // is used as the offset in the address range base address.
+        m_addr_range.SetByteSize((intptr_t)ConstString(fspec.GetPath().c_str()).GetCString());
+        return true;
+    }
+    return false;
+    
+}
+
 uint32_t
 Symbol::GetSiblingIndex() const
 {
@@ -267,6 +328,19 @@ Symbol::Dump(Stream *s, Target *target,
                     m_flags,
                     m_mangled.GetName().AsCString(""));
     }
+    else if (m_type == eSymbolTypeReExported)
+    {
+        s->Printf ("                                                         0x%8.8x %s",
+                   m_flags,
+                   m_mangled.GetName().AsCString(""));
+        
+        ConstString reexport_name = GetReExportedSymbolName();
+        intptr_t shlib = m_addr_range.GetByteSize();
+        if (shlib)
+            s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString());
+        else
+            s->Printf(" -> %s\n", reexport_name.GetCString());
+    }
     else
     {
         const char *format = m_size_is_sibling ?
@@ -380,6 +454,7 @@ Symbol::GetTypeAsString() const
     ENUM_TO_CSTRING(Invalid);
     ENUM_TO_CSTRING(Absolute);
     ENUM_TO_CSTRING(Code);
+    ENUM_TO_CSTRING(Resolver);
     ENUM_TO_CSTRING(Data);
     ENUM_TO_CSTRING(Trampoline);
     ENUM_TO_CSTRING(Runtime);
@@ -404,6 +479,7 @@ Symbol::GetTypeAsString() const
     ENUM_TO_CSTRING(ObjCClass);
     ENUM_TO_CSTRING(ObjCMetaClass);
     ENUM_TO_CSTRING(ObjCIVar);
+    ENUM_TO_CSTRING(ReExported);
     default:
         break;
     }
@@ -460,3 +536,47 @@ Symbol::GetByteSize () const
     return m_addr_range.GetByteSize();
 }
 
+Symbol *
+Symbol::ResolveReExportedSymbol (Target &target)
+{
+    ConstString reexport_name (GetReExportedSymbolName());
+    if (reexport_name)
+    {
+        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)
+            {
+                // 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)
+        {
+            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)
+                {
+                    lldb_private::SymbolContext sc;
+                    if (sc_list.GetContextAtIndex(i, sc))
+                    {
+                        if (sc.symbol->IsExternal())
+                            return sc.symbol;
+                    }
+                }
+            }
+        }
+    }
+    return NULL;
+}

Modified: lldb/trunk/source/Symbol/Symtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symtab.cpp?rev=193101&r1=193100&r2=193101&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symtab.cpp (original)
+++ lldb/trunk/source/Symbol/Symtab.cpp Mon Oct 21 13:40:51 2013
@@ -1135,6 +1135,7 @@ Symtab::FindFunctionSymbols (const Const
                     {
                     case eSymbolTypeCode:
                     case eSymbolTypeResolver:
+                    case eSymbolTypeReExported:
                         symbol_indexes.push_back(temp_symbol_indexes[i]);
                         break;
                     default:





More information about the lldb-commits mailing list