[Lldb-commits] [lldb] r230562 - Optimize finding the Complete Definition of an ObjC class for debug with .o files with lots of .o files.

Greg Clayton gclayton at apple.com
Wed Feb 25 14:41:35 PST 2015


Author: gclayton
Date: Wed Feb 25 16:41:34 2015
New Revision: 230562

URL: http://llvm.org/viewvc/llvm-project?rev=230562&view=rev
Log:
Optimize finding the Complete Definition of an ObjC class for debug with .o files with lots of .o files.
 
When we have a debug map we have an executable with a bunch of STAB symbols and each source file has a N_SO symbol which scopes a bunch of symbols inside of it. We can use this to our advantage here when looking for the complete definition of an objective C class by looking for a symbol whose name matches the class name and whose type is eSymbolTypeObjCClass. If we find one, that symbol will be contained within a N_SO symbol. This symbol gets turned into a symbol whose type is eSymbolTypeSourceFile and that symbol will contain the eSymbolTypeObjCClass which helps us to locate the correct .o file and allows us to only look in that file.

To further accelerate things, if we are looking for the implementation, we can avoid looking at all .o files if we don't find a matching symbol because we have a debug map, which means the objective C symbol for the class can't have been stripped, so we can safely not search all remaining .o files. This will save us lots of time when trying to look for "NSObject" and any other AppKit and Foundation classes that we never have implementation definitions for.

<rdar://problem/19234225>


Modified:
    lldb/trunk/include/lldb/Symbol/Symtab.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
    lldb/trunk/source/Symbol/Symbol.cpp
    lldb/trunk/source/Symbol/Symtab.cpp

Modified: lldb/trunk/include/lldb/Symbol/Symtab.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Symtab.h?rev=230562&r1=230561&r2=230562&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Symtab.h (original)
+++ lldb/trunk/include/lldb/Symbol/Symtab.h Wed Feb 25 16:41:34 2015
@@ -58,6 +58,14 @@ public:
             Symbol *    SymbolAtIndex (size_t idx);
     const   Symbol *    SymbolAtIndex (size_t idx) const;
             Symbol *    FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx);
+            //----------------------------------------------------------------------
+            /// Get the parent symbol for the given symbol.
+            ///
+            /// Many symbols in symbol tables are scoped by other symbols that
+            /// contain one or more symbol. This function will look for such a
+            /// containing symbol and return it if there is one.
+            //----------------------------------------------------------------------
+    const   Symbol *    GetParent (Symbol *symbol) const;
             uint32_t    AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
             uint32_t    AppendSymbolIndexesWithTypeAndFlagsValue (lldb::SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
             uint32_t    AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=230562&r1=230561&r2=230562&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Wed Feb 25 16:41:34 2015
@@ -416,7 +416,7 @@ SymbolFileDWARFDebugMap::InitOSO()
                     m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
                     uint32_t sibling_idx = so_symbol->GetSiblingIndex();
                     // The sibling index can't be less that or equal to the current index "i"
-                    if (sibling_idx <= i)
+                    if (sibling_idx == UINT32_MAX)
                     {
                         m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
                     }
@@ -1219,15 +1219,63 @@ SymbolFileDWARFDebugMap::FindCompleteObj
                                                                const ConstString &type_name,
                                                                bool must_be_implementation)
 {
+    // If we have a debug map, we will have an Objective C symbol whose name is
+    // the type name and whose type is eSymbolTypeObjCClass. If we can find that
+    // symbol and find its containing parent, we can locate the .o file that will
+    // contain the implementation definition since it will be scoped inside the N_SO
+    // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
+    SymbolFileDWARF *oso_dwarf = NULL;
     TypeSP type_sp;
-    SymbolFileDWARF *oso_dwarf;
-    for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
+    ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
+    if (module_objfile)
     {
-        type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
-        if (type_sp)
-            break;
+        Symtab *symtab = module_objfile->GetSymtab();
+        if (symtab)
+        {
+            Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny);
+            if (objc_class_symbol)
+            {
+                // Get the N_SO symbol that contains the objective C class symbol as this
+                // should be the .o file that contains the real definition...
+                const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
+
+                if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile)
+                {
+                    const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol);
+                    if (source_file_symbol_idx != UINT32_MAX)
+                    {
+                        CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL);
+                        if (compile_unit_info)
+                        {
+                            oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info);
+                            if (oso_dwarf)
+                            {
+                                TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
+                                if (type_sp)
+                                {
+                                    return type_sp;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
-    return type_sp;
+
+    // Only search all .o files for the definition if we don't need the implementation
+    // because otherwise, with a valid debug map we should have the ObjC class symbol and
+    // the code above should have found it.
+    if (must_be_implementation == false)
+    {
+        for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx)
+        {
+            TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
+            if (type_sp)
+                return type_sp;
+        }
+    }
+    return TypeSP();
 }
 
 uint32_t

Modified: lldb/trunk/source/Symbol/Symbol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symbol.cpp?rev=230562&r1=230561&r2=230562&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symbol.cpp (original)
+++ lldb/trunk/source/Symbol/Symbol.cpp Wed Feb 25 16:41:34 2015
@@ -235,7 +235,7 @@ Symbol::SetReExportedSymbolSharedLibrary
 uint32_t
 Symbol::GetSiblingIndex() const
 {
-    return m_size_is_sibling ? m_addr_range.GetByteSize() : 0;
+    return m_size_is_sibling ? m_addr_range.GetByteSize() : UINT32_MAX;
 }
 
 bool

Modified: lldb/trunk/source/Symbol/Symtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symtab.cpp?rev=230562&r1=230561&r2=230562&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symtab.cpp (original)
+++ lldb/trunk/source/Symbol/Symtab.cpp Wed Feb 25 16:41:34 2015
@@ -14,6 +14,7 @@
 #include "lldb/Core/Section.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symbol.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Symbol/Symtab.h"
 #include "lldb/Target/CPPLanguageRuntime.h"
@@ -546,9 +547,12 @@ Symtab::AppendSymbolIndexesWithType (Sym
 uint32_t
 Symtab::GetIndexForSymbol (const Symbol *symbol) const
 {
-    const Symbol *first_symbol = &m_symbols[0];
-    if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size())
-        return symbol - first_symbol;
+    if (!m_symbols.empty())
+    {
+        const Symbol *first_symbol = &m_symbols[0];
+        if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size())
+            return symbol - first_symbol;
+    }
     return UINT32_MAX;
 }
 
@@ -1178,3 +1182,20 @@ Symtab::FindFunctionSymbols (const Const
     return count;
 }
 
+
+const Symbol *
+Symtab::GetParent (Symbol *child_symbol) const
+{
+    uint32_t child_idx = GetIndexForSymbol(child_symbol);
+    if (child_idx != UINT32_MAX && child_idx > 0)
+    {
+        for (uint32_t idx = child_idx - 1; idx != UINT32_MAX; --idx)
+        {
+            const Symbol *symbol = SymbolAtIndex (idx);
+            const uint32_t sibling_idx = symbol->GetSiblingIndex();
+            if (sibling_idx != UINT32_MAX && sibling_idx > child_idx)
+                return symbol;
+        }
+    }
+    return NULL;
+}





More information about the lldb-commits mailing list