blob: 3155e6f7965f9eb42fbb4e0f9c4c15eeefcced4f [file] [log] [blame]
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +00001//===-- ThreadPlanCallFunctionUsingABI.cpp ----------------------*- C++ -*-===//
Ewan Crawford90ff7912015-07-14 10:56:58 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Ewan Crawford90ff7912015-07-14 10:56:58 +00006//
7//===----------------------------------------------------------------------===//
8
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +00009#include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"
Ewan Crawford90ff7912015-07-14 10:56:58 +000010#include "lldb/Core/Address.h"
Ewan Crawford90ff7912015-07-14 10:56:58 +000011#include "lldb/Target/Process.h"
12#include "lldb/Target/RegisterContext.h"
13#include "lldb/Target/Target.h"
14#include "lldb/Target/Thread.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000015#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000016#include "lldb/Utility/Stream.h"
Ewan Crawford90ff7912015-07-14 10:56:58 +000017
18using namespace lldb;
19using namespace lldb_private;
20
Kate Stoneb9c1b512016-09-06 20:57:50 +000021// ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI
22// instead of JIT
Kate Stoneb9c1b512016-09-06 20:57:50 +000023ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI(
24 Thread &thread, const Address &function, llvm::Type &prototype,
25 llvm::Type &return_type, llvm::ArrayRef<ABI::CallArgument> args,
26 const EvaluateExpressionOptions &options)
27 : ThreadPlanCallFunction(thread, function, options),
28 m_return_type(return_type) {
29 lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
30 lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
31 ABI *abi = nullptr;
Ewan Crawford90ff7912015-07-14 10:56:58 +000032
Kate Stoneb9c1b512016-09-06 20:57:50 +000033 if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
34 return;
Ewan Crawford90ff7912015-07-14 10:56:58 +000035
Kate Stoneb9c1b512016-09-06 20:57:50 +000036 if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
37 start_load_addr, prototype, args))
38 return;
Ewan Crawford90ff7912015-07-14 10:56:58 +000039
Kate Stoneb9c1b512016-09-06 20:57:50 +000040 ReportRegisterState("ABI Function call was set up. Register state was:");
Ewan Crawford90ff7912015-07-14 10:56:58 +000041
Kate Stoneb9c1b512016-09-06 20:57:50 +000042 m_valid = true;
Ewan Crawford90ff7912015-07-14 10:56:58 +000043}
44
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +000045ThreadPlanCallFunctionUsingABI::~ThreadPlanCallFunctionUsingABI() = default;
Ewan Crawford90ff7912015-07-14 10:56:58 +000046
Kate Stoneb9c1b512016-09-06 20:57:50 +000047void ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s,
48 DescriptionLevel level) {
49 if (level == eDescriptionLevelBrief) {
50 s->Printf("Function call thread plan using ABI instead of JIT");
51 } else {
52 TargetSP target_sp(m_thread.CalculateTarget());
53 s->Printf("Thread plan to call 0x%" PRIx64 " using ABI instead of JIT",
54 m_function_addr.GetLoadAddress(target_sp.get()));
55 }
Ewan Crawford90ff7912015-07-14 10:56:58 +000056}
57
Kate Stoneb9c1b512016-09-06 20:57:50 +000058void ThreadPlanCallFunctionUsingABI::SetReturnValue() {
59 ProcessSP process_sp(m_thread.GetProcess());
60 const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;
Ewan Crawford90ff7912015-07-14 10:56:58 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 // Ask the abi for the return value
63 if (abi) {
64 const bool persistent = false;
65 m_return_valobj_sp =
66 abi->GetReturnValueObject(m_thread, m_return_type, persistent);
67 }
Ewan Crawford90ff7912015-07-14 10:56:58 +000068}