1254721Semaste//===-- ClangUserExpression.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// C Includes 11254721Semaste#include <stdio.h> 12254721Semaste#if HAVE_SYS_TYPES_H 13254721Semaste# include <sys/types.h> 14254721Semaste#endif 15254721Semaste 16254721Semaste// C++ Includes 17254721Semaste#include <cstdlib> 18254721Semaste#include <string> 19254721Semaste#include <map> 20254721Semaste 21254721Semaste#include "lldb/Core/ConstString.h" 22254721Semaste#include "lldb/Core/Log.h" 23254721Semaste#include "lldb/Core/StreamFile.h" 24254721Semaste#include "lldb/Core/StreamString.h" 25254721Semaste#include "lldb/Core/ValueObjectConstResult.h" 26254721Semaste#include "lldb/Expression/ASTResultSynthesizer.h" 27254721Semaste#include "lldb/Expression/ClangExpressionDeclMap.h" 28254721Semaste#include "lldb/Expression/ClangExpressionParser.h" 29254721Semaste#include "lldb/Expression/ClangFunction.h" 30254721Semaste#include "lldb/Expression/ClangUserExpression.h" 31254721Semaste#include "lldb/Expression/ExpressionSourceCode.h" 32254721Semaste#include "lldb/Expression/IRExecutionUnit.h" 33254721Semaste#include "lldb/Expression/IRInterpreter.h" 34254721Semaste#include "lldb/Expression/Materializer.h" 35254721Semaste#include "lldb/Host/Host.h" 36254721Semaste#include "lldb/Symbol/Block.h" 37254721Semaste#include "lldb/Symbol/ClangASTContext.h" 38254721Semaste#include "lldb/Symbol/Function.h" 39254721Semaste#include "lldb/Symbol/Type.h" 40254721Semaste#include "lldb/Symbol/ClangExternalASTSourceCommon.h" 41254721Semaste#include "lldb/Symbol/VariableList.h" 42254721Semaste#include "lldb/Target/ExecutionContext.h" 43254721Semaste#include "lldb/Target/Process.h" 44254721Semaste#include "lldb/Target/StackFrame.h" 45254721Semaste#include "lldb/Target/Target.h" 46254721Semaste#include "lldb/Target/ThreadPlan.h" 47254721Semaste#include "lldb/Target/ThreadPlanCallUserExpression.h" 48254721Semaste 49254721Semaste#include "clang/AST/DeclCXX.h" 50254721Semaste#include "clang/AST/DeclObjC.h" 51254721Semaste 52254721Semasteusing namespace lldb_private; 53254721Semaste 54254721SemasteClangUserExpression::ClangUserExpression (const char *expr, 55254721Semaste const char *expr_prefix, 56254721Semaste lldb::LanguageType language, 57254721Semaste ResultType desired_type) : 58254721Semaste ClangExpression (), 59254721Semaste m_stack_frame_bottom (LLDB_INVALID_ADDRESS), 60254721Semaste m_stack_frame_top (LLDB_INVALID_ADDRESS), 61254721Semaste m_expr_text (expr), 62254721Semaste m_expr_prefix (expr_prefix ? expr_prefix : ""), 63254721Semaste m_language (language), 64254721Semaste m_transformed_text (), 65254721Semaste m_desired_type (desired_type), 66254721Semaste m_enforce_valid_object (true), 67254721Semaste m_cplusplus (false), 68254721Semaste m_objectivec (false), 69254721Semaste m_static_method(false), 70254721Semaste m_needs_object_ptr (false), 71254721Semaste m_const_object (false), 72254721Semaste m_target (NULL), 73254721Semaste m_can_interpret (false), 74254721Semaste m_materialized_address (LLDB_INVALID_ADDRESS) 75254721Semaste{ 76254721Semaste switch (m_language) 77254721Semaste { 78254721Semaste case lldb::eLanguageTypeC_plus_plus: 79254721Semaste m_allow_cxx = true; 80254721Semaste break; 81254721Semaste case lldb::eLanguageTypeObjC: 82254721Semaste m_allow_objc = true; 83254721Semaste break; 84254721Semaste case lldb::eLanguageTypeObjC_plus_plus: 85254721Semaste default: 86254721Semaste m_allow_cxx = true; 87254721Semaste m_allow_objc = true; 88254721Semaste break; 89254721Semaste } 90254721Semaste} 91254721Semaste 92254721SemasteClangUserExpression::~ClangUserExpression () 93254721Semaste{ 94254721Semaste} 95254721Semaste 96254721Semasteclang::ASTConsumer * 97254721SemasteClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough) 98263363Semaste{ 99263363Semaste m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough, 100263363Semaste *m_target)); 101254721Semaste 102254721Semaste return m_result_synthesizer.get(); 103254721Semaste} 104254721Semaste 105254721Semastevoid 106254721SemasteClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) 107254721Semaste{ 108254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 109254721Semaste 110254721Semaste if (log) 111254721Semaste log->Printf("ClangUserExpression::ScanContext()"); 112254721Semaste 113254721Semaste m_target = exe_ctx.GetTargetPtr(); 114254721Semaste 115254721Semaste if (!(m_allow_cxx || m_allow_objc)) 116254721Semaste { 117254721Semaste if (log) 118254721Semaste log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C"); 119254721Semaste return; 120254721Semaste } 121254721Semaste 122254721Semaste StackFrame *frame = exe_ctx.GetFramePtr(); 123254721Semaste if (frame == NULL) 124254721Semaste { 125254721Semaste if (log) 126254721Semaste log->Printf(" [CUE::SC] Null stack frame"); 127254721Semaste return; 128254721Semaste } 129254721Semaste 130254721Semaste SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock); 131254721Semaste 132254721Semaste if (!sym_ctx.function) 133254721Semaste { 134254721Semaste if (log) 135254721Semaste log->Printf(" [CUE::SC] Null function"); 136254721Semaste return; 137254721Semaste } 138254721Semaste 139254721Semaste // Find the block that defines the function represented by "sym_ctx" 140254721Semaste Block *function_block = sym_ctx.GetFunctionBlock(); 141254721Semaste 142254721Semaste if (!function_block) 143254721Semaste { 144254721Semaste if (log) 145254721Semaste log->Printf(" [CUE::SC] Null function block"); 146254721Semaste return; 147254721Semaste } 148254721Semaste 149254721Semaste clang::DeclContext *decl_context = function_block->GetClangDeclContext(); 150254721Semaste 151254721Semaste if (!decl_context) 152254721Semaste { 153254721Semaste if (log) 154254721Semaste log->Printf(" [CUE::SC] Null decl context"); 155254721Semaste return; 156254721Semaste } 157254721Semaste 158254721Semaste if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context)) 159254721Semaste { 160254721Semaste if (m_allow_cxx && method_decl->isInstance()) 161254721Semaste { 162254721Semaste if (m_enforce_valid_object) 163254721Semaste { 164254721Semaste lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 165254721Semaste 166254721Semaste const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context"; 167254721Semaste 168254721Semaste if (!variable_list_sp) 169254721Semaste { 170254721Semaste err.SetErrorString(thisErrorString); 171254721Semaste return; 172254721Semaste } 173254721Semaste 174254721Semaste lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this"))); 175254721Semaste 176254721Semaste if (!this_var_sp || 177254721Semaste !this_var_sp->IsInScope(frame) || 178254721Semaste !this_var_sp->LocationIsValidForFrame (frame)) 179254721Semaste { 180254721Semaste err.SetErrorString(thisErrorString); 181254721Semaste return; 182254721Semaste } 183254721Semaste } 184254721Semaste 185254721Semaste m_cplusplus = true; 186254721Semaste m_needs_object_ptr = true; 187254721Semaste } 188254721Semaste } 189254721Semaste else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context)) 190254721Semaste { 191254721Semaste if (m_allow_objc) 192254721Semaste { 193254721Semaste if (m_enforce_valid_object) 194254721Semaste { 195254721Semaste lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 196254721Semaste 197254721Semaste const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context"; 198254721Semaste 199254721Semaste if (!variable_list_sp) 200254721Semaste { 201254721Semaste err.SetErrorString(selfErrorString); 202254721Semaste return; 203254721Semaste } 204254721Semaste 205254721Semaste lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self")); 206254721Semaste 207254721Semaste if (!self_variable_sp || 208254721Semaste !self_variable_sp->IsInScope(frame) || 209254721Semaste !self_variable_sp->LocationIsValidForFrame (frame)) 210254721Semaste { 211254721Semaste err.SetErrorString(selfErrorString); 212254721Semaste return; 213254721Semaste } 214254721Semaste } 215254721Semaste 216254721Semaste m_objectivec = true; 217254721Semaste m_needs_object_ptr = true; 218254721Semaste 219254721Semaste if (!method_decl->isInstanceMethod()) 220254721Semaste m_static_method = true; 221254721Semaste } 222254721Semaste } 223254721Semaste else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context)) 224254721Semaste { 225254721Semaste // We might also have a function that said in the debug information that it captured an 226254721Semaste // object pointer. The best way to deal with getting to the ivars at present it by pretending 227254721Semaste // that this is a method of a class in whatever runtime the debug info says the object pointer 228254721Semaste // belongs to. Do that here. 229254721Semaste 230254721Semaste ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl); 231254721Semaste if (metadata && metadata->HasObjectPtr()) 232254721Semaste { 233254721Semaste lldb::LanguageType language = metadata->GetObjectPtrLanguage(); 234254721Semaste if (language == lldb::eLanguageTypeC_plus_plus) 235254721Semaste { 236254721Semaste if (m_enforce_valid_object) 237254721Semaste { 238254721Semaste lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 239254721Semaste 240254721Semaste 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"; 241254721Semaste 242254721Semaste if (!variable_list_sp) 243254721Semaste { 244254721Semaste err.SetErrorString(thisErrorString); 245254721Semaste return; 246254721Semaste } 247254721Semaste 248254721Semaste lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this"))); 249254721Semaste 250254721Semaste if (!this_var_sp || 251254721Semaste !this_var_sp->IsInScope(frame) || 252254721Semaste !this_var_sp->LocationIsValidForFrame (frame)) 253254721Semaste { 254254721Semaste err.SetErrorString(thisErrorString); 255254721Semaste return; 256254721Semaste } 257254721Semaste } 258254721Semaste 259254721Semaste m_cplusplus = true; 260254721Semaste m_needs_object_ptr = true; 261254721Semaste } 262254721Semaste else if (language == lldb::eLanguageTypeObjC) 263254721Semaste { 264254721Semaste if (m_enforce_valid_object) 265254721Semaste { 266254721Semaste lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 267254721Semaste 268254721Semaste 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"; 269254721Semaste 270254721Semaste if (!variable_list_sp) 271254721Semaste { 272254721Semaste err.SetErrorString(selfErrorString); 273254721Semaste return; 274254721Semaste } 275254721Semaste 276254721Semaste lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self")); 277254721Semaste 278254721Semaste if (!self_variable_sp || 279254721Semaste !self_variable_sp->IsInScope(frame) || 280254721Semaste !self_variable_sp->LocationIsValidForFrame (frame)) 281254721Semaste { 282254721Semaste err.SetErrorString(selfErrorString); 283254721Semaste return; 284254721Semaste } 285254721Semaste 286254721Semaste Type *self_type = self_variable_sp->GetType(); 287254721Semaste 288254721Semaste if (!self_type) 289254721Semaste { 290254721Semaste err.SetErrorString(selfErrorString); 291254721Semaste return; 292254721Semaste } 293254721Semaste 294254721Semaste ClangASTType self_clang_type = self_type->GetClangForwardType(); 295254721Semaste 296254721Semaste if (!self_clang_type) 297254721Semaste { 298254721Semaste err.SetErrorString(selfErrorString); 299254721Semaste return; 300254721Semaste } 301254721Semaste 302254721Semaste if (self_clang_type.IsObjCClassType()) 303254721Semaste { 304254721Semaste return; 305254721Semaste } 306254721Semaste else if (self_clang_type.IsObjCObjectPointerType()) 307254721Semaste { 308254721Semaste m_objectivec = true; 309254721Semaste m_needs_object_ptr = true; 310254721Semaste } 311254721Semaste else 312254721Semaste { 313254721Semaste err.SetErrorString(selfErrorString); 314254721Semaste return; 315254721Semaste } 316254721Semaste } 317254721Semaste else 318254721Semaste { 319254721Semaste m_objectivec = true; 320254721Semaste m_needs_object_ptr = true; 321254721Semaste } 322254721Semaste } 323254721Semaste } 324254721Semaste } 325254721Semaste} 326254721Semaste 327254721Semastevoid 328254721SemasteClangUserExpression::InstallContext (ExecutionContext &exe_ctx) 329254721Semaste{ 330254721Semaste m_process_wp = exe_ctx.GetProcessSP(); 331254721Semaste 332254721Semaste lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP(); 333254721Semaste 334254721Semaste if (frame_sp) 335254721Semaste m_address = frame_sp->GetFrameCodeAddress(); 336254721Semaste} 337254721Semaste 338254721Semastebool 339254721SemasteClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx, 340254721Semaste lldb::TargetSP &target_sp, 341254721Semaste lldb::ProcessSP &process_sp, 342254721Semaste lldb::StackFrameSP &frame_sp) 343254721Semaste{ 344254721Semaste lldb::ProcessSP expected_process_sp = m_process_wp.lock(); 345254721Semaste process_sp = exe_ctx.GetProcessSP(); 346254721Semaste 347254721Semaste if (process_sp != expected_process_sp) 348254721Semaste return false; 349254721Semaste 350254721Semaste process_sp = exe_ctx.GetProcessSP(); 351254721Semaste target_sp = exe_ctx.GetTargetSP(); 352254721Semaste frame_sp = exe_ctx.GetFrameSP(); 353254721Semaste 354254721Semaste if (m_address.IsValid()) 355254721Semaste { 356254721Semaste if (!frame_sp) 357254721Semaste return false; 358254721Semaste else 359254721Semaste return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get())); 360254721Semaste } 361254721Semaste 362254721Semaste return true; 363254721Semaste} 364254721Semaste 365254721Semastebool 366254721SemasteClangUserExpression::MatchesContext (ExecutionContext &exe_ctx) 367254721Semaste{ 368254721Semaste lldb::TargetSP target_sp; 369254721Semaste lldb::ProcessSP process_sp; 370254721Semaste lldb::StackFrameSP frame_sp; 371254721Semaste 372254721Semaste return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp); 373254721Semaste} 374254721Semaste 375254721Semaste// This is a really nasty hack, meant to fix Objective-C expressions of the form 376254721Semaste// (int)[myArray count]. Right now, because the type information for count is 377254721Semaste// not available, [myArray count] returns id, which can't be directly cast to 378254721Semaste// int without causing a clang error. 379254721Semastestatic void 380254721SemasteApplyObjcCastHack(std::string &expr) 381254721Semaste{ 382254721Semaste#define OBJC_CAST_HACK_FROM "(int)[" 383254721Semaste#define OBJC_CAST_HACK_TO "(int)(long long)[" 384254721Semaste 385254721Semaste size_t from_offset; 386254721Semaste 387254721Semaste while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos) 388254721Semaste expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO); 389254721Semaste 390254721Semaste#undef OBJC_CAST_HACK_TO 391254721Semaste#undef OBJC_CAST_HACK_FROM 392254721Semaste} 393254721Semaste 394254721Semaste// Another hack, meant to allow use of unichar despite it not being available in 395254721Semaste// the type information. Although we could special-case it in type lookup, 396254721Semaste// hopefully we'll figure out a way to #include the same environment as is 397254721Semaste// present in the original source file rather than try to hack specific type 398254721Semaste// definitions in as needed. 399254721Semastestatic void 400254721SemasteApplyUnicharHack(std::string &expr) 401254721Semaste{ 402254721Semaste#define UNICHAR_HACK_FROM "unichar" 403254721Semaste#define UNICHAR_HACK_TO "unsigned short" 404254721Semaste 405254721Semaste size_t from_offset; 406254721Semaste 407254721Semaste while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos) 408254721Semaste expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO); 409254721Semaste 410254721Semaste#undef UNICHAR_HACK_TO 411254721Semaste#undef UNICHAR_HACK_FROM 412254721Semaste} 413254721Semaste 414254721Semastebool 415254721SemasteClangUserExpression::Parse (Stream &error_stream, 416254721Semaste ExecutionContext &exe_ctx, 417254721Semaste lldb_private::ExecutionPolicy execution_policy, 418254721Semaste bool keep_result_in_memory) 419254721Semaste{ 420254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 421254721Semaste 422254721Semaste Error err; 423254721Semaste 424254721Semaste InstallContext(exe_ctx); 425254721Semaste 426254721Semaste ScanContext(exe_ctx, err); 427254721Semaste 428254721Semaste if (!err.Success()) 429254721Semaste { 430254721Semaste error_stream.Printf("warning: %s\n", err.AsCString()); 431254721Semaste } 432254721Semaste 433254721Semaste StreamString m_transformed_stream; 434254721Semaste 435254721Semaste //////////////////////////////////// 436254721Semaste // Generate the expression 437254721Semaste // 438254721Semaste 439254721Semaste ApplyObjcCastHack(m_expr_text); 440254721Semaste //ApplyUnicharHack(m_expr_text); 441254721Semaste 442254721Semaste std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str())); 443254721Semaste 444254721Semaste lldb::LanguageType lang_type; 445254721Semaste 446254721Semaste if (m_cplusplus) 447254721Semaste lang_type = lldb::eLanguageTypeC_plus_plus; 448254721Semaste else if(m_objectivec) 449254721Semaste lang_type = lldb::eLanguageTypeObjC; 450254721Semaste else 451254721Semaste lang_type = lldb::eLanguageTypeC; 452254721Semaste 453254721Semaste if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method)) 454254721Semaste { 455254721Semaste error_stream.PutCString ("error: couldn't construct expression body"); 456254721Semaste return false; 457254721Semaste } 458254721Semaste 459254721Semaste if (log) 460254721Semaste log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); 461254721Semaste 462254721Semaste //////////////////////////////////// 463254721Semaste // Set up the target and compiler 464254721Semaste // 465254721Semaste 466254721Semaste Target *target = exe_ctx.GetTargetPtr(); 467254721Semaste 468254721Semaste if (!target) 469254721Semaste { 470254721Semaste error_stream.PutCString ("error: invalid target\n"); 471254721Semaste return false; 472254721Semaste } 473254721Semaste 474254721Semaste ////////////////////////// 475254721Semaste // Parse the expression 476254721Semaste // 477254721Semaste 478254721Semaste m_materializer_ap.reset(new Materializer()); 479254721Semaste 480254721Semaste m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx)); 481254721Semaste 482254721Semaste class OnExit 483254721Semaste { 484254721Semaste public: 485254721Semaste typedef std::function <void (void)> Callback; 486254721Semaste 487254721Semaste OnExit (Callback const &callback) : 488254721Semaste m_callback(callback) 489254721Semaste { 490254721Semaste } 491254721Semaste 492254721Semaste ~OnExit () 493254721Semaste { 494254721Semaste m_callback(); 495254721Semaste } 496254721Semaste private: 497254721Semaste Callback m_callback; 498254721Semaste }; 499254721Semaste 500254721Semaste OnExit on_exit([this]() { m_expr_decl_map.reset(); }); 501254721Semaste 502254721Semaste if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get())) 503254721Semaste { 504254721Semaste error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n"); 505263363Semaste 506263363Semaste m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions. 507263363Semaste 508254721Semaste return false; 509254721Semaste } 510254721Semaste 511254721Semaste Process *process = exe_ctx.GetProcessPtr(); 512254721Semaste ExecutionContextScope *exe_scope = process; 513254721Semaste 514254721Semaste if (!exe_scope) 515254721Semaste exe_scope = exe_ctx.GetTargetPtr(); 516254721Semaste 517254721Semaste ClangExpressionParser parser(exe_scope, *this); 518254721Semaste 519254721Semaste unsigned num_errors = parser.Parse (error_stream); 520254721Semaste 521254721Semaste if (num_errors) 522254721Semaste { 523254721Semaste error_stream.Printf ("error: %d errors parsing expression\n", num_errors); 524254721Semaste 525263363Semaste m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions. 526254721Semaste 527254721Semaste return false; 528254721Semaste } 529254721Semaste 530254721Semaste ////////////////////////////////////////////////////////////////////////////////////////// 531254721Semaste // Prepare the output of the parser for execution, evaluating it statically if possible 532254721Semaste // 533254721Semaste 534254721Semaste Error jit_error = parser.PrepareForExecution (m_jit_start_addr, 535254721Semaste m_jit_end_addr, 536254721Semaste m_execution_unit_ap, 537254721Semaste exe_ctx, 538254721Semaste m_can_interpret, 539254721Semaste execution_policy); 540263363Semaste 541263363Semaste m_expr_decl_map.reset(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions. 542254721Semaste 543254721Semaste if (jit_error.Success()) 544254721Semaste { 545254721Semaste if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS) 546254721Semaste m_jit_process_wp = lldb::ProcessWP(process->shared_from_this()); 547254721Semaste return true; 548254721Semaste } 549254721Semaste else 550254721Semaste { 551254721Semaste const char *error_cstr = jit_error.AsCString(); 552254721Semaste if (error_cstr && error_cstr[0]) 553254721Semaste error_stream.Printf ("error: %s\n", error_cstr); 554254721Semaste else 555254721Semaste error_stream.Printf ("error: expression can't be interpreted or run\n"); 556254721Semaste return false; 557254721Semaste } 558254721Semaste} 559254721Semaste 560254721Semastestatic lldb::addr_t 561254721SemasteGetObjectPointer (lldb::StackFrameSP frame_sp, 562254721Semaste ConstString &object_name, 563254721Semaste Error &err) 564254721Semaste{ 565254721Semaste err.Clear(); 566254721Semaste 567254721Semaste if (!frame_sp) 568254721Semaste { 569254721Semaste err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString()); 570254721Semaste return LLDB_INVALID_ADDRESS; 571254721Semaste } 572254721Semaste 573254721Semaste lldb::VariableSP var_sp; 574254721Semaste lldb::ValueObjectSP valobj_sp; 575254721Semaste 576254721Semaste valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(), 577254721Semaste lldb::eNoDynamicValues, 578254721Semaste StackFrame::eExpressionPathOptionCheckPtrVsMember || 579254721Semaste StackFrame::eExpressionPathOptionsAllowDirectIVarAccess || 580254721Semaste StackFrame::eExpressionPathOptionsNoFragileObjcIvar || 581254721Semaste StackFrame::eExpressionPathOptionsNoSyntheticChildren || 582254721Semaste StackFrame::eExpressionPathOptionsNoSyntheticArrayRange, 583254721Semaste var_sp, 584254721Semaste err); 585254721Semaste 586254721Semaste if (!err.Success()) 587254721Semaste return LLDB_INVALID_ADDRESS; 588254721Semaste 589254721Semaste lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 590254721Semaste 591254721Semaste if (ret == LLDB_INVALID_ADDRESS) 592254721Semaste { 593254721Semaste err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString()); 594254721Semaste return LLDB_INVALID_ADDRESS; 595254721Semaste } 596254721Semaste 597254721Semaste return ret; 598254721Semaste} 599254721Semaste 600254721Semastebool 601254721SemasteClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, 602254721Semaste ExecutionContext &exe_ctx, 603254721Semaste lldb::addr_t &struct_address, 604254721Semaste lldb::addr_t &object_ptr, 605254721Semaste lldb::addr_t &cmd_ptr) 606254721Semaste{ 607254721Semaste lldb::TargetSP target; 608254721Semaste lldb::ProcessSP process; 609254721Semaste lldb::StackFrameSP frame; 610254721Semaste 611254721Semaste if (!LockAndCheckContext(exe_ctx, 612254721Semaste target, 613254721Semaste process, 614254721Semaste frame)) 615254721Semaste { 616254721Semaste error_stream.Printf("The context has changed before we could JIT the expression!\n"); 617254721Semaste return false; 618254721Semaste } 619254721Semaste 620254721Semaste if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) 621254721Semaste { 622254721Semaste if (m_needs_object_ptr) 623254721Semaste { 624254721Semaste ConstString object_name; 625254721Semaste 626254721Semaste if (m_cplusplus) 627254721Semaste { 628254721Semaste object_name.SetCString("this"); 629254721Semaste } 630254721Semaste else if (m_objectivec) 631254721Semaste { 632254721Semaste object_name.SetCString("self"); 633254721Semaste } 634254721Semaste else 635254721Semaste { 636254721Semaste error_stream.Printf("Need object pointer but don't know the language\n"); 637254721Semaste return false; 638254721Semaste } 639254721Semaste 640254721Semaste Error object_ptr_error; 641254721Semaste 642254721Semaste object_ptr = GetObjectPointer(frame, object_name, object_ptr_error); 643254721Semaste 644254721Semaste if (!object_ptr_error.Success()) 645254721Semaste { 646254721Semaste error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString()); 647254721Semaste object_ptr = 0; 648254721Semaste } 649254721Semaste 650254721Semaste if (m_objectivec) 651254721Semaste { 652254721Semaste ConstString cmd_name("_cmd"); 653254721Semaste 654254721Semaste cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error); 655254721Semaste 656254721Semaste if (!object_ptr_error.Success()) 657254721Semaste { 658254721Semaste error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString()); 659254721Semaste cmd_ptr = 0; 660254721Semaste } 661254721Semaste } 662254721Semaste } 663254721Semaste 664254721Semaste if (m_materialized_address == LLDB_INVALID_ADDRESS) 665254721Semaste { 666254721Semaste Error alloc_error; 667254721Semaste 668254721Semaste IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror; 669254721Semaste 670254721Semaste m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(), 671254721Semaste m_materializer_ap->GetStructAlignment(), 672254721Semaste lldb::ePermissionsReadable | lldb::ePermissionsWritable, 673254721Semaste policy, 674254721Semaste alloc_error); 675254721Semaste 676254721Semaste if (!alloc_error.Success()) 677254721Semaste { 678254721Semaste error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString()); 679254721Semaste return false; 680254721Semaste } 681254721Semaste } 682254721Semaste 683254721Semaste struct_address = m_materialized_address; 684254721Semaste 685254721Semaste if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) 686254721Semaste { 687254721Semaste Error alloc_error; 688254721Semaste 689254721Semaste const size_t stack_frame_size = 512 * 1024; 690254721Semaste 691254721Semaste m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size, 692254721Semaste 8, 693254721Semaste lldb::ePermissionsReadable | lldb::ePermissionsWritable, 694254721Semaste IRMemoryMap::eAllocationPolicyHostOnly, 695254721Semaste alloc_error); 696254721Semaste 697254721Semaste m_stack_frame_top = m_stack_frame_bottom + stack_frame_size; 698254721Semaste 699254721Semaste if (!alloc_error.Success()) 700254721Semaste { 701254721Semaste error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString()); 702254721Semaste return false; 703254721Semaste } 704254721Semaste } 705254721Semaste 706254721Semaste Error materialize_error; 707254721Semaste 708254721Semaste m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error); 709254721Semaste 710254721Semaste if (!materialize_error.Success()) 711254721Semaste { 712254721Semaste error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString()); 713254721Semaste return false; 714254721Semaste } 715254721Semaste } 716254721Semaste return true; 717254721Semaste} 718254721Semaste 719254721Semastebool 720254721SemasteClangUserExpression::FinalizeJITExecution (Stream &error_stream, 721254721Semaste ExecutionContext &exe_ctx, 722254721Semaste lldb::ClangExpressionVariableSP &result, 723254721Semaste lldb::addr_t function_stack_bottom, 724254721Semaste lldb::addr_t function_stack_top) 725254721Semaste{ 726254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 727254721Semaste 728254721Semaste if (log) 729254721Semaste log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --"); 730254721Semaste 731254721Semaste if (!m_dematerializer_sp) 732254721Semaste { 733254721Semaste error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present"); 734254721Semaste return false; 735254721Semaste } 736254721Semaste 737254721Semaste Error dematerialize_error; 738254721Semaste 739254721Semaste m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top); 740254721Semaste 741254721Semaste if (!dematerialize_error.Success()) 742254721Semaste { 743254721Semaste error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error")); 744254721Semaste return false; 745254721Semaste } 746254721Semaste 747254721Semaste if (result) 748254721Semaste result->TransferAddress(); 749254721Semaste 750254721Semaste m_dematerializer_sp.reset(); 751254721Semaste 752254721Semaste return true; 753254721Semaste} 754254721Semaste 755254721SemasteExecutionResults 756254721SemasteClangUserExpression::Execute (Stream &error_stream, 757254721Semaste ExecutionContext &exe_ctx, 758263363Semaste const EvaluateExpressionOptions& options, 759254721Semaste ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me, 760263363Semaste lldb::ClangExpressionVariableSP &result) 761254721Semaste{ 762254721Semaste // The expression log is quite verbose, and if you're just tracking the execution of the 763254721Semaste // expression, it's quite convenient to have these logs come out with the STEP log as well. 764254721Semaste Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); 765254721Semaste 766254721Semaste if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) 767254721Semaste { 768254721Semaste lldb::addr_t struct_address = LLDB_INVALID_ADDRESS; 769254721Semaste 770254721Semaste lldb::addr_t object_ptr = 0; 771254721Semaste lldb::addr_t cmd_ptr = 0; 772254721Semaste 773254721Semaste if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr)) 774254721Semaste { 775254721Semaste error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__); 776254721Semaste return eExecutionSetupError; 777254721Semaste } 778254721Semaste 779254721Semaste lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS; 780254721Semaste lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS; 781254721Semaste 782254721Semaste if (m_can_interpret) 783254721Semaste { 784254721Semaste llvm::Module *module = m_execution_unit_ap->GetModule(); 785254721Semaste llvm::Function *function = m_execution_unit_ap->GetFunction(); 786254721Semaste 787254721Semaste if (!module || !function) 788254721Semaste { 789254721Semaste error_stream.Printf("Supposed to interpret, but nothing is there"); 790254721Semaste return eExecutionSetupError; 791254721Semaste } 792254721Semaste 793254721Semaste Error interpreter_error; 794254721Semaste 795254721Semaste llvm::SmallVector <lldb::addr_t, 3> args; 796254721Semaste 797254721Semaste if (m_needs_object_ptr) 798254721Semaste { 799254721Semaste args.push_back(object_ptr); 800254721Semaste 801254721Semaste if (m_objectivec) 802254721Semaste args.push_back(cmd_ptr); 803254721Semaste } 804254721Semaste 805254721Semaste args.push_back(struct_address); 806254721Semaste 807254721Semaste function_stack_bottom = m_stack_frame_bottom; 808254721Semaste function_stack_top = m_stack_frame_top; 809254721Semaste 810254721Semaste IRInterpreter::Interpret (*module, 811254721Semaste *function, 812254721Semaste args, 813254721Semaste *m_execution_unit_ap.get(), 814254721Semaste interpreter_error, 815254721Semaste function_stack_bottom, 816254721Semaste function_stack_top); 817254721Semaste 818254721Semaste if (!interpreter_error.Success()) 819254721Semaste { 820254721Semaste error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString()); 821254721Semaste return eExecutionDiscarded; 822254721Semaste } 823254721Semaste } 824254721Semaste else 825254721Semaste { 826263367Semaste Address wrapper_address (m_jit_start_addr); 827263367Semaste 828263367Semaste llvm::SmallVector <lldb::addr_t, 3> args; 829263367Semaste 830263367Semaste if (m_needs_object_ptr) { 831263367Semaste args.push_back(object_ptr); 832263367Semaste if (m_objectivec) 833263367Semaste args.push_back(cmd_ptr); 834263363Semaste } 835263367Semaste 836263367Semaste args.push_back(struct_address); 837263367Semaste 838254721Semaste lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(), 839254721Semaste wrapper_address, 840263367Semaste args, 841263367Semaste options, 842254721Semaste shared_ptr_to_me)); 843254721Semaste 844254721Semaste if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream)) 845254721Semaste return eExecutionSetupError; 846254721Semaste 847254721Semaste lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer(); 848254721Semaste 849254721Semaste function_stack_bottom = function_stack_pointer - Host::GetPageSize(); 850254721Semaste function_stack_top = function_stack_pointer; 851254721Semaste 852254721Semaste if (log) 853254721Semaste log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --"); 854254721Semaste 855254721Semaste if (exe_ctx.GetProcessPtr()) 856254721Semaste exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); 857254721Semaste 858254721Semaste ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx, 859263367Semaste call_plan_sp, 860263367Semaste options, 861254721Semaste error_stream); 862254721Semaste 863254721Semaste if (exe_ctx.GetProcessPtr()) 864254721Semaste exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); 865254721Semaste 866254721Semaste if (log) 867254721Semaste log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --"); 868254721Semaste 869254721Semaste if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint) 870254721Semaste { 871254721Semaste const char *error_desc = NULL; 872254721Semaste 873254721Semaste if (call_plan_sp) 874254721Semaste { 875254721Semaste lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); 876254721Semaste if (real_stop_info_sp) 877254721Semaste error_desc = real_stop_info_sp->GetDescription(); 878254721Semaste } 879254721Semaste if (error_desc) 880254721Semaste error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc); 881254721Semaste else 882263367Semaste error_stream.PutCString ("Execution was interrupted."); 883254721Semaste 884263367Semaste if ((execution_result == eExecutionInterrupted && options.DoesUnwindOnError()) 885263367Semaste || (execution_result == eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints())) 886263367Semaste error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation."); 887254721Semaste else 888263367Semaste error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation."); 889254721Semaste 890254721Semaste return execution_result; 891254721Semaste } 892263367Semaste else if (execution_result == eExecutionStoppedForDebug) 893263367Semaste { 894263367Semaste error_stream.PutCString ("Execution was halted at the first instruction of the expression function because \"debug\" was requested.\n" 895263367Semaste "Use \"thread return -x\" to return to the state before expression evaluation."); 896263367Semaste return execution_result; 897263367Semaste } 898254721Semaste else if (execution_result != eExecutionCompleted) 899254721Semaste { 900254721Semaste error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result)); 901254721Semaste return execution_result; 902254721Semaste } 903254721Semaste } 904254721Semaste 905254721Semaste if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top)) 906254721Semaste { 907254721Semaste return eExecutionCompleted; 908254721Semaste } 909254721Semaste else 910254721Semaste { 911254721Semaste return eExecutionSetupError; 912254721Semaste } 913254721Semaste } 914254721Semaste else 915254721Semaste { 916254721Semaste error_stream.Printf("Expression can't be run, because there is no JIT compiled function"); 917254721Semaste return eExecutionSetupError; 918254721Semaste } 919254721Semaste} 920254721Semaste 921254721SemasteExecutionResults 922254721SemasteClangUserExpression::Evaluate (ExecutionContext &exe_ctx, 923263363Semaste const EvaluateExpressionOptions& options, 924254721Semaste const char *expr_cstr, 925254721Semaste const char *expr_prefix, 926254721Semaste lldb::ValueObjectSP &result_valobj_sp, 927263363Semaste Error &error) 928254721Semaste{ 929254721Semaste Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); 930254721Semaste 931263363Semaste lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); 932263363Semaste const lldb::LanguageType language = options.GetLanguage(); 933263363Semaste const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny; 934254721Semaste ExecutionResults execution_results = eExecutionSetupError; 935254721Semaste 936254721Semaste Process *process = exe_ctx.GetProcessPtr(); 937254721Semaste 938254721Semaste if (process == NULL || process->GetState() != lldb::eStateStopped) 939254721Semaste { 940254721Semaste if (execution_policy == eExecutionPolicyAlways) 941254721Semaste { 942254721Semaste if (log) 943254721Semaste log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant =="); 944254721Semaste 945254721Semaste error.SetErrorString ("expression needed to run but couldn't"); 946254721Semaste 947254721Semaste return execution_results; 948254721Semaste } 949254721Semaste } 950254721Semaste 951254721Semaste if (process == NULL || !process->CanJIT()) 952254721Semaste execution_policy = eExecutionPolicyNever; 953254721Semaste 954254721Semaste ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type)); 955254721Semaste 956254721Semaste StreamString error_stream; 957254721Semaste 958254721Semaste if (log) 959254721Semaste log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr); 960254721Semaste 961254721Semaste const bool keep_expression_in_memory = true; 962254721Semaste 963254721Semaste if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory)) 964254721Semaste { 965254721Semaste if (error_stream.GetString().empty()) 966254721Semaste error.SetErrorString ("expression failed to parse, unknown error"); 967254721Semaste else 968254721Semaste error.SetErrorString (error_stream.GetString().c_str()); 969254721Semaste } 970254721Semaste else 971254721Semaste { 972254721Semaste lldb::ClangExpressionVariableSP expr_result; 973254721Semaste 974254721Semaste if (execution_policy == eExecutionPolicyNever && 975254721Semaste !user_expression_sp->CanInterpret()) 976254721Semaste { 977254721Semaste if (log) 978254721Semaste log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant =="); 979254721Semaste 980254721Semaste if (error_stream.GetString().empty()) 981254721Semaste error.SetErrorString ("expression needed to run but couldn't"); 982254721Semaste } 983254721Semaste else 984254721Semaste { 985254721Semaste error_stream.GetString().clear(); 986254721Semaste 987254721Semaste if (log) 988254721Semaste log->Printf("== [ClangUserExpression::Evaluate] Executing expression =="); 989254721Semaste 990254721Semaste execution_results = user_expression_sp->Execute (error_stream, 991263363Semaste exe_ctx, 992263363Semaste options, 993263363Semaste user_expression_sp, 994263363Semaste expr_result); 995254721Semaste 996254721Semaste if (execution_results != eExecutionCompleted) 997254721Semaste { 998254721Semaste if (log) 999254721Semaste log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally =="); 1000254721Semaste 1001254721Semaste if (error_stream.GetString().empty()) 1002254721Semaste error.SetErrorString ("expression failed to execute, unknown error"); 1003254721Semaste else 1004254721Semaste error.SetErrorString (error_stream.GetString().c_str()); 1005254721Semaste } 1006254721Semaste else 1007254721Semaste { 1008254721Semaste if (expr_result) 1009254721Semaste { 1010254721Semaste result_valobj_sp = expr_result->GetValueObject(); 1011254721Semaste 1012254721Semaste if (log) 1013254721Semaste log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString()); 1014254721Semaste } 1015254721Semaste else 1016254721Semaste { 1017254721Semaste if (log) 1018254721Semaste log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result =="); 1019254721Semaste 1020254721Semaste error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric); 1021254721Semaste } 1022254721Semaste } 1023254721Semaste } 1024254721Semaste } 1025254721Semaste 1026254721Semaste if (result_valobj_sp.get() == NULL) 1027269024Semaste { 1028269024Semaste result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error); 1029269024Semaste } 1030254721Semaste 1031254721Semaste return execution_results; 1032254721Semaste} 1033