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 14using namespace lldb; 15using namespace lldb_private; 16 17 18class ExceptionSearchFilter : public SearchFilter 19{ 20public: 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 66protected: 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. 108class ExceptionBreakpointResolver : public BreakpointResolver 109{ 110public: 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 } 176protected: 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 228LanguageRuntime* 229LanguageRuntime::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//---------------------------------------------------------------------- 250LanguageRuntime::LanguageRuntime(Process *process) : 251 m_process (process) 252{ 253} 254 255//---------------------------------------------------------------------- 256// Destructor 257//---------------------------------------------------------------------- 258LanguageRuntime::~LanguageRuntime() 259{ 260} 261 262BreakpointSP 263LanguageRuntime::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 279struct language_name_pair { 280 const char *name; 281 LanguageType type; 282}; 283 284struct 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 314static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair); 315 316LanguageType 317LanguageRuntime::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 327const char * 328LanguageRuntime::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 336lldb::SearchFilterSP 337LanguageRuntime::CreateExceptionSearchFilter () 338{ 339 return m_process->GetTarget().GetSearchFilterForModule(NULL); 340} 341 342 343 344