1//===-- ClangFunctionCaller.cpp -------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "ClangFunctionCaller.h" 10 11#include "ASTStructExtractor.h" 12#include "ClangExpressionParser.h" 13 14#include "clang/AST/ASTContext.h" 15#include "clang/AST/RecordLayout.h" 16#include "clang/CodeGen/CodeGenAction.h" 17#include "clang/CodeGen/ModuleBuilder.h" 18#include "clang/Frontend/CompilerInstance.h" 19#include "llvm/ADT/StringRef.h" 20#include "llvm/ExecutionEngine/ExecutionEngine.h" 21#include "llvm/IR/Module.h" 22#include "llvm/TargetParser/Triple.h" 23 24#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 25#include "lldb/Core/Module.h" 26#include "lldb/Core/ValueObject.h" 27#include "lldb/Core/ValueObjectList.h" 28#include "lldb/Expression/IRExecutionUnit.h" 29#include "lldb/Interpreter/CommandReturnObject.h" 30#include "lldb/Symbol/Function.h" 31#include "lldb/Symbol/Type.h" 32#include "lldb/Target/ExecutionContext.h" 33#include "lldb/Target/Process.h" 34#include "lldb/Target/RegisterContext.h" 35#include "lldb/Target/Target.h" 36#include "lldb/Target/Thread.h" 37#include "lldb/Target/ThreadPlan.h" 38#include "lldb/Target/ThreadPlanCallFunction.h" 39#include "lldb/Utility/DataExtractor.h" 40#include "lldb/Utility/LLDBLog.h" 41#include "lldb/Utility/Log.h" 42#include "lldb/Utility/State.h" 43 44using namespace lldb_private; 45 46char ClangFunctionCaller::ID; 47 48// ClangFunctionCaller constructor 49ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope, 50 const CompilerType &return_type, 51 const Address &functionAddress, 52 const ValueList &arg_value_list, 53 const char *name) 54 : FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, 55 name), 56 m_type_system_helper(*this) { 57 m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess()); 58 // Can't make a ClangFunctionCaller without a process. 59 assert(m_jit_process_wp.lock()); 60} 61 62// Destructor 63ClangFunctionCaller::~ClangFunctionCaller() = default; 64 65unsigned 66 67ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, 68 DiagnosticManager &diagnostic_manager) { 69 if (m_compiled) 70 return 0; 71 72 // Compilation might call code, make sure to keep on the thread the caller 73 // indicated. 74 ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher( 75 thread_to_use_sp); 76 77 // FIXME: How does clang tell us there's no return value? We need to handle 78 // that case. 79 unsigned num_errors = 0; 80 81 std::string return_type_str( 82 m_function_return_type.GetTypeName().AsCString("")); 83 84 // Cons up the function we're going to wrap our call in, then compile it... 85 // We declare the function "extern "C"" because the compiler might be in C++ 86 // mode which would mangle the name and then we couldn't find it again... 87 m_wrapper_function_text.clear(); 88 m_wrapper_function_text.append("extern \"C\" void "); 89 m_wrapper_function_text.append(m_wrapper_function_name); 90 m_wrapper_function_text.append(" (void *input)\n{\n struct "); 91 m_wrapper_function_text.append(m_wrapper_struct_name); 92 m_wrapper_function_text.append(" \n {\n"); 93 m_wrapper_function_text.append(" "); 94 m_wrapper_function_text.append(return_type_str); 95 m_wrapper_function_text.append(" (*fn_ptr) ("); 96 97 // Get the number of arguments. If we have a function type and it is 98 // prototyped, trust that, otherwise use the values we were given. 99 100 // FIXME: This will need to be extended to handle Variadic functions. We'll 101 // need 102 // to pull the defined arguments out of the function, then add the types from 103 // the arguments list for the variable arguments. 104 105 uint32_t num_args = UINT32_MAX; 106 bool trust_function = false; 107 // GetArgumentCount returns -1 for an unprototyped function. 108 CompilerType function_clang_type; 109 if (m_function_ptr) { 110 function_clang_type = m_function_ptr->GetCompilerType(); 111 if (function_clang_type) { 112 int num_func_args = function_clang_type.GetFunctionArgumentCount(); 113 if (num_func_args >= 0) { 114 trust_function = true; 115 num_args = num_func_args; 116 } 117 } 118 } 119 120 if (num_args == UINT32_MAX) 121 num_args = m_arg_values.GetSize(); 122 123 std::string args_buffer; // This one stores the definition of all the args in 124 // "struct caller". 125 std::string args_list_buffer; // This one stores the argument list called from 126 // the structure. 127 for (size_t i = 0; i < num_args; i++) { 128 std::string type_name; 129 130 if (trust_function) { 131 type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i) 132 .GetTypeName() 133 .AsCString(""); 134 } else { 135 CompilerType clang_qual_type = 136 m_arg_values.GetValueAtIndex(i)->GetCompilerType(); 137 if (clang_qual_type) { 138 type_name = clang_qual_type.GetTypeName().AsCString(""); 139 } else { 140 diagnostic_manager.Printf( 141 eDiagnosticSeverityError, 142 "Could not determine type of input value %" PRIu64 ".", 143 (uint64_t)i); 144 return 1; 145 } 146 } 147 148 m_wrapper_function_text.append(type_name); 149 if (i < num_args - 1) 150 m_wrapper_function_text.append(", "); 151 152 char arg_buf[32]; 153 args_buffer.append(" "); 154 args_buffer.append(type_name); 155 snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i); 156 args_buffer.push_back(' '); 157 args_buffer.append(arg_buf); 158 args_buffer.append(";\n"); 159 160 args_list_buffer.append("__lldb_fn_data->"); 161 args_list_buffer.append(arg_buf); 162 if (i < num_args - 1) 163 args_list_buffer.append(", "); 164 } 165 m_wrapper_function_text.append( 166 ");\n"); // Close off the function calling prototype. 167 168 m_wrapper_function_text.append(args_buffer); 169 170 m_wrapper_function_text.append(" "); 171 m_wrapper_function_text.append(return_type_str); 172 m_wrapper_function_text.append(" return_value;"); 173 m_wrapper_function_text.append("\n };\n struct "); 174 m_wrapper_function_text.append(m_wrapper_struct_name); 175 m_wrapper_function_text.append("* __lldb_fn_data = (struct "); 176 m_wrapper_function_text.append(m_wrapper_struct_name); 177 m_wrapper_function_text.append(" *) input;\n"); 178 179 m_wrapper_function_text.append( 180 " __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr ("); 181 m_wrapper_function_text.append(args_list_buffer); 182 m_wrapper_function_text.append(");\n}\n"); 183 184 Log *log = GetLog(LLDBLog::Expressions); 185 LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); 186 187 // Okay, now compile this expression 188 189 lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock()); 190 if (jit_process_sp) { 191 const bool generate_debug_info = true; 192 auto *clang_parser = new ClangExpressionParser(jit_process_sp.get(), *this, 193 generate_debug_info); 194 num_errors = clang_parser->Parse(diagnostic_manager); 195 m_parser.reset(clang_parser); 196 } else { 197 diagnostic_manager.PutString(eDiagnosticSeverityError, 198 "no process - unable to inject function"); 199 num_errors = 1; 200 } 201 202 m_compiled = (num_errors == 0); 203 204 if (!m_compiled) 205 return num_errors; 206 207 return num_errors; 208} 209 210char ClangFunctionCaller::ClangFunctionCallerHelper::ID; 211 212clang::ASTConsumer * 213ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer( 214 clang::ASTConsumer *passthrough) { 215 m_struct_extractor = std::make_unique<ASTStructExtractor>( 216 passthrough, m_owner.GetWrapperStructName(), m_owner); 217 218 return m_struct_extractor.get(); 219} 220