1 //===-- ClangFunctionCaller.cpp -------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ClangFunctionCaller.h"
11 #include "ASTStructExtractor.h"
12 #include "ClangExpressionParser.h"
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"
24 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
25 #include "lldb/Core/Module.h"
26 #include "lldb/Expression/IRExecutionUnit.h"
27 #include "lldb/Interpreter/CommandReturnObject.h"
28 #include "lldb/Symbol/Function.h"
29 #include "lldb/Symbol/Type.h"
30 #include "lldb/Target/ExecutionContext.h"
31 #include "lldb/Target/Process.h"
32 #include "lldb/Target/RegisterContext.h"
33 #include "lldb/Target/Target.h"
34 #include "lldb/Target/Thread.h"
35 #include "lldb/Target/ThreadPlan.h"
36 #include "lldb/Target/ThreadPlanCallFunction.h"
37 #include "lldb/Utility/DataExtractor.h"
38 #include "lldb/Utility/LLDBLog.h"
39 #include "lldb/Utility/Log.h"
40 #include "lldb/Utility/State.h"
41 #include "lldb/ValueObject/ValueObject.h"
42 #include "lldb/ValueObject/ValueObjectList.h"
44 using namespace lldb_private
;
46 char ClangFunctionCaller::ID
;
48 // ClangFunctionCaller constructor
49 ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope
&exe_scope
,
50 const CompilerType
&return_type
,
51 const Address
&functionAddress
,
52 const ValueList
&arg_value_list
,
54 : FunctionCaller(exe_scope
, return_type
, functionAddress
, arg_value_list
,
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());
63 ClangFunctionCaller::~ClangFunctionCaller() = default;
67 ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp
,
68 DiagnosticManager
&diagnostic_manager
) {
72 // Compilation might call code, make sure to keep on the thread the caller
74 ThreadList::ExpressionExecutionThreadPusher
execution_thread_pusher(
77 // FIXME: How does clang tell us there's no return value? We need to handle
79 unsigned num_errors
= 0;
81 std::string
return_type_str(
82 m_function_return_type
.GetTypeName().AsCString(""));
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) (");
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.
100 // FIXME: This will need to be extended to handle Variadic functions. We'll
102 // to pull the defined arguments out of the function, then add the types from
103 // the arguments list for the variable arguments.
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
;
120 if (num_args
== UINT32_MAX
)
121 num_args
= m_arg_values
.GetSize();
123 std::string args_buffer
; // This one stores the definition of all the args in
125 std::string args_list_buffer
; // This one stores the argument list called from
127 for (size_t i
= 0; i
< num_args
; i
++) {
128 std::string type_name
;
130 if (trust_function
) {
131 type_name
= function_clang_type
.GetFunctionArgumentTypeAtIndex(i
)
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("");
140 diagnostic_manager
.Printf(
141 lldb::eSeverityError
,
142 "Could not determine type of input value %" PRIu64
".",
148 m_wrapper_function_text
.append(type_name
);
149 if (i
< num_args
- 1)
150 m_wrapper_function_text
.append(", ");
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");
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(", ");
165 m_wrapper_function_text
.append(
166 ");\n"); // Close off the function calling prototype.
168 m_wrapper_function_text
.append(args_buffer
);
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");
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");
184 Log
*log
= GetLog(LLDBLog::Expressions
);
185 LLDB_LOGF(log
, "Expression: \n\n%s\n\n", m_wrapper_function_text
.c_str());
187 // Okay, now compile this expression
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
);
197 diagnostic_manager
.PutString(lldb::eSeverityError
,
198 "no process - unable to inject function");
202 m_compiled
= (num_errors
== 0);
210 char ClangFunctionCaller::ClangFunctionCallerHelper::ID
;
213 ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer(
214 clang::ASTConsumer
*passthrough
) {
215 m_struct_extractor
= std::make_unique
<ASTStructExtractor
>(
216 passthrough
, m_owner
.GetWrapperStructName(), m_owner
);
218 return m_struct_extractor
.get();