15ffd83dbSDimitry Andric //===-- ClangFunctionCaller.cpp -------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "ClangFunctionCaller.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "ASTStructExtractor.h" 120b57cec5SDimitry Andric #include "ClangExpressionParser.h" 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 150b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h" 160b57cec5SDimitry Andric #include "clang/CodeGen/CodeGenAction.h" 170b57cec5SDimitry Andric #include "clang/CodeGen/ModuleBuilder.h" 180b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h" 190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 200b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ExecutionEngine.h" 210b57cec5SDimitry Andric #include "llvm/IR/Module.h" 2206c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 230b57cec5SDimitry Andric 245ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 250b57cec5SDimitry Andric #include "lldb/Core/Module.h" 260b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h" 270b57cec5SDimitry Andric #include "lldb/Core/ValueObjectList.h" 280b57cec5SDimitry Andric #include "lldb/Expression/IRExecutionUnit.h" 290b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h" 300b57cec5SDimitry Andric #include "lldb/Symbol/Function.h" 310b57cec5SDimitry Andric #include "lldb/Symbol/Type.h" 320b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h" 330b57cec5SDimitry Andric #include "lldb/Target/Process.h" 340b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h" 350b57cec5SDimitry Andric #include "lldb/Target/Target.h" 360b57cec5SDimitry Andric #include "lldb/Target/Thread.h" 370b57cec5SDimitry Andric #include "lldb/Target/ThreadPlan.h" 380b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanCallFunction.h" 390b57cec5SDimitry Andric #include "lldb/Utility/DataExtractor.h" 4081ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 410b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 420b57cec5SDimitry Andric #include "lldb/Utility/State.h" 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric using namespace lldb_private; 450b57cec5SDimitry Andric 46480093f4SDimitry Andric char ClangFunctionCaller::ID; 47480093f4SDimitry Andric 480b57cec5SDimitry Andric // ClangFunctionCaller constructor 490b57cec5SDimitry Andric ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope, 500b57cec5SDimitry Andric const CompilerType &return_type, 510b57cec5SDimitry Andric const Address &functionAddress, 520b57cec5SDimitry Andric const ValueList &arg_value_list, 530b57cec5SDimitry Andric const char *name) 540b57cec5SDimitry Andric : FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, 550b57cec5SDimitry Andric name), 560b57cec5SDimitry Andric m_type_system_helper(*this) { 570b57cec5SDimitry Andric m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess()); 580b57cec5SDimitry Andric // Can't make a ClangFunctionCaller without a process. 590b57cec5SDimitry Andric assert(m_jit_process_wp.lock()); 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric // Destructor 63fe6060f1SDimitry Andric ClangFunctionCaller::~ClangFunctionCaller() = default; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric unsigned 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, 680b57cec5SDimitry Andric DiagnosticManager &diagnostic_manager) { 690b57cec5SDimitry Andric if (m_compiled) 700b57cec5SDimitry Andric return 0; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric // Compilation might call code, make sure to keep on the thread the caller 730b57cec5SDimitry Andric // indicated. 740b57cec5SDimitry Andric ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher( 750b57cec5SDimitry Andric thread_to_use_sp); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // FIXME: How does clang tell us there's no return value? We need to handle 780b57cec5SDimitry Andric // that case. 790b57cec5SDimitry Andric unsigned num_errors = 0; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric std::string return_type_str( 820b57cec5SDimitry Andric m_function_return_type.GetTypeName().AsCString("")); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric // Cons up the function we're going to wrap our call in, then compile it... 850b57cec5SDimitry Andric // We declare the function "extern "C"" because the compiler might be in C++ 860b57cec5SDimitry Andric // mode which would mangle the name and then we couldn't find it again... 870b57cec5SDimitry Andric m_wrapper_function_text.clear(); 880b57cec5SDimitry Andric m_wrapper_function_text.append("extern \"C\" void "); 890b57cec5SDimitry Andric m_wrapper_function_text.append(m_wrapper_function_name); 900b57cec5SDimitry Andric m_wrapper_function_text.append(" (void *input)\n{\n struct "); 910b57cec5SDimitry Andric m_wrapper_function_text.append(m_wrapper_struct_name); 920b57cec5SDimitry Andric m_wrapper_function_text.append(" \n {\n"); 930b57cec5SDimitry Andric m_wrapper_function_text.append(" "); 940b57cec5SDimitry Andric m_wrapper_function_text.append(return_type_str); 950b57cec5SDimitry Andric m_wrapper_function_text.append(" (*fn_ptr) ("); 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric // Get the number of arguments. If we have a function type and it is 980b57cec5SDimitry Andric // prototyped, trust that, otherwise use the values we were given. 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // FIXME: This will need to be extended to handle Variadic functions. We'll 1010b57cec5SDimitry Andric // need 1020b57cec5SDimitry Andric // to pull the defined arguments out of the function, then add the types from 1030b57cec5SDimitry Andric // the arguments list for the variable arguments. 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric uint32_t num_args = UINT32_MAX; 1060b57cec5SDimitry Andric bool trust_function = false; 1070b57cec5SDimitry Andric // GetArgumentCount returns -1 for an unprototyped function. 1080b57cec5SDimitry Andric CompilerType function_clang_type; 1090b57cec5SDimitry Andric if (m_function_ptr) { 1100b57cec5SDimitry Andric function_clang_type = m_function_ptr->GetCompilerType(); 1110b57cec5SDimitry Andric if (function_clang_type) { 1120b57cec5SDimitry Andric int num_func_args = function_clang_type.GetFunctionArgumentCount(); 1130b57cec5SDimitry Andric if (num_func_args >= 0) { 1140b57cec5SDimitry Andric trust_function = true; 1150b57cec5SDimitry Andric num_args = num_func_args; 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric if (num_args == UINT32_MAX) 1210b57cec5SDimitry Andric num_args = m_arg_values.GetSize(); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric std::string args_buffer; // This one stores the definition of all the args in 1240b57cec5SDimitry Andric // "struct caller". 1250b57cec5SDimitry Andric std::string args_list_buffer; // This one stores the argument list called from 1260b57cec5SDimitry Andric // the structure. 1270b57cec5SDimitry Andric for (size_t i = 0; i < num_args; i++) { 1280b57cec5SDimitry Andric std::string type_name; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric if (trust_function) { 1310b57cec5SDimitry Andric type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i) 1320b57cec5SDimitry Andric .GetTypeName() 1330b57cec5SDimitry Andric .AsCString(""); 1340b57cec5SDimitry Andric } else { 1350b57cec5SDimitry Andric CompilerType clang_qual_type = 1360b57cec5SDimitry Andric m_arg_values.GetValueAtIndex(i)->GetCompilerType(); 1370b57cec5SDimitry Andric if (clang_qual_type) { 1380b57cec5SDimitry Andric type_name = clang_qual_type.GetTypeName().AsCString(""); 1390b57cec5SDimitry Andric } else { 1400b57cec5SDimitry Andric diagnostic_manager.Printf( 141*0fca6ea1SDimitry Andric lldb::eSeverityError, 1420b57cec5SDimitry Andric "Could not determine type of input value %" PRIu64 ".", 1430b57cec5SDimitry Andric (uint64_t)i); 1440b57cec5SDimitry Andric return 1; 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric m_wrapper_function_text.append(type_name); 1490b57cec5SDimitry Andric if (i < num_args - 1) 1500b57cec5SDimitry Andric m_wrapper_function_text.append(", "); 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric char arg_buf[32]; 1530b57cec5SDimitry Andric args_buffer.append(" "); 1540b57cec5SDimitry Andric args_buffer.append(type_name); 1550b57cec5SDimitry Andric snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i); 1560b57cec5SDimitry Andric args_buffer.push_back(' '); 1570b57cec5SDimitry Andric args_buffer.append(arg_buf); 1580b57cec5SDimitry Andric args_buffer.append(";\n"); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric args_list_buffer.append("__lldb_fn_data->"); 1610b57cec5SDimitry Andric args_list_buffer.append(arg_buf); 1620b57cec5SDimitry Andric if (i < num_args - 1) 1630b57cec5SDimitry Andric args_list_buffer.append(", "); 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric m_wrapper_function_text.append( 1660b57cec5SDimitry Andric ");\n"); // Close off the function calling prototype. 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric m_wrapper_function_text.append(args_buffer); 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric m_wrapper_function_text.append(" "); 1710b57cec5SDimitry Andric m_wrapper_function_text.append(return_type_str); 1720b57cec5SDimitry Andric m_wrapper_function_text.append(" return_value;"); 1730b57cec5SDimitry Andric m_wrapper_function_text.append("\n };\n struct "); 1740b57cec5SDimitry Andric m_wrapper_function_text.append(m_wrapper_struct_name); 1750b57cec5SDimitry Andric m_wrapper_function_text.append("* __lldb_fn_data = (struct "); 1760b57cec5SDimitry Andric m_wrapper_function_text.append(m_wrapper_struct_name); 1770b57cec5SDimitry Andric m_wrapper_function_text.append(" *) input;\n"); 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric m_wrapper_function_text.append( 1800b57cec5SDimitry Andric " __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr ("); 1810b57cec5SDimitry Andric m_wrapper_function_text.append(args_list_buffer); 1820b57cec5SDimitry Andric m_wrapper_function_text.append(");\n}\n"); 1830b57cec5SDimitry Andric 18481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 1859dba64beSDimitry Andric LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric // Okay, now compile this expression 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock()); 1900b57cec5SDimitry Andric if (jit_process_sp) { 1910b57cec5SDimitry Andric const bool generate_debug_info = true; 192480093f4SDimitry Andric auto *clang_parser = new ClangExpressionParser(jit_process_sp.get(), *this, 193480093f4SDimitry Andric generate_debug_info); 194480093f4SDimitry Andric num_errors = clang_parser->Parse(diagnostic_manager); 195480093f4SDimitry Andric m_parser.reset(clang_parser); 1960b57cec5SDimitry Andric } else { 197*0fca6ea1SDimitry Andric diagnostic_manager.PutString(lldb::eSeverityError, 1980b57cec5SDimitry Andric "no process - unable to inject function"); 1990b57cec5SDimitry Andric num_errors = 1; 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric m_compiled = (num_errors == 0); 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric if (!m_compiled) 2050b57cec5SDimitry Andric return num_errors; 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric return num_errors; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 21006c3fb27SDimitry Andric char ClangFunctionCaller::ClangFunctionCallerHelper::ID; 21106c3fb27SDimitry Andric 2120b57cec5SDimitry Andric clang::ASTConsumer * 2130b57cec5SDimitry Andric ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer( 2140b57cec5SDimitry Andric clang::ASTConsumer *passthrough) { 2155ffd83dbSDimitry Andric m_struct_extractor = std::make_unique<ASTStructExtractor>( 2165ffd83dbSDimitry Andric passthrough, m_owner.GetWrapperStructName(), m_owner); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric return m_struct_extractor.get(); 2190b57cec5SDimitry Andric } 220