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