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