1e65b2cf2SEugene Zelenko //===-- ThreadPlanCallFunctionUsingABI.cpp ----------------------*- C++ -*-===//
290ff7911SEwan Crawford //
390ff7911SEwan Crawford //                     The LLVM Compiler Infrastructure
490ff7911SEwan Crawford //
590ff7911SEwan Crawford // This file is distributed under the University of Illinois Open Source
690ff7911SEwan Crawford // License. See LICENSE.TXT for details.
790ff7911SEwan Crawford //
890ff7911SEwan Crawford //===----------------------------------------------------------------------===//
990ff7911SEwan Crawford 
1090ff7911SEwan Crawford // C Includes
1190ff7911SEwan Crawford // C++ Includes
1290ff7911SEwan Crawford // Other libraries and framework includes
1390ff7911SEwan Crawford // Project includes
14e65b2cf2SEugene Zelenko #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"
1590ff7911SEwan Crawford #include "lldb/Core/Address.h"
1690ff7911SEwan Crawford #include "lldb/Core/Log.h"
1790ff7911SEwan Crawford #include "lldb/Target/Process.h"
1890ff7911SEwan Crawford #include "lldb/Target/RegisterContext.h"
1990ff7911SEwan Crawford #include "lldb/Target/Target.h"
2090ff7911SEwan Crawford #include "lldb/Target/Thread.h"
21*bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
2290ff7911SEwan Crawford 
2390ff7911SEwan Crawford using namespace lldb;
2490ff7911SEwan Crawford using namespace lldb_private;
2590ff7911SEwan Crawford 
2690ff7911SEwan Crawford //--------------------------------------------------------------------------------------------
27b9c1b51eSKate Stone // ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI
28b9c1b51eSKate Stone // instead of JIT
2990ff7911SEwan Crawford //-------------------------------------------------------------------------------------------
30b9c1b51eSKate Stone ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI(
31b9c1b51eSKate Stone     Thread &thread, const Address &function, llvm::Type &prototype,
32b9c1b51eSKate Stone     llvm::Type &return_type, llvm::ArrayRef<ABI::CallArgument> args,
33b9c1b51eSKate Stone     const EvaluateExpressionOptions &options)
34b9c1b51eSKate Stone     : ThreadPlanCallFunction(thread, function, options),
35b9c1b51eSKate Stone       m_return_type(return_type) {
3690ff7911SEwan Crawford   lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
3790ff7911SEwan Crawford   lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
3890ff7911SEwan Crawford   ABI *abi = nullptr;
3990ff7911SEwan Crawford 
4090ff7911SEwan Crawford   if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
4190ff7911SEwan Crawford     return;
4290ff7911SEwan Crawford 
43b9c1b51eSKate Stone   if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
44b9c1b51eSKate Stone                                start_load_addr, prototype, args))
4590ff7911SEwan Crawford     return;
4690ff7911SEwan Crawford 
4790ff7911SEwan Crawford   ReportRegisterState("ABI Function call was set up.  Register state was:");
4890ff7911SEwan Crawford 
4990ff7911SEwan Crawford   m_valid = true;
5090ff7911SEwan Crawford }
5190ff7911SEwan Crawford 
52e65b2cf2SEugene Zelenko ThreadPlanCallFunctionUsingABI::~ThreadPlanCallFunctionUsingABI() = default;
5390ff7911SEwan Crawford 
54b9c1b51eSKate Stone void ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s,
55b9c1b51eSKate Stone                                                     DescriptionLevel level) {
56b9c1b51eSKate Stone   if (level == eDescriptionLevelBrief) {
5790ff7911SEwan Crawford     s->Printf("Function call thread plan using ABI instead of JIT");
58b9c1b51eSKate Stone   } else {
5990ff7911SEwan Crawford     TargetSP target_sp(m_thread.CalculateTarget());
60b9c1b51eSKate Stone     s->Printf("Thread plan to call 0x%" PRIx64 " using ABI instead of JIT",
61b9c1b51eSKate Stone               m_function_addr.GetLoadAddress(target_sp.get()));
6290ff7911SEwan Crawford   }
6390ff7911SEwan Crawford }
6490ff7911SEwan Crawford 
65b9c1b51eSKate Stone void ThreadPlanCallFunctionUsingABI::SetReturnValue() {
6690ff7911SEwan Crawford   ProcessSP process_sp(m_thread.GetProcess());
67e65b2cf2SEugene Zelenko   const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
6890ff7911SEwan Crawford 
6990ff7911SEwan Crawford   // Ask the abi for the return value
70b9c1b51eSKate Stone   if (abi) {
7190ff7911SEwan Crawford     const bool persistent = false;
72b9c1b51eSKate Stone     m_return_valobj_sp =
73b9c1b51eSKate Stone         abi->GetReturnValueObject(m_thread, m_return_type, persistent);
7490ff7911SEwan Crawford   }
7590ff7911SEwan Crawford }
76