xref: /src/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1cfca06d7SDimitry Andric //===-- ThreadPlanCallFunctionUsingABI.cpp --------------------------------===//
2027f1c96SDimitry Andric //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6027f1c96SDimitry Andric //
7027f1c96SDimitry Andric //===----------------------------------------------------------------------===//
8027f1c96SDimitry Andric 
9e81d9d49SDimitry Andric #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"
10027f1c96SDimitry Andric #include "lldb/Core/Address.h"
11027f1c96SDimitry Andric #include "lldb/Target/Process.h"
12027f1c96SDimitry Andric #include "lldb/Target/RegisterContext.h"
13027f1c96SDimitry Andric #include "lldb/Target/Target.h"
14027f1c96SDimitry Andric #include "lldb/Target/Thread.h"
1574a628f7SDimitry Andric #include "lldb/Utility/Log.h"
1674a628f7SDimitry Andric #include "lldb/Utility/Stream.h"
17027f1c96SDimitry Andric 
18027f1c96SDimitry Andric using namespace lldb;
19027f1c96SDimitry Andric using namespace lldb_private;
20027f1c96SDimitry Andric 
2114f1b3e8SDimitry Andric // ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI
2214f1b3e8SDimitry Andric // instead of JIT
ThreadPlanCallFunctionUsingABI(Thread & thread,const Address & function,llvm::Type & prototype,llvm::Type & return_type,llvm::ArrayRef<ABI::CallArgument> args,const EvaluateExpressionOptions & options)2314f1b3e8SDimitry Andric ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI(
2414f1b3e8SDimitry Andric     Thread &thread, const Address &function, llvm::Type &prototype,
2514f1b3e8SDimitry Andric     llvm::Type &return_type, llvm::ArrayRef<ABI::CallArgument> args,
2614f1b3e8SDimitry Andric     const EvaluateExpressionOptions &options)
2714f1b3e8SDimitry Andric     : ThreadPlanCallFunction(thread, function, options),
2814f1b3e8SDimitry Andric       m_return_type(return_type) {
29027f1c96SDimitry Andric   lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
30027f1c96SDimitry Andric   lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
31027f1c96SDimitry Andric   ABI *abi = nullptr;
32027f1c96SDimitry Andric 
33027f1c96SDimitry Andric   if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
34027f1c96SDimitry Andric     return;
35027f1c96SDimitry Andric 
3614f1b3e8SDimitry Andric   if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
3714f1b3e8SDimitry Andric                                start_load_addr, prototype, args))
38027f1c96SDimitry Andric     return;
39027f1c96SDimitry Andric 
40027f1c96SDimitry Andric   ReportRegisterState("ABI Function call was set up.  Register state was:");
41027f1c96SDimitry Andric 
42027f1c96SDimitry Andric   m_valid = true;
43027f1c96SDimitry Andric }
44027f1c96SDimitry Andric 
45e81d9d49SDimitry Andric ThreadPlanCallFunctionUsingABI::~ThreadPlanCallFunctionUsingABI() = default;
46027f1c96SDimitry Andric 
GetDescription(Stream * s,DescriptionLevel level)4714f1b3e8SDimitry Andric void ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s,
4814f1b3e8SDimitry Andric                                                     DescriptionLevel level) {
4914f1b3e8SDimitry Andric   if (level == eDescriptionLevelBrief) {
50027f1c96SDimitry Andric     s->Printf("Function call thread plan using ABI instead of JIT");
5114f1b3e8SDimitry Andric   } else {
5214f1b3e8SDimitry Andric     s->Printf("Thread plan to call 0x%" PRIx64 " using ABI instead of JIT",
53cfca06d7SDimitry Andric               m_function_addr.GetLoadAddress(&GetTarget()));
54027f1c96SDimitry Andric   }
55027f1c96SDimitry Andric }
56027f1c96SDimitry Andric 
SetReturnValue()5714f1b3e8SDimitry Andric void ThreadPlanCallFunctionUsingABI::SetReturnValue() {
58cfca06d7SDimitry Andric   const ABI *abi = m_process.GetABI().get();
59027f1c96SDimitry Andric 
60027f1c96SDimitry Andric   // Ask the abi for the return value
6114f1b3e8SDimitry Andric   if (abi) {
62027f1c96SDimitry Andric     const bool persistent = false;
6314f1b3e8SDimitry Andric     m_return_valobj_sp =
64cfca06d7SDimitry Andric         abi->GetReturnValueObject(GetThread(), m_return_type, persistent);
65027f1c96SDimitry Andric   }
66027f1c96SDimitry Andric }
67