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