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