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 // C Includes
11 #include <stdio.h>
12 #if HAVE_SYS_TYPES_H
13 # include <sys/types.h>
14 #endif
15
16 // C++ Includes
17 #include <cstdlib>
18 #include <string>
19 #include <map>
20
21 #include "lldb/Core/ConstString.h"
22 #include "lldb/Core/Log.h"
23 #include "lldb/Core/StreamFile.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Core/ValueObjectConstResult.h"
26 #include "lldb/Expression/ASTResultSynthesizer.h"
27 #include "lldb/Expression/ClangExpressionDeclMap.h"
28 #include "lldb/Expression/ClangExpressionParser.h"
29 #include "lldb/Expression/ClangFunction.h"
30 #include "lldb/Expression/ClangUserExpression.h"
31 #include "lldb/Expression/ExpressionSourceCode.h"
32 #include "lldb/Expression/IRExecutionUnit.h"
33 #include "lldb/Expression/IRInterpreter.h"
34 #include "lldb/Expression/Materializer.h"
35 #include "lldb/Host/Host.h"
36 #include "lldb/Symbol/Block.h"
37 #include "lldb/Symbol/ClangASTContext.h"
38 #include "lldb/Symbol/Function.h"
39 #include "lldb/Symbol/Type.h"
40 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
41 #include "lldb/Symbol/VariableList.h"
42 #include "lldb/Target/ExecutionContext.h"
43 #include "lldb/Target/Process.h"
44 #include "lldb/Target/StackFrame.h"
45 #include "lldb/Target/Target.h"
46 #include "lldb/Target/ThreadPlan.h"
47 #include "lldb/Target/ThreadPlanCallUserExpression.h"
48
49 #include "clang/AST/DeclCXX.h"
50 #include "clang/AST/DeclObjC.h"
51
52 using namespace lldb_private;
53
ClangUserExpression(const char * expr,const char * expr_prefix,lldb::LanguageType language,ResultType desired_type)54 ClangUserExpression::ClangUserExpression (const char *expr,
55 const char *expr_prefix,
56 lldb::LanguageType language,
57 ResultType desired_type) :
58 ClangExpression (),
59 m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
60 m_stack_frame_top (LLDB_INVALID_ADDRESS),
61 m_expr_text (expr),
62 m_expr_prefix (expr_prefix ? expr_prefix : ""),
63 m_language (language),
64 m_transformed_text (),
65 m_desired_type (desired_type),
66 m_enforce_valid_object (true),
67 m_cplusplus (false),
68 m_objectivec (false),
69 m_static_method(false),
70 m_needs_object_ptr (false),
71 m_const_object (false),
72 m_target (NULL),
73 m_can_interpret (false),
74 m_materialized_address (LLDB_INVALID_ADDRESS)
75 {
76 switch (m_language)
77 {
78 case lldb::eLanguageTypeC_plus_plus:
79 m_allow_cxx = true;
80 break;
81 case lldb::eLanguageTypeObjC:
82 m_allow_objc = true;
83 break;
84 case lldb::eLanguageTypeObjC_plus_plus:
85 default:
86 m_allow_cxx = true;
87 m_allow_objc = true;
88 break;
89 }
90 }
91
~ClangUserExpression()92 ClangUserExpression::~ClangUserExpression ()
93 {
94 }
95
96 clang::ASTConsumer *
ASTTransformer(clang::ASTConsumer * passthrough)97 ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
98 {
99 ClangASTContext *clang_ast_context = m_target->GetScratchClangASTContext();
100
101 if (!clang_ast_context)
102 return NULL;
103
104 if (!m_result_synthesizer.get())
105 m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
106 *m_target));
107
108 return m_result_synthesizer.get();
109 }
110
111 void
ScanContext(ExecutionContext & exe_ctx,Error & err)112 ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
113 {
114 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
115
116 if (log)
117 log->Printf("ClangUserExpression::ScanContext()");
118
119 m_target = exe_ctx.GetTargetPtr();
120
121 if (!(m_allow_cxx || m_allow_objc))
122 {
123 if (log)
124 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
125 return;
126 }
127
128 StackFrame *frame = exe_ctx.GetFramePtr();
129 if (frame == NULL)
130 {
131 if (log)
132 log->Printf(" [CUE::SC] Null stack frame");
133 return;
134 }
135
136 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
137
138 if (!sym_ctx.function)
139 {
140 if (log)
141 log->Printf(" [CUE::SC] Null function");
142 return;
143 }
144
145 // Find the block that defines the function represented by "sym_ctx"
146 Block *function_block = sym_ctx.GetFunctionBlock();
147
148 if (!function_block)
149 {
150 if (log)
151 log->Printf(" [CUE::SC] Null function block");
152 return;
153 }
154
155 clang::DeclContext *decl_context = function_block->GetClangDeclContext();
156
157 if (!decl_context)
158 {
159 if (log)
160 log->Printf(" [CUE::SC] Null decl context");
161 return;
162 }
163
164 if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
165 {
166 if (m_allow_cxx && method_decl->isInstance())
167 {
168 if (m_enforce_valid_object)
169 {
170 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
171
172 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
173
174 if (!variable_list_sp)
175 {
176 err.SetErrorString(thisErrorString);
177 return;
178 }
179
180 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
181
182 if (!this_var_sp ||
183 !this_var_sp->IsInScope(frame) ||
184 !this_var_sp->LocationIsValidForFrame (frame))
185 {
186 err.SetErrorString(thisErrorString);
187 return;
188 }
189 }
190
191 m_cplusplus = true;
192 m_needs_object_ptr = true;
193 }
194 }
195 else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
196 {
197 if (m_allow_objc)
198 {
199 if (m_enforce_valid_object)
200 {
201 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
202
203 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
204
205 if (!variable_list_sp)
206 {
207 err.SetErrorString(selfErrorString);
208 return;
209 }
210
211 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
212
213 if (!self_variable_sp ||
214 !self_variable_sp->IsInScope(frame) ||
215 !self_variable_sp->LocationIsValidForFrame (frame))
216 {
217 err.SetErrorString(selfErrorString);
218 return;
219 }
220 }
221
222 m_objectivec = true;
223 m_needs_object_ptr = true;
224
225 if (!method_decl->isInstanceMethod())
226 m_static_method = true;
227 }
228 }
229 else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
230 {
231 // We might also have a function that said in the debug information that it captured an
232 // object pointer. The best way to deal with getting to the ivars at present it by pretending
233 // that this is a method of a class in whatever runtime the debug info says the object pointer
234 // belongs to. Do that here.
235
236 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
237 if (metadata && metadata->HasObjectPtr())
238 {
239 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
240 if (language == lldb::eLanguageTypeC_plus_plus)
241 {
242 if (m_enforce_valid_object)
243 {
244 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
245
246 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";
247
248 if (!variable_list_sp)
249 {
250 err.SetErrorString(thisErrorString);
251 return;
252 }
253
254 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
255
256 if (!this_var_sp ||
257 !this_var_sp->IsInScope(frame) ||
258 !this_var_sp->LocationIsValidForFrame (frame))
259 {
260 err.SetErrorString(thisErrorString);
261 return;
262 }
263 }
264
265 m_cplusplus = true;
266 m_needs_object_ptr = true;
267 }
268 else if (language == lldb::eLanguageTypeObjC)
269 {
270 if (m_enforce_valid_object)
271 {
272 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
273
274 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";
275
276 if (!variable_list_sp)
277 {
278 err.SetErrorString(selfErrorString);
279 return;
280 }
281
282 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
283
284 if (!self_variable_sp ||
285 !self_variable_sp->IsInScope(frame) ||
286 !self_variable_sp->LocationIsValidForFrame (frame))
287 {
288 err.SetErrorString(selfErrorString);
289 return;
290 }
291
292 Type *self_type = self_variable_sp->GetType();
293
294 if (!self_type)
295 {
296 err.SetErrorString(selfErrorString);
297 return;
298 }
299
300 ClangASTType self_clang_type = self_type->GetClangForwardType();
301
302 if (!self_clang_type)
303 {
304 err.SetErrorString(selfErrorString);
305 return;
306 }
307
308 if (self_clang_type.IsObjCClassType())
309 {
310 return;
311 }
312 else if (self_clang_type.IsObjCObjectPointerType())
313 {
314 m_objectivec = true;
315 m_needs_object_ptr = true;
316 }
317 else
318 {
319 err.SetErrorString(selfErrorString);
320 return;
321 }
322 }
323 else
324 {
325 m_objectivec = true;
326 m_needs_object_ptr = true;
327 }
328 }
329 }
330 }
331 }
332
333 void
InstallContext(ExecutionContext & exe_ctx)334 ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
335 {
336 m_process_wp = exe_ctx.GetProcessSP();
337
338 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
339
340 if (frame_sp)
341 m_address = frame_sp->GetFrameCodeAddress();
342 }
343
344 bool
LockAndCheckContext(ExecutionContext & exe_ctx,lldb::TargetSP & target_sp,lldb::ProcessSP & process_sp,lldb::StackFrameSP & frame_sp)345 ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
346 lldb::TargetSP &target_sp,
347 lldb::ProcessSP &process_sp,
348 lldb::StackFrameSP &frame_sp)
349 {
350 lldb::ProcessSP expected_process_sp = m_process_wp.lock();
351 process_sp = exe_ctx.GetProcessSP();
352
353 if (process_sp != expected_process_sp)
354 return false;
355
356 process_sp = exe_ctx.GetProcessSP();
357 target_sp = exe_ctx.GetTargetSP();
358 frame_sp = exe_ctx.GetFrameSP();
359
360 if (m_address.IsValid())
361 {
362 if (!frame_sp)
363 return false;
364 else
365 return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
366 }
367
368 return true;
369 }
370
371 bool
MatchesContext(ExecutionContext & exe_ctx)372 ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
373 {
374 lldb::TargetSP target_sp;
375 lldb::ProcessSP process_sp;
376 lldb::StackFrameSP frame_sp;
377
378 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
379 }
380
381 // This is a really nasty hack, meant to fix Objective-C expressions of the form
382 // (int)[myArray count]. Right now, because the type information for count is
383 // not available, [myArray count] returns id, which can't be directly cast to
384 // int without causing a clang error.
385 static void
ApplyObjcCastHack(std::string & expr)386 ApplyObjcCastHack(std::string &expr)
387 {
388 #define OBJC_CAST_HACK_FROM "(int)["
389 #define OBJC_CAST_HACK_TO "(int)(long long)["
390
391 size_t from_offset;
392
393 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
394 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
395
396 #undef OBJC_CAST_HACK_TO
397 #undef OBJC_CAST_HACK_FROM
398 }
399
400 // Another hack, meant to allow use of unichar despite it not being available in
401 // the type information. Although we could special-case it in type lookup,
402 // hopefully we'll figure out a way to #include the same environment as is
403 // present in the original source file rather than try to hack specific type
404 // definitions in as needed.
405 static void
ApplyUnicharHack(std::string & expr)406 ApplyUnicharHack(std::string &expr)
407 {
408 #define UNICHAR_HACK_FROM "unichar"
409 #define UNICHAR_HACK_TO "unsigned short"
410
411 size_t from_offset;
412
413 while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
414 expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
415
416 #undef UNICHAR_HACK_TO
417 #undef UNICHAR_HACK_FROM
418 }
419
420 bool
Parse(Stream & error_stream,ExecutionContext & exe_ctx,lldb_private::ExecutionPolicy execution_policy,bool keep_result_in_memory)421 ClangUserExpression::Parse (Stream &error_stream,
422 ExecutionContext &exe_ctx,
423 lldb_private::ExecutionPolicy execution_policy,
424 bool keep_result_in_memory)
425 {
426 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
427
428 Error err;
429
430 InstallContext(exe_ctx);
431
432 ScanContext(exe_ctx, err);
433
434 if (!err.Success())
435 {
436 error_stream.Printf("warning: %s\n", err.AsCString());
437 }
438
439 StreamString m_transformed_stream;
440
441 ////////////////////////////////////
442 // Generate the expression
443 //
444
445 ApplyObjcCastHack(m_expr_text);
446 //ApplyUnicharHack(m_expr_text);
447
448 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
449
450 lldb::LanguageType lang_type;
451
452 if (m_cplusplus)
453 lang_type = lldb::eLanguageTypeC_plus_plus;
454 else if(m_objectivec)
455 lang_type = lldb::eLanguageTypeObjC;
456 else
457 lang_type = lldb::eLanguageTypeC;
458
459 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
460 {
461 error_stream.PutCString ("error: couldn't construct expression body");
462 return false;
463 }
464
465 if (log)
466 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
467
468 ////////////////////////////////////
469 // Set up the target and compiler
470 //
471
472 Target *target = exe_ctx.GetTargetPtr();
473
474 if (!target)
475 {
476 error_stream.PutCString ("error: invalid target\n");
477 return false;
478 }
479
480 //////////////////////////
481 // Parse the expression
482 //
483
484 m_materializer_ap.reset(new Materializer());
485
486 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
487
488 class OnExit
489 {
490 public:
491 typedef std::function <void (void)> Callback;
492
493 OnExit (Callback const &callback) :
494 m_callback(callback)
495 {
496 }
497
498 ~OnExit ()
499 {
500 m_callback();
501 }
502 private:
503 Callback m_callback;
504 };
505
506 OnExit on_exit([this]() { m_expr_decl_map.reset(); });
507
508 if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
509 {
510 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
511 return false;
512 }
513
514 Process *process = exe_ctx.GetProcessPtr();
515 ExecutionContextScope *exe_scope = process;
516
517 if (!exe_scope)
518 exe_scope = exe_ctx.GetTargetPtr();
519
520 ClangExpressionParser parser(exe_scope, *this);
521
522 unsigned num_errors = parser.Parse (error_stream);
523
524 if (num_errors)
525 {
526 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
527
528 m_expr_decl_map->DidParse();
529
530 return false;
531 }
532
533 //////////////////////////////////////////////////////////////////////////////////////////
534 // Prepare the output of the parser for execution, evaluating it statically if possible
535 //
536
537 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
538 m_jit_end_addr,
539 m_execution_unit_ap,
540 exe_ctx,
541 m_can_interpret,
542 execution_policy);
543
544 if (jit_error.Success())
545 {
546 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
547 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
548 return true;
549 }
550 else
551 {
552 const char *error_cstr = jit_error.AsCString();
553 if (error_cstr && error_cstr[0])
554 error_stream.Printf ("error: %s\n", error_cstr);
555 else
556 error_stream.Printf ("error: expression can't be interpreted or run\n");
557 return false;
558 }
559 }
560
561 static lldb::addr_t
GetObjectPointer(lldb::StackFrameSP frame_sp,ConstString & object_name,Error & err)562 GetObjectPointer (lldb::StackFrameSP frame_sp,
563 ConstString &object_name,
564 Error &err)
565 {
566 err.Clear();
567
568 if (!frame_sp)
569 {
570 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
571 return LLDB_INVALID_ADDRESS;
572 }
573
574 lldb::VariableSP var_sp;
575 lldb::ValueObjectSP valobj_sp;
576
577 valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
578 lldb::eNoDynamicValues,
579 StackFrame::eExpressionPathOptionCheckPtrVsMember ||
580 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
581 StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
582 StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
583 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
584 var_sp,
585 err);
586
587 if (!err.Success())
588 return LLDB_INVALID_ADDRESS;
589
590 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
591
592 if (ret == LLDB_INVALID_ADDRESS)
593 {
594 err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
595 return LLDB_INVALID_ADDRESS;
596 }
597
598 return ret;
599 }
600
601 bool
PrepareToExecuteJITExpression(Stream & error_stream,ExecutionContext & exe_ctx,lldb::addr_t & struct_address,lldb::addr_t & object_ptr,lldb::addr_t & cmd_ptr)602 ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
603 ExecutionContext &exe_ctx,
604 lldb::addr_t &struct_address,
605 lldb::addr_t &object_ptr,
606 lldb::addr_t &cmd_ptr)
607 {
608 lldb::TargetSP target;
609 lldb::ProcessSP process;
610 lldb::StackFrameSP frame;
611
612 if (!LockAndCheckContext(exe_ctx,
613 target,
614 process,
615 frame))
616 {
617 error_stream.Printf("The context has changed before we could JIT the expression!\n");
618 return false;
619 }
620
621 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
622 {
623 if (m_needs_object_ptr)
624 {
625 ConstString object_name;
626
627 if (m_cplusplus)
628 {
629 object_name.SetCString("this");
630 }
631 else if (m_objectivec)
632 {
633 object_name.SetCString("self");
634 }
635 else
636 {
637 error_stream.Printf("Need object pointer but don't know the language\n");
638 return false;
639 }
640
641 Error object_ptr_error;
642
643 object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
644
645 if (!object_ptr_error.Success())
646 {
647 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
648 object_ptr = 0;
649 }
650
651 if (m_objectivec)
652 {
653 ConstString cmd_name("_cmd");
654
655 cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
656
657 if (!object_ptr_error.Success())
658 {
659 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
660 cmd_ptr = 0;
661 }
662 }
663 }
664
665 if (m_materialized_address == LLDB_INVALID_ADDRESS)
666 {
667 Error alloc_error;
668
669 IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
670
671 m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
672 m_materializer_ap->GetStructAlignment(),
673 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
674 policy,
675 alloc_error);
676
677 if (!alloc_error.Success())
678 {
679 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
680 return false;
681 }
682 }
683
684 struct_address = m_materialized_address;
685
686 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
687 {
688 Error alloc_error;
689
690 const size_t stack_frame_size = 512 * 1024;
691
692 m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
693 8,
694 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
695 IRMemoryMap::eAllocationPolicyHostOnly,
696 alloc_error);
697
698 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
699
700 if (!alloc_error.Success())
701 {
702 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
703 return false;
704 }
705 }
706
707 Error materialize_error;
708
709 m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
710
711 if (!materialize_error.Success())
712 {
713 error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
714 return false;
715 }
716 }
717 return true;
718 }
719
720 ThreadPlan *
GetThreadPlanToExecuteJITExpression(Stream & error_stream,ExecutionContext & exe_ctx)721 ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
722 ExecutionContext &exe_ctx)
723 {
724 lldb::addr_t struct_address;
725
726 lldb::addr_t object_ptr = 0;
727 lldb::addr_t cmd_ptr = 0;
728
729 PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
730
731 // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
732 // ClangUserExpression resources before the thread plan finishes execution in the target. But because we are
733 // forcing unwind_on_error to be true here, in practical terms that can't happen.
734
735 const bool stop_others = true;
736 const bool unwind_on_error = true;
737 const bool ignore_breakpoints = false;
738 return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
739 m_jit_start_addr,
740 struct_address,
741 error_stream,
742 stop_others,
743 unwind_on_error,
744 ignore_breakpoints,
745 (m_needs_object_ptr ? &object_ptr : NULL),
746 (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
747 }
748
749 bool
FinalizeJITExecution(Stream & error_stream,ExecutionContext & exe_ctx,lldb::ClangExpressionVariableSP & result,lldb::addr_t function_stack_bottom,lldb::addr_t function_stack_top)750 ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
751 ExecutionContext &exe_ctx,
752 lldb::ClangExpressionVariableSP &result,
753 lldb::addr_t function_stack_bottom,
754 lldb::addr_t function_stack_top)
755 {
756 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
757
758 if (log)
759 log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
760
761 if (!m_dematerializer_sp)
762 {
763 error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
764 return false;
765 }
766
767 Error dematerialize_error;
768
769 m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
770
771 if (!dematerialize_error.Success())
772 {
773 error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
774 return false;
775 }
776
777 if (result)
778 result->TransferAddress();
779
780 m_dematerializer_sp.reset();
781
782 return true;
783 }
784
785 ExecutionResults
Execute(Stream & error_stream,ExecutionContext & exe_ctx,bool unwind_on_error,bool ignore_breakpoints,ClangUserExpression::ClangUserExpressionSP & shared_ptr_to_me,lldb::ClangExpressionVariableSP & result,bool run_others,uint32_t timeout_usec)786 ClangUserExpression::Execute (Stream &error_stream,
787 ExecutionContext &exe_ctx,
788 bool unwind_on_error,
789 bool ignore_breakpoints,
790 ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
791 lldb::ClangExpressionVariableSP &result,
792 bool run_others,
793 uint32_t timeout_usec)
794 {
795 // The expression log is quite verbose, and if you're just tracking the execution of the
796 // expression, it's quite convenient to have these logs come out with the STEP log as well.
797 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
798
799 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
800 {
801 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
802
803 lldb::addr_t object_ptr = 0;
804 lldb::addr_t cmd_ptr = 0;
805
806 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
807 {
808 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
809 return eExecutionSetupError;
810 }
811
812 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
813 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
814
815 if (m_can_interpret)
816 {
817 llvm::Module *module = m_execution_unit_ap->GetModule();
818 llvm::Function *function = m_execution_unit_ap->GetFunction();
819
820 if (!module || !function)
821 {
822 error_stream.Printf("Supposed to interpret, but nothing is there");
823 return eExecutionSetupError;
824 }
825
826 Error interpreter_error;
827
828 llvm::SmallVector <lldb::addr_t, 3> args;
829
830 if (m_needs_object_ptr)
831 {
832 args.push_back(object_ptr);
833
834 if (m_objectivec)
835 args.push_back(cmd_ptr);
836 }
837
838 args.push_back(struct_address);
839
840 function_stack_bottom = m_stack_frame_bottom;
841 function_stack_top = m_stack_frame_top;
842
843 IRInterpreter::Interpret (*module,
844 *function,
845 args,
846 *m_execution_unit_ap.get(),
847 interpreter_error,
848 function_stack_bottom,
849 function_stack_top);
850
851 if (!interpreter_error.Success())
852 {
853 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
854 return eExecutionDiscarded;
855 }
856 }
857 else
858 {
859 const bool stop_others = true;
860 const bool try_all_threads = run_others;
861
862 Address wrapper_address (m_jit_start_addr);
863 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
864 wrapper_address,
865 struct_address,
866 stop_others,
867 unwind_on_error,
868 ignore_breakpoints,
869 (m_needs_object_ptr ? &object_ptr : NULL),
870 ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
871 shared_ptr_to_me));
872
873 if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
874 return eExecutionSetupError;
875
876 lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
877
878 function_stack_bottom = function_stack_pointer - Host::GetPageSize();
879 function_stack_top = function_stack_pointer;
880
881 if (log)
882 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
883
884 if (exe_ctx.GetProcessPtr())
885 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
886
887 ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
888 call_plan_sp,
889 stop_others,
890 try_all_threads,
891 unwind_on_error,
892 ignore_breakpoints,
893 timeout_usec,
894 error_stream);
895
896 if (exe_ctx.GetProcessPtr())
897 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
898
899 if (log)
900 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
901
902 if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
903 {
904 const char *error_desc = NULL;
905
906 if (call_plan_sp)
907 {
908 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
909 if (real_stop_info_sp)
910 error_desc = real_stop_info_sp->GetDescription();
911 }
912 if (error_desc)
913 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
914 else
915 error_stream.Printf ("Execution was interrupted.");
916
917 if ((execution_result == eExecutionInterrupted && unwind_on_error)
918 || (execution_result == eExecutionHitBreakpoint && ignore_breakpoints))
919 error_stream.Printf ("\nThe process has been returned to the state before expression evaluation.");
920 else
921 error_stream.Printf ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
922
923 return execution_result;
924 }
925 else if (execution_result != eExecutionCompleted)
926 {
927 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
928 return execution_result;
929 }
930 }
931
932 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
933 {
934 return eExecutionCompleted;
935 }
936 else
937 {
938 return eExecutionSetupError;
939 }
940 }
941 else
942 {
943 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
944 return eExecutionSetupError;
945 }
946 }
947
948 ExecutionResults
Evaluate(ExecutionContext & exe_ctx,lldb_private::ExecutionPolicy execution_policy,lldb::LanguageType language,ResultType desired_type,bool unwind_on_error,bool ignore_breakpoints,const char * expr_cstr,const char * expr_prefix,lldb::ValueObjectSP & result_valobj_sp,bool run_others,uint32_t timeout_usec)949 ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
950 lldb_private::ExecutionPolicy execution_policy,
951 lldb::LanguageType language,
952 ResultType desired_type,
953 bool unwind_on_error,
954 bool ignore_breakpoints,
955 const char *expr_cstr,
956 const char *expr_prefix,
957 lldb::ValueObjectSP &result_valobj_sp,
958 bool run_others,
959 uint32_t timeout_usec)
960 {
961 Error error;
962 return EvaluateWithError (exe_ctx,
963 execution_policy,
964 language,
965 desired_type,
966 unwind_on_error,
967 ignore_breakpoints,
968 expr_cstr,
969 expr_prefix,
970 result_valobj_sp,
971 error,
972 run_others,
973 timeout_usec);
974 }
975
976 ExecutionResults
EvaluateWithError(ExecutionContext & exe_ctx,lldb_private::ExecutionPolicy execution_policy,lldb::LanguageType language,ResultType desired_type,bool unwind_on_error,bool ignore_breakpoints,const char * expr_cstr,const char * expr_prefix,lldb::ValueObjectSP & result_valobj_sp,Error & error,bool run_others,uint32_t timeout_usec)977 ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
978 lldb_private::ExecutionPolicy execution_policy,
979 lldb::LanguageType language,
980 ResultType desired_type,
981 bool unwind_on_error,
982 bool ignore_breakpoints,
983 const char *expr_cstr,
984 const char *expr_prefix,
985 lldb::ValueObjectSP &result_valobj_sp,
986 Error &error,
987 bool run_others,
988 uint32_t timeout_usec)
989 {
990 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
991
992 ExecutionResults execution_results = eExecutionSetupError;
993
994 Process *process = exe_ctx.GetProcessPtr();
995
996 if (process == NULL || process->GetState() != lldb::eStateStopped)
997 {
998 if (execution_policy == eExecutionPolicyAlways)
999 {
1000 if (log)
1001 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
1002
1003 error.SetErrorString ("expression needed to run but couldn't");
1004
1005 return execution_results;
1006 }
1007 }
1008
1009 if (process == NULL || !process->CanJIT())
1010 execution_policy = eExecutionPolicyNever;
1011
1012 ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
1013
1014 StreamString error_stream;
1015
1016 if (log)
1017 log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
1018
1019 const bool keep_expression_in_memory = true;
1020
1021 if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
1022 {
1023 if (error_stream.GetString().empty())
1024 error.SetErrorString ("expression failed to parse, unknown error");
1025 else
1026 error.SetErrorString (error_stream.GetString().c_str());
1027 }
1028 else
1029 {
1030 lldb::ClangExpressionVariableSP expr_result;
1031
1032 if (execution_policy == eExecutionPolicyNever &&
1033 !user_expression_sp->CanInterpret())
1034 {
1035 if (log)
1036 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
1037
1038 if (error_stream.GetString().empty())
1039 error.SetErrorString ("expression needed to run but couldn't");
1040 }
1041 else
1042 {
1043 error_stream.GetString().clear();
1044
1045 if (log)
1046 log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
1047
1048 execution_results = user_expression_sp->Execute (error_stream,
1049 exe_ctx,
1050 unwind_on_error,
1051 ignore_breakpoints,
1052 user_expression_sp,
1053 expr_result,
1054 run_others,
1055 timeout_usec);
1056
1057 if (execution_results != eExecutionCompleted)
1058 {
1059 if (log)
1060 log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
1061
1062 if (error_stream.GetString().empty())
1063 error.SetErrorString ("expression failed to execute, unknown error");
1064 else
1065 error.SetErrorString (error_stream.GetString().c_str());
1066 }
1067 else
1068 {
1069 if (expr_result)
1070 {
1071 result_valobj_sp = expr_result->GetValueObject();
1072
1073 if (log)
1074 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
1075 }
1076 else
1077 {
1078 if (log)
1079 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
1080
1081 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
1082 }
1083 }
1084 }
1085 }
1086
1087 if (result_valobj_sp.get() == NULL)
1088 result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
1089
1090 return execution_results;
1091 }
1092