19f2f44ceSEd Maste //===-- ThreadPlanCallFunctionUsingABI.cpp ----------------------*- C++ -*-===//
2b91a7dfcSDimitry Andric //
3b91a7dfcSDimitry Andric //                     The LLVM Compiler Infrastructure
4b91a7dfcSDimitry Andric //
5b91a7dfcSDimitry Andric // This file is distributed under the University of Illinois Open Source
6b91a7dfcSDimitry Andric // License. See LICENSE.TXT for details.
7b91a7dfcSDimitry Andric //
8b91a7dfcSDimitry Andric //===----------------------------------------------------------------------===//
9b91a7dfcSDimitry Andric 
10b91a7dfcSDimitry Andric // C Includes
11b91a7dfcSDimitry Andric // C++ Includes
12b91a7dfcSDimitry Andric // Other libraries and framework includes
13b91a7dfcSDimitry Andric // Project includes
149f2f44ceSEd Maste #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"
15b91a7dfcSDimitry Andric #include "lldb/Core/Address.h"
16b91a7dfcSDimitry Andric #include "lldb/Target/Process.h"
17b91a7dfcSDimitry Andric #include "lldb/Target/RegisterContext.h"
18b91a7dfcSDimitry Andric #include "lldb/Target/Target.h"
19b91a7dfcSDimitry Andric #include "lldb/Target/Thread.h"
20f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
21f678e45dSDimitry Andric #include "lldb/Utility/Stream.h"
22b91a7dfcSDimitry Andric 
23b91a7dfcSDimitry Andric using namespace lldb;
24b91a7dfcSDimitry Andric using namespace lldb_private;
25b91a7dfcSDimitry Andric 
26b91a7dfcSDimitry Andric //--------------------------------------------------------------------------------------------
27435933ddSDimitry Andric // ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI
28435933ddSDimitry Andric // instead of JIT
29b91a7dfcSDimitry Andric //-------------------------------------------------------------------------------------------
30435933ddSDimitry Andric ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI(
31435933ddSDimitry Andric     Thread &thread, const Address &function, llvm::Type &prototype,
32435933ddSDimitry Andric     llvm::Type &return_type, llvm::ArrayRef<ABI::CallArgument> args,
33435933ddSDimitry Andric     const EvaluateExpressionOptions &options)
34435933ddSDimitry Andric     : ThreadPlanCallFunction(thread, function, options),
35435933ddSDimitry Andric       m_return_type(return_type) {
36b91a7dfcSDimitry Andric   lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
37b91a7dfcSDimitry Andric   lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
38b91a7dfcSDimitry Andric   ABI *abi = nullptr;
39b91a7dfcSDimitry Andric 
40b91a7dfcSDimitry Andric   if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
41b91a7dfcSDimitry Andric     return;
42b91a7dfcSDimitry Andric 
43435933ddSDimitry Andric   if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
44435933ddSDimitry Andric                                start_load_addr, prototype, args))
45b91a7dfcSDimitry Andric     return;
46b91a7dfcSDimitry Andric 
47b91a7dfcSDimitry Andric   ReportRegisterState("ABI Function call was set up.  Register state was:");
48b91a7dfcSDimitry Andric 
49b91a7dfcSDimitry Andric   m_valid = true;
50b91a7dfcSDimitry Andric }
51b91a7dfcSDimitry Andric 
529f2f44ceSEd Maste ThreadPlanCallFunctionUsingABI::~ThreadPlanCallFunctionUsingABI() = default;
53b91a7dfcSDimitry Andric 
54435933ddSDimitry Andric void ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s,
55435933ddSDimitry Andric                                                     DescriptionLevel level) {
56435933ddSDimitry Andric   if (level == eDescriptionLevelBrief) {
57b91a7dfcSDimitry Andric     s->Printf("Function call thread plan using ABI instead of JIT");
58435933ddSDimitry Andric   } else {
59b91a7dfcSDimitry Andric     TargetSP target_sp(m_thread.CalculateTarget());
60435933ddSDimitry Andric     s->Printf("Thread plan to call 0x%" PRIx64 " using ABI instead of JIT",
61435933ddSDimitry Andric               m_function_addr.GetLoadAddress(target_sp.get()));
62b91a7dfcSDimitry Andric   }
63b91a7dfcSDimitry Andric }
64b91a7dfcSDimitry Andric 
65435933ddSDimitry Andric void ThreadPlanCallFunctionUsingABI::SetReturnValue() {
66b91a7dfcSDimitry Andric   ProcessSP process_sp(m_thread.GetProcess());
679f2f44ceSEd Maste   const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
68b91a7dfcSDimitry Andric 
69b91a7dfcSDimitry Andric   // Ask the abi for the return value
70435933ddSDimitry Andric   if (abi) {
71b91a7dfcSDimitry Andric     const bool persistent = false;
72435933ddSDimitry Andric     m_return_valobj_sp =
73435933ddSDimitry Andric         abi->GetReturnValueObject(m_thread, m_return_type, persistent);
74b91a7dfcSDimitry Andric   }
75b91a7dfcSDimitry Andric }
76