LLDB  mainline
ClangFunctionCaller.cpp
Go to the documentation of this file.
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/ADT/Triple.h"
21 #include "llvm/ExecutionEngine/ExecutionEngine.h"
22 #include "llvm/IR/Module.h"
23 
25 #include "lldb/Core/Module.h"
26 #include "lldb/Core/ValueObject.h"
30 #include "lldb/Symbol/Function.h"
31 #include "lldb/Symbol/Type.h"
33 #include "lldb/Target/Process.h"
35 #include "lldb/Target/Target.h"
36 #include "lldb/Target/Thread.h"
37 #include "lldb/Target/ThreadPlan.h"
40 #include "lldb/Utility/Log.h"
41 #include "lldb/Utility/State.h"
42 
43 using namespace lldb_private;
44 
46 
47 // ClangFunctionCaller constructor
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 // Destructor
63 
64 unsigned
65 
66 ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp,
67  DiagnosticManager &diagnostic_manager) {
68  if (m_compiled)
69  return 0;
70 
71  // Compilation might call code, make sure to keep on the thread the caller
72  // indicated.
73  ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(
74  thread_to_use_sp);
75 
76  // FIXME: How does clang tell us there's no return value? We need to handle
77  // that case.
78  unsigned num_errors = 0;
79 
80  std::string return_type_str(
82 
83  // Cons up the function we're going to wrap our call in, then compile it...
84  // We declare the function "extern "C"" because the compiler might be in C++
85  // mode which would mangle the name and then we couldn't find it again...
87  m_wrapper_function_text.append("extern \"C\" void ");
89  m_wrapper_function_text.append(" (void *input)\n{\n struct ");
91  m_wrapper_function_text.append(" \n {\n");
92  m_wrapper_function_text.append(" ");
93  m_wrapper_function_text.append(return_type_str);
94  m_wrapper_function_text.append(" (*fn_ptr) (");
95 
96  // Get the number of arguments. If we have a function type and it is
97  // prototyped, trust that, otherwise use the values we were given.
98 
99  // FIXME: This will need to be extended to handle Variadic functions. We'll
100  // need
101  // to pull the defined arguments out of the function, then add the types from
102  // the arguments list for the variable arguments.
103 
104  uint32_t num_args = UINT32_MAX;
105  bool trust_function = false;
106  // GetArgumentCount returns -1 for an unprototyped function.
107  CompilerType function_clang_type;
108  if (m_function_ptr) {
109  function_clang_type = m_function_ptr->GetCompilerType();
110  if (function_clang_type) {
111  int num_func_args = function_clang_type.GetFunctionArgumentCount();
112  if (num_func_args >= 0) {
113  trust_function = true;
114  num_args = num_func_args;
115  }
116  }
117  }
118 
119  if (num_args == UINT32_MAX)
120  num_args = m_arg_values.GetSize();
121 
122  std::string args_buffer; // This one stores the definition of all the args in
123  // "struct caller".
124  std::string args_list_buffer; // This one stores the argument list called from
125  // the structure.
126  for (size_t i = 0; i < num_args; i++) {
127  std::string type_name;
128 
129  if (trust_function) {
130  type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i)
131  .GetTypeName()
132  .AsCString("");
133  } else {
134  CompilerType clang_qual_type =
136  if (clang_qual_type) {
137  type_name = clang_qual_type.GetTypeName().AsCString("");
138  } else {
139  diagnostic_manager.Printf(
141  "Could not determine type of input value %" PRIu64 ".",
142  (uint64_t)i);
143  return 1;
144  }
145  }
146 
147  m_wrapper_function_text.append(type_name);
148  if (i < num_args - 1)
149  m_wrapper_function_text.append(", ");
150 
151  char arg_buf[32];
152  args_buffer.append(" ");
153  args_buffer.append(type_name);
154  snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
155  args_buffer.push_back(' ');
156  args_buffer.append(arg_buf);
157  args_buffer.append(";\n");
158 
159  args_list_buffer.append("__lldb_fn_data->");
160  args_list_buffer.append(arg_buf);
161  if (i < num_args - 1)
162  args_list_buffer.append(", ");
163  }
165  ");\n"); // Close off the function calling prototype.
166 
167  m_wrapper_function_text.append(args_buffer);
168 
169  m_wrapper_function_text.append(" ");
170  m_wrapper_function_text.append(return_type_str);
171  m_wrapper_function_text.append(" return_value;");
172  m_wrapper_function_text.append("\n };\n struct ");
174  m_wrapper_function_text.append("* __lldb_fn_data = (struct ");
176  m_wrapper_function_text.append(" *) input;\n");
177 
179  " __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
180  m_wrapper_function_text.append(args_list_buffer);
181  m_wrapper_function_text.append(");\n}\n");
182 
184  LLDB_LOGF(log, "Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
185 
186  // Okay, now compile this expression
187 
188  lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
189  if (jit_process_sp) {
190  const bool generate_debug_info = true;
191  auto *clang_parser = new ClangExpressionParser(jit_process_sp.get(), *this,
192  generate_debug_info);
193  num_errors = clang_parser->Parse(diagnostic_manager);
194  m_parser.reset(clang_parser);
195  } else {
196  diagnostic_manager.PutString(eDiagnosticSeverityError,
197  "no process - unable to inject function");
198  num_errors = 1;
199  }
200 
201  m_compiled = (num_errors == 0);
202 
203  if (!m_compiled)
204  return num_errors;
205 
206  return num_errors;
207 }
208 
209 clang::ASTConsumer *
211  clang::ASTConsumer *passthrough) {
212  m_struct_extractor = std::make_unique<ASTStructExtractor>(
213  passthrough, m_owner.GetWrapperStructName(), m_owner);
214 
215  return m_struct_extractor.get();
216 }
lldb_private::ClangFunctionCaller::ID
static char ID
Definition: ClangFunctionCaller.h:89
lldb_private::FunctionCaller::m_wrapper_function_name
std::string m_wrapper_function_name
The name of the wrapper function.
Definition: FunctionCaller.h:309
lldb_private::FunctionCaller::m_function_ptr
Function * m_function_ptr
The function we're going to call.
Definition: FunctionCaller.h:301
lldb_private::ValueList::GetValueAtIndex
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:679
lldb_private::ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer
clang::ASTConsumer * ASTTransformer(clang::ASTConsumer *passthrough) override
Return the object that the parser should allow to access ASTs.
Definition: ClangFunctionCaller.cpp:210
lldb_private::Expression::m_jit_process_wp
lldb::ProcessWP m_jit_process_wp
Expression's always have to have a target...
Definition: Expression.h:93
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:249
Module.h
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:193
lldb_private::ClangFunctionCaller::~ClangFunctionCaller
~ClangFunctionCaller() override
lldb_private::ValueList
Definition: Value.h:157
CommandReturnObject.h
lldb_private::CompilerType::GetFunctionArgumentTypeAtIndex
CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const
Definition: CompilerType.cpp:366
lldb_private::ValueList::GetSize
size_t GetSize()
Definition: Value.cpp:677
Process.h
lldb_private::FunctionCaller::m_wrapper_function_text
std::string m_wrapper_function_text
The contents of the wrapper function.
Definition: FunctionCaller.h:311
Target.h
LIBLLDB_LOG_EXPRESSIONS
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
lldb_private::eDiagnosticSeverityError
@ eDiagnosticSeverityError
Definition: DiagnosticManager.h:32
lldb_private::FunctionCaller::m_wrapper_struct_name
std::string m_wrapper_struct_name
The name of the struct that contains the target function address, arguments, and result.
Definition: FunctionCaller.h:312
Log.h
lldb_private::ExecutionContextScope
Definition: ExecutionContextScope.h:32
TypeSystemClang.h
Type.h
lldb_private::ClangFunctionCaller::CompileFunction
unsigned CompileFunction(lldb::ThreadSP thread_to_use_sp, DiagnosticManager &diagnostic_manager) override
Compile the wrapper function.
Definition: ClangFunctionCaller.cpp:66
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
lldb_private::FunctionCaller::m_arg_values
ValueList m_arg_values
The default values of the arguments.
Definition: FunctionCaller.h:330
lldb_private::ClangFunctionCaller::GetWrapperStructName
const char * GetWrapperStructName()
Definition: ClangFunctionCaller.h:140
IRExecutionUnit.h
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:39
Thread.h
ClangExpressionParser.h
ThreadPlanCallFunction.h
ValueObject.h
lldb_private::ClangFunctionCaller::ClangFunctionCallerHelper::m_owner
ClangFunctionCaller & m_owner
Definition: ClangFunctionCaller.h:81
lldb_private::ThreadList::ExpressionExecutionThreadPusher
Definition: ThreadList.h:47
ThreadPlan.h
lldb_private::CompilerType::GetFunctionArgumentCount
int GetFunctionArgumentCount() const
Returns -1 if this isn't a function of if the function doesn't have a prototype Returns a value >= 0 ...
Definition: CompilerType.cpp:359
lldb_private::ClangExpressionParser
Definition: ClangExpressionParser.h:45
uint32_t
lldb_private::Address
Definition: Address.h:59
lldb_private::DiagnosticManager::PutString
size_t void PutString(DiagnosticSeverity severity, llvm::StringRef str)
Definition: DiagnosticManager.cpp:73
lldb_private::CompilerType::GetTypeName
ConstString GetTypeName() const
Definition: CompilerType.cpp:277
ASTStructExtractor.h
lldb_private::FunctionCaller::m_parser
std::unique_ptr< ExpressionParser > m_parser
The parser responsible for compiling the function.
Definition: FunctionCaller.h:293
lldb_private::DiagnosticManager
Definition: DiagnosticManager.h:93
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
lldb_private::ClangFunctionCaller::ClangFunctionCaller
ClangFunctionCaller(ExecutionContextScope &exe_scope, const CompilerType &return_type, const Address &function_address, const ValueList &arg_value_list, const char *name)
Constructor.
Definition: ClangFunctionCaller.cpp:48
DataExtractor.h
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
Function.h
ClangFunctionCaller.h
lldb_private::Value::GetCompilerType
const CompilerType & GetCompilerType()
Definition: Value.cpp:225
lldb_private::FunctionCaller::m_function_return_type
CompilerType m_function_return_type
The opaque clang qual type for the function return type.
Definition: FunctionCaller.h:306
lldb_private::ExecutionContextScope::CalculateProcess
virtual lldb::ProcessSP CalculateProcess()=0
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::Function::GetCompilerType
CompilerType GetCompilerType()
Definition: Function.cpp:522
lldb_private::ClangFunctionCaller::ClangFunctionCallerHelper::m_struct_extractor
std::unique_ptr< ASTStructExtractor > m_struct_extractor
The class that generates the argument struct layout.
Definition: ClangFunctionCaller.h:82
State.h
lldb_private::FunctionCaller::m_compiled
bool m_compiled
True if the wrapper function has already been parsed.
Definition: FunctionCaller.h:332
lldb_private::Log
Definition: Log.h:49
ValueObjectList.h
RegisterContext.h
ExecutionContext.h
lldb_private::DiagnosticManager::Printf
size_t Printf(DiagnosticSeverity severity, const char *format,...) __attribute__((format(printf
Definition: DiagnosticManager.cpp:59
lldb_private::FunctionCaller
Definition: FunctionCaller.h:56