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