1 //===-- ClangUserExpression.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 <stdio.h> 11 #if HAVE_SYS_TYPES_H 12 # include <sys/types.h> 13 #endif 14 15 #include <cstdlib> 16 #include <string> 17 #include <map> 18 19 #include "ClangUserExpression.h" 20 21 #include "ASTResultSynthesizer.h" 22 #include "ClangExpressionDeclMap.h" 23 #include "ClangExpressionParser.h" 24 #include "ClangModulesDeclVendor.h" 25 #include "ClangPersistentVariables.h" 26 27 #include "lldb/Core/ConstString.h" 28 #include "lldb/Core/Log.h" 29 #include "lldb/Core/Module.h" 30 #include "lldb/Core/StreamFile.h" 31 #include "lldb/Core/StreamString.h" 32 #include "lldb/Core/ValueObjectConstResult.h" 33 #include "lldb/Expression/ExpressionSourceCode.h" 34 #include "lldb/Expression/IRExecutionUnit.h" 35 #include "lldb/Expression/IRInterpreter.h" 36 #include "lldb/Expression/Materializer.h" 37 #include "lldb/Host/HostInfo.h" 38 #include "lldb/Symbol/Block.h" 39 #include "lldb/Symbol/ClangASTContext.h" 40 #include "lldb/Symbol/Function.h" 41 #include "lldb/Symbol/ObjectFile.h" 42 #include "lldb/Symbol/SymbolVendor.h" 43 #include "lldb/Symbol/Type.h" 44 #include "lldb/Symbol/ClangExternalASTSourceCommon.h" 45 #include "lldb/Symbol/VariableList.h" 46 #include "lldb/Target/ExecutionContext.h" 47 #include "lldb/Target/Process.h" 48 #include "lldb/Target/StackFrame.h" 49 #include "lldb/Target/Target.h" 50 #include "lldb/Target/ThreadPlan.h" 51 #include "lldb/Target/ThreadPlanCallUserExpression.h" 52 53 #include "clang/AST/DeclCXX.h" 54 #include "clang/AST/DeclObjC.h" 55 56 using namespace lldb_private; 57 58 ClangUserExpression::ClangUserExpression (ExecutionContextScope &exe_scope, 59 const char *expr, 60 const char *expr_prefix, 61 lldb::LanguageType language, 62 ResultType desired_type, 63 const EvaluateExpressionOptions &options) : 64 LLVMUserExpression (exe_scope, expr, expr_prefix, language, desired_type, options), 65 m_type_system_helper(*m_target_wp.lock().get()) 66 { 67 switch (m_language) 68 { 69 case lldb::eLanguageTypeC_plus_plus: 70 m_allow_cxx = true; 71 break; 72 case lldb::eLanguageTypeObjC: 73 m_allow_objc = true; 74 break; 75 case lldb::eLanguageTypeObjC_plus_plus: 76 default: 77 m_allow_cxx = true; 78 m_allow_objc = true; 79 break; 80 } 81 } 82 83 ClangUserExpression::~ClangUserExpression () 84 { 85 } 86 87 void 88 ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) 89 { 90 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 91 92 if (log) 93 log->Printf("ClangUserExpression::ScanContext()"); 94 95 m_target = exe_ctx.GetTargetPtr(); 96 97 if (!(m_allow_cxx || m_allow_objc)) 98 { 99 if (log) 100 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C"); 101 return; 102 } 103 104 StackFrame *frame = exe_ctx.GetFramePtr(); 105 if (frame == NULL) 106 { 107 if (log) 108 log->Printf(" [CUE::SC] Null stack frame"); 109 return; 110 } 111 112 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock); 113 114 if (!sym_ctx.function) 115 { 116 if (log) 117 log->Printf(" [CUE::SC] Null function"); 118 return; 119 } 120 121 // Find the block that defines the function represented by "sym_ctx" 122 Block *function_block = sym_ctx.GetFunctionBlock(); 123 124 if (!function_block) 125 { 126 if (log) 127 log->Printf(" [CUE::SC] Null function block"); 128 return; 129 } 130 131 CompilerDeclContext decl_context = function_block->GetDeclContext(); 132 133 if (!decl_context) 134 { 135 if (log) 136 log->Printf(" [CUE::SC] Null decl context"); 137 return; 138 } 139 140 if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) 141 { 142 if (m_allow_cxx && method_decl->isInstance()) 143 { 144 if (m_enforce_valid_object) 145 { 146 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 147 148 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context"; 149 150 if (!variable_list_sp) 151 { 152 err.SetErrorString(thisErrorString); 153 return; 154 } 155 156 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this"))); 157 158 if (!this_var_sp || 159 !this_var_sp->IsInScope(frame) || 160 !this_var_sp->LocationIsValidForFrame (frame)) 161 { 162 err.SetErrorString(thisErrorString); 163 return; 164 } 165 } 166 167 m_in_cplusplus_method = true; 168 m_needs_object_ptr = true; 169 } 170 } 171 else if (clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(decl_context)) 172 { 173 if (m_allow_objc) 174 { 175 if (m_enforce_valid_object) 176 { 177 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 178 179 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context"; 180 181 if (!variable_list_sp) 182 { 183 err.SetErrorString(selfErrorString); 184 return; 185 } 186 187 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self")); 188 189 if (!self_variable_sp || 190 !self_variable_sp->IsInScope(frame) || 191 !self_variable_sp->LocationIsValidForFrame (frame)) 192 { 193 err.SetErrorString(selfErrorString); 194 return; 195 } 196 } 197 198 m_in_objectivec_method = true; 199 m_needs_object_ptr = true; 200 201 if (!method_decl->isInstanceMethod()) 202 m_in_static_method = true; 203 } 204 } 205 else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) 206 { 207 // We might also have a function that said in the debug information that it captured an 208 // object pointer. The best way to deal with getting to the ivars at present is by pretending 209 // that this is a method of a class in whatever runtime the debug info says the object pointer 210 // belongs to. Do that here. 211 212 ClangASTMetadata *metadata = ClangASTContext::DeclContextGetMetaData (decl_context, function_decl); 213 if (metadata && metadata->HasObjectPtr()) 214 { 215 lldb::LanguageType language = metadata->GetObjectPtrLanguage(); 216 if (language == lldb::eLanguageTypeC_plus_plus) 217 { 218 if (m_enforce_valid_object) 219 { 220 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 221 222 const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context"; 223 224 if (!variable_list_sp) 225 { 226 err.SetErrorString(thisErrorString); 227 return; 228 } 229 230 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this"))); 231 232 if (!this_var_sp || 233 !this_var_sp->IsInScope(frame) || 234 !this_var_sp->LocationIsValidForFrame (frame)) 235 { 236 err.SetErrorString(thisErrorString); 237 return; 238 } 239 } 240 241 m_in_cplusplus_method = true; 242 m_needs_object_ptr = true; 243 } 244 else if (language == lldb::eLanguageTypeObjC) 245 { 246 if (m_enforce_valid_object) 247 { 248 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 249 250 const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context"; 251 252 if (!variable_list_sp) 253 { 254 err.SetErrorString(selfErrorString); 255 return; 256 } 257 258 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self")); 259 260 if (!self_variable_sp || 261 !self_variable_sp->IsInScope(frame) || 262 !self_variable_sp->LocationIsValidForFrame (frame)) 263 { 264 err.SetErrorString(selfErrorString); 265 return; 266 } 267 268 Type *self_type = self_variable_sp->GetType(); 269 270 if (!self_type) 271 { 272 err.SetErrorString(selfErrorString); 273 return; 274 } 275 276 CompilerType self_clang_type = self_type->GetForwardCompilerType (); 277 278 if (!self_clang_type) 279 { 280 err.SetErrorString(selfErrorString); 281 return; 282 } 283 284 if (ClangASTContext::IsObjCClassType(self_clang_type)) 285 { 286 return; 287 } 288 else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type)) 289 { 290 m_in_objectivec_method = true; 291 m_needs_object_ptr = true; 292 } 293 else 294 { 295 err.SetErrorString(selfErrorString); 296 return; 297 } 298 } 299 else 300 { 301 m_in_objectivec_method = true; 302 m_needs_object_ptr = true; 303 } 304 } 305 } 306 } 307 } 308 309 // This is a really nasty hack, meant to fix Objective-C expressions of the form 310 // (int)[myArray count]. Right now, because the type information for count is 311 // not available, [myArray count] returns id, which can't be directly cast to 312 // int without causing a clang error. 313 static void 314 ApplyObjcCastHack(std::string &expr) 315 { 316 #define OBJC_CAST_HACK_FROM "(int)[" 317 #define OBJC_CAST_HACK_TO "(int)(long long)[" 318 319 size_t from_offset; 320 321 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos) 322 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO); 323 324 #undef OBJC_CAST_HACK_TO 325 #undef OBJC_CAST_HACK_FROM 326 } 327 328 bool 329 ClangUserExpression::Parse (Stream &error_stream, 330 ExecutionContext &exe_ctx, 331 lldb_private::ExecutionPolicy execution_policy, 332 bool keep_result_in_memory, 333 bool generate_debug_info) 334 { 335 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 336 337 Error err; 338 339 InstallContext(exe_ctx); 340 341 if (Target *target = exe_ctx.GetTargetPtr()) 342 { 343 if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)) 344 { 345 m_result_delegate.RegisterPersistentState(persistent_state); 346 } 347 else 348 { 349 error_stream.PutCString ("error: couldn't start parsing (no persistent data)"); 350 return false; 351 } 352 } 353 else 354 { 355 error_stream.PutCString ("error: couldn't start parsing (no target)"); 356 return false; 357 } 358 359 ScanContext(exe_ctx, err); 360 361 if (!err.Success()) 362 { 363 error_stream.Printf("warning: %s\n", err.AsCString()); 364 } 365 366 StreamString m_transformed_stream; 367 368 //////////////////////////////////// 369 // Generate the expression 370 // 371 372 ApplyObjcCastHack(m_expr_text); 373 //ApplyUnicharHack(m_expr_text); 374 375 std::string prefix = m_expr_prefix; 376 377 if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor()) 378 { 379 const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules(); 380 ClangModulesDeclVendor::ModuleVector modules_for_macros; 381 382 for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) 383 { 384 modules_for_macros.push_back(module); 385 } 386 387 if (m_target->GetEnableAutoImportClangModules()) 388 { 389 if (StackFrame *frame = exe_ctx.GetFramePtr()) 390 { 391 if (Block *block = frame->GetFrameBlock()) 392 { 393 SymbolContext sc; 394 395 block->CalculateSymbolContext(&sc); 396 397 if (sc.comp_unit) 398 { 399 StreamString error_stream; 400 401 decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream); 402 } 403 } 404 } 405 } 406 } 407 408 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str())); 409 410 lldb::LanguageType lang_type; 411 412 if (m_in_cplusplus_method) 413 lang_type = lldb::eLanguageTypeC_plus_plus; 414 else if (m_in_objectivec_method) 415 lang_type = lldb::eLanguageTypeObjC; 416 else 417 lang_type = lldb::eLanguageTypeC; 418 419 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_in_static_method, exe_ctx)) 420 { 421 error_stream.PutCString ("error: couldn't construct expression body"); 422 return false; 423 } 424 425 if (log) 426 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); 427 428 //////////////////////////////////// 429 // Set up the target and compiler 430 // 431 432 Target *target = exe_ctx.GetTargetPtr(); 433 434 if (!target) 435 { 436 error_stream.PutCString ("error: invalid target\n"); 437 return false; 438 } 439 440 ////////////////////////// 441 // Parse the expression 442 // 443 444 m_materializer_ap.reset(new Materializer()); 445 446 ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory); 447 448 class OnExit 449 { 450 public: 451 typedef std::function <void (void)> Callback; 452 453 OnExit (Callback const &callback) : 454 m_callback(callback) 455 { 456 } 457 458 ~OnExit () 459 { 460 m_callback(); 461 } 462 private: 463 Callback m_callback; 464 }; 465 466 OnExit on_exit([this]() { ResetDeclMap(); }); 467 468 if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) 469 { 470 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n"); 471 472 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions. 473 474 return false; 475 } 476 477 Process *process = exe_ctx.GetProcessPtr(); 478 ExecutionContextScope *exe_scope = process; 479 480 if (!exe_scope) 481 exe_scope = exe_ctx.GetTargetPtr(); 482 483 ClangExpressionParser parser(exe_scope, *this, generate_debug_info); 484 485 unsigned num_errors = parser.Parse (error_stream); 486 487 if (num_errors) 488 { 489 error_stream.Printf ("error: %d errors parsing expression\n", num_errors); 490 491 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions. 492 493 return false; 494 } 495 496 ////////////////////////////////////////////////////////////////////////////////////////// 497 // Prepare the output of the parser for execution, evaluating it statically if possible 498 // 499 500 Error jit_error = parser.PrepareForExecution (m_jit_start_addr, 501 m_jit_end_addr, 502 m_execution_unit_sp, 503 exe_ctx, 504 m_can_interpret, 505 execution_policy); 506 507 if (generate_debug_info) 508 { 509 lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule()); 510 511 if (jit_module_sp) 512 { 513 ConstString const_func_name(FunctionName()); 514 FileSpec jit_file; 515 jit_file.GetFilename() = const_func_name; 516 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString()); 517 m_jit_module_wp = jit_module_sp; 518 target->GetImages().Append(jit_module_sp); 519 } 520 // lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile(); 521 // StreamFile strm (stdout, false); 522 // if (jit_obj_file) 523 // { 524 // jit_obj_file->GetSectionList(); 525 // jit_obj_file->GetSymtab(); 526 // jit_obj_file->Dump(&strm); 527 // } 528 // lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor(); 529 // if (jit_sym_vendor) 530 // { 531 // lldb_private::SymbolContextList sc_list; 532 // jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list); 533 // sc_list.Dump(&strm, target); 534 // jit_sym_vendor->Dump(&strm); 535 // } 536 } 537 538 ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions. 539 540 if (jit_error.Success()) 541 { 542 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS) 543 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this()); 544 return true; 545 } 546 else 547 { 548 const char *error_cstr = jit_error.AsCString(); 549 if (error_cstr && error_cstr[0]) 550 error_stream.Printf ("error: %s\n", error_cstr); 551 else 552 error_stream.Printf ("error: expression can't be interpreted or run\n"); 553 return false; 554 } 555 } 556 557 bool 558 ClangUserExpression::AddArguments (ExecutionContext &exe_ctx, 559 std::vector<lldb::addr_t> &args, 560 lldb::addr_t struct_address, 561 Stream &error_stream) 562 { 563 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS; 564 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS; 565 566 if (m_needs_object_ptr) 567 { 568 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); 569 if (!frame_sp) 570 return true; 571 572 ConstString object_name; 573 574 if (m_in_cplusplus_method) 575 { 576 object_name.SetCString("this"); 577 } 578 else if (m_in_objectivec_method) 579 { 580 object_name.SetCString("self"); 581 } 582 else 583 { 584 error_stream.Printf("Need object pointer but don't know the language\n"); 585 return false; 586 } 587 588 Error object_ptr_error; 589 590 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error); 591 592 if (!object_ptr_error.Success()) 593 { 594 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString()); 595 object_ptr = 0; 596 } 597 598 if (m_in_objectivec_method) 599 { 600 ConstString cmd_name("_cmd"); 601 602 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error); 603 604 if (!object_ptr_error.Success()) 605 { 606 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString()); 607 cmd_ptr = 0; 608 } 609 } 610 if (object_ptr) 611 args.push_back(object_ptr); 612 613 if (m_in_objectivec_method) 614 args.push_back(cmd_ptr); 615 616 args.push_back(struct_address); 617 } 618 else 619 { 620 args.push_back(struct_address); 621 } 622 return true; 623 } 624 625 lldb::ExpressionVariableSP 626 ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope) 627 { 628 return m_result_delegate.GetVariable(); 629 } 630 631 void 632 ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory) 633 { 634 m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx)); 635 } 636 637 clang::ASTConsumer * 638 ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough) 639 { 640 m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, 641 m_target)); 642 643 return m_result_synthesizer_up.get(); 644 } 645 646 ClangUserExpression::ResultDelegate::ResultDelegate() 647 { 648 } 649 650 ConstString 651 ClangUserExpression::ResultDelegate::GetName() 652 { 653 return m_persistent_state->GetNextPersistentVariableName(); 654 } 655 656 void 657 ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable) 658 { 659 m_variable = variable; 660 } 661 662 void 663 ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state) 664 { 665 m_persistent_state = persistent_state; 666 } 667 668 lldb::ExpressionVariableSP & 669 ClangUserExpression::ResultDelegate::GetVariable() 670 { 671 return m_variable; 672 } 673 674