diff options
author | Greg Clayton <gclayton@apple.com> | 2015-02-25 22:41:34 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2015-02-25 22:41:34 +0000 |
commit | bc63aaccf7df033abd1f1060c681fe4853433383 (patch) | |
tree | e385259899e61666da36145e1ceb43d7b8b112a0 /lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp | |
parent | 75dbd7ca3e20bf432a6b94e92df6c4537fa9f78f (diff) | |
download | bcm5719-llvm-bc63aaccf7df033abd1f1060c681fe4853433383.tar.gz bcm5719-llvm-bc63aaccf7df033abd1f1060c681fe4853433383.zip |
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>
llvm-svn: 230562
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index af16c03a8c0..e7c68595b6f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -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::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugI 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 |