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