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