Home | History | Annotate | Download | only in Target
      1 //===-- LanguageRuntime.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/Target/LanguageRuntime.h"
     11 #include "lldb/Target/Target.h"
     12 #include "lldb/Core/PluginManager.h"
     13 
     14 using namespace lldb;
     15 using namespace lldb_private;
     16 
     17 
     18 class ExceptionSearchFilter : public SearchFilter
     19 {
     20 public:
     21     ExceptionSearchFilter (const lldb::TargetSP &target_sp,
     22                            lldb::LanguageType language) :
     23         SearchFilter (target_sp),
     24         m_language (language),
     25         m_language_runtime (NULL),
     26         m_filter_sp ()
     27     {
     28         UpdateModuleListIfNeeded ();
     29     }
     30 
     31     virtual bool
     32     ModulePasses (const lldb::ModuleSP &module_sp)
     33     {
     34         UpdateModuleListIfNeeded ();
     35         if (m_filter_sp)
     36             return m_filter_sp->ModulePasses (module_sp);
     37         return false;
     38     }
     39 
     40     virtual bool
     41     ModulePasses (const FileSpec &spec)
     42     {
     43         UpdateModuleListIfNeeded ();
     44         if (m_filter_sp)
     45             return m_filter_sp->ModulePasses (spec);
     46         return false;
     47 
     48     }
     49 
     50     virtual void
     51     Search (Searcher &searcher)
     52     {
     53         UpdateModuleListIfNeeded ();
     54         if (m_filter_sp)
     55             m_filter_sp->Search (searcher);
     56     }
     57 
     58     virtual void
     59     GetDescription (Stream *s)
     60     {
     61         UpdateModuleListIfNeeded ();
     62         if (m_filter_sp)
     63             m_filter_sp->GetDescription (s);
     64     }
     65 
     66 protected:
     67     LanguageType m_language;
     68     LanguageRuntime *m_language_runtime;
     69     SearchFilterSP m_filter_sp;
     70 
     71     void
     72     UpdateModuleListIfNeeded ()
     73     {
     74         ProcessSP process_sp (m_target_sp->GetProcessSP());
     75         if (process_sp)
     76         {
     77             bool refreash_filter = !m_filter_sp;
     78             if (m_language_runtime == NULL)
     79             {
     80                 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
     81                 refreash_filter = true;
     82             }
     83             else
     84             {
     85                 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
     86                 if (m_language_runtime != language_runtime)
     87                 {
     88                     m_language_runtime = language_runtime;
     89                     refreash_filter = true;
     90                 }
     91             }
     92 
     93             if (refreash_filter && m_language_runtime)
     94             {
     95                 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
     96             }
     97         }
     98         else
     99         {
    100             m_filter_sp.reset();
    101             m_language_runtime = NULL;
    102         }
    103     }
    104 };
    105 
    106 // The Target is the one that knows how to create breakpoints, so this function
    107 // is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
    108 class ExceptionBreakpointResolver : public BreakpointResolver
    109 {
    110 public:
    111     ExceptionBreakpointResolver (lldb::LanguageType language,
    112                                  bool catch_bp,
    113                                  bool throw_bp) :
    114         BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
    115         m_language (language),
    116         m_language_runtime (NULL),
    117         m_catch_bp (catch_bp),
    118         m_throw_bp (throw_bp)
    119     {
    120     }
    121 
    122     virtual
    123     ~ExceptionBreakpointResolver()
    124     {
    125     }
    126 
    127     virtual Searcher::CallbackReturn
    128     SearchCallback (SearchFilter &filter,
    129                     SymbolContext &context,
    130                     Address *addr,
    131                     bool containing)
    132     {
    133 
    134         if (SetActualResolver())
    135             return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
    136         else
    137             return eCallbackReturnStop;
    138     }
    139 
    140     virtual Searcher::Depth
    141     GetDepth ()
    142     {
    143         if (SetActualResolver())
    144             return m_actual_resolver_sp->GetDepth();
    145         else
    146             return eDepthTarget;
    147     }
    148 
    149     virtual void
    150     GetDescription (Stream *s)
    151     {
    152         s->Printf ("Exception breakpoint (catch: %s throw: %s)",
    153                    m_catch_bp ? "on" : "off",
    154                    m_throw_bp ? "on" : "off");
    155 
    156         SetActualResolver();
    157         if (m_actual_resolver_sp)
    158         {
    159             s->Printf (" using: ");
    160             m_actual_resolver_sp->GetDescription (s);
    161         }
    162         else
    163             s->Printf (" the correct runtime exception handler will be determined when you run");
    164     }
    165 
    166     virtual void
    167     Dump (Stream *s) const
    168     {
    169     }
    170 
    171     /// Methods for support type inquiry through isa, cast, and dyn_cast:
    172     static inline bool classof(const BreakpointResolverName *) { return true; }
    173     static inline bool classof(const BreakpointResolver *V) {
    174         return V->getResolverID() == BreakpointResolver::ExceptionResolver;
    175     }
    176 protected:
    177     bool
    178     SetActualResolver()
    179     {
    180         ProcessSP process_sp;
    181         if (m_breakpoint)
    182         {
    183             process_sp = m_breakpoint->GetTarget().GetProcessSP();
    184             if (process_sp)
    185             {
    186                 bool refreash_resolver = !m_actual_resolver_sp;
    187                 if (m_language_runtime == NULL)
    188                 {
    189                     m_language_runtime = process_sp->GetLanguageRuntime(m_language);
    190                     refreash_resolver = true;
    191                 }
    192                 else
    193                 {
    194                     LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
    195                     if (m_language_runtime != language_runtime)
    196                     {
    197                         m_language_runtime = language_runtime;
    198                         refreash_resolver = true;
    199                     }
    200                 }
    201 
    202                 if (refreash_resolver && m_language_runtime)
    203                 {
    204                     m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
    205                 }
    206             }
    207             else
    208             {
    209                 m_actual_resolver_sp.reset();
    210                 m_language_runtime = NULL;
    211             }
    212         }
    213         else
    214         {
    215             m_actual_resolver_sp.reset();
    216             m_language_runtime = NULL;
    217         }
    218         return (bool)m_actual_resolver_sp;
    219     }
    220     lldb::BreakpointResolverSP m_actual_resolver_sp;
    221     lldb::LanguageType m_language;
    222     LanguageRuntime *m_language_runtime;
    223     bool m_catch_bp;
    224     bool m_throw_bp;
    225 };
    226 
    227 
    228 LanguageRuntime*
    229 LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
    230 {
    231     std::unique_ptr<LanguageRuntime> language_runtime_ap;
    232     LanguageRuntimeCreateInstance create_callback;
    233 
    234     for (uint32_t idx = 0;
    235          (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
    236          ++idx)
    237     {
    238         language_runtime_ap.reset (create_callback(process, language));
    239 
    240         if (language_runtime_ap.get())
    241             return language_runtime_ap.release();
    242     }
    243 
    244     return NULL;
    245 }
    246 
    247 //----------------------------------------------------------------------
    248 // Constructor
    249 //----------------------------------------------------------------------
    250 LanguageRuntime::LanguageRuntime(Process *process) :
    251     m_process (process)
    252 {
    253 }
    254 
    255 //----------------------------------------------------------------------
    256 // Destructor
    257 //----------------------------------------------------------------------
    258 LanguageRuntime::~LanguageRuntime()
    259 {
    260 }
    261 
    262 BreakpointSP
    263 LanguageRuntime::CreateExceptionBreakpoint (Target &target,
    264                                             lldb::LanguageType language,
    265                                             bool catch_bp,
    266                                             bool throw_bp,
    267                                             bool is_internal)
    268 {
    269     BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
    270     SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
    271 
    272     BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal));
    273     if (is_internal)
    274         exc_breakpt_sp->SetBreakpointKind("exception");
    275 
    276     return exc_breakpt_sp;
    277 }
    278 
    279 struct language_name_pair {
    280     const char *name;
    281     LanguageType type;
    282 };
    283 
    284 struct language_name_pair language_names[] =
    285 {
    286     // To allow GetNameForLanguageType to be a simple array lookup, the first
    287     // part of this array must follow enum LanguageType exactly.
    288     {   "unknown",          eLanguageTypeUnknown        },
    289     {   "c89",              eLanguageTypeC89            },
    290     {   "c",                eLanguageTypeC              },
    291     {   "ada83",            eLanguageTypeAda83          },
    292     {   "c++",              eLanguageTypeC_plus_plus    },
    293     {   "cobol74",          eLanguageTypeCobol74        },
    294     {   "cobol85",          eLanguageTypeCobol85        },
    295     {   "fortran77",        eLanguageTypeFortran77      },
    296     {   "fortran90",        eLanguageTypeFortran90      },
    297     {   "pascal83",         eLanguageTypePascal83       },
    298     {   "modula2",          eLanguageTypeModula2        },
    299     {   "java",             eLanguageTypeJava           },
    300     {   "c99",              eLanguageTypeC99            },
    301     {   "ada95",            eLanguageTypeAda95          },
    302     {   "fortran95",        eLanguageTypeFortran95      },
    303     {   "pli",              eLanguageTypePLI            },
    304     {   "objective-c",      eLanguageTypeObjC           },
    305     {   "objective-c++",    eLanguageTypeObjC_plus_plus },
    306     {   "upc",              eLanguageTypeUPC            },
    307     {   "d",                eLanguageTypeD              },
    308     {   "python",           eLanguageTypePython         },
    309     // Now synonyms, in arbitrary order
    310     {   "objc",             eLanguageTypeObjC           },
    311     {   "objc++",           eLanguageTypeObjC_plus_plus }
    312 };
    313 
    314 static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
    315 
    316 LanguageType
    317 LanguageRuntime::GetLanguageTypeFromString (const char *string)
    318 {
    319     for (uint32_t i = 0; i < num_languages; i++)
    320     {
    321         if (strcasecmp (language_names[i].name, string) == 0)
    322             return (LanguageType) language_names[i].type;
    323     }
    324     return eLanguageTypeUnknown;
    325 }
    326 
    327 const char *
    328 LanguageRuntime::GetNameForLanguageType (LanguageType language)
    329 {
    330     if (language < num_languages)
    331         return language_names[language].name;
    332     else
    333         return language_names[eLanguageTypeUnknown].name;
    334 }
    335 
    336 lldb::SearchFilterSP
    337 LanguageRuntime::CreateExceptionSearchFilter ()
    338 {
    339     return m_process->GetTarget().GetSearchFilterForModule(NULL);
    340 }
    341 
    342 
    343 
    344