1314564Sdim//===-- ClangFunctionCaller.cpp ---------------------------------*- C++ -*-===// 2292932Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6292932Sdim// 7292932Sdim//===----------------------------------------------------------------------===// 8292932Sdim 9292932Sdim#include "ClangFunctionCaller.h" 10292932Sdim 11292932Sdim#include "ASTStructExtractor.h" 12292932Sdim#include "ClangExpressionParser.h" 13292932Sdim 14292932Sdim#include "clang/AST/ASTContext.h" 15292932Sdim#include "clang/AST/RecordLayout.h" 16292932Sdim#include "clang/CodeGen/CodeGenAction.h" 17292932Sdim#include "clang/CodeGen/ModuleBuilder.h" 18292932Sdim#include "clang/Frontend/CompilerInstance.h" 19292932Sdim#include "llvm/ADT/StringRef.h" 20292932Sdim#include "llvm/ADT/Triple.h" 21292932Sdim#include "llvm/ExecutionEngine/ExecutionEngine.h" 22292932Sdim#include "llvm/IR/Module.h" 23292932Sdim 24292932Sdim#include "lldb/Core/Module.h" 25292932Sdim#include "lldb/Core/ValueObject.h" 26292932Sdim#include "lldb/Core/ValueObjectList.h" 27292932Sdim#include "lldb/Expression/IRExecutionUnit.h" 28292932Sdim#include "lldb/Interpreter/CommandReturnObject.h" 29292932Sdim#include "lldb/Symbol/ClangASTContext.h" 30292932Sdim#include "lldb/Symbol/Function.h" 31292932Sdim#include "lldb/Symbol/Type.h" 32292932Sdim#include "lldb/Target/ExecutionContext.h" 33292932Sdim#include "lldb/Target/Process.h" 34292932Sdim#include "lldb/Target/RegisterContext.h" 35292932Sdim#include "lldb/Target/Target.h" 36292932Sdim#include "lldb/Target/Thread.h" 37292932Sdim#include "lldb/Target/ThreadPlan.h" 38292932Sdim#include "lldb/Target/ThreadPlanCallFunction.h" 39321369Sdim#include "lldb/Utility/DataExtractor.h" 40321369Sdim#include "lldb/Utility/Log.h" 41344779Sdim#include "lldb/Utility/State.h" 42292932Sdim 43292932Sdimusing namespace lldb_private; 44292932Sdim 45360784Sdimchar ClangFunctionCaller::ID; 46360784Sdim 47292932Sdim// ClangFunctionCaller constructor 48314564SdimClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope, 49314564Sdim const CompilerType &return_type, 50314564Sdim const Address &functionAddress, 51314564Sdim const ValueList &arg_value_list, 52314564Sdim const char *name) 53314564Sdim : FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, 54314564Sdim name), 55314564Sdim m_type_system_helper(*this) { 56314564Sdim m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess()); 57314564Sdim // Can't make a ClangFunctionCaller without a process. 58314564Sdim assert(m_jit_process_wp.lock()); 59292932Sdim} 60292932Sdim 61292932Sdim// Destructor 62314564SdimClangFunctionCaller::~ClangFunctionCaller() {} 63292932Sdim 64292932Sdimunsigned 65309124Sdim 66314564SdimClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, 67314564Sdim DiagnosticManager &diagnostic_manager) { 68314564Sdim if (m_compiled) 69314564Sdim return 0; 70309124Sdim 71314564Sdim // Compilation might call code, make sure to keep on the thread the caller 72314564Sdim // indicated. 73314564Sdim ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher( 74314564Sdim thread_to_use_sp); 75292932Sdim 76314564Sdim // FIXME: How does clang tell us there's no return value? We need to handle 77314564Sdim // that case. 78314564Sdim unsigned num_errors = 0; 79292932Sdim 80314564Sdim std::string return_type_str( 81314564Sdim m_function_return_type.GetTypeName().AsCString("")); 82292932Sdim 83314564Sdim // Cons up the function we're going to wrap our call in, then compile it... 84314564Sdim // We declare the function "extern "C"" because the compiler might be in C++ 85314564Sdim // mode which would mangle the name and then we couldn't find it again... 86314564Sdim m_wrapper_function_text.clear(); 87314564Sdim m_wrapper_function_text.append("extern \"C\" void "); 88314564Sdim m_wrapper_function_text.append(m_wrapper_function_name); 89314564Sdim m_wrapper_function_text.append(" (void *input)\n{\n struct "); 90314564Sdim m_wrapper_function_text.append(m_wrapper_struct_name); 91314564Sdim m_wrapper_function_text.append(" \n {\n"); 92314564Sdim m_wrapper_function_text.append(" "); 93314564Sdim m_wrapper_function_text.append(return_type_str); 94314564Sdim m_wrapper_function_text.append(" (*fn_ptr) ("); 95314564Sdim 96314564Sdim // Get the number of arguments. If we have a function type and it is 97341825Sdim // prototyped, trust that, otherwise use the values we were given. 98314564Sdim 99314564Sdim // FIXME: This will need to be extended to handle Variadic functions. We'll 100314564Sdim // need 101314564Sdim // to pull the defined arguments out of the function, then add the types from 102341825Sdim // the arguments list for the variable arguments. 103314564Sdim 104314564Sdim uint32_t num_args = UINT32_MAX; 105314564Sdim bool trust_function = false; 106314564Sdim // GetArgumentCount returns -1 for an unprototyped function. 107314564Sdim CompilerType function_clang_type; 108314564Sdim if (m_function_ptr) { 109314564Sdim function_clang_type = m_function_ptr->GetCompilerType(); 110314564Sdim if (function_clang_type) { 111314564Sdim int num_func_args = function_clang_type.GetFunctionArgumentCount(); 112314564Sdim if (num_func_args >= 0) { 113314564Sdim trust_function = true; 114314564Sdim num_args = num_func_args; 115314564Sdim } 116292932Sdim } 117314564Sdim } 118292932Sdim 119314564Sdim if (num_args == UINT32_MAX) 120314564Sdim num_args = m_arg_values.GetSize(); 121292932Sdim 122314564Sdim std::string args_buffer; // This one stores the definition of all the args in 123314564Sdim // "struct caller". 124314564Sdim std::string args_list_buffer; // This one stores the argument list called from 125314564Sdim // the structure. 126314564Sdim for (size_t i = 0; i < num_args; i++) { 127314564Sdim std::string type_name; 128292932Sdim 129314564Sdim if (trust_function) { 130314564Sdim type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i) 131314564Sdim .GetTypeName() 132314564Sdim .AsCString(""); 133314564Sdim } else { 134314564Sdim CompilerType clang_qual_type = 135314564Sdim m_arg_values.GetValueAtIndex(i)->GetCompilerType(); 136314564Sdim if (clang_qual_type) { 137314564Sdim type_name = clang_qual_type.GetTypeName().AsCString(""); 138314564Sdim } else { 139314564Sdim diagnostic_manager.Printf( 140314564Sdim eDiagnosticSeverityError, 141314564Sdim "Could not determine type of input value %" PRIu64 ".", 142314564Sdim (uint64_t)i); 143314564Sdim return 1; 144314564Sdim } 145314564Sdim } 146292932Sdim 147314564Sdim m_wrapper_function_text.append(type_name); 148314564Sdim if (i < num_args - 1) 149314564Sdim m_wrapper_function_text.append(", "); 150292932Sdim 151314564Sdim char arg_buf[32]; 152314564Sdim args_buffer.append(" "); 153314564Sdim args_buffer.append(type_name); 154314564Sdim snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i); 155314564Sdim args_buffer.push_back(' '); 156314564Sdim args_buffer.append(arg_buf); 157314564Sdim args_buffer.append(";\n"); 158292932Sdim 159314564Sdim args_list_buffer.append("__lldb_fn_data->"); 160314564Sdim args_list_buffer.append(arg_buf); 161314564Sdim if (i < num_args - 1) 162314564Sdim args_list_buffer.append(", "); 163314564Sdim } 164314564Sdim m_wrapper_function_text.append( 165314564Sdim ");\n"); // Close off the function calling prototype. 166292932Sdim 167314564Sdim m_wrapper_function_text.append(args_buffer); 168292932Sdim 169314564Sdim m_wrapper_function_text.append(" "); 170314564Sdim m_wrapper_function_text.append(return_type_str); 171314564Sdim m_wrapper_function_text.append(" return_value;"); 172314564Sdim m_wrapper_function_text.append("\n };\n struct "); 173314564Sdim m_wrapper_function_text.append(m_wrapper_struct_name); 174314564Sdim m_wrapper_function_text.append("* __lldb_fn_data = (struct "); 175314564Sdim m_wrapper_function_text.append(m_wrapper_struct_name); 176314564Sdim m_wrapper_function_text.append(" *) input;\n"); 177292932Sdim 178314564Sdim m_wrapper_function_text.append( 179314564Sdim " __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr ("); 180314564Sdim m_wrapper_function_text.append(args_list_buffer); 181314564Sdim m_wrapper_function_text.append(");\n}\n"); 182292932Sdim 183314564Sdim Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 184360784Sdim LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); 185292932Sdim 186314564Sdim // Okay, now compile this expression 187309124Sdim 188314564Sdim lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock()); 189314564Sdim if (jit_process_sp) { 190314564Sdim const bool generate_debug_info = true; 191360784Sdim auto *clang_parser = new ClangExpressionParser(jit_process_sp.get(), *this, 192360784Sdim generate_debug_info); 193360784Sdim num_errors = clang_parser->Parse(diagnostic_manager); 194360784Sdim m_parser.reset(clang_parser); 195314564Sdim } else { 196314564Sdim diagnostic_manager.PutString(eDiagnosticSeverityError, 197314564Sdim "no process - unable to inject function"); 198314564Sdim num_errors = 1; 199314564Sdim } 200292932Sdim 201314564Sdim m_compiled = (num_errors == 0); 202314564Sdim 203314564Sdim if (!m_compiled) 204292932Sdim return num_errors; 205314564Sdim 206314564Sdim return num_errors; 207292932Sdim} 208292932Sdim 209292932Sdimclang::ASTConsumer * 210314564SdimClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer( 211314564Sdim clang::ASTConsumer *passthrough) { 212314564Sdim m_struct_extractor.reset(new ASTStructExtractor( 213314564Sdim passthrough, m_owner.GetWrapperStructName(), m_owner)); 214314564Sdim 215314564Sdim return m_struct_extractor.get(); 216292932Sdim} 217