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/Core/Log.h"
17b91a7dfcSDimitry Andric #include "lldb/Core/Stream.h"
18b91a7dfcSDimitry Andric #include "lldb/Target/Process.h"
19b91a7dfcSDimitry Andric #include "lldb/Target/RegisterContext.h"
20b91a7dfcSDimitry Andric #include "lldb/Target/Target.h"
21b91a7dfcSDimitry Andric #include "lldb/Target/Thread.h"
22b91a7dfcSDimitry Andric 
23b91a7dfcSDimitry Andric using namespace lldb;
24b91a7dfcSDimitry Andric using namespace lldb_private;
25b91a7dfcSDimitry Andric 
26b91a7dfcSDimitry Andric //--------------------------------------------------------------------------------------------
27b91a7dfcSDimitry Andric // ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI instead of JIT
28b91a7dfcSDimitry Andric //-------------------------------------------------------------------------------------------
29b91a7dfcSDimitry Andric ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI (Thread &thread,
30b91a7dfcSDimitry Andric                                                           const Address &function,
31b91a7dfcSDimitry Andric                                                           llvm::Type &prototype,
32b91a7dfcSDimitry Andric                                                           llvm::Type &return_type,
33b91a7dfcSDimitry Andric                                                           llvm::ArrayRef<ABI::CallArgument> args,
34b91a7dfcSDimitry Andric                                                           const EvaluateExpressionOptions &options) :
35b91a7dfcSDimitry Andric      ThreadPlanCallFunction(thread,function,options),
36b91a7dfcSDimitry Andric      m_return_type(return_type)
37b91a7dfcSDimitry Andric {
38b91a7dfcSDimitry Andric     lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
39b91a7dfcSDimitry Andric     lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
40b91a7dfcSDimitry Andric     ABI *abi = nullptr;
41b91a7dfcSDimitry Andric 
42b91a7dfcSDimitry Andric     if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
43b91a7dfcSDimitry Andric         return;
44b91a7dfcSDimitry Andric 
45b91a7dfcSDimitry Andric     if (!abi->PrepareTrivialCall(thread,
46b91a7dfcSDimitry Andric         m_function_sp,
47b91a7dfcSDimitry Andric         function_load_addr,
48b91a7dfcSDimitry Andric         start_load_addr,
49b91a7dfcSDimitry Andric         prototype,
50b91a7dfcSDimitry Andric         args))
51b91a7dfcSDimitry Andric         return;
52b91a7dfcSDimitry Andric 
53b91a7dfcSDimitry Andric     ReportRegisterState("ABI Function call was set up.  Register state was:");
54b91a7dfcSDimitry Andric 
55b91a7dfcSDimitry Andric     m_valid = true;
56b91a7dfcSDimitry Andric }
57b91a7dfcSDimitry Andric 
589f2f44ceSEd Maste ThreadPlanCallFunctionUsingABI::~ThreadPlanCallFunctionUsingABI() = default;
59b91a7dfcSDimitry Andric 
60b91a7dfcSDimitry Andric void
61b91a7dfcSDimitry Andric ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s, DescriptionLevel level)
62b91a7dfcSDimitry Andric {
63b91a7dfcSDimitry Andric     if (level == eDescriptionLevelBrief)
64b91a7dfcSDimitry Andric     {
65b91a7dfcSDimitry Andric         s->Printf("Function call thread plan using ABI instead of JIT");
66b91a7dfcSDimitry Andric     }
67b91a7dfcSDimitry Andric     else
68b91a7dfcSDimitry Andric     {
69b91a7dfcSDimitry Andric         TargetSP target_sp(m_thread.CalculateTarget());
70b91a7dfcSDimitry Andric         s->Printf("Thread plan to call 0x%" PRIx64" using ABI instead of JIT", m_function_addr.GetLoadAddress(target_sp.get()));
71b91a7dfcSDimitry Andric     }
72b91a7dfcSDimitry Andric }
73b91a7dfcSDimitry Andric 
74b91a7dfcSDimitry Andric void
75b91a7dfcSDimitry Andric ThreadPlanCallFunctionUsingABI::SetReturnValue()
76b91a7dfcSDimitry Andric {
77b91a7dfcSDimitry Andric     ProcessSP process_sp(m_thread.GetProcess());
789f2f44ceSEd Maste     const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
79b91a7dfcSDimitry Andric 
80b91a7dfcSDimitry Andric     // Ask the abi for the return value
81b91a7dfcSDimitry Andric     if (abi)
82b91a7dfcSDimitry Andric     {
83b91a7dfcSDimitry Andric         const bool persistent = false;
84b91a7dfcSDimitry Andric         m_return_valobj_sp = abi->GetReturnValueObject(m_thread, m_return_type, persistent);
85b91a7dfcSDimitry Andric     }
86b91a7dfcSDimitry Andric }
87