Home | History | Annotate | Download | only in Symtab
      1 //===-- SymbolFileSymtab.cpp ------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "SymbolFileSymtab.h"
     11 #include "lldb/Core/Module.h"
     12 #include "lldb/Core/PluginManager.h"
     13 #include "lldb/Core/RegularExpression.h"
     14 #include "lldb/Core/Timer.h"
     15 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
     16 #include "lldb/Symbol/CompileUnit.h"
     17 #include "lldb/Symbol/Function.h"
     18 #include "lldb/Symbol/ObjectFile.h"
     19 #include "lldb/Symbol/ObjectFile.h"
     20 #include "lldb/Symbol/Symbol.h"
     21 #include "lldb/Symbol/SymbolContext.h"
     22 #include "lldb/Symbol/Symtab.h"
     23 #include "lldb/Symbol/TypeList.h"
     24 
     25 using namespace lldb;
     26 using namespace lldb_private;
     27 
     28 void
     29 SymbolFileSymtab::Initialize()
     30 {
     31     PluginManager::RegisterPlugin (GetPluginNameStatic(),
     32                                    GetPluginDescriptionStatic(),
     33                                    CreateInstance);
     34 }
     35 
     36 void
     37 SymbolFileSymtab::Terminate()
     38 {
     39     PluginManager::UnregisterPlugin (CreateInstance);
     40 }
     41 
     42 
     43 lldb_private::ConstString
     44 SymbolFileSymtab::GetPluginNameStatic()
     45 {
     46     static ConstString g_name("symtab");
     47     return g_name;
     48 }
     49 
     50 const char *
     51 SymbolFileSymtab::GetPluginDescriptionStatic()
     52 {
     53     return "Reads debug symbols from an object file's symbol table.";
     54 }
     55 
     56 
     57 SymbolFile*
     58 SymbolFileSymtab::CreateInstance (ObjectFile* obj_file)
     59 {
     60     return new SymbolFileSymtab(obj_file);
     61 }
     62 
     63 size_t
     64 SymbolFileSymtab::GetTypes (SymbolContextScope *sc_scope, uint32_t type_mask, lldb_private::TypeList &type_list)
     65 {
     66     return 0;
     67 }
     68 
     69 SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
     70     SymbolFile(obj_file),
     71     m_source_indexes(),
     72     m_func_indexes(),
     73     m_code_indexes(),
     74     m_objc_class_name_to_index ()
     75 {
     76 }
     77 
     78 SymbolFileSymtab::~SymbolFileSymtab()
     79 {
     80 }
     81 
     82 ClangASTContext &
     83 SymbolFileSymtab::GetClangASTContext ()
     84 {
     85     ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
     86 
     87     return ast;
     88 }
     89 
     90 uint32_t
     91 SymbolFileSymtab::CalculateAbilities ()
     92 {
     93     uint32_t abilities = 0;
     94     if (m_obj_file)
     95     {
     96         const Symtab *symtab = m_obj_file->GetSymtab();
     97         if (symtab)
     98         {
     99             //----------------------------------------------------------------------
    100             // The snippet of code below will get the indexes the module symbol
    101             // table entries that are code, data, or function related (debug info),
    102             // sort them by value (address) and dump the sorted symbols.
    103             //----------------------------------------------------------------------
    104             if (symtab->AppendSymbolIndexesWithType(eSymbolTypeSourceFile, m_source_indexes))
    105             {
    106                 abilities |= CompileUnits;
    107             }
    108 
    109             if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes))
    110             {
    111                 symtab->SortSymbolIndexesByValue(m_func_indexes, true);
    112                 abilities |= Functions;
    113             }
    114 
    115             if (symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny, m_code_indexes))
    116             {
    117                 symtab->SortSymbolIndexesByValue(m_code_indexes, true);
    118             }
    119 
    120             if (symtab->AppendSymbolIndexesWithType(eSymbolTypeData, m_data_indexes))
    121             {
    122                 symtab->SortSymbolIndexesByValue(m_data_indexes, true);
    123                 abilities |= GlobalVariables;
    124             }
    125 
    126             lldb_private::Symtab::IndexCollection objc_class_indexes;
    127             if (symtab->AppendSymbolIndexesWithType (eSymbolTypeObjCClass, objc_class_indexes))
    128             {
    129                 symtab->AppendSymbolNamesToMap (objc_class_indexes,
    130                                                 true,
    131                                                 true,
    132                                                 m_objc_class_name_to_index);
    133                 m_objc_class_name_to_index.Sort();
    134             }
    135         }
    136     }
    137     return abilities;
    138 }
    139 
    140 uint32_t
    141 SymbolFileSymtab::GetNumCompileUnits()
    142 {
    143     // If we don't have any source file symbols we will just have one compile unit for
    144     // the entire object file
    145     if (m_source_indexes.empty())
    146         return 0;
    147 
    148     // If we have any source file symbols we will logically orgnize the object symbols
    149     // using these.
    150     return m_source_indexes.size();
    151 }
    152 
    153 CompUnitSP
    154 SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
    155 {
    156     CompUnitSP cu_sp;
    157 
    158     // If we don't have any source file symbols we will just have one compile unit for
    159     // the entire object file
    160     if (idx < m_source_indexes.size())
    161     {
    162         const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
    163         if (cu_symbol)
    164             cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown));
    165     }
    166     return cu_sp;
    167 }
    168 
    169 lldb::LanguageType
    170 SymbolFileSymtab::ParseCompileUnitLanguage (const SymbolContext& sc)
    171 {
    172     return eLanguageTypeUnknown;
    173 }
    174 
    175 
    176 size_t
    177 SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
    178 {
    179     size_t num_added = 0;
    180     // We must at least have a valid compile unit
    181     assert (sc.comp_unit != NULL);
    182     const Symtab *symtab = m_obj_file->GetSymtab();
    183     const Symbol *curr_symbol = NULL;
    184     const Symbol *next_symbol = NULL;
    185 //  const char *prefix = m_obj_file->SymbolPrefix();
    186 //  if (prefix == NULL)
    187 //      prefix == "";
    188 //
    189 //  const uint32_t prefix_len = strlen(prefix);
    190 
    191     // If we don't have any source file symbols we will just have one compile unit for
    192     // the entire object file
    193     if (m_source_indexes.empty())
    194     {
    195         // The only time we will have a user ID of zero is when we don't have
    196         // and source file symbols and we declare one compile unit for the
    197         // entire object file
    198         if (!m_func_indexes.empty())
    199         {
    200 
    201         }
    202 
    203         if (!m_code_indexes.empty())
    204         {
    205 //          StreamFile s(stdout);
    206 //          symtab->Dump(&s, m_code_indexes);
    207 
    208             uint32_t idx = 0;   // Index into the indexes
    209             const uint32_t num_indexes = m_code_indexes.size();
    210             for (idx = 0; idx < num_indexes; ++idx)
    211             {
    212                 uint32_t symbol_idx = m_code_indexes[idx];
    213                 curr_symbol = symtab->SymbolAtIndex(symbol_idx);
    214                 if (curr_symbol)
    215                 {
    216                     // Union of all ranges in the function DIE (if the function is discontiguous)
    217                     AddressRange func_range(curr_symbol->GetAddress(), 0);
    218                     if (func_range.GetBaseAddress().IsSectionOffset())
    219                     {
    220                         uint32_t symbol_size = curr_symbol->GetByteSize();
    221                         if (symbol_size != 0 && !curr_symbol->GetSizeIsSibling())
    222                             func_range.SetByteSize(symbol_size);
    223                         else if (idx + 1 < num_indexes)
    224                         {
    225                             next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
    226                             if (next_symbol)
    227                             {
    228                                 func_range.SetByteSize(next_symbol->GetAddress().GetOffset() - curr_symbol->GetAddress().GetOffset());
    229                             }
    230                         }
    231 
    232                         FunctionSP func_sp(new Function(sc.comp_unit,
    233                                                             symbol_idx,                 // UserID is the DIE offset
    234                                                             LLDB_INVALID_UID,           // We don't have any type info for this function
    235                                                             curr_symbol->GetMangled(),  // Linker/mangled name
    236                                                             NULL,                       // no return type for a code symbol...
    237                                                             func_range));               // first address range
    238 
    239                         if (func_sp.get() != NULL)
    240                         {
    241                             sc.comp_unit->AddFunction(func_sp);
    242                             ++num_added;
    243                         }
    244                     }
    245                 }
    246             }
    247 
    248         }
    249     }
    250     else
    251     {
    252         // We assume we
    253     }
    254     return num_added;
    255 }
    256 
    257 bool
    258 SymbolFileSymtab::ParseCompileUnitLineTable (const SymbolContext &sc)
    259 {
    260     return false;
    261 }
    262 
    263 bool
    264 SymbolFileSymtab::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
    265 {
    266     return false;
    267 }
    268 
    269 size_t
    270 SymbolFileSymtab::ParseFunctionBlocks (const SymbolContext &sc)
    271 {
    272     return 0;
    273 }
    274 
    275 
    276 size_t
    277 SymbolFileSymtab::ParseTypes (const SymbolContext &sc)
    278 {
    279     return 0;
    280 }
    281 
    282 
    283 size_t
    284 SymbolFileSymtab::ParseVariablesForContext (const SymbolContext& sc)
    285 {
    286     return 0;
    287 }
    288 
    289 Type*
    290 SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid)
    291 {
    292     return NULL;
    293 }
    294 
    295 bool
    296 SymbolFileSymtab::ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_opaque_type)
    297 {
    298     return false;
    299 }
    300 
    301 ClangNamespaceDecl
    302 SymbolFileSymtab::FindNamespace (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl)
    303 {
    304     return ClangNamespaceDecl();
    305 }
    306 
    307 uint32_t
    308 SymbolFileSymtab::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
    309 {
    310     if (m_obj_file->GetSymtab() == NULL)
    311         return 0;
    312 
    313     uint32_t resolved_flags = 0;
    314     if (resolve_scope & eSymbolContextSymbol)
    315     {
    316         sc.symbol = m_obj_file->GetSymtab()->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
    317         if (sc.symbol)
    318             resolved_flags |= eSymbolContextSymbol;
    319     }
    320     return resolved_flags;
    321 }
    322 
    323 uint32_t
    324 SymbolFileSymtab::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
    325 {
    326     return 0;
    327 }
    328 
    329 uint32_t
    330 SymbolFileSymtab::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
    331 {
    332     return 0;
    333 }
    334 
    335 uint32_t
    336 SymbolFileSymtab::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
    337 {
    338     return 0;
    339 }
    340 
    341 uint32_t
    342 SymbolFileSymtab::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines,  bool append, SymbolContextList& sc_list)
    343 {
    344     Timer scoped_timer (__PRETTY_FUNCTION__,
    345                         "SymbolFileSymtab::FindFunctions (name = '%s')",
    346                         name.GetCString());
    347     // If we ever support finding STABS or COFF debug info symbols,
    348     // we will need to add support here. We are not trying to find symbols
    349     // here, just "lldb_private::Function" objects that come from complete
    350     // debug information. Any symbol queries should go through the symbol
    351     // table itself in the module's object file.
    352     return 0;
    353 }
    354 
    355 uint32_t
    356 SymbolFileSymtab::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
    357 {
    358     Timer scoped_timer (__PRETTY_FUNCTION__,
    359                         "SymbolFileSymtab::FindFunctions (regex = '%s')",
    360                         regex.GetText());
    361     // If we ever support finding STABS or COFF debug info symbols,
    362     // we will need to add support here. We are not trying to find symbols
    363     // here, just "lldb_private::Function" objects that come from complete
    364     // debug information. Any symbol queries should go through the symbol
    365     // table itself in the module's object file.
    366     return 0;
    367 }
    368 
    369 static int CountMethodArgs(const char *method_signature)
    370 {
    371     int num_args = 0;
    372 
    373     for (const char *colon_pos = strchr(method_signature, ':');
    374          colon_pos != NULL;
    375          colon_pos = strchr(colon_pos + 1, ':'))
    376     {
    377         num_args++;
    378     }
    379 
    380     return num_args;
    381 }
    382 
    383 uint32_t
    384 SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc,
    385                              const lldb_private::ConstString &name,
    386                              const ClangNamespaceDecl *namespace_decl,
    387                              bool append,
    388                              uint32_t max_matches,
    389                              lldb_private::TypeList& types)
    390 {
    391     return 0;
    392 }
    393 
    394 //------------------------------------------------------------------
    395 // PluginInterface protocol
    396 //------------------------------------------------------------------
    397 lldb_private::ConstString
    398 SymbolFileSymtab::GetPluginName()
    399 {
    400     return GetPluginNameStatic();
    401 }
    402 
    403 uint32_t
    404 SymbolFileSymtab::GetPluginVersion()
    405 {
    406     return 1;
    407 }
    408