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