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