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