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