1 //===-- LLVMUserExpression.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 // C Includes 11 // C++ Includes 12 13 // Project includes 14 #include "lldb/Expression/LLVMUserExpression.h" 15 #include "lldb/Core/ConstString.h" 16 #include "lldb/Core/Log.h" 17 #include "lldb/Core/Module.h" 18 #include "lldb/Core/StreamFile.h" 19 #include "lldb/Core/StreamString.h" 20 #include "lldb/Core/ValueObjectConstResult.h" 21 #include "lldb/Expression/DiagnosticManager.h" 22 #include "lldb/Expression/ExpressionSourceCode.h" 23 #include "lldb/Expression/IRExecutionUnit.h" 24 #include "lldb/Expression/IRInterpreter.h" 25 #include "lldb/Expression/Materializer.h" 26 #include "lldb/Host/HostInfo.h" 27 #include "lldb/Symbol/Block.h" 28 #include "lldb/Symbol/ClangASTContext.h" 29 #include "lldb/Symbol/ClangExternalASTSourceCommon.h" 30 #include "lldb/Symbol/Function.h" 31 #include "lldb/Symbol/ObjectFile.h" 32 #include "lldb/Symbol/SymbolVendor.h" 33 #include "lldb/Symbol/Type.h" 34 #include "lldb/Symbol/VariableList.h" 35 #include "lldb/Target/ExecutionContext.h" 36 #include "lldb/Target/Process.h" 37 #include "lldb/Target/StackFrame.h" 38 #include "lldb/Target/Target.h" 39 #include "lldb/Target/ThreadPlan.h" 40 #include "lldb/Target/ThreadPlanCallUserExpression.h" 41 42 using namespace lldb_private; 43 44 LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope, 45 const char *expr, 46 const char *expr_prefix, 47 lldb::LanguageType language, 48 ResultType desired_type, 49 const EvaluateExpressionOptions &options) 50 : UserExpression(exe_scope, expr, expr_prefix, language, desired_type, options), 51 m_stack_frame_bottom(LLDB_INVALID_ADDRESS), 52 m_stack_frame_top(LLDB_INVALID_ADDRESS), 53 m_transformed_text(), 54 m_execution_unit_sp(), 55 m_materializer_ap(), 56 m_jit_module_wp(), 57 m_enforce_valid_object(true), 58 m_in_cplusplus_method(false), 59 m_in_objectivec_method(false), 60 m_in_static_method(false), 61 m_needs_object_ptr(false), 62 m_const_object(false), 63 m_target(NULL), 64 m_can_interpret(false), 65 m_materialized_address(LLDB_INVALID_ADDRESS) 66 { 67 } 68 69 LLVMUserExpression::~LLVMUserExpression() 70 { 71 if (m_target) 72 { 73 lldb::ModuleSP jit_module_sp(m_jit_module_wp.lock()); 74 if (jit_module_sp) 75 m_target->GetImages().Remove(jit_module_sp); 76 } 77 } 78 79 lldb::ExpressionResults 80 LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, 81 const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me, 82 lldb::ExpressionVariableSP &result) 83 { 84 // The expression log is quite verbose, and if you're just tracking the execution of the 85 // expression, it's quite convenient to have these logs come out with the STEP log as well. 86 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); 87 88 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) 89 { 90 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS; 91 92 if (!PrepareToExecuteJITExpression(diagnostic_manager, exe_ctx, struct_address)) 93 { 94 diagnostic_manager.Printf(eDiagnosticSeverityError, 95 "errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__); 96 return lldb::eExpressionSetupError; 97 } 98 99 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS; 100 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS; 101 102 if (m_can_interpret) 103 { 104 llvm::Module *module = m_execution_unit_sp->GetModule(); 105 llvm::Function *function = m_execution_unit_sp->GetFunction(); 106 107 if (!module || !function) 108 { 109 diagnostic_manager.PutCString(eDiagnosticSeverityError, "supposed to interpret, but nothing is there"); 110 return lldb::eExpressionSetupError; 111 } 112 113 Error interpreter_error; 114 115 std::vector<lldb::addr_t> args; 116 117 if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) 118 { 119 diagnostic_manager.Printf(eDiagnosticSeverityError, "errored out in %s, couldn't AddArguments", 120 __FUNCTION__); 121 return lldb::eExpressionSetupError; 122 } 123 124 function_stack_bottom = m_stack_frame_bottom; 125 function_stack_top = m_stack_frame_top; 126 127 IRInterpreter::Interpret(*module, *function, args, *m_execution_unit_sp.get(), interpreter_error, 128 function_stack_bottom, function_stack_top, exe_ctx); 129 130 if (!interpreter_error.Success()) 131 { 132 diagnostic_manager.Printf(eDiagnosticSeverityError, "supposed to interpret, but failed: %s", 133 interpreter_error.AsCString()); 134 return lldb::eExpressionDiscarded; 135 } 136 } 137 else 138 { 139 if (!exe_ctx.HasThreadScope()) 140 { 141 diagnostic_manager.Printf(eDiagnosticSeverityError, "%s called with no thread selected", __FUNCTION__); 142 return lldb::eExpressionSetupError; 143 } 144 145 Address wrapper_address(m_jit_start_addr); 146 147 std::vector<lldb::addr_t> args; 148 149 if (!AddArguments(exe_ctx, args, struct_address, diagnostic_manager)) 150 { 151 diagnostic_manager.Printf(eDiagnosticSeverityError, "errored out in %s, couldn't AddArguments", 152 __FUNCTION__); 153 return lldb::eExpressionSetupError; 154 } 155 156 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression(exe_ctx.GetThreadRef(), wrapper_address, 157 args, options, shared_ptr_to_me)); 158 159 StreamString ss; 160 if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) 161 { 162 diagnostic_manager.PutCString(eDiagnosticSeverityError, ss.GetData()); 163 return lldb::eExpressionSetupError; 164 } 165 166 ThreadPlanCallUserExpression *user_expression_plan = 167 static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get()); 168 169 lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer(); 170 171 function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize(); 172 function_stack_top = function_stack_pointer; 173 174 if (log) 175 log->Printf("-- [UserExpression::Execute] Execution of expression begins --"); 176 177 if (exe_ctx.GetProcessPtr()) 178 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); 179 180 lldb::ExpressionResults execution_result = 181 exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostic_manager); 182 183 if (exe_ctx.GetProcessPtr()) 184 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); 185 186 if (log) 187 log->Printf("-- [UserExpression::Execute] Execution of expression completed --"); 188 189 if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint) 190 { 191 const char *error_desc = NULL; 192 193 if (call_plan_sp) 194 { 195 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); 196 if (real_stop_info_sp) 197 error_desc = real_stop_info_sp->GetDescription(); 198 } 199 if (error_desc) 200 diagnostic_manager.Printf(eDiagnosticSeverityError, "Execution was interrupted, reason: %s.", 201 error_desc); 202 else 203 diagnostic_manager.PutCString(eDiagnosticSeverityError, "Execution was interrupted."); 204 205 if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError()) || 206 (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints())) 207 diagnostic_manager.AppendMessageToDiagnostic( 208 "The process has been returned to the state before expression evaluation."); 209 else 210 { 211 if (execution_result == lldb::eExpressionHitBreakpoint) 212 user_expression_plan->TransferExpressionOwnership(); 213 diagnostic_manager.AppendMessageToDiagnostic( 214 "The process has been left at the point where it was interrupted, " 215 "use \"thread return -x\" to return to the state before expression evaluation."); 216 } 217 218 return execution_result; 219 } 220 else if (execution_result == lldb::eExpressionStoppedForDebug) 221 { 222 diagnostic_manager.PutCString( 223 eDiagnosticSeverityRemark, 224 "Execution was halted at the first instruction of the expression " 225 "function because \"debug\" was requested.\n" 226 "Use \"thread return -x\" to return to the state before expression evaluation."); 227 return execution_result; 228 } 229 else if (execution_result != lldb::eExpressionCompleted) 230 { 231 diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't execute function; result was %s", 232 Process::ExecutionResultAsCString(execution_result)); 233 return execution_result; 234 } 235 } 236 237 if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result, function_stack_bottom, function_stack_top)) 238 { 239 return lldb::eExpressionCompleted; 240 } 241 else 242 { 243 return lldb::eExpressionResultUnavailable; 244 } 245 } 246 else 247 { 248 diagnostic_manager.PutCString(eDiagnosticSeverityError, 249 "Expression can't be run, because there is no JIT compiled function"); 250 return lldb::eExpressionSetupError; 251 } 252 } 253 254 bool 255 LLVMUserExpression::FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, 256 lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom, 257 lldb::addr_t function_stack_top) 258 { 259 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 260 261 if (log) 262 log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing after execution --"); 263 264 if (!m_dematerializer_sp) 265 { 266 diagnostic_manager.Printf(eDiagnosticSeverityError, 267 "Couldn't apply expression side effects : no dematerializer is present"); 268 return false; 269 } 270 271 Error dematerialize_error; 272 273 m_dematerializer_sp->Dematerialize(dematerialize_error, function_stack_bottom, function_stack_top); 274 275 if (!dematerialize_error.Success()) 276 { 277 diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't apply expression side effects : %s", 278 dematerialize_error.AsCString("unknown error")); 279 return false; 280 } 281 282 result = GetResultAfterDematerialization(exe_ctx.GetBestExecutionContextScope()); 283 284 if (result) 285 result->TransferAddress(); 286 287 m_dematerializer_sp.reset(); 288 289 return true; 290 } 291 292 bool 293 LLVMUserExpression::PrepareToExecuteJITExpression(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, 294 lldb::addr_t &struct_address) 295 { 296 lldb::TargetSP target; 297 lldb::ProcessSP process; 298 lldb::StackFrameSP frame; 299 300 if (!LockAndCheckContext(exe_ctx, target, process, frame)) 301 { 302 diagnostic_manager.PutCString(eDiagnosticSeverityError, 303 "The context has changed before we could JIT the expression!"); 304 return false; 305 } 306 307 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) 308 { 309 if (m_materialized_address == LLDB_INVALID_ADDRESS) 310 { 311 Error alloc_error; 312 313 IRMemoryMap::AllocationPolicy policy = 314 m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror; 315 316 const bool zero_memory = false; 317 318 m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(), 319 m_materializer_ap->GetStructAlignment(), 320 lldb::ePermissionsReadable | lldb::ePermissionsWritable, 321 policy, 322 zero_memory, 323 alloc_error); 324 325 if (!alloc_error.Success()) 326 { 327 diagnostic_manager.Printf(eDiagnosticSeverityError, 328 "Couldn't allocate space for materialized struct: %s", 329 alloc_error.AsCString()); 330 return false; 331 } 332 } 333 334 struct_address = m_materialized_address; 335 336 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) 337 { 338 Error alloc_error; 339 340 const size_t stack_frame_size = 512 * 1024; 341 342 const bool zero_memory = false; 343 344 m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size, 345 8, 346 lldb::ePermissionsReadable | lldb::ePermissionsWritable, 347 IRMemoryMap::eAllocationPolicyHostOnly, 348 zero_memory, 349 alloc_error); 350 351 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size; 352 353 if (!alloc_error.Success()) 354 { 355 diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't allocate space for the stack frame: %s", 356 alloc_error.AsCString()); 357 return false; 358 } 359 } 360 361 Error materialize_error; 362 363 m_dematerializer_sp = 364 m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error); 365 366 if (!materialize_error.Success()) 367 { 368 diagnostic_manager.Printf(eDiagnosticSeverityError, "Couldn't materialize: %s", 369 materialize_error.AsCString()); 370 return false; 371 } 372 } 373 return true; 374 } 375 376 lldb::ModuleSP 377 LLVMUserExpression::GetJITModule() 378 { 379 if (m_execution_unit_sp) 380 return m_execution_unit_sp->GetJITModule(); 381 return lldb::ModuleSP(); 382 } 383