19f2f44ceSEd Maste //===-- FunctionCaller.cpp ---------------------------------------*- C++-*-===//
29f2f44ceSEd Maste //
39f2f44ceSEd Maste // The LLVM Compiler Infrastructure
49f2f44ceSEd Maste //
59f2f44ceSEd Maste // This file is distributed under the University of Illinois Open Source
69f2f44ceSEd Maste // License. See LICENSE.TXT for details.
79f2f44ceSEd Maste //
89f2f44ceSEd Maste //===----------------------------------------------------------------------===//
99f2f44ceSEd Maste
109f2f44ceSEd Maste
114bb0738eSEd Maste #include "lldb/Expression/FunctionCaller.h"
129f2f44ceSEd Maste #include "lldb/Core/Module.h"
139f2f44ceSEd Maste #include "lldb/Core/ValueObject.h"
149f2f44ceSEd Maste #include "lldb/Core/ValueObjectList.h"
154bb0738eSEd Maste #include "lldb/Expression/DiagnosticManager.h"
169f2f44ceSEd Maste #include "lldb/Expression/IRExecutionUnit.h"
179f2f44ceSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
189f2f44ceSEd Maste #include "lldb/Symbol/Function.h"
199f2f44ceSEd Maste #include "lldb/Symbol/Type.h"
209f2f44ceSEd Maste #include "lldb/Target/ExecutionContext.h"
219f2f44ceSEd Maste #include "lldb/Target/Process.h"
229f2f44ceSEd Maste #include "lldb/Target/RegisterContext.h"
239f2f44ceSEd Maste #include "lldb/Target/Target.h"
249f2f44ceSEd Maste #include "lldb/Target/Thread.h"
259f2f44ceSEd Maste #include "lldb/Target/ThreadPlan.h"
269f2f44ceSEd Maste #include "lldb/Target/ThreadPlanCallFunction.h"
27f678e45dSDimitry Andric #include "lldb/Utility/DataExtractor.h"
28f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
29*b5893f02SDimitry Andric #include "lldb/Utility/State.h"
309f2f44ceSEd Maste
319f2f44ceSEd Maste using namespace lldb_private;
329f2f44ceSEd Maste
339f2f44ceSEd Maste //----------------------------------------------------------------------
349f2f44ceSEd Maste // FunctionCaller constructor
359f2f44ceSEd Maste //----------------------------------------------------------------------
FunctionCaller(ExecutionContextScope & exe_scope,const CompilerType & return_type,const Address & functionAddress,const ValueList & arg_value_list,const char * name)36435933ddSDimitry Andric FunctionCaller::FunctionCaller(ExecutionContextScope &exe_scope,
379f2f44ceSEd Maste const CompilerType &return_type,
389f2f44ceSEd Maste const Address &functionAddress,
399f2f44ceSEd Maste const ValueList &arg_value_list,
40435933ddSDimitry Andric const char *name)
41435933ddSDimitry Andric : Expression(exe_scope), m_execution_unit_sp(), m_parser(),
42435933ddSDimitry Andric m_jit_module_wp(), m_name(name ? name : "<unknown>"),
43435933ddSDimitry Andric m_function_ptr(NULL), m_function_addr(functionAddress),
449f2f44ceSEd Maste m_function_return_type(return_type),
459f2f44ceSEd Maste m_wrapper_function_name("__lldb_caller_function"),
46435933ddSDimitry Andric m_wrapper_struct_name("__lldb_caller_struct"), m_wrapper_args_addrs(),
474ba319b5SDimitry Andric m_struct_valid(false), m_arg_values(arg_value_list), m_compiled(false),
484ba319b5SDimitry Andric m_JITted(false) {
499f2f44ceSEd Maste m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
509f2f44ceSEd Maste // Can't make a FunctionCaller without a process.
519f2f44ceSEd Maste assert(m_jit_process_wp.lock());
529f2f44ceSEd Maste }
539f2f44ceSEd Maste
549f2f44ceSEd Maste //----------------------------------------------------------------------
559f2f44ceSEd Maste // Destructor
569f2f44ceSEd Maste //----------------------------------------------------------------------
~FunctionCaller()57435933ddSDimitry Andric FunctionCaller::~FunctionCaller() {
589f2f44ceSEd Maste lldb::ProcessSP process_sp(m_jit_process_wp.lock());
59435933ddSDimitry Andric if (process_sp) {
609f2f44ceSEd Maste lldb::ModuleSP jit_module_sp(m_jit_module_wp.lock());
619f2f44ceSEd Maste if (jit_module_sp)
629f2f44ceSEd Maste process_sp->GetTarget().GetImages().Remove(jit_module_sp);
639f2f44ceSEd Maste }
649f2f44ceSEd Maste }
659f2f44ceSEd Maste
WriteFunctionWrapper(ExecutionContext & exe_ctx,DiagnosticManager & diagnostic_manager)66435933ddSDimitry Andric bool FunctionCaller::WriteFunctionWrapper(
67435933ddSDimitry Andric ExecutionContext &exe_ctx, DiagnosticManager &diagnostic_manager) {
689f2f44ceSEd Maste Process *process = exe_ctx.GetProcessPtr();
699f2f44ceSEd Maste
709f2f44ceSEd Maste if (!process)
719f2f44ceSEd Maste return false;
729f2f44ceSEd Maste
739f2f44ceSEd Maste lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
749f2f44ceSEd Maste
759f2f44ceSEd Maste if (process != jit_process_sp.get())
769f2f44ceSEd Maste return false;
779f2f44ceSEd Maste
789f2f44ceSEd Maste if (!m_compiled)
799f2f44ceSEd Maste return false;
809f2f44ceSEd Maste
819f2f44ceSEd Maste if (m_JITted)
829f2f44ceSEd Maste return true;
839f2f44ceSEd Maste
849f2f44ceSEd Maste bool can_interpret = false; // should stay that way
859f2f44ceSEd Maste
865517e702SDimitry Andric Status jit_error(m_parser->PrepareForExecution(
87435933ddSDimitry Andric m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
88435933ddSDimitry Andric can_interpret, eExecutionPolicyAlways));
899f2f44ceSEd Maste
904ba319b5SDimitry Andric if (!jit_error.Success()) {
914ba319b5SDimitry Andric diagnostic_manager.Printf(eDiagnosticSeverityError,
924ba319b5SDimitry Andric "Error in PrepareForExecution: %s.",
934ba319b5SDimitry Andric jit_error.AsCString());
949f2f44ceSEd Maste return false;
954ba319b5SDimitry Andric }
969f2f44ceSEd Maste
97435933ddSDimitry Andric if (m_parser->GetGenerateDebugInfo()) {
989f2f44ceSEd Maste lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
999f2f44ceSEd Maste
100435933ddSDimitry Andric if (jit_module_sp) {
1019f2f44ceSEd Maste ConstString const_func_name(FunctionName());
1029f2f44ceSEd Maste FileSpec jit_file;
1039f2f44ceSEd Maste jit_file.GetFilename() = const_func_name;
1049f2f44ceSEd Maste jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
1059f2f44ceSEd Maste m_jit_module_wp = jit_module_sp;
1069f2f44ceSEd Maste process->GetTarget().GetImages().Append(jit_module_sp);
1079f2f44ceSEd Maste }
1089f2f44ceSEd Maste }
1099f2f44ceSEd Maste if (process && m_jit_start_addr)
1109f2f44ceSEd Maste m_jit_process_wp = process->shared_from_this();
1119f2f44ceSEd Maste
1129f2f44ceSEd Maste m_JITted = true;
1139f2f44ceSEd Maste
1149f2f44ceSEd Maste return true;
1159f2f44ceSEd Maste }
1169f2f44ceSEd Maste
WriteFunctionArguments(ExecutionContext & exe_ctx,lldb::addr_t & args_addr_ref,DiagnosticManager & diagnostic_manager)117435933ddSDimitry Andric bool FunctionCaller::WriteFunctionArguments(
118435933ddSDimitry Andric ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
119435933ddSDimitry Andric DiagnosticManager &diagnostic_manager) {
120435933ddSDimitry Andric return WriteFunctionArguments(exe_ctx, args_addr_ref, m_arg_values,
121435933ddSDimitry Andric diagnostic_manager);
1229f2f44ceSEd Maste }
1239f2f44ceSEd Maste
124435933ddSDimitry Andric // FIXME: Assure that the ValueList we were passed in is consistent with the one
125435933ddSDimitry Andric // that defined this function.
1269f2f44ceSEd Maste
WriteFunctionArguments(ExecutionContext & exe_ctx,lldb::addr_t & args_addr_ref,ValueList & arg_values,DiagnosticManager & diagnostic_manager)127435933ddSDimitry Andric bool FunctionCaller::WriteFunctionArguments(
128435933ddSDimitry Andric ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref,
129435933ddSDimitry Andric ValueList &arg_values, DiagnosticManager &diagnostic_manager) {
1309f2f44ceSEd Maste // All the information to reconstruct the struct is provided by the
1319f2f44ceSEd Maste // StructExtractor.
132435933ddSDimitry Andric if (!m_struct_valid) {
133435933ddSDimitry Andric diagnostic_manager.PutString(eDiagnosticSeverityError,
134435933ddSDimitry Andric "Argument information was not correctly "
135435933ddSDimitry Andric "parsed, so the function cannot be called.");
1369f2f44ceSEd Maste return false;
1379f2f44ceSEd Maste }
1389f2f44ceSEd Maste
1395517e702SDimitry Andric Status error;
1409f2f44ceSEd Maste lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
1419f2f44ceSEd Maste
1429f2f44ceSEd Maste Process *process = exe_ctx.GetProcessPtr();
1439f2f44ceSEd Maste
1449f2f44ceSEd Maste if (process == NULL)
1459f2f44ceSEd Maste return return_value;
1469f2f44ceSEd Maste
1479f2f44ceSEd Maste lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
1489f2f44ceSEd Maste
1499f2f44ceSEd Maste if (process != jit_process_sp.get())
1509f2f44ceSEd Maste return false;
1519f2f44ceSEd Maste
152435933ddSDimitry Andric if (args_addr_ref == LLDB_INVALID_ADDRESS) {
153435933ddSDimitry Andric args_addr_ref = process->AllocateMemory(
154435933ddSDimitry Andric m_struct_size, lldb::ePermissionsReadable | lldb::ePermissionsWritable,
155435933ddSDimitry Andric error);
1569f2f44ceSEd Maste if (args_addr_ref == LLDB_INVALID_ADDRESS)
1579f2f44ceSEd Maste return false;
1589f2f44ceSEd Maste m_wrapper_args_addrs.push_back(args_addr_ref);
159435933ddSDimitry Andric } else {
1609f2f44ceSEd Maste // Make sure this is an address that we've already handed out.
161435933ddSDimitry Andric if (find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(),
162435933ddSDimitry Andric args_addr_ref) == m_wrapper_args_addrs.end()) {
1639f2f44ceSEd Maste return false;
1649f2f44ceSEd Maste }
1659f2f44ceSEd Maste }
1669f2f44ceSEd Maste
1679f2f44ceSEd Maste // TODO: verify fun_addr needs to be a callable address
168435933ddSDimitry Andric Scalar fun_addr(
169435933ddSDimitry Andric m_function_addr.GetCallableLoadAddress(exe_ctx.GetTargetPtr()));
1709f2f44ceSEd Maste uint64_t first_offset = m_member_offsets[0];
171435933ddSDimitry Andric process->WriteScalarToMemory(args_addr_ref + first_offset, fun_addr,
172435933ddSDimitry Andric process->GetAddressByteSize(), error);
1739f2f44ceSEd Maste
1749f2f44ceSEd Maste // FIXME: We will need to extend this for Variadic functions.
1759f2f44ceSEd Maste
1765517e702SDimitry Andric Status value_error;
1779f2f44ceSEd Maste
1789f2f44ceSEd Maste size_t num_args = arg_values.GetSize();
179435933ddSDimitry Andric if (num_args != m_arg_values.GetSize()) {
180435933ddSDimitry Andric diagnostic_manager.Printf(
181435933ddSDimitry Andric eDiagnosticSeverityError,
1824bb0738eSEd Maste "Wrong number of arguments - was: %" PRIu64 " should be: %" PRIu64 "",
1834bb0738eSEd Maste (uint64_t)num_args, (uint64_t)m_arg_values.GetSize());
1849f2f44ceSEd Maste return false;
1859f2f44ceSEd Maste }
1869f2f44ceSEd Maste
187435933ddSDimitry Andric for (size_t i = 0; i < num_args; i++) {
1889f2f44ceSEd Maste // FIXME: We should sanity check sizes.
1899f2f44ceSEd Maste
1909f2f44ceSEd Maste uint64_t offset = m_member_offsets[i + 1]; // Clang sizes are in bytes.
1919f2f44ceSEd Maste Value *arg_value = arg_values.GetValueAtIndex(i);
1929f2f44ceSEd Maste
1939f2f44ceSEd Maste // FIXME: For now just do scalars:
1949f2f44ceSEd Maste
195435933ddSDimitry Andric // Special case: if it's a pointer, don't do anything (the ABI supports
196435933ddSDimitry Andric // passing cstrings)
1979f2f44ceSEd Maste
1989f2f44ceSEd Maste if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
1999f2f44ceSEd Maste arg_value->GetContextType() == Value::eContextTypeInvalid &&
2009f2f44ceSEd Maste arg_value->GetCompilerType().IsPointerType())
2019f2f44ceSEd Maste continue;
2029f2f44ceSEd Maste
2039f2f44ceSEd Maste const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx);
2049f2f44ceSEd Maste
205435933ddSDimitry Andric if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar,
206435933ddSDimitry Andric arg_scalar.GetByteSize(), error))
2079f2f44ceSEd Maste return false;
2089f2f44ceSEd Maste }
2099f2f44ceSEd Maste
2109f2f44ceSEd Maste return true;
2119f2f44ceSEd Maste }
2129f2f44ceSEd Maste
InsertFunction(ExecutionContext & exe_ctx,lldb::addr_t & args_addr_ref,DiagnosticManager & diagnostic_manager)213435933ddSDimitry Andric bool FunctionCaller::InsertFunction(ExecutionContext &exe_ctx,
214435933ddSDimitry Andric lldb::addr_t &args_addr_ref,
215435933ddSDimitry Andric DiagnosticManager &diagnostic_manager) {
2164bb0738eSEd Maste if (CompileFunction(exe_ctx.GetThreadSP(), diagnostic_manager) != 0)
2179f2f44ceSEd Maste return false;
2184bb0738eSEd Maste if (!WriteFunctionWrapper(exe_ctx, diagnostic_manager))
2199f2f44ceSEd Maste return false;
2204bb0738eSEd Maste if (!WriteFunctionArguments(exe_ctx, args_addr_ref, diagnostic_manager))
2219f2f44ceSEd Maste return false;
2229f2f44ceSEd Maste
2239f2f44ceSEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
2249f2f44ceSEd Maste if (log)
225435933ddSDimitry Andric log->Printf("Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n",
226435933ddSDimitry Andric m_jit_start_addr, args_addr_ref);
2279f2f44ceSEd Maste
2289f2f44ceSEd Maste return true;
2299f2f44ceSEd Maste }
2309f2f44ceSEd Maste
GetThreadPlanToCallFunction(ExecutionContext & exe_ctx,lldb::addr_t args_addr,const EvaluateExpressionOptions & options,DiagnosticManager & diagnostic_manager)231435933ddSDimitry Andric lldb::ThreadPlanSP FunctionCaller::GetThreadPlanToCallFunction(
232435933ddSDimitry Andric ExecutionContext &exe_ctx, lldb::addr_t args_addr,
2339f2f44ceSEd Maste const EvaluateExpressionOptions &options,
234435933ddSDimitry Andric DiagnosticManager &diagnostic_manager) {
235435933ddSDimitry Andric Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
236435933ddSDimitry Andric LIBLLDB_LOG_STEP));
2379f2f44ceSEd Maste
2389f2f44ceSEd Maste if (log)
239435933ddSDimitry Andric log->Printf("-- [FunctionCaller::GetThreadPlanToCallFunction] Creating "
240435933ddSDimitry Andric "thread plan to call function \"%s\" --",
241435933ddSDimitry Andric m_name.c_str());
2429f2f44ceSEd Maste
2439f2f44ceSEd Maste // FIXME: Use the errors Stream for better error reporting.
2449f2f44ceSEd Maste Thread *thread = exe_ctx.GetThreadPtr();
245435933ddSDimitry Andric if (thread == NULL) {
246435933ddSDimitry Andric diagnostic_manager.PutString(
247435933ddSDimitry Andric eDiagnosticSeverityError,
248435933ddSDimitry Andric "Can't call a function without a valid thread.");
2499f2f44ceSEd Maste return NULL;
2509f2f44ceSEd Maste }
2519f2f44ceSEd Maste
2529f2f44ceSEd Maste // Okay, now run the function:
2539f2f44ceSEd Maste
2549f2f44ceSEd Maste Address wrapper_address(m_jit_start_addr);
2559f2f44ceSEd Maste
2569f2f44ceSEd Maste lldb::addr_t args = {args_addr};
2579f2f44ceSEd Maste
258435933ddSDimitry Andric lldb::ThreadPlanSP new_plan_sp(new ThreadPlanCallFunction(
259435933ddSDimitry Andric *thread, wrapper_address, CompilerType(), args, options));
2609f2f44ceSEd Maste new_plan_sp->SetIsMasterPlan(true);
2619f2f44ceSEd Maste new_plan_sp->SetOkayToDiscard(false);
2629f2f44ceSEd Maste return new_plan_sp;
2639f2f44ceSEd Maste }
2649f2f44ceSEd Maste
FetchFunctionResults(ExecutionContext & exe_ctx,lldb::addr_t args_addr,Value & ret_value)265435933ddSDimitry Andric bool FunctionCaller::FetchFunctionResults(ExecutionContext &exe_ctx,
266435933ddSDimitry Andric lldb::addr_t args_addr,
267435933ddSDimitry Andric Value &ret_value) {
2689f2f44ceSEd Maste // Read the return value - it is the last field in the struct:
269435933ddSDimitry Andric // FIXME: How does clang tell us there's no return value? We need to handle
270435933ddSDimitry Andric // that case.
271435933ddSDimitry Andric // FIXME: Create our ThreadPlanCallFunction with the return CompilerType, and
272435933ddSDimitry Andric // then use GetReturnValueObject
2739f2f44ceSEd Maste // to fetch the value. That way we can fetch any values we need.
2749f2f44ceSEd Maste
275435933ddSDimitry Andric Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
276435933ddSDimitry Andric LIBLLDB_LOG_STEP));
2779f2f44ceSEd Maste
2789f2f44ceSEd Maste if (log)
279435933ddSDimitry Andric log->Printf("-- [FunctionCaller::FetchFunctionResults] Fetching function "
280435933ddSDimitry Andric "results for \"%s\"--",
281435933ddSDimitry Andric m_name.c_str());
2829f2f44ceSEd Maste
2839f2f44ceSEd Maste Process *process = exe_ctx.GetProcessPtr();
2849f2f44ceSEd Maste
2859f2f44ceSEd Maste if (process == NULL)
2869f2f44ceSEd Maste return false;
2879f2f44ceSEd Maste
2889f2f44ceSEd Maste lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
2899f2f44ceSEd Maste
2909f2f44ceSEd Maste if (process != jit_process_sp.get())
2919f2f44ceSEd Maste return false;
2929f2f44ceSEd Maste
2935517e702SDimitry Andric Status error;
294435933ddSDimitry Andric ret_value.GetScalar() = process->ReadUnsignedIntegerFromMemory(
295435933ddSDimitry Andric args_addr + m_return_offset, m_return_size, 0, error);
2969f2f44ceSEd Maste
2979f2f44ceSEd Maste if (error.Fail())
2989f2f44ceSEd Maste return false;
2999f2f44ceSEd Maste
3009f2f44ceSEd Maste ret_value.SetCompilerType(m_function_return_type);
3019f2f44ceSEd Maste ret_value.SetValueType(Value::eValueTypeScalar);
3029f2f44ceSEd Maste return true;
3039f2f44ceSEd Maste }
3049f2f44ceSEd Maste
DeallocateFunctionResults(ExecutionContext & exe_ctx,lldb::addr_t args_addr)305435933ddSDimitry Andric void FunctionCaller::DeallocateFunctionResults(ExecutionContext &exe_ctx,
306435933ddSDimitry Andric lldb::addr_t args_addr) {
3079f2f44ceSEd Maste std::list<lldb::addr_t>::iterator pos;
308435933ddSDimitry Andric pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(),
309435933ddSDimitry Andric args_addr);
3109f2f44ceSEd Maste if (pos != m_wrapper_args_addrs.end())
3119f2f44ceSEd Maste m_wrapper_args_addrs.erase(pos);
3129f2f44ceSEd Maste
3139f2f44ceSEd Maste exe_ctx.GetProcessRef().DeallocateMemory(args_addr);
3149f2f44ceSEd Maste }
3159f2f44ceSEd Maste
ExecuteFunction(ExecutionContext & exe_ctx,lldb::addr_t * args_addr_ptr,const EvaluateExpressionOptions & options,DiagnosticManager & diagnostic_manager,Value & results)316435933ddSDimitry Andric lldb::ExpressionResults FunctionCaller::ExecuteFunction(
317435933ddSDimitry Andric ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr,
318435933ddSDimitry Andric const EvaluateExpressionOptions &options,
319435933ddSDimitry Andric DiagnosticManager &diagnostic_manager, Value &results) {
3209f2f44ceSEd Maste lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
3219f2f44ceSEd Maste
3224ba319b5SDimitry Andric // FunctionCaller::ExecuteFunction execution is always just to get the
3234ba319b5SDimitry Andric // result. Do make sure we ignore breakpoints, unwind on error, and don't try
3244ba319b5SDimitry Andric // to debug it.
3259f2f44ceSEd Maste EvaluateExpressionOptions real_options = options;
3269f2f44ceSEd Maste real_options.SetDebug(false);
3279f2f44ceSEd Maste real_options.SetUnwindOnError(true);
3289f2f44ceSEd Maste real_options.SetIgnoreBreakpoints(true);
3299f2f44ceSEd Maste
3309f2f44ceSEd Maste lldb::addr_t args_addr;
3319f2f44ceSEd Maste
3329f2f44ceSEd Maste if (args_addr_ptr != NULL)
3339f2f44ceSEd Maste args_addr = *args_addr_ptr;
3349f2f44ceSEd Maste else
3359f2f44ceSEd Maste args_addr = LLDB_INVALID_ADDRESS;
3369f2f44ceSEd Maste
3374bb0738eSEd Maste if (CompileFunction(exe_ctx.GetThreadSP(), diagnostic_manager) != 0)
3389f2f44ceSEd Maste return lldb::eExpressionSetupError;
3399f2f44ceSEd Maste
340435933ddSDimitry Andric if (args_addr == LLDB_INVALID_ADDRESS) {
3414bb0738eSEd Maste if (!InsertFunction(exe_ctx, args_addr, diagnostic_manager))
3429f2f44ceSEd Maste return lldb::eExpressionSetupError;
3439f2f44ceSEd Maste }
3449f2f44ceSEd Maste
345435933ddSDimitry Andric Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
346435933ddSDimitry Andric LIBLLDB_LOG_STEP));
3479f2f44ceSEd Maste
3489f2f44ceSEd Maste if (log)
349435933ddSDimitry Andric log->Printf(
350435933ddSDimitry Andric "== [FunctionCaller::ExecuteFunction] Executing function \"%s\" ==",
351435933ddSDimitry Andric m_name.c_str());
3529f2f44ceSEd Maste
353435933ddSDimitry Andric lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction(
354435933ddSDimitry Andric exe_ctx, args_addr, real_options, diagnostic_manager);
3559f2f44ceSEd Maste if (!call_plan_sp)
3569f2f44ceSEd Maste return lldb::eExpressionSetupError;
3579f2f44ceSEd Maste
358435933ddSDimitry Andric // We need to make sure we record the fact that we are running an expression
3594ba319b5SDimitry Andric // here otherwise this fact will fail to be recorded when fetching an
3604ba319b5SDimitry Andric // Objective-C object description
3619f2f44ceSEd Maste if (exe_ctx.GetProcessPtr())
3629f2f44ceSEd Maste exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
3639f2f44ceSEd Maste
364435933ddSDimitry Andric return_value = exe_ctx.GetProcessRef().RunThreadPlan(
365435933ddSDimitry Andric exe_ctx, call_plan_sp, real_options, diagnostic_manager);
3669f2f44ceSEd Maste
367435933ddSDimitry Andric if (log) {
368435933ddSDimitry Andric if (return_value != lldb::eExpressionCompleted) {
369435933ddSDimitry Andric log->Printf("== [FunctionCaller::ExecuteFunction] Execution of \"%s\" "
370435933ddSDimitry Andric "completed abnormally ==",
371435933ddSDimitry Andric m_name.c_str());
372435933ddSDimitry Andric } else {
373435933ddSDimitry Andric log->Printf("== [FunctionCaller::ExecuteFunction] Execution of \"%s\" "
374435933ddSDimitry Andric "completed normally ==",
375435933ddSDimitry Andric m_name.c_str());
3769f2f44ceSEd Maste }
3779f2f44ceSEd Maste }
3789f2f44ceSEd Maste
3799f2f44ceSEd Maste if (exe_ctx.GetProcessPtr())
3809f2f44ceSEd Maste exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
3819f2f44ceSEd Maste
3829f2f44ceSEd Maste if (args_addr_ptr != NULL)
3839f2f44ceSEd Maste *args_addr_ptr = args_addr;
3849f2f44ceSEd Maste
3859f2f44ceSEd Maste if (return_value != lldb::eExpressionCompleted)
3869f2f44ceSEd Maste return return_value;
3879f2f44ceSEd Maste
3889f2f44ceSEd Maste FetchFunctionResults(exe_ctx, args_addr, results);
3899f2f44ceSEd Maste
3909f2f44ceSEd Maste if (args_addr_ptr == NULL)
3919f2f44ceSEd Maste DeallocateFunctionResults(exe_ctx, args_addr);
3929f2f44ceSEd Maste
3939f2f44ceSEd Maste return lldb::eExpressionCompleted;
3949f2f44ceSEd Maste }
395