1*80814287SRaphael Isemann //===-- ThreadPlanCallFunctionUsingABI.cpp --------------------------------===// 290ff7911SEwan Crawford // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 690ff7911SEwan Crawford // 790ff7911SEwan Crawford //===----------------------------------------------------------------------===// 890ff7911SEwan Crawford 9e65b2cf2SEugene Zelenko #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h" 1090ff7911SEwan Crawford #include "lldb/Core/Address.h" 1190ff7911SEwan Crawford #include "lldb/Target/Process.h" 1290ff7911SEwan Crawford #include "lldb/Target/RegisterContext.h" 1390ff7911SEwan Crawford #include "lldb/Target/Target.h" 1490ff7911SEwan Crawford #include "lldb/Target/Thread.h" 156f9e6901SZachary Turner #include "lldb/Utility/Log.h" 16bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 1790ff7911SEwan Crawford 1890ff7911SEwan Crawford using namespace lldb; 1990ff7911SEwan Crawford using namespace lldb_private; 2090ff7911SEwan Crawford 21b9c1b51eSKate Stone // ThreadPlanCallFunctionUsingABI: Plan to call a single function using the ABI 22b9c1b51eSKate Stone // instead of JIT 23b9c1b51eSKate Stone ThreadPlanCallFunctionUsingABI::ThreadPlanCallFunctionUsingABI( 24b9c1b51eSKate Stone Thread &thread, const Address &function, llvm::Type &prototype, 25b9c1b51eSKate Stone llvm::Type &return_type, llvm::ArrayRef<ABI::CallArgument> args, 26b9c1b51eSKate Stone const EvaluateExpressionOptions &options) 27b9c1b51eSKate Stone : ThreadPlanCallFunction(thread, function, options), 28b9c1b51eSKate Stone m_return_type(return_type) { 2990ff7911SEwan Crawford lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS; 3090ff7911SEwan Crawford lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS; 3190ff7911SEwan Crawford ABI *abi = nullptr; 3290ff7911SEwan Crawford 3390ff7911SEwan Crawford if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr)) 3490ff7911SEwan Crawford return; 3590ff7911SEwan Crawford 36b9c1b51eSKate Stone if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr, 37b9c1b51eSKate Stone start_load_addr, prototype, args)) 3890ff7911SEwan Crawford return; 3990ff7911SEwan Crawford 4090ff7911SEwan Crawford ReportRegisterState("ABI Function call was set up. Register state was:"); 4190ff7911SEwan Crawford 4290ff7911SEwan Crawford m_valid = true; 4390ff7911SEwan Crawford } 4490ff7911SEwan Crawford 45e65b2cf2SEugene Zelenko ThreadPlanCallFunctionUsingABI::~ThreadPlanCallFunctionUsingABI() = default; 4690ff7911SEwan Crawford 47b9c1b51eSKate Stone void ThreadPlanCallFunctionUsingABI::GetDescription(Stream *s, 48b9c1b51eSKate Stone DescriptionLevel level) { 49b9c1b51eSKate Stone if (level == eDescriptionLevelBrief) { 5090ff7911SEwan Crawford s->Printf("Function call thread plan using ABI instead of JIT"); 51b9c1b51eSKate Stone } else { 5290ff7911SEwan Crawford TargetSP target_sp(m_thread.CalculateTarget()); 53b9c1b51eSKate Stone s->Printf("Thread plan to call 0x%" PRIx64 " using ABI instead of JIT", 54b9c1b51eSKate Stone m_function_addr.GetLoadAddress(target_sp.get())); 5590ff7911SEwan Crawford } 5690ff7911SEwan Crawford } 5790ff7911SEwan Crawford 58b9c1b51eSKate Stone void ThreadPlanCallFunctionUsingABI::SetReturnValue() { 5990ff7911SEwan Crawford ProcessSP process_sp(m_thread.GetProcess()); 60e65b2cf2SEugene Zelenko const ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr; 6190ff7911SEwan Crawford 6290ff7911SEwan Crawford // Ask the abi for the return value 63b9c1b51eSKate Stone if (abi) { 6490ff7911SEwan Crawford const bool persistent = false; 65b9c1b51eSKate Stone m_return_valobj_sp = 66b9c1b51eSKate Stone abi->GetReturnValueObject(m_thread, m_return_type, persistent); 6790ff7911SEwan Crawford } 6890ff7911SEwan Crawford } 69