Home | History | Annotate | Download | only in Core
      1 //===-- AddressResolverName.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 "lldb/Core/AddressResolverName.h"
     11 
     12 // Project includes
     13 #include "lldb/Core/Log.h"
     14 #include "lldb/Core/Module.h"
     15 #include "lldb/Core/StreamString.h"
     16 #include "lldb/Symbol/ClangNamespaceDecl.h"
     17 #include "lldb/Symbol/Function.h"
     18 #include "lldb/Symbol/SymbolContext.h"
     19 #include "lldb/Symbol/Symbol.h"
     20 #include "lldb/lldb-private-log.h"
     21 
     22 using namespace lldb;
     23 using namespace lldb_private;
     24 
     25 AddressResolverName::AddressResolverName
     26 (
     27     const char *func_name,
     28     AddressResolver::MatchType type
     29 ) :
     30     AddressResolver (),
     31     m_func_name (func_name),
     32     m_class_name (NULL),
     33     m_regex (),
     34     m_match_type (type)
     35 {
     36     if (m_match_type == AddressResolver::Regexp)
     37     {
     38         if (!m_regex.Compile (m_func_name.AsCString()))
     39         {
     40             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
     41 
     42             if (log)
     43                 log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString());
     44         }
     45     }
     46 }
     47 
     48 AddressResolverName::AddressResolverName
     49 (
     50     RegularExpression &func_regex
     51 ) :
     52     AddressResolver (),
     53     m_func_name (NULL),
     54     m_class_name (NULL),
     55     m_regex (func_regex),
     56     m_match_type (AddressResolver::Regexp)
     57 {
     58 
     59 }
     60 
     61 AddressResolverName::AddressResolverName
     62 (
     63     const char *class_name,
     64     const char *method,
     65     AddressResolver::MatchType type
     66 ) :
     67     AddressResolver (),
     68     m_func_name (method),
     69     m_class_name (class_name),
     70     m_regex (),
     71     m_match_type (type)
     72 {
     73 
     74 }
     75 
     76 AddressResolverName::~AddressResolverName ()
     77 {
     78 }
     79 
     80 // FIXME: Right now we look at the module level, and call the module's "FindFunctions".
     81 // Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
     82 // lookup.  At that point, we should switch the depth to CompileUnit, and look in these tables.
     83 
     84 Searcher::CallbackReturn
     85 AddressResolverName::SearchCallback
     86 (
     87     SearchFilter &filter,
     88     SymbolContext &context,
     89     Address *addr,
     90     bool containing
     91 )
     92 {
     93     SymbolContextList func_list;
     94     SymbolContextList sym_list;
     95 
     96     bool skip_prologue = true;
     97     uint32_t i;
     98     SymbolContext sc;
     99     Address func_addr;
    100 
    101     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
    102 
    103     if (m_class_name)
    104     {
    105         if (log)
    106             log->Warning ("Class/method function specification not supported yet.\n");
    107         return Searcher::eCallbackReturnStop;
    108     }
    109 
    110     const bool include_symbols = false;
    111     const bool include_inlines = true;
    112     const bool append = false;
    113     switch (m_match_type)
    114     {
    115     case AddressResolver::Exact:
    116         if (context.module_sp)
    117         {
    118             context.module_sp->FindSymbolsWithNameAndType (m_func_name,
    119                                                            eSymbolTypeCode,
    120                                                            sym_list);
    121             context.module_sp->FindFunctions (m_func_name,
    122                                               NULL,
    123                                               eFunctionNameTypeAuto,
    124                                               include_symbols,
    125                                               include_inlines,
    126                                               append,
    127                                               func_list);
    128         }
    129         break;
    130 
    131     case AddressResolver::Regexp:
    132         if (context.module_sp)
    133         {
    134             context.module_sp->FindSymbolsMatchingRegExAndType (m_regex,
    135                                                                 eSymbolTypeCode,
    136                                                                 sym_list);
    137             context.module_sp->FindFunctions (m_regex,
    138                                               include_symbols,
    139                                               include_inlines,
    140                                               append,
    141                                               func_list);
    142         }
    143         break;
    144 
    145     case AddressResolver::Glob:
    146         if (log)
    147             log->Warning ("glob is not supported yet.");
    148         break;
    149     }
    150 
    151     // Remove any duplicates between the funcion list and the symbol list
    152     if (func_list.GetSize())
    153     {
    154         for (i = 0; i < func_list.GetSize(); i++)
    155         {
    156             if (func_list.GetContextAtIndex(i, sc) == false)
    157                 continue;
    158 
    159             if (sc.function == NULL)
    160                 continue;
    161             uint32_t j = 0;
    162             while (j < sym_list.GetSize())
    163             {
    164                 SymbolContext symbol_sc;
    165                 if (sym_list.GetContextAtIndex(j, symbol_sc))
    166                 {
    167                     if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress())
    168                     {
    169                         if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
    170                         {
    171                             sym_list.RemoveContextAtIndex(j);
    172                             continue;   // Don't increment j
    173                         }
    174                     }
    175                 }
    176 
    177                 j++;
    178             }
    179         }
    180 
    181         for (i = 0; i < func_list.GetSize(); i++)
    182         {
    183             if (func_list.GetContextAtIndex(i, sc))
    184             {
    185                 if (sc.function)
    186                 {
    187                     func_addr = sc.function->GetAddressRange().GetBaseAddress();
    188                     addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
    189                     if (skip_prologue)
    190                     {
    191                         const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
    192                         if (prologue_byte_size)
    193                         {
    194                             func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
    195                             byte_size -= prologue_byte_size;
    196                         }
    197                     }
    198 
    199                     if (filter.AddressPasses (func_addr))
    200                     {
    201                         AddressRange new_range (func_addr, byte_size);
    202                         m_address_ranges.push_back (new_range);
    203                     }
    204                 }
    205             }
    206         }
    207     }
    208 
    209     for (i = 0; i < sym_list.GetSize(); i++)
    210     {
    211         if (sym_list.GetContextAtIndex(i, sc))
    212         {
    213             if (sc.symbol && sc.symbol->ValueIsAddress())
    214             {
    215                 func_addr = sc.symbol->GetAddress();
    216                 addr_t byte_size = sc.symbol->GetByteSize();
    217 
    218                 if (skip_prologue)
    219                 {
    220                     const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
    221                     if (prologue_byte_size)
    222                     {
    223                         func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
    224                         byte_size -= prologue_byte_size;
    225                     }
    226                 }
    227 
    228                 if (filter.AddressPasses (func_addr))
    229                 {
    230                     AddressRange new_range (func_addr, byte_size);
    231                     m_address_ranges.push_back (new_range);
    232                 }
    233             }
    234         }
    235     }
    236     return Searcher::eCallbackReturnContinue;
    237 }
    238 
    239 Searcher::Depth
    240 AddressResolverName::GetDepth()
    241 {
    242     return Searcher::eDepthModule;
    243 }
    244 
    245 void
    246 AddressResolverName::GetDescription (Stream *s)
    247 {
    248     s->PutCString("Address by function name: ");
    249 
    250     if (m_match_type == AddressResolver::Regexp)
    251         s->Printf("'%s' (regular expression)", m_regex.GetText());
    252     else
    253         s->Printf("'%s'", m_func_name.AsCString());
    254 }
    255 
    256