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                                std::string *fixed_expression,
164                                lldb::ModuleSP *jit_module_sp_ptr)
165 {
166     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
167 
168     lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
169     lldb::LanguageType language = options.GetLanguage();
170     const ResultType desired_type = options.DoesCoerceToId() ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny;
171     lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
172 
173     Target *target = exe_ctx.GetTargetPtr();
174     if (!target)
175     {
176         if (log)
177             log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't run expressions.");
178         return lldb::eExpressionSetupError;
179     }
180 
181     Process *process = exe_ctx.GetProcessPtr();
182 
183     if (process == NULL || process->GetState() != lldb::eStateStopped)
184     {
185         if (execution_policy == eExecutionPolicyAlways)
186         {
187             if (log)
188                 log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
189 
190             error.SetErrorString ("expression needed to run but couldn't");
191 
192             return execution_results;
193         }
194     }
195 
196     if (process == NULL || !process->CanJIT())
197         execution_policy = eExecutionPolicyNever;
198 
199     // We need to set the expression execution thread here, turns out parse can call functions in the process of
200     // looking up symbols, which will escape the context set by exe_ctx passed to Execute.
201     lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP();
202     ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_sp);
203 
204     const char *full_prefix = NULL;
205     const char *option_prefix = options.GetPrefix();
206     std::string full_prefix_storage;
207     if (expr_prefix && option_prefix)
208     {
209         full_prefix_storage.assign(expr_prefix);
210         full_prefix_storage.append(option_prefix);
211         if (!full_prefix_storage.empty())
212             full_prefix = full_prefix_storage.c_str();
213     }
214     else if (expr_prefix)
215         full_prefix = expr_prefix;
216     else
217         full_prefix = option_prefix;
218 
219     // If the language was not specified in the expression command,
220     // set it to the language in the target's properties if
221     // specified, else default to the langage for the frame.
222     if (language == lldb::eLanguageTypeUnknown)
223     {
224         if (target->GetLanguage() != lldb::eLanguageTypeUnknown)
225             language = target->GetLanguage();
226         else if (StackFrame *frame = exe_ctx.GetFramePtr())
227             language = frame->GetLanguage();
228     }
229 
230     lldb::UserExpressionSP user_expression_sp(target->GetUserExpressionForLanguage (expr_cstr,
231                                                                                     full_prefix,
232                                                                                     language,
233                                                                                     desired_type,
234                                                                                     options,
235                                                                                     error));
236     if (error.Fail())
237     {
238         if (log)
239             log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString());
240         return lldb::eExpressionSetupError;
241     }
242 
243     if (log)
244         log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
245 
246     const bool keep_expression_in_memory = true;
247     const bool generate_debug_info = options.GetGenerateDebugInfo();
248 
249     if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
250     {
251         error.SetErrorString ("expression interrupted by callback before parse");
252         result_valobj_sp = ValueObjectConstResult::Create(exe_ctx.GetBestExecutionContextScope(), error);
253         return lldb::eExpressionInterrupted;
254     }
255 
256     DiagnosticManager diagnostic_manager;
257 
258     bool parse_success = user_expression_sp->Parse(diagnostic_manager,
259                                                    exe_ctx,
260                                                    execution_policy,
261                                                    keep_expression_in_memory,
262                                                    generate_debug_info);
263 
264     // Calculate the fixed expression always, since we need it for errors.
265     std::string tmp_fixed_expression;
266     if (fixed_expression == nullptr)
267         fixed_expression = &tmp_fixed_expression;
268 
269     const char *fixed_text = user_expression_sp->GetFixedText();
270     if (fixed_text != nullptr)
271             fixed_expression->append(fixed_text);
272 
273     // If there is a fixed expression, try to parse it:
274     if (!parse_success)
275     {
276         execution_results = lldb::eExpressionParseError;
277         if (fixed_expression && !fixed_expression->empty() && options.GetAutoApplyFixIts())
278         {
279             lldb::UserExpressionSP fixed_expression_sp(target->GetUserExpressionForLanguage (fixed_expression->c_str(),
280                                                                                              full_prefix,
281                                                                                              language,
282                                                                                              desired_type,
283                                                                                              options,
284                                                                                              error));
285             DiagnosticManager fixed_diagnostic_manager;
286             parse_success = fixed_expression_sp->Parse(fixed_diagnostic_manager,
287                                                        exe_ctx,
288                                                        execution_policy,
289                                                        keep_expression_in_memory,
290                                                        generate_debug_info);
291             if (parse_success)
292             {
293                 diagnostic_manager.Clear();
294                 user_expression_sp = fixed_expression_sp;
295             }
296             else
297             {
298                 // If the fixed expression failed to parse, don't tell the user about, that won't help.
299                 fixed_expression->clear();
300             }
301         }
302 
303         if (!parse_success)
304         {
305             if (!fixed_expression->empty() && target->GetEnableNotifyAboutFixIts())
306             {
307                 error.SetExpressionErrorWithFormat(execution_results, "expression failed to parse, fixed expression suggested:\n  %s",
308                                                    fixed_expression->c_str());
309             }
310             else
311             {
312                 if (!diagnostic_manager.Diagnostics().size())
313                     error.SetExpressionError(execution_results, "expression failed to parse, unknown error");
314                 else
315                     error.SetExpressionError(execution_results, diagnostic_manager.GetString().c_str());
316             }
317         }
318     }
319 
320     if (parse_success)
321     {
322         // If a pointer to a lldb::ModuleSP was passed in, return the JIT'ed module if one was created
323         if (jit_module_sp_ptr)
324             *jit_module_sp_ptr = user_expression_sp->GetJITModule();
325 
326         lldb::ExpressionVariableSP expr_result;
327 
328         if (execution_policy == eExecutionPolicyNever &&
329             !user_expression_sp->CanInterpret())
330         {
331             if (log)
332                 log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
333 
334             if (!diagnostic_manager.Diagnostics().size())
335                 error.SetExpressionError(lldb::eExpressionSetupError, "expression needed to run but couldn't");
336         }
337         else if (execution_policy == eExecutionPolicyTopLevel)
338         {
339             error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
340             return lldb::eExpressionCompleted;
341         }
342         else
343         {
344             if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
345             {
346                 error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
347                 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
348                 return lldb::eExpressionInterrupted;
349             }
350 
351             diagnostic_manager.Clear();
352 
353             if (log)
354                 log->Printf("== [UserExpression::Evaluate] Executing expression ==");
355 
356             execution_results =
357                 user_expression_sp->Execute(diagnostic_manager, exe_ctx, options, user_expression_sp, expr_result);
358 
359             if (execution_results != lldb::eExpressionCompleted)
360             {
361                 if (log)
362                     log->Printf("== [UserExpression::Evaluate] Execution completed abnormally ==");
363 
364                 if (!diagnostic_manager.Diagnostics().size())
365                     error.SetExpressionError(execution_results, "expression failed to execute, unknown error");
366                 else
367                     error.SetExpressionError(execution_results, diagnostic_manager.GetString().c_str());
368             }
369             else
370             {
371                 if (expr_result)
372                 {
373                     result_valobj_sp = expr_result->GetValueObject();
374 
375                     if (log)
376                         log->Printf("== [UserExpression::Evaluate] Execution completed normally with result %s ==",
377                                     result_valobj_sp->GetValueAsCString());
378                 }
379                 else
380                 {
381                     if (log)
382                         log->Printf("== [UserExpression::Evaluate] Execution completed normally with no result ==");
383 
384                     error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
385                 }
386             }
387         }
388     }
389 
390     if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
391     {
392         error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
393         return lldb::eExpressionInterrupted;
394     }
395 
396     if (result_valobj_sp.get() == NULL)
397     {
398         result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
399     }
400 
401     return execution_results;
402 }
403 
404 lldb::ExpressionResults
405 UserExpression::Execute(DiagnosticManager &diagnostic_manager,
406                         ExecutionContext &exe_ctx,
407                         const EvaluateExpressionOptions &options,
408                         lldb::UserExpressionSP &shared_ptr_to_me,
409                         lldb::ExpressionVariableSP &result_var)
410 {
411     lldb::ExpressionResults expr_result = DoExecute(diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var);
412     Target *target = exe_ctx.GetTargetPtr();
413     if (options.GetResultIsInternal() && result_var && target)
414     {
415         target->GetPersistentExpressionStateForLanguage(m_language)->RemovePersistentVariable (result_var);
416     }
417     return expr_result;
418 }
419 
420 
421