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/LLDBLog.h"
41 #include "lldb/Utility/Log.h"
42 #include "lldb/Utility/State.h"
43 
44 using namespace lldb_private;
45 
47 
48 // ClangFunctionCaller constructor
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
64 
65 unsigned
66 
67 ClangFunctionCaller::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(
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...
88  m_wrapper_function_text.append("extern \"C\" void ");
90  m_wrapper_function_text.append(" (void *input)\n{\n struct ");
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 =
137  if (clang_qual_type) {
138  type_name = clang_qual_type.GetTypeName().AsCString("");
139  } else {
140  diagnostic_manager.Printf(
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  }
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 ");
175  m_wrapper_function_text.append("* __lldb_fn_data = (struct ");
177  m_wrapper_function_text.append(" *) input;\n");
178 
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 
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 
210 clang::ASTConsumer *
212  clang::ASTConsumer *passthrough) {
213  m_struct_extractor = std::make_unique<ASTStructExtractor>(
214  passthrough, m_owner.GetWrapperStructName(), m_owner);
215 
216  return m_struct_extractor.get();
217 }
lldb_private::ClangFunctionCaller::ID
static char ID
Definition: ClangFunctionCaller.h:88
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:669
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:211
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:344
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:192
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:667
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
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:67
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:139
IRExecutionUnit.h
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
Thread.h
ClangExpressionParser.h
ThreadPlanCallFunction.h
ValueObject.h
lldb_private::ClangFunctionCaller::ClangFunctionCallerHelper::m_owner
ClangFunctionCaller & m_owner
Definition: ClangFunctionCaller.h:80
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:19
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:49
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:222
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:521
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:81
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:115
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
lldb_private::LLDBLog::Expressions
@ Expressions
ValueObjectList.h
RegisterContext.h
LLDBLog.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