blob: fc32bfbd37a20ce7f15224a9a82b47deef0dca0a [file] [log] [blame]
Ryan Brown998c8a1c12015-11-02 19:30:40 +00001//===-- LLVMUserExpression.cpp ----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12
13// Project includes
14#include "lldb/Expression/LLVMUserExpression.h"
Ryan Brown998c8a1c12015-11-02 19:30:40 +000015#include "lldb/Core/Module.h"
16#include "lldb/Core/StreamFile.h"
Ryan Brown998c8a1c12015-11-02 19:30:40 +000017#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan579e70c2016-03-19 00:03:59 +000018#include "lldb/Expression/DiagnosticManager.h"
Ryan Brown998c8a1c12015-11-02 19:30:40 +000019#include "lldb/Expression/ExpressionSourceCode.h"
20#include "lldb/Expression/IRExecutionUnit.h"
21#include "lldb/Expression/IRInterpreter.h"
22#include "lldb/Expression/Materializer.h"
23#include "lldb/Host/HostInfo.h"
24#include "lldb/Symbol/Block.h"
25#include "lldb/Symbol/ClangASTContext.h"
Sean Callanan579e70c2016-03-19 00:03:59 +000026#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Ryan Brown998c8a1c12015-11-02 19:30:40 +000027#include "lldb/Symbol/Function.h"
28#include "lldb/Symbol/ObjectFile.h"
29#include "lldb/Symbol/SymbolVendor.h"
30#include "lldb/Symbol/Type.h"
Ryan Brown998c8a1c12015-11-02 19:30:40 +000031#include "lldb/Symbol/VariableList.h"
32#include "lldb/Target/ExecutionContext.h"
33#include "lldb/Target/Process.h"
34#include "lldb/Target/StackFrame.h"
35#include "lldb/Target/Target.h"
36#include "lldb/Target/ThreadPlan.h"
37#include "lldb/Target/ThreadPlanCallUserExpression.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000038#include "lldb/Utility/ConstString.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000039#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000040#include "lldb/Utility/StreamString.h"
Ryan Brown998c8a1c12015-11-02 19:30:40 +000041
42using namespace lldb_private;
43
Kate Stoneb9c1b512016-09-06 20:57:50 +000044LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope,
Zachary Turnerc5d7df92016-11-08 04:52:16 +000045 llvm::StringRef expr,
46 llvm::StringRef prefix,
Kate Stoneb9c1b512016-09-06 20:57:50 +000047 lldb::LanguageType language,
48 ResultType desired_type,
Jim Ingham19a63fc2015-11-03 02:11:24 +000049 const EvaluateExpressionOptions &options)
Zachary Turnerc5d7df92016-11-08 04:52:16 +000050 : UserExpression(exe_scope, expr, prefix, language, desired_type, options),
Ryan Brown998c8a1c12015-11-02 19:30:40 +000051 m_stack_frame_bottom(LLDB_INVALID_ADDRESS),
Bruce Mitcheneref4536c2017-03-23 09:52:26 +000052 m_stack_frame_top(LLDB_INVALID_ADDRESS),
Jason Molendaab2dae02017-03-21 02:59:15 +000053 m_allow_cxx(false),
54 m_allow_objc(false),
Bruce Mitcheneref4536c2017-03-23 09:52:26 +000055 m_transformed_text(),
Kate Stoneb9c1b512016-09-06 20:57:50 +000056 m_execution_unit_sp(), m_materializer_ap(), m_jit_module_wp(),
57 m_enforce_valid_object(true), m_in_cplusplus_method(false),
58 m_in_objectivec_method(false), m_in_static_method(false),
59 m_needs_object_ptr(false), m_target(NULL), m_can_interpret(false),
60 m_materialized_address(LLDB_INVALID_ADDRESS) {}
Ryan Brown998c8a1c12015-11-02 19:30:40 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062LLVMUserExpression::~LLVMUserExpression() {
63 if (m_target) {
64 lldb::ModuleSP jit_module_sp(m_jit_module_wp.lock());
65 if (jit_module_sp)
66 m_target->GetImages().Remove(jit_module_sp);
67 }
Ryan Brown998c8a1c12015-11-02 19:30:40 +000068}
69
70lldb::ExpressionResults
Kate Stoneb9c1b512016-09-06 20:57:50 +000071LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
72 ExecutionContext &exe_ctx,
73 const EvaluateExpressionOptions &options,
74 lldb::UserExpressionSP &shared_ptr_to_me,
75 lldb::ExpressionVariableSP &result) {
76 // The expression log is quite verbose, and if you're just tracking the
Adrian Prantl05097242018-04-30 16:49:04 +000077 // execution of the expression, it's quite convenient to have these logs come
78 // out with the STEP log as well.
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
80 LIBLLDB_LOG_STEP));
Ryan Brown998c8a1c12015-11-02 19:30:40 +000081
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) {
83 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
Ryan Brown998c8a1c12015-11-02 19:30:40 +000084
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 if (!PrepareToExecuteJITExpression(diagnostic_manager, exe_ctx,
86 struct_address)) {
87 diagnostic_manager.Printf(
88 eDiagnosticSeverityError,
89 "errored out in %s, couldn't PrepareToExecuteJITExpression",
90 __FUNCTION__);
91 return lldb::eExpressionSetupError;
Ryan Brown998c8a1c12015-11-02 19:30:40 +000092 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000093
94 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
95 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
96
97 if (m_can_interpret) {
98 llvm::Module *module = m_execution_unit_sp->GetModule();
99 llvm::Function *function = m_execution_unit_sp->GetFunction();
100
101 if (!module || !function) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000102 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 eDiagnosticSeverityError,
104 "supposed to interpret, but nothing is there");
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000105 return lldb::eExpressionSetupError;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106 }
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000107
Zachary Turner97206d52017-05-12 04:51:55 +0000108 Status interpreter_error;
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 std::vector<lldb::addr_t> args;
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000111
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112 if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) {
Sean Callanan579e70c2016-03-19 00:03:59 +0000113 diagnostic_manager.Printf(eDiagnosticSeverityError,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 "errored out in %s, couldn't AddArguments",
115 __FUNCTION__);
116 return lldb::eExpressionSetupError;
117 }
118
119 function_stack_bottom = m_stack_frame_bottom;
120 function_stack_top = m_stack_frame_top;
121
122 IRInterpreter::Interpret(*module, *function, args,
123 *m_execution_unit_sp.get(), interpreter_error,
124 function_stack_bottom, function_stack_top,
125 exe_ctx);
126
127 if (!interpreter_error.Success()) {
128 diagnostic_manager.Printf(eDiagnosticSeverityError,
129 "supposed to interpret, but failed: %s",
130 interpreter_error.AsCString());
131 return lldb::eExpressionDiscarded;
132 }
133 } else {
134 if (!exe_ctx.HasThreadScope()) {
135 diagnostic_manager.Printf(eDiagnosticSeverityError,
136 "%s called with no thread selected",
137 __FUNCTION__);
138 return lldb::eExpressionSetupError;
139 }
140
141 Address wrapper_address(m_jit_start_addr);
142
143 std::vector<lldb::addr_t> args;
144
145 if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) {
146 diagnostic_manager.Printf(eDiagnosticSeverityError,
147 "errored out in %s, couldn't AddArguments",
148 __FUNCTION__);
149 return lldb::eExpressionSetupError;
150 }
151
152 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression(
153 exe_ctx.GetThreadRef(), wrapper_address, args, options,
154 shared_ptr_to_me));
155
156 StreamString ss;
157 if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) {
Zachary Turnerc1564272016-11-16 21:15:24 +0000158 diagnostic_manager.PutString(eDiagnosticSeverityError, ss.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 return lldb::eExpressionSetupError;
160 }
161
162 ThreadPlanCallUserExpression *user_expression_plan =
163 static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
164
165 lldb::addr_t function_stack_pointer =
166 user_expression_plan->GetFunctionStackPointer();
167
168 function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
169 function_stack_top = function_stack_pointer;
170
171 if (log)
172 log->Printf(
173 "-- [UserExpression::Execute] Execution of expression begins --");
174
175 if (exe_ctx.GetProcessPtr())
176 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
177
178 lldb::ExpressionResults execution_result =
179 exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options,
180 diagnostic_manager);
181
182 if (exe_ctx.GetProcessPtr())
183 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
184
185 if (log)
186 log->Printf("-- [UserExpression::Execute] Execution of expression "
187 "completed --");
188
189 if (execution_result == lldb::eExpressionInterrupted ||
190 execution_result == lldb::eExpressionHitBreakpoint) {
191 const char *error_desc = NULL;
192
193 if (call_plan_sp) {
194 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
195 if (real_stop_info_sp)
196 error_desc = real_stop_info_sp->GetDescription();
197 }
198 if (error_desc)
199 diagnostic_manager.Printf(eDiagnosticSeverityError,
200 "Execution was interrupted, reason: %s.",
201 error_desc);
202 else
Zachary Turnere2411fa2016-11-12 19:12:56 +0000203 diagnostic_manager.PutString(eDiagnosticSeverityError,
204 "Execution was interrupted.");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205
206 if ((execution_result == lldb::eExpressionInterrupted &&
207 options.DoesUnwindOnError()) ||
208 (execution_result == lldb::eExpressionHitBreakpoint &&
209 options.DoesIgnoreBreakpoints()))
210 diagnostic_manager.AppendMessageToDiagnostic(
211 "The process has been returned to the state before expression "
212 "evaluation.");
213 else {
214 if (execution_result == lldb::eExpressionHitBreakpoint)
215 user_expression_plan->TransferExpressionOwnership();
216 diagnostic_manager.AppendMessageToDiagnostic(
217 "The process has been left at the point where it was "
218 "interrupted, "
219 "use \"thread return -x\" to return to the state before "
220 "expression evaluation.");
221 }
222
223 return execution_result;
224 } else if (execution_result == lldb::eExpressionStoppedForDebug) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000225 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226 eDiagnosticSeverityRemark,
227 "Execution was halted at the first instruction of the expression "
228 "function because \"debug\" was requested.\n"
229 "Use \"thread return -x\" to return to the state before expression "
230 "evaluation.");
231 return execution_result;
232 } else if (execution_result != lldb::eExpressionCompleted) {
233 diagnostic_manager.Printf(
234 eDiagnosticSeverityError,
235 "Couldn't execute function; result was %s",
236 Process::ExecutionResultAsCString(execution_result));
237 return execution_result;
238 }
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000239 }
240
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241 if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result,
242 function_stack_bottom, function_stack_top)) {
243 return lldb::eExpressionCompleted;
244 } else {
245 return lldb::eExpressionResultUnavailable;
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000246 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247 } else {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000248 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249 eDiagnosticSeverityError,
250 "Expression can't be run, because there is no JIT compiled function");
251 return lldb::eExpressionSetupError;
252 }
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000253}
254
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255bool LLVMUserExpression::FinalizeJITExecution(
256 DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
257 lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom,
258 lldb::addr_t function_stack_top) {
259 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000260
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261 if (log)
262 log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing "
263 "after execution --");
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000264
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265 if (!m_dematerializer_sp) {
266 diagnostic_manager.Printf(eDiagnosticSeverityError,
267 "Couldn't apply expression side effects : no "
268 "dematerializer is present");
269 return false;
270 }
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000271
Zachary Turner97206d52017-05-12 04:51:55 +0000272 Status dematerialize_error;
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000273
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 m_dematerializer_sp->Dematerialize(dematerialize_error, function_stack_bottom,
275 function_stack_top);
Jim Ingham2c381412015-11-04 20:32:27 +0000276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 if (!dematerialize_error.Success()) {
278 diagnostic_manager.Printf(eDiagnosticSeverityError,
279 "Couldn't apply expression side effects : %s",
280 dematerialize_error.AsCString("unknown error"));
281 return false;
282 }
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000283
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 result =
285 GetResultAfterDematerialization(exe_ctx.GetBestExecutionContextScope());
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000286
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287 if (result)
288 result->TransferAddress();
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000289
Kate Stoneb9c1b512016-09-06 20:57:50 +0000290 m_dematerializer_sp.reset();
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000291
Kate Stoneb9c1b512016-09-06 20:57:50 +0000292 return true;
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000293}
294
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295bool LLVMUserExpression::PrepareToExecuteJITExpression(
296 DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
297 lldb::addr_t &struct_address) {
298 lldb::TargetSP target;
299 lldb::ProcessSP process;
300 lldb::StackFrameSP frame;
301
302 if (!LockAndCheckContext(exe_ctx, target, process, frame)) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000303 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000304 eDiagnosticSeverityError,
305 "The context has changed before we could JIT the expression!");
306 return false;
307 }
308
309 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) {
310 if (m_materialized_address == LLDB_INVALID_ADDRESS) {
Zachary Turner97206d52017-05-12 04:51:55 +0000311 Status alloc_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000312
313 IRMemoryMap::AllocationPolicy policy =
314 m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly
315 : IRMemoryMap::eAllocationPolicyMirror;
316
317 const bool zero_memory = false;
318
319 m_materialized_address = m_execution_unit_sp->Malloc(
320 m_materializer_ap->GetStructByteSize(),
321 m_materializer_ap->GetStructAlignment(),
322 lldb::ePermissionsReadable | lldb::ePermissionsWritable, policy,
323 zero_memory, alloc_error);
324
325 if (!alloc_error.Success()) {
326 diagnostic_manager.Printf(
327 eDiagnosticSeverityError,
328 "Couldn't allocate space for materialized struct: %s",
329 alloc_error.AsCString());
330 return false;
331 }
332 }
333
334 struct_address = m_materialized_address;
335
336 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) {
Zachary Turner97206d52017-05-12 04:51:55 +0000337 Status alloc_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338
339 const size_t stack_frame_size = 512 * 1024;
340
341 const bool zero_memory = false;
342
343 m_stack_frame_bottom = m_execution_unit_sp->Malloc(
344 stack_frame_size, 8,
345 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
346 IRMemoryMap::eAllocationPolicyHostOnly, zero_memory, alloc_error);
347
348 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
349
350 if (!alloc_error.Success()) {
351 diagnostic_manager.Printf(
352 eDiagnosticSeverityError,
353 "Couldn't allocate space for the stack frame: %s",
354 alloc_error.AsCString());
355 return false;
356 }
357 }
358
Zachary Turner97206d52017-05-12 04:51:55 +0000359 Status materialize_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360
361 m_dematerializer_sp = m_materializer_ap->Materialize(
362 frame, *m_execution_unit_sp, struct_address, materialize_error);
363
364 if (!materialize_error.Success()) {
365 diagnostic_manager.Printf(eDiagnosticSeverityError,
366 "Couldn't materialize: %s",
367 materialize_error.AsCString());
368 return false;
369 }
370 }
371 return true;
372}
373
374lldb::ModuleSP LLVMUserExpression::GetJITModule() {
375 if (m_execution_unit_sp)
376 return m_execution_unit_sp->GetJITModule();
377 return lldb::ModuleSP();
Ryan Brown998c8a1c12015-11-02 19:30:40 +0000378}