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