1e65b2cf2SEugene Zelenko //===-- ThreadPlanCallFunctionUsingABI.cpp ----------------------*- C++ -*-===//
290ff7911SEwan Crawford //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
690ff7911SEwan Crawford //
790ff7911SEwan Crawford //===----------------------------------------------------------------------===//
890ff7911SEwan Crawford 
9e65b2cf2SEugene Zelenko #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"
1090ff7911SEwan Crawford #include "lldb/Core/Address.h"
1190ff7911SEwan Crawford #include "lldb/Target/Process.h"
1290ff7911SEwan Crawford #include "lldb/Target/RegisterContext.h"
1390ff7911SEwan Crawford #include "lldb/Target/Target.h"
1490ff7911SEwan Crawford #include "lldb/Target/Thread.h"
156f9e6901SZachary Turner #include "lldb/Utility/Log.h"
16bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
1790ff7911SEwan Crawford 
1890ff7911SEwan Crawford using namespace lldb;
1990ff7911SEwan Crawford using namespace lldb_private;
2090ff7911SEwan Crawford 
2190ff7911SEwan Crawford //--------------------------------------------------------------------------------------------
22b9c1b51eSKate Stone // ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI
23b9c1b51eSKate Stone // instead of JIT
2490ff7911SEwan Crawford //-------------------------------------------------------------------------------------------
25b9c1b51eSKate Stone ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI(
26b9c1b51eSKate Stone     Thread &thread, const Address &function, llvm::Type &prototype,
27b9c1b51eSKate Stone     llvm::Type &return_type, llvm::ArrayRef<ABI::CallArgument> args,
28b9c1b51eSKate Stone     const EvaluateExpressionOptions &options)
29b9c1b51eSKate Stone     : ThreadPlanCallFunction(thread, function, options),
30b9c1b51eSKate Stone       m_return_type(return_type) {
3190ff7911SEwan Crawford   lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
3290ff7911SEwan Crawford   lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
3390ff7911SEwan Crawford   ABI *abi = nullptr;
3490ff7911SEwan Crawford 
3590ff7911SEwan Crawford   if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
3690ff7911SEwan Crawford     return;
3790ff7911SEwan Crawford 
38b9c1b51eSKate Stone   if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
39b9c1b51eSKate Stone                                start_load_addr, prototype, args))
4090ff7911SEwan Crawford     return;
4190ff7911SEwan Crawford 
4290ff7911SEwan Crawford   ReportRegisterState("ABI Function call was set up.  Register state was:");
4390ff7911SEwan Crawford 
4490ff7911SEwan Crawford   m_valid = true;
4590ff7911SEwan Crawford }
4690ff7911SEwan Crawford 
47e65b2cf2SEugene Zelenko ThreadPlanCallFunctionUsingABI::~ThreadPlanCallFunctionUsingABI() = default;
4890ff7911SEwan Crawford 
49b9c1b51eSKate Stone void ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s,
50b9c1b51eSKate Stone                                                     DescriptionLevel level) {
51b9c1b51eSKate Stone   if (level == eDescriptionLevelBrief) {
5290ff7911SEwan Crawford     s->Printf("Function call thread plan using ABI instead of JIT");
53b9c1b51eSKate Stone   } else {
5490ff7911SEwan Crawford     TargetSP target_sp(m_thread.CalculateTarget());
55b9c1b51eSKate Stone     s->Printf("Thread plan to call 0x%" PRIx64 " using ABI instead of JIT",
56b9c1b51eSKate Stone               m_function_addr.GetLoadAddress(target_sp.get()));
5790ff7911SEwan Crawford   }
5890ff7911SEwan Crawford }
5990ff7911SEwan Crawford 
60b9c1b51eSKate Stone void ThreadPlanCallFunctionUsingABI::SetReturnValue() {
6190ff7911SEwan Crawford   ProcessSP process_sp(m_thread.GetProcess());
62e65b2cf2SEugene Zelenko   const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
6390ff7911SEwan Crawford 
6490ff7911SEwan Crawford   // Ask the abi for the return value
65b9c1b51eSKate Stone   if (abi) {
6690ff7911SEwan Crawford     const bool persistent = false;
67b9c1b51eSKate Stone     m_return_valobj_sp =
68b9c1b51eSKate Stone         abi->GetReturnValueObject(m_thread, m_return_type, persistent);
6990ff7911SEwan Crawford   }
7090ff7911SEwan Crawford }
71