1 | //===-- FunctionCaller.h ----------------------------------------*- 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 | #ifndef LLDB_EXPRESSION_FUNCTIONCALLER_H |
10 | #define LLDB_EXPRESSION_FUNCTIONCALLER_H |
11 | |
12 | #include <list> |
13 | #include <memory> |
14 | #include <string> |
15 | #include <vector> |
16 | |
17 | #include "lldb/Core/Address.h" |
18 | #include "lldb/Core/Value.h" |
19 | #include "lldb/Expression/Expression.h" |
20 | #include "lldb/Expression/ExpressionParser.h" |
21 | #include "lldb/Symbol/CompilerType.h" |
22 | |
23 | namespace lldb_private { |
24 | |
25 | /// \class FunctionCaller FunctionCaller.h "lldb/Expression/FunctionCaller.h" |
26 | /// Encapsulates a function that can be called. |
27 | /// |
28 | /// A given FunctionCaller object can handle a single function signature. |
29 | /// Once constructed, it can set up any number of concurrent calls to |
30 | /// functions with that signature. |
31 | /// |
32 | /// It performs the call by synthesizing a structure that contains the pointer |
33 | /// to the function and the arguments that should be passed to that function, |
34 | /// and producing a special-purpose JIT-compiled function that accepts a void* |
35 | /// pointing to this struct as its only argument and calls the function in the |
36 | /// struct with the written arguments. This method lets Clang handle the |
37 | /// vagaries of function calling conventions. |
38 | /// |
39 | /// The simplest use of the FunctionCaller is to construct it with a function |
40 | /// representative of the signature you want to use, then call |
41 | /// ExecuteFunction(ExecutionContext &, Stream &, Value &). |
42 | /// |
43 | /// If you need to reuse the arguments for several calls, you can call |
44 | /// InsertFunction() followed by WriteFunctionArguments(), which will return |
45 | /// the location of the args struct for the wrapper function in args_addr_ref. |
46 | /// |
47 | /// If you need to call the function on the thread plan stack, you can also |
48 | /// call InsertFunction() followed by GetThreadPlanToCallFunction(). |
49 | /// |
50 | /// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed a |
51 | /// pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated |
52 | /// and its address returned in that variable. |
53 | /// |
54 | /// Any of the methods that take arg_addr_ptr can be passed nullptr, and the |
55 | /// argument space will be managed for you. |
56 | class FunctionCaller : public Expression { |
57 | // LLVM RTTI support |
58 | static char ID; |
59 | |
60 | public: |
61 | bool isA(const void *ClassID) const override { return ClassID == &ID; } |
62 | static bool classof(const Expression *obj) { return obj->isA(ClassID: &ID); } |
63 | |
64 | /// Constructor |
65 | /// |
66 | /// \param[in] exe_scope |
67 | /// An execution context scope that gets us at least a target and |
68 | /// process. |
69 | /// |
70 | /// \param[in] return_type |
71 | /// An opaque Clang QualType for the function result. Should be |
72 | /// defined in ast_context. |
73 | /// |
74 | /// \param[in] function_address |
75 | /// The address of the function to call. |
76 | /// |
77 | /// \param[in] arg_value_list |
78 | /// The default values to use when calling this function. Can |
79 | /// be overridden using WriteFunctionArguments(). |
80 | FunctionCaller(ExecutionContextScope &exe_scope, |
81 | const CompilerType &return_type, |
82 | const Address &function_address, |
83 | const ValueList &arg_value_list, const char *name); |
84 | |
85 | /// Destructor |
86 | ~FunctionCaller() override; |
87 | |
88 | /// Compile the wrapper function |
89 | /// |
90 | /// \param[in] thread_to_use_sp |
91 | /// Compilation might end up calling functions. Pass in the thread you |
92 | /// want the compilation to use. If you pass in an empty ThreadSP it will |
93 | /// use the currently selected thread. |
94 | /// |
95 | /// \param[in] diagnostic_manager |
96 | /// The diagnostic manager to report parser errors to. |
97 | /// |
98 | /// \return |
99 | /// The number of errors. |
100 | virtual unsigned CompileFunction(lldb::ThreadSP thread_to_use_sp, |
101 | DiagnosticManager &diagnostic_manager) = 0; |
102 | |
103 | /// Insert the default function wrapper and its default argument struct |
104 | /// |
105 | /// \param[in] exe_ctx |
106 | /// The execution context to insert the function and its arguments |
107 | /// into. |
108 | /// |
109 | /// \param[in,out] args_addr_ref |
110 | /// The address of the structure to write the arguments into. May |
111 | /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated |
112 | /// and args_addr_ref is pointed to it. |
113 | /// |
114 | /// \param[in] diagnostic_manager |
115 | /// The diagnostic manager to report errors to. |
116 | /// |
117 | /// \return |
118 | /// True on success; false otherwise. |
119 | bool InsertFunction(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, |
120 | DiagnosticManager &diagnostic_manager); |
121 | |
122 | /// Insert the default function wrapper (using the JIT) |
123 | /// |
124 | /// \param[in] exe_ctx |
125 | /// The execution context to insert the function and its arguments |
126 | /// into. |
127 | /// |
128 | /// \param[in] diagnostic_manager |
129 | /// The diagnostic manager to report errors to. |
130 | /// |
131 | /// \return |
132 | /// True on success; false otherwise. |
133 | bool WriteFunctionWrapper(ExecutionContext &exe_ctx, |
134 | DiagnosticManager &diagnostic_manager); |
135 | |
136 | /// Insert the default function argument struct |
137 | /// |
138 | /// \param[in] exe_ctx |
139 | /// The execution context to insert the function and its arguments |
140 | /// into. |
141 | /// |
142 | /// \param[in,out] args_addr_ref |
143 | /// The address of the structure to write the arguments into. May |
144 | /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated |
145 | /// and args_addr_ref is pointed to it. |
146 | /// |
147 | /// \param[in] diagnostic_manager |
148 | /// The diagnostic manager to report errors to. |
149 | /// |
150 | /// \return |
151 | /// True on success; false otherwise. |
152 | bool WriteFunctionArguments(ExecutionContext &exe_ctx, |
153 | lldb::addr_t &args_addr_ref, |
154 | DiagnosticManager &diagnostic_manager); |
155 | |
156 | /// Insert an argument struct with a non-default function address and non- |
157 | /// default argument values |
158 | /// |
159 | /// \param[in] exe_ctx |
160 | /// The execution context to insert the function and its arguments |
161 | /// into. |
162 | /// |
163 | /// \param[in,out] args_addr_ref |
164 | /// The address of the structure to write the arguments into. May |
165 | /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated |
166 | /// and args_addr_ref is pointed at it. |
167 | /// |
168 | /// \param[in] arg_values |
169 | /// The values of the function's arguments. |
170 | /// |
171 | /// \param[in] diagnostic_manager |
172 | /// The diagnostic manager to report errors to. |
173 | /// |
174 | /// \return |
175 | /// True on success; false otherwise. |
176 | bool WriteFunctionArguments(ExecutionContext &exe_ctx, |
177 | lldb::addr_t &args_addr_ref, |
178 | ValueList &arg_values, |
179 | DiagnosticManager &diagnostic_manager); |
180 | |
181 | /// Run the function this FunctionCaller was created with. |
182 | /// |
183 | /// This is the full version. |
184 | /// |
185 | /// \param[in] exe_ctx |
186 | /// The thread & process in which this function will run. |
187 | /// |
188 | /// \param[in] args_addr_ptr |
189 | /// If nullptr, the function will take care of allocating & deallocating |
190 | /// the wrapper |
191 | /// args structure. Otherwise, if set to LLDB_INVALID_ADDRESS, a new |
192 | /// structure |
193 | /// will be allocated, filled and the address returned to you. You are |
194 | /// responsible |
195 | /// for deallocating it. And if passed in with a value other than |
196 | /// LLDB_INVALID_ADDRESS, |
197 | /// this should point to an already allocated structure with the values |
198 | /// already written. |
199 | /// |
200 | /// \param[in] diagnostic_manager |
201 | /// The diagnostic manager to report errors to. |
202 | /// |
203 | /// \param[in] options |
204 | /// The options for this expression execution. |
205 | /// |
206 | /// \param[out] results |
207 | /// The result value will be put here after running the function. |
208 | /// |
209 | /// \return |
210 | /// Returns one of the ExpressionResults enum indicating function call |
211 | /// status. |
212 | lldb::ExpressionResults |
213 | ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, |
214 | const EvaluateExpressionOptions &options, |
215 | DiagnosticManager &diagnostic_manager, Value &results); |
216 | |
217 | /// Get a thread plan to run the function this FunctionCaller was created |
218 | /// with. |
219 | /// |
220 | /// \param[in] exe_ctx |
221 | /// The execution context to insert the function and its arguments |
222 | /// into. |
223 | /// |
224 | /// \param[in] args_addr |
225 | /// The address of the argument struct. |
226 | /// |
227 | /// \param[in] diagnostic_manager |
228 | /// The diagnostic manager to report errors to. |
229 | /// |
230 | /// \return |
231 | /// A ThreadPlan shared pointer for executing the function. |
232 | lldb::ThreadPlanSP |
233 | GetThreadPlanToCallFunction(ExecutionContext &exe_ctx, lldb::addr_t args_addr, |
234 | const EvaluateExpressionOptions &options, |
235 | DiagnosticManager &diagnostic_manager); |
236 | |
237 | /// Get the result of the function from its struct |
238 | /// |
239 | /// \param[in] exe_ctx |
240 | /// The execution context to retrieve the result from. |
241 | /// |
242 | /// \param[in] args_addr |
243 | /// The address of the argument struct. |
244 | /// |
245 | /// \param[out] ret_value |
246 | /// The value returned by the function. |
247 | /// |
248 | /// \return |
249 | /// True on success; false otherwise. |
250 | bool FetchFunctionResults(ExecutionContext &exe_ctx, lldb::addr_t args_addr, |
251 | Value &ret_value); |
252 | |
253 | /// Deallocate the arguments structure |
254 | /// |
255 | /// \param[in] exe_ctx |
256 | /// The execution context to insert the function and its arguments |
257 | /// into. |
258 | /// |
259 | /// \param[in] args_addr |
260 | /// The address of the argument struct. |
261 | void DeallocateFunctionResults(ExecutionContext &exe_ctx, |
262 | lldb::addr_t args_addr); |
263 | |
264 | /// Interface for ClangExpression |
265 | |
266 | /// Return the string that the parser should parse. Must be a full |
267 | /// translation unit. |
268 | const char *Text() override { return m_wrapper_function_text.c_str(); } |
269 | |
270 | /// Return the function name that should be used for executing the |
271 | /// expression. Text() should contain the definition of this function. |
272 | const char *FunctionName() override { |
273 | return m_wrapper_function_name.c_str(); |
274 | } |
275 | |
276 | /// Return the object that the parser should use when registering local |
277 | /// variables. May be nullptr if the Expression doesn't care. |
278 | ExpressionVariableList *LocalVariables() { return nullptr; } |
279 | |
280 | /// Return true if validation code should be inserted into the expression. |
281 | bool NeedsValidation() override { return false; } |
282 | |
283 | /// Return true if external variables in the expression should be resolved. |
284 | bool NeedsVariableResolution() override { return false; } |
285 | |
286 | ValueList GetArgumentValues() const { return m_arg_values; } |
287 | |
288 | protected: |
289 | // Note: the parser needs to be destructed before the execution unit, so |
290 | // declare the execution unit first. |
291 | std::shared_ptr<IRExecutionUnit> m_execution_unit_sp; |
292 | std::unique_ptr<ExpressionParser> |
293 | m_parser; ///< The parser responsible for compiling the function. |
294 | ///< This will get made in CompileFunction, so it is |
295 | ///< safe to access it after that. |
296 | |
297 | lldb::ModuleWP m_jit_module_wp; |
298 | std::string |
299 | m_name; ///< The name of this clang function - for debugging purposes. |
300 | |
301 | Function *m_function_ptr; ///< The function we're going to call. May be |
302 | ///nullptr if we don't have debug info for the |
303 | ///function. |
304 | Address m_function_addr; ///< If we don't have the FunctionSP, we at least |
305 | ///need the address & return type. |
306 | CompilerType m_function_return_type; ///< The opaque clang qual type for the |
307 | ///function return type. |
308 | |
309 | std::string m_wrapper_function_name; ///< The name of the wrapper function. |
310 | std::string |
311 | m_wrapper_function_text; ///< The contents of the wrapper function. |
312 | std::string m_wrapper_struct_name; ///< The name of the struct that contains |
313 | ///the target function address, arguments, |
314 | ///and result. |
315 | std::list<lldb::addr_t> m_wrapper_args_addrs; ///< The addresses of the |
316 | ///arguments to the wrapper |
317 | ///function. |
318 | |
319 | bool m_struct_valid; ///< True if the ASTStructExtractor has populated the |
320 | ///variables below. |
321 | |
322 | /// These values are populated by the ASTStructExtractor |
323 | size_t m_struct_size; ///< The size of the argument struct, in bytes. |
324 | std::vector<uint64_t> |
325 | m_member_offsets; ///< The offset of each member in the struct, in bytes. |
326 | uint64_t m_return_size; ///< The size of the result variable, in bytes. |
327 | uint64_t m_return_offset; ///< The offset of the result variable in the |
328 | ///struct, in bytes. |
329 | |
330 | ValueList m_arg_values; ///< The default values of the arguments. |
331 | |
332 | bool m_compiled; ///< True if the wrapper function has already been parsed. |
333 | bool |
334 | m_JITted; ///< True if the wrapper function has already been JIT-compiled. |
335 | }; |
336 | |
337 | } // namespace lldb_private |
338 | |
339 | #endif // LLDB_EXPRESSION_FUNCTIONCALLER_H |
340 | |