1 //===-- 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 "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
20 #include "lldb/Core/ConstString.h"
21 #include "lldb/Core/Log.h"
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/StreamFile.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Core/ValueObjectConstResult.h"
26 #include "lldb/Expression/DiagnosticManager.h"
27 #include "lldb/Expression/ExpressionSourceCode.h"
28 #include "lldb/Expression/IRExecutionUnit.h"
29 #include "lldb/Expression/IRInterpreter.h"
30 #include "lldb/Expression/Materializer.h"
31 #include "lldb/Expression/UserExpression.h"
32 #include "lldb/Host/HostInfo.h"
33 #include "lldb/Symbol/Block.h"
34 #include "lldb/Symbol/Function.h"
35 #include "lldb/Symbol/ObjectFile.h"
36 #include "lldb/Symbol/SymbolVendor.h"
37 #include "lldb/Symbol/Type.h"
38 #include "lldb/Symbol/TypeSystem.h"
39 #include "lldb/Symbol/VariableList.h"
40 #include "lldb/Target/ExecutionContext.h"
41 #include "lldb/Target/Process.h"
42 #include "lldb/Target/StackFrame.h"
43 #include "lldb/Target/Target.h"
44 #include "lldb/Target/ThreadPlan.h"
45 #include "lldb/Target/ThreadPlanCallUserExpression.h"
46 
47 using namespace lldb_private;
48 
49 UserExpression::UserExpression (ExecutionContextScope &exe_scope,
50                                 const char *expr,
51                                 const char *expr_prefix,
52                                 lldb::LanguageType language,
53                                 ResultType desired_type,
54                                 const EvaluateExpressionOptions &options) :
55       Expression(exe_scope),
56       m_expr_text(expr),
57       m_expr_prefix(expr_prefix ? expr_prefix : ""),
58       m_language(language),
59       m_desired_type(desired_type),
60       m_options (options)
61 {
62 }
63 
64 UserExpression::~UserExpression ()
65 {
66 }
67 
68 void
69 UserExpression::InstallContext (ExecutionContext &exe_ctx)
70 {
71     m_jit_process_wp = exe_ctx.GetProcessSP();
72 
73     lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
74 
75     if (frame_sp)
76         m_address = frame_sp->GetFrameCodeAddress();
77 }
78 
79 bool
80 UserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
81                                           lldb::TargetSP &target_sp,
82                                           lldb::ProcessSP &process_sp,
83                                           lldb::StackFrameSP &frame_sp)
84 {
85     lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock();
86     process_sp = exe_ctx.GetProcessSP();
87 
88     if (process_sp != expected_process_sp)
89         return false;
90 
91     process_sp = exe_ctx.GetProcessSP();
92     target_sp = exe_ctx.GetTargetSP();
93     frame_sp = exe_ctx.GetFrameSP();
94 
95     if (m_address.IsValid())
96     {
97         if (!frame_sp)
98             return false;
99         else
100             return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
101     }
102 
103     return true;
104 }
105 
106 bool
107 UserExpression::MatchesContext (ExecutionContext &exe_ctx)
108 {
109     lldb::TargetSP target_sp;
110     lldb::ProcessSP process_sp;
111     lldb::StackFrameSP frame_sp;
112 
113     return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
114 }
115 
116 lldb::addr_t
117 UserExpression::GetObjectPointer (lldb::StackFrameSP frame_sp,
118                   ConstString &object_name,
119                   Error &err)
120 {
121     err.Clear();
122 
123     if (!frame_sp)
124     {
125         err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
126         return LLDB_INVALID_ADDRESS;
127     }
128 
129     lldb::VariableSP var_sp;
130     lldb::ValueObjectSP valobj_sp;
131 
132     valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
133                                                             lldb::eNoDynamicValues,
134                                                             StackFrame::eExpressionPathOptionCheckPtrVsMember |
135                                                             StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
136                                                             StackFrame::eExpressionPathOptionsNoSyntheticChildren |
137                                                             StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
138                                                             var_sp,
139                                                             err);
140 
141     if (!err.Success() || !valobj_sp.get())
142         return LLDB_INVALID_ADDRESS;
143 
144     lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
145 
146     if (ret == LLDB_INVALID_ADDRESS)
147     {
148         err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
149         return LLDB_INVALID_ADDRESS;
150     }
151 
152     return ret;
153 }
154 
155 lldb::ExpressionResults
156 UserExpression::Evaluate (ExecutionContext &exe_ctx,
157                                const EvaluateExpressionOptions& options,
158                                const char *expr_cstr,
159                                const char *expr_prefix,
160                                lldb::ValueObjectSP &result_valobj_sp,
161                                Error &error,
162                                uint32_t line_offset,
163                                lldb::ModuleSP *jit_module_sp_ptr)
164 {
165     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
166 
167     lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
168     lldb::LanguageType language = options.GetLanguage();
169     const ResultType desired_type = options.DoesCoerceToId() ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny;
170     lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
171 
172     Target *target = exe_ctx.GetTargetPtr();
173     if (!target)
174     {
175         if (log)
176             log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't run expressions.");
177         return lldb::eExpressionSetupError;
178     }
179 
180     Process *process = exe_ctx.GetProcessPtr();
181 
182     if (process == NULL || process->GetState() != lldb::eStateStopped)
183     {
184         if (execution_policy == eExecutionPolicyAlways)
185         {
186             if (log)
187                 log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
188 
189             error.SetErrorString ("expression needed to run but couldn't");
190 
191             return execution_results;
192         }
193     }
194 
195     if (process == NULL || !process->CanJIT())
196         execution_policy = eExecutionPolicyNever;
197 
198     // We need to set the expression execution thread here, turns out parse can call functions in the process of
199     // looking up symbols, which will escape the context set by exe_ctx passed to Execute.
200     lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP();
201     ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_sp);
202 
203     const char *full_prefix = NULL;
204     const char *option_prefix = options.GetPrefix();
205     std::string full_prefix_storage;
206     if (expr_prefix && option_prefix)
207     {
208         full_prefix_storage.assign(expr_prefix);
209         full_prefix_storage.append(option_prefix);
210         if (!full_prefix_storage.empty())
211             full_prefix = full_prefix_storage.c_str();
212     }
213     else if (expr_prefix)
214         full_prefix = expr_prefix;
215     else
216         full_prefix = option_prefix;
217 
218     // If the language was not specified in the expression command,
219     // set it to the language in the target's properties if
220     // specified, else default to the langage for the frame.
221     if (language == lldb::eLanguageTypeUnknown)
222     {
223         if (target->GetLanguage() != lldb::eLanguageTypeUnknown)
224             language = target->GetLanguage();
225         else if (StackFrame *frame = exe_ctx.GetFramePtr())
226             language = frame->GetLanguage();
227     }
228 
229     lldb::UserExpressionSP user_expression_sp(target->GetUserExpressionForLanguage (expr_cstr,
230                                                                                     full_prefix,
231                                                                                     language,
232                                                                                     desired_type,
233                                                                                     options,
234                                                                                     error));
235     if (error.Fail())
236     {
237         if (log)
238             log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString());
239         return lldb::eExpressionSetupError;
240     }
241 
242     if (log)
243         log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
244 
245     const bool keep_expression_in_memory = true;
246     const bool generate_debug_info = options.GetGenerateDebugInfo();
247 
248     if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
249     {
250         error.SetErrorString ("expression interrupted by callback before parse");
251         result_valobj_sp = ValueObjectConstResult::Create(exe_ctx.GetBestExecutionContextScope(), error);
252         return lldb::eExpressionInterrupted;
253     }
254 
255     DiagnosticManager diagnostic_manager;
256     diagnostic_manager.SetAutoApplyFixIts(options.GetAutoApplyFixIts());
257 
258     if (!user_expression_sp->Parse(diagnostic_manager, exe_ctx, execution_policy, keep_expression_in_memory,
259                                    generate_debug_info))
260     {
261         execution_results = lldb::eExpressionParseError;
262         if (!diagnostic_manager.Diagnostics().size())
263             error.SetExpressionError(execution_results, "expression failed to parse, unknown error");
264         else
265             error.SetExpressionError(execution_results, diagnostic_manager.GetString().c_str());
266     }
267     else
268     {
269         // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module if one was created
270         if (jit_module_sp_ptr)
271             *jit_module_sp_ptr = user_expression_sp->GetJITModule();
272 
273         lldb::ExpressionVariableSP expr_result;
274 
275         if (execution_policy == eExecutionPolicyNever &&
276             !user_expression_sp->CanInterpret())
277         {
278             if (log)
279                 log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
280 
281             if (!diagnostic_manager.Diagnostics().size())
282                 error.SetExpressionError(lldb::eExpressionSetupError, "expression needed to run but couldn't");
283         }
284         else
285         {
286             if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
287             {
288                 error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
289                 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
290                 return lldb::eExpressionInterrupted;
291             }
292 
293             diagnostic_manager.Clear();
294 
295             if (log)
296                 log->Printf("== [UserExpression::Evaluate] Executing expression ==");
297 
298             execution_results =
299                 user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, user_expression_sp, expr_result);
300 
301             if (options.GetResultIsInternal() && expr_result && process)
302             {
303                 process->GetTarget().GetPersistentExpressionStateForLanguage(language)->RemovePersistentVariable (expr_result);
304             }
305 
306             if (execution_results != lldb::eExpressionCompleted)
307             {
308                 if (log)
309                     log->Printf("== [UserExpression::Evaluate] Execution completed abnormally ==");
310 
311                 if (!diagnostic_manager.Diagnostics().size())
312                     error.SetExpressionError(execution_results, "expression failed to execute, unknown error");
313                 else
314                     error.SetExpressionError(execution_results, diagnostic_manager.GetString().c_str());
315             }
316             else
317             {
318                 if (expr_result)
319                 {
320                     result_valobj_sp = expr_result->GetValueObject();
321 
322                     if (log)
323                         log->Printf("== [UserExpression::Evaluate] Execution completed normally with result %s ==",
324                                     result_valobj_sp->GetValueAsCString());
325                 }
326                 else
327                 {
328                     if (log)
329                         log->Printf("== [UserExpression::Evaluate] Execution completed normally with no result ==");
330 
331                     error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
332                 }
333             }
334         }
335     }
336 
337     if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
338     {
339         error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
340         return lldb::eExpressionInterrupted;
341     }
342 
343     if (result_valobj_sp.get() == NULL)
344     {
345         result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
346     }
347 
348     return execution_results;
349 }
350