blob: 1537e031d379dbf8ec6af1421cc15d64f104d526 [file] [log] [blame]
Jim Ingham151c0322015-09-15 21:13:50 +00001//===-- UserExpression.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"
Jim Ingham151c0322015-09-15 21:13:50 +000025#include "lldb/Expression/ExpressionSourceCode.h"
26#include "lldb/Expression/IRExecutionUnit.h"
27#include "lldb/Expression/IRInterpreter.h"
28#include "lldb/Expression/Materializer.h"
29#include "lldb/Expression/UserExpression.h"
Sean Callanan4dbb2712015-09-25 20:35:58 +000030#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
Jim Ingham151c0322015-09-15 21:13:50 +000031#include "lldb/Host/HostInfo.h"
32#include "lldb/Symbol/Block.h"
Jim Ingham151c0322015-09-15 21:13:50 +000033#include "lldb/Symbol/Function.h"
34#include "lldb/Symbol/ObjectFile.h"
35#include "lldb/Symbol/SymbolVendor.h"
36#include "lldb/Symbol/Type.h"
Jim Ingham151c0322015-09-15 21:13:50 +000037#include "lldb/Symbol/VariableList.h"
38#include "lldb/Target/ExecutionContext.h"
39#include "lldb/Target/Process.h"
40#include "lldb/Target/StackFrame.h"
41#include "lldb/Target/Target.h"
42#include "lldb/Target/ThreadPlan.h"
43#include "lldb/Target/ThreadPlanCallUserExpression.h"
44
Jim Ingham151c0322015-09-15 21:13:50 +000045using namespace lldb_private;
46
47UserExpression::UserExpression (ExecutionContextScope &exe_scope,
48 const char *expr,
49 const char *expr_prefix,
50 lldb::LanguageType language,
51 ResultType desired_type) :
52 Expression (exe_scope),
53 m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
54 m_stack_frame_top (LLDB_INVALID_ADDRESS),
55 m_expr_text (expr),
56 m_expr_prefix (expr_prefix ? expr_prefix : ""),
57 m_language (language),
58 m_transformed_text (),
59 m_desired_type (desired_type),
60 m_execution_unit_sp(),
61 m_materializer_ap(),
62 m_jit_module_wp(),
63 m_enforce_valid_object (true),
64 m_in_cplusplus_method (false),
65 m_in_objectivec_method (false),
66 m_in_static_method(false),
67 m_needs_object_ptr (false),
68 m_const_object (false),
69 m_target (NULL),
70 m_can_interpret (false),
71 m_materialized_address (LLDB_INVALID_ADDRESS)
72{
73}
74
75UserExpression::~UserExpression ()
76{
77 if (m_target)
78 {
79 lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
80 if (jit_module_sp)
81 m_target->GetImages().Remove(jit_module_sp);
82 }
83}
84
85void
86UserExpression::InstallContext (ExecutionContext &exe_ctx)
87{
88 m_jit_process_wp = exe_ctx.GetProcessSP();
89
90 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
91
92 if (frame_sp)
93 m_address = frame_sp->GetFrameCodeAddress();
94}
95
96bool
97UserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
98 lldb::TargetSP &target_sp,
99 lldb::ProcessSP &process_sp,
100 lldb::StackFrameSP &frame_sp)
101{
102 lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock();
103 process_sp = exe_ctx.GetProcessSP();
104
105 if (process_sp != expected_process_sp)
106 return false;
107
108 process_sp = exe_ctx.GetProcessSP();
109 target_sp = exe_ctx.GetTargetSP();
110 frame_sp = exe_ctx.GetFrameSP();
111
112 if (m_address.IsValid())
113 {
114 if (!frame_sp)
115 return false;
116 else
117 return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
118 }
119
120 return true;
121}
122
123bool
124UserExpression::MatchesContext (ExecutionContext &exe_ctx)
125{
126 lldb::TargetSP target_sp;
127 lldb::ProcessSP process_sp;
128 lldb::StackFrameSP frame_sp;
129
130 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
131}
132
133lldb::addr_t
134UserExpression::GetObjectPointer (lldb::StackFrameSP frame_sp,
135 ConstString &object_name,
136 Error &err)
137{
138 err.Clear();
139
140 if (!frame_sp)
141 {
142 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
143 return LLDB_INVALID_ADDRESS;
144 }
145
146 lldb::VariableSP var_sp;
147 lldb::ValueObjectSP valobj_sp;
148
149 valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
150 lldb::eNoDynamicValues,
151 StackFrame::eExpressionPathOptionCheckPtrVsMember |
152 StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
153 StackFrame::eExpressionPathOptionsNoSyntheticChildren |
154 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
155 var_sp,
156 err);
157
158 if (!err.Success() || !valobj_sp.get())
159 return LLDB_INVALID_ADDRESS;
160
161 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
162
163 if (ret == LLDB_INVALID_ADDRESS)
164 {
165 err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
166 return LLDB_INVALID_ADDRESS;
167 }
168
169 return ret;
170}
171
172bool
173UserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
174 ExecutionContext &exe_ctx,
175 lldb::addr_t &struct_address)
176{
177 lldb::TargetSP target;
178 lldb::ProcessSP process;
179 lldb::StackFrameSP frame;
180
181 if (!LockAndCheckContext(exe_ctx,
182 target,
183 process,
184 frame))
185 {
186 error_stream.Printf("The context has changed before we could JIT the expression!\n");
187 return false;
188 }
189
190 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
191 {
192 if (m_materialized_address == LLDB_INVALID_ADDRESS)
193 {
194 Error alloc_error;
195
196 IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
197
198 m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
199 m_materializer_ap->GetStructAlignment(),
200 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
201 policy,
202 alloc_error);
203
204 if (!alloc_error.Success())
205 {
206 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
207 return false;
208 }
209 }
210
211 struct_address = m_materialized_address;
212
213 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
214 {
215 Error alloc_error;
216
217 const size_t stack_frame_size = 512 * 1024;
218
219 m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
220 8,
221 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
222 IRMemoryMap::eAllocationPolicyHostOnly,
223 alloc_error);
224
225 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
226
227 if (!alloc_error.Success())
228 {
229 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
230 return false;
231 }
232 }
233
234 Error materialize_error;
235
236 m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
237
238 if (!materialize_error.Success())
239 {
240 error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
241 return false;
242 }
243 }
244 return true;
245}
246
247bool
248UserExpression::FinalizeJITExecution (Stream &error_stream,
249 ExecutionContext &exe_ctx,
250 lldb::ExpressionVariableSP &result,
251 lldb::addr_t function_stack_bottom,
252 lldb::addr_t function_stack_top)
253{
254 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
255
256 if (log)
257 log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing after execution --");
258
259 if (!m_dematerializer_sp)
260 {
261 error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
262 return false;
263 }
264
265 Error dematerialize_error;
266
267 m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
268
269 if (!dematerialize_error.Success())
270 {
271 error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
272 return false;
273 }
274
275 if (result)
276 result->TransferAddress();
277
278 m_dematerializer_sp.reset();
279
280 return true;
281}
282
283lldb::ExpressionResults
284UserExpression::Execute (Stream &error_stream,
285 ExecutionContext &exe_ctx,
286 const EvaluateExpressionOptions& options,
287 lldb::UserExpressionSP &shared_ptr_to_me,
288 lldb::ExpressionVariableSP &result)
289{
290 // The expression log is quite verbose, and if you're just tracking the execution of the
291 // expression, it's quite convenient to have these logs come out with the STEP log as well.
292 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
293
294 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
295 {
296 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
297
298 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address))
299 {
300 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
301 return lldb::eExpressionSetupError;
302 }
303
304 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
305 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
306
307 if (m_can_interpret)
308 {
309 llvm::Module *module = m_execution_unit_sp->GetModule();
310 llvm::Function *function = m_execution_unit_sp->GetFunction();
311
312 if (!module || !function)
313 {
314 error_stream.Printf("Supposed to interpret, but nothing is there");
315 return lldb::eExpressionSetupError;
316 }
317
318 Error interpreter_error;
319
320 std::vector<lldb::addr_t> args;
321
322 if (!AddInitialArguments(exe_ctx, args, error_stream))
323 {
324 error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__);
325 return lldb::eExpressionSetupError;
326 }
327
328 args.push_back(struct_address);
329
330 function_stack_bottom = m_stack_frame_bottom;
331 function_stack_top = m_stack_frame_top;
332
333 IRInterpreter::Interpret (*module,
334 *function,
335 args,
336 *m_execution_unit_sp.get(),
337 interpreter_error,
338 function_stack_bottom,
339 function_stack_top,
340 exe_ctx);
341
342 if (!interpreter_error.Success())
343 {
344 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
345 return lldb::eExpressionDiscarded;
346 }
347 }
348 else
349 {
350 if (!exe_ctx.HasThreadScope())
351 {
352 error_stream.Printf("UserExpression::Execute called with no thread selected.");
353 return lldb::eExpressionSetupError;
354 }
355
356 Address wrapper_address (m_jit_start_addr);
357
358 std::vector<lldb::addr_t> args;
359
360 if (!AddInitialArguments(exe_ctx, args, error_stream))
361 {
362 error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__);
363 return lldb::eExpressionSetupError;
364 }
365
366 args.push_back(struct_address);
367
368 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
369 wrapper_address,
370 args,
371 options,
372 shared_ptr_to_me));
373
374 if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
375 return lldb::eExpressionSetupError;
376
377 ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
378
379 lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer();
380
381 function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
382 function_stack_top = function_stack_pointer;
383
384 if (log)
385 log->Printf("-- [UserExpression::Execute] Execution of expression begins --");
386
387 if (exe_ctx.GetProcessPtr())
388 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
389
390 lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
391 call_plan_sp,
392 options,
393 error_stream);
394
395 if (exe_ctx.GetProcessPtr())
396 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
397
398 if (log)
399 log->Printf("-- [UserExpression::Execute] Execution of expression completed --");
400
401 if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint)
402 {
403 const char *error_desc = NULL;
404
405 if (call_plan_sp)
406 {
407 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
408 if (real_stop_info_sp)
409 error_desc = real_stop_info_sp->GetDescription();
410 }
411 if (error_desc)
412 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
413 else
414 error_stream.PutCString ("Execution was interrupted.");
415
416 if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError())
417 || (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints()))
418 error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
419 else
420 {
421 if (execution_result == lldb::eExpressionHitBreakpoint)
422 user_expression_plan->TransferExpressionOwnership();
423 error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
424 "use \"thread return -x\" to return to the state before expression evaluation.");
425 }
426
427 return execution_result;
428 }
429 else if (execution_result == lldb::eExpressionStoppedForDebug)
430 {
431 error_stream.PutCString ("Execution was halted at the first instruction of the expression "
432 "function because \"debug\" was requested.\n"
433 "Use \"thread return -x\" to return to the state before expression evaluation.");
434 return execution_result;
435 }
436 else if (execution_result != lldb::eExpressionCompleted)
437 {
438 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
439 return execution_result;
440 }
441 }
442
443 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
444 {
445 return lldb::eExpressionCompleted;
446 }
447 else
448 {
449 return lldb::eExpressionResultUnavailable;
450 }
451 }
452 else
453 {
454 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
455 return lldb::eExpressionSetupError;
456 }
457}
458
459lldb::ExpressionResults
460UserExpression::Evaluate (ExecutionContext &exe_ctx,
461 const EvaluateExpressionOptions& options,
462 const char *expr_cstr,
463 const char *expr_prefix,
464 lldb::ValueObjectSP &result_valobj_sp,
465 Error &error)
466{
467 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
468
469 lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
470 const lldb::LanguageType language = options.GetLanguage();
471 const ResultType desired_type = options.DoesCoerceToId() ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny;
472 lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
473
474 Target *target = exe_ctx.GetTargetPtr();
475 if (!target)
476 {
477 if (log)
478 log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't run expressions.");
479 return lldb::eExpressionSetupError;
480 }
481
482 Process *process = exe_ctx.GetProcessPtr();
483
484 if (process == NULL || process->GetState() != lldb::eStateStopped)
485 {
486 if (execution_policy == eExecutionPolicyAlways)
487 {
488 if (log)
489 log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
490
491 error.SetErrorString ("expression needed to run but couldn't");
492
493 return execution_results;
494 }
495 }
496
497 if (process == NULL || !process->CanJIT())
498 execution_policy = eExecutionPolicyNever;
499
500 const char *full_prefix = NULL;
501 const char *option_prefix = options.GetPrefix();
502 std::string full_prefix_storage;
503 if (expr_prefix && option_prefix)
504 {
505 full_prefix_storage.assign(expr_prefix);
506 full_prefix_storage.append(option_prefix);
507 if (!full_prefix_storage.empty())
508 full_prefix = full_prefix_storage.c_str();
509 }
510 else if (expr_prefix)
511 full_prefix = expr_prefix;
512 else
513 full_prefix = option_prefix;
514
515 lldb::UserExpressionSP user_expression_sp(target->GetUserExpressionForLanguage (expr_cstr,
516 full_prefix,
517 language,
518 desired_type,
519 error));
520 if (error.Fail())
521 {
522 if (log)
523 log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString());
524 return lldb::eExpressionSetupError;
525 }
526
527 StreamString error_stream;
528
529 if (log)
530 log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
531
532 const bool keep_expression_in_memory = true;
533 const bool generate_debug_info = options.GetGenerateDebugInfo();
534
535 if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
536 {
537 error.SetErrorString ("expression interrupted by callback before parse");
538 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
539 return lldb::eExpressionInterrupted;
540 }
541
542 if (!user_expression_sp->Parse (error_stream,
543 exe_ctx,
544 execution_policy,
545 keep_expression_in_memory,
546 generate_debug_info))
547 {
548 execution_results = lldb::eExpressionParseError;
549 if (error_stream.GetString().empty())
550 error.SetExpressionError (execution_results, "expression failed to parse, unknown error");
551 else
552 error.SetExpressionError (execution_results, error_stream.GetString().c_str());
553 }
554 else
555 {
556 lldb::ExpressionVariableSP expr_result;
557
558 if (execution_policy == eExecutionPolicyNever &&
559 !user_expression_sp->CanInterpret())
560 {
561 if (log)
562 log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
563
564 if (error_stream.GetString().empty())
565 error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
566 }
567 else
568 {
569 if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
570 {
571 error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
572 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
573 return lldb::eExpressionInterrupted;
574 }
575
576 error_stream.GetString().clear();
577
578 if (log)
579 log->Printf("== [UserExpression::Evaluate] Executing expression ==");
580
581 execution_results = user_expression_sp->Execute (error_stream,
582 exe_ctx,
583 options,
584 user_expression_sp,
585 expr_result);
586
587 if (options.GetResultIsInternal() && expr_result && process)
588 {
589 process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result);
590 }
591
592 if (execution_results != lldb::eExpressionCompleted)
593 {
594 if (log)
595 log->Printf("== [UserExpression::Evaluate] Execution completed abnormally ==");
596
597 if (error_stream.GetString().empty())
598 error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
599 else
600 error.SetExpressionError (execution_results, error_stream.GetString().c_str());
601 }
602 else
603 {
604 if (expr_result)
605 {
606 result_valobj_sp = expr_result->GetValueObject();
607
608 if (log)
609 log->Printf("== [UserExpression::Evaluate] Execution completed normally with result %s ==",
610 result_valobj_sp->GetValueAsCString());
611 }
612 else
613 {
614 if (log)
615 log->Printf("== [UserExpression::Evaluate] Execution completed normally with no result ==");
616
617 error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
618 }
619 }
620 }
621 }
622
623 if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
624 {
625 error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
626 return lldb::eExpressionInterrupted;
627 }
628
629 if (result_valobj_sp.get() == NULL)
630 {
631 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
632 }
633
634 return execution_results;
635}