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