1254721Semaste//===-- LanguageRuntime.cpp -------------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Target/LanguageRuntime.h" 11254721Semaste#include "lldb/Target/Target.h" 12254721Semaste#include "lldb/Core/PluginManager.h" 13254721Semaste 14254721Semasteusing namespace lldb; 15254721Semasteusing namespace lldb_private; 16254721Semaste 17254721Semaste 18254721Semasteclass ExceptionSearchFilter : public SearchFilter 19254721Semaste{ 20254721Semastepublic: 21254721Semaste ExceptionSearchFilter (const lldb::TargetSP &target_sp, 22254721Semaste lldb::LanguageType language) : 23254721Semaste SearchFilter (target_sp), 24254721Semaste m_language (language), 25254721Semaste m_language_runtime (NULL), 26254721Semaste m_filter_sp () 27254721Semaste { 28254721Semaste UpdateModuleListIfNeeded (); 29254721Semaste } 30254721Semaste 31254721Semaste virtual bool 32254721Semaste ModulePasses (const lldb::ModuleSP &module_sp) 33254721Semaste { 34254721Semaste UpdateModuleListIfNeeded (); 35254721Semaste if (m_filter_sp) 36254721Semaste return m_filter_sp->ModulePasses (module_sp); 37254721Semaste return false; 38254721Semaste } 39254721Semaste 40254721Semaste virtual bool 41254721Semaste ModulePasses (const FileSpec &spec) 42254721Semaste { 43254721Semaste UpdateModuleListIfNeeded (); 44254721Semaste if (m_filter_sp) 45254721Semaste return m_filter_sp->ModulePasses (spec); 46254721Semaste return false; 47254721Semaste 48254721Semaste } 49254721Semaste 50254721Semaste virtual void 51254721Semaste Search (Searcher &searcher) 52254721Semaste { 53254721Semaste UpdateModuleListIfNeeded (); 54254721Semaste if (m_filter_sp) 55254721Semaste m_filter_sp->Search (searcher); 56254721Semaste } 57254721Semaste 58254721Semaste virtual void 59254721Semaste GetDescription (Stream *s) 60254721Semaste { 61254721Semaste UpdateModuleListIfNeeded (); 62254721Semaste if (m_filter_sp) 63254721Semaste m_filter_sp->GetDescription (s); 64254721Semaste } 65254721Semaste 66254721Semasteprotected: 67254721Semaste LanguageType m_language; 68254721Semaste LanguageRuntime *m_language_runtime; 69254721Semaste SearchFilterSP m_filter_sp; 70254721Semaste 71254721Semaste void 72254721Semaste UpdateModuleListIfNeeded () 73254721Semaste { 74254721Semaste ProcessSP process_sp (m_target_sp->GetProcessSP()); 75254721Semaste if (process_sp) 76254721Semaste { 77254721Semaste bool refreash_filter = !m_filter_sp; 78254721Semaste if (m_language_runtime == NULL) 79254721Semaste { 80254721Semaste m_language_runtime = process_sp->GetLanguageRuntime(m_language); 81254721Semaste refreash_filter = true; 82254721Semaste } 83254721Semaste else 84254721Semaste { 85254721Semaste LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language); 86254721Semaste if (m_language_runtime != language_runtime) 87254721Semaste { 88254721Semaste m_language_runtime = language_runtime; 89254721Semaste refreash_filter = true; 90254721Semaste } 91254721Semaste } 92254721Semaste 93254721Semaste if (refreash_filter && m_language_runtime) 94254721Semaste { 95254721Semaste m_filter_sp = m_language_runtime->CreateExceptionSearchFilter (); 96254721Semaste } 97254721Semaste } 98254721Semaste else 99254721Semaste { 100254721Semaste m_filter_sp.reset(); 101254721Semaste m_language_runtime = NULL; 102254721Semaste } 103254721Semaste } 104254721Semaste}; 105254721Semaste 106254721Semaste// The Target is the one that knows how to create breakpoints, so this function 107254721Semaste// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints. 108254721Semasteclass ExceptionBreakpointResolver : public BreakpointResolver 109254721Semaste{ 110254721Semastepublic: 111254721Semaste ExceptionBreakpointResolver (lldb::LanguageType language, 112254721Semaste bool catch_bp, 113254721Semaste bool throw_bp) : 114254721Semaste BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver), 115254721Semaste m_language (language), 116254721Semaste m_language_runtime (NULL), 117254721Semaste m_catch_bp (catch_bp), 118254721Semaste m_throw_bp (throw_bp) 119254721Semaste { 120254721Semaste } 121254721Semaste 122254721Semaste virtual 123254721Semaste ~ExceptionBreakpointResolver() 124254721Semaste { 125254721Semaste } 126254721Semaste 127254721Semaste virtual Searcher::CallbackReturn 128254721Semaste SearchCallback (SearchFilter &filter, 129254721Semaste SymbolContext &context, 130254721Semaste Address *addr, 131254721Semaste bool containing) 132254721Semaste { 133254721Semaste 134254721Semaste if (SetActualResolver()) 135254721Semaste return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing); 136254721Semaste else 137254721Semaste return eCallbackReturnStop; 138254721Semaste } 139254721Semaste 140254721Semaste virtual Searcher::Depth 141254721Semaste GetDepth () 142254721Semaste { 143254721Semaste if (SetActualResolver()) 144254721Semaste return m_actual_resolver_sp->GetDepth(); 145254721Semaste else 146254721Semaste return eDepthTarget; 147254721Semaste } 148254721Semaste 149254721Semaste virtual void 150254721Semaste GetDescription (Stream *s) 151254721Semaste { 152254721Semaste s->Printf ("Exception breakpoint (catch: %s throw: %s)", 153254721Semaste m_catch_bp ? "on" : "off", 154254721Semaste m_throw_bp ? "on" : "off"); 155254721Semaste 156254721Semaste SetActualResolver(); 157254721Semaste if (m_actual_resolver_sp) 158254721Semaste { 159254721Semaste s->Printf (" using: "); 160254721Semaste m_actual_resolver_sp->GetDescription (s); 161254721Semaste } 162254721Semaste else 163254721Semaste s->Printf (" the correct runtime exception handler will be determined when you run"); 164254721Semaste } 165254721Semaste 166254721Semaste virtual void 167254721Semaste Dump (Stream *s) const 168254721Semaste { 169254721Semaste } 170254721Semaste 171254721Semaste /// Methods for support type inquiry through isa, cast, and dyn_cast: 172254721Semaste static inline bool classof(const BreakpointResolverName *) { return true; } 173254721Semaste static inline bool classof(const BreakpointResolver *V) { 174254721Semaste return V->getResolverID() == BreakpointResolver::ExceptionResolver; 175254721Semaste } 176254721Semasteprotected: 177254721Semaste bool 178254721Semaste SetActualResolver() 179254721Semaste { 180254721Semaste ProcessSP process_sp; 181254721Semaste if (m_breakpoint) 182254721Semaste { 183254721Semaste process_sp = m_breakpoint->GetTarget().GetProcessSP(); 184254721Semaste if (process_sp) 185254721Semaste { 186254721Semaste bool refreash_resolver = !m_actual_resolver_sp; 187254721Semaste if (m_language_runtime == NULL) 188254721Semaste { 189254721Semaste m_language_runtime = process_sp->GetLanguageRuntime(m_language); 190254721Semaste refreash_resolver = true; 191254721Semaste } 192254721Semaste else 193254721Semaste { 194254721Semaste LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language); 195254721Semaste if (m_language_runtime != language_runtime) 196254721Semaste { 197254721Semaste m_language_runtime = language_runtime; 198254721Semaste refreash_resolver = true; 199254721Semaste } 200254721Semaste } 201254721Semaste 202254721Semaste if (refreash_resolver && m_language_runtime) 203254721Semaste { 204254721Semaste m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp); 205254721Semaste } 206254721Semaste } 207254721Semaste else 208254721Semaste { 209254721Semaste m_actual_resolver_sp.reset(); 210254721Semaste m_language_runtime = NULL; 211254721Semaste } 212254721Semaste } 213254721Semaste else 214254721Semaste { 215254721Semaste m_actual_resolver_sp.reset(); 216254721Semaste m_language_runtime = NULL; 217254721Semaste } 218254721Semaste return (bool)m_actual_resolver_sp; 219254721Semaste } 220254721Semaste lldb::BreakpointResolverSP m_actual_resolver_sp; 221254721Semaste lldb::LanguageType m_language; 222254721Semaste LanguageRuntime *m_language_runtime; 223254721Semaste bool m_catch_bp; 224254721Semaste bool m_throw_bp; 225254721Semaste}; 226254721Semaste 227254721Semaste 228254721SemasteLanguageRuntime* 229254721SemasteLanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language) 230254721Semaste{ 231254721Semaste std::unique_ptr<LanguageRuntime> language_runtime_ap; 232254721Semaste LanguageRuntimeCreateInstance create_callback; 233254721Semaste 234254721Semaste for (uint32_t idx = 0; 235254721Semaste (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL; 236254721Semaste ++idx) 237254721Semaste { 238254721Semaste language_runtime_ap.reset (create_callback(process, language)); 239254721Semaste 240254721Semaste if (language_runtime_ap.get()) 241254721Semaste return language_runtime_ap.release(); 242254721Semaste } 243254721Semaste 244254721Semaste return NULL; 245254721Semaste} 246254721Semaste 247254721Semaste//---------------------------------------------------------------------- 248254721Semaste// Constructor 249254721Semaste//---------------------------------------------------------------------- 250254721SemasteLanguageRuntime::LanguageRuntime(Process *process) : 251254721Semaste m_process (process) 252254721Semaste{ 253254721Semaste} 254254721Semaste 255254721Semaste//---------------------------------------------------------------------- 256254721Semaste// Destructor 257254721Semaste//---------------------------------------------------------------------- 258254721SemasteLanguageRuntime::~LanguageRuntime() 259254721Semaste{ 260254721Semaste} 261254721Semaste 262254721SemasteBreakpointSP 263254721SemasteLanguageRuntime::CreateExceptionBreakpoint (Target &target, 264254721Semaste lldb::LanguageType language, 265254721Semaste bool catch_bp, 266254721Semaste bool throw_bp, 267254721Semaste bool is_internal) 268254721Semaste{ 269254721Semaste BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp)); 270254721Semaste SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language)); 271263363Semaste bool hardware = false; 272269024Semaste bool resolve_indirect_functions = false; 273269024Semaste BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions)); 274254721Semaste if (is_internal) 275254721Semaste exc_breakpt_sp->SetBreakpointKind("exception"); 276254721Semaste 277254721Semaste return exc_breakpt_sp; 278254721Semaste} 279254721Semaste 280254721Semastestruct language_name_pair { 281254721Semaste const char *name; 282254721Semaste LanguageType type; 283254721Semaste}; 284254721Semaste 285254721Semastestruct language_name_pair language_names[] = 286254721Semaste{ 287254721Semaste // To allow GetNameForLanguageType to be a simple array lookup, the first 288254721Semaste // part of this array must follow enum LanguageType exactly. 289254721Semaste { "unknown", eLanguageTypeUnknown }, 290254721Semaste { "c89", eLanguageTypeC89 }, 291254721Semaste { "c", eLanguageTypeC }, 292254721Semaste { "ada83", eLanguageTypeAda83 }, 293254721Semaste { "c++", eLanguageTypeC_plus_plus }, 294254721Semaste { "cobol74", eLanguageTypeCobol74 }, 295254721Semaste { "cobol85", eLanguageTypeCobol85 }, 296254721Semaste { "fortran77", eLanguageTypeFortran77 }, 297254721Semaste { "fortran90", eLanguageTypeFortran90 }, 298254721Semaste { "pascal83", eLanguageTypePascal83 }, 299254721Semaste { "modula2", eLanguageTypeModula2 }, 300254721Semaste { "java", eLanguageTypeJava }, 301254721Semaste { "c99", eLanguageTypeC99 }, 302254721Semaste { "ada95", eLanguageTypeAda95 }, 303254721Semaste { "fortran95", eLanguageTypeFortran95 }, 304254721Semaste { "pli", eLanguageTypePLI }, 305254721Semaste { "objective-c", eLanguageTypeObjC }, 306254721Semaste { "objective-c++", eLanguageTypeObjC_plus_plus }, 307254721Semaste { "upc", eLanguageTypeUPC }, 308254721Semaste { "d", eLanguageTypeD }, 309254721Semaste { "python", eLanguageTypePython }, 310254721Semaste // Now synonyms, in arbitrary order 311254721Semaste { "objc", eLanguageTypeObjC }, 312254721Semaste { "objc++", eLanguageTypeObjC_plus_plus } 313254721Semaste}; 314254721Semaste 315254721Semastestatic uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair); 316254721Semaste 317254721SemasteLanguageType 318254721SemasteLanguageRuntime::GetLanguageTypeFromString (const char *string) 319254721Semaste{ 320254721Semaste for (uint32_t i = 0; i < num_languages; i++) 321254721Semaste { 322254721Semaste if (strcasecmp (language_names[i].name, string) == 0) 323254721Semaste return (LanguageType) language_names[i].type; 324254721Semaste } 325254721Semaste return eLanguageTypeUnknown; 326254721Semaste} 327254721Semaste 328254721Semasteconst char * 329254721SemasteLanguageRuntime::GetNameForLanguageType (LanguageType language) 330254721Semaste{ 331254721Semaste if (language < num_languages) 332254721Semaste return language_names[language].name; 333254721Semaste else 334254721Semaste return language_names[eLanguageTypeUnknown].name; 335254721Semaste} 336254721Semaste 337254721Semastelldb::SearchFilterSP 338254721SemasteLanguageRuntime::CreateExceptionSearchFilter () 339254721Semaste{ 340254721Semaste return m_process->GetTarget().GetSearchFilterForModule(NULL); 341254721Semaste} 342254721Semaste 343254721Semaste 344254721Semaste 345