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