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