blob: 0ded1909bbc14cf22ec19159e60ae00fc24bc17a [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangFunction.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
11// C Includes
12// C++ Includes
13// Other libraries and framework includes
Chris Lattner24943d22010-06-08 16:52:24 +000014#include "clang/AST/ASTContext.h"
15#include "clang/AST/RecordLayout.h"
Greg Claytonc4f51102010-07-02 18:39:06 +000016#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"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "llvm/Module.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022
23// Project includes
Sean Callanan65dafa82010-08-27 01:01:44 +000024#include "lldb/Expression/ASTStructExtractor.h"
25#include "lldb/Expression/ClangExpressionParser.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "lldb/Expression/ClangFunction.h"
27#include "lldb/Symbol/Type.h"
28#include "lldb/Core/DataExtractor.h"
29#include "lldb/Core/ValueObject.h"
30#include "lldb/Core/ValueObjectList.h"
31#include "lldb/Interpreter/CommandReturnObject.h"
32#include "lldb/Symbol/ClangASTContext.h"
33#include "lldb/Symbol/Function.h"
34#include "lldb/Target/ExecutionContext.h"
35#include "lldb/Target/Process.h"
Sean Callanan841026f2010-07-23 00:16:21 +000036#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000037#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038#include "lldb/Target/Thread.h"
39#include "lldb/Target/ThreadPlan.h"
40#include "lldb/Target/ThreadPlanCallFunction.h"
41#include "lldb/Core/Log.h"
42
43using namespace lldb_private;
Sean Callanan65dafa82010-08-27 01:01:44 +000044
Chris Lattner24943d22010-06-08 16:52:24 +000045//----------------------------------------------------------------------
46// ClangFunction constructor
47//----------------------------------------------------------------------
Greg Clayton8de27c72010-10-15 22:48:33 +000048ClangFunction::ClangFunction
49(
50 const char *target_triple,
51 ClangASTContext *ast_context,
52 void *return_qualtype,
53 const Address& functionAddress,
54 const ValueList &arg_value_list
55) :
Sean Callanan65dafa82010-08-27 01:01:44 +000056 m_target_triple (target_triple),
Chris Lattner24943d22010-06-08 16:52:24 +000057 m_function_ptr (NULL),
Greg Clayton54e7afa2010-07-09 20:39:50 +000058 m_function_addr (functionAddress),
Chris Lattner24943d22010-06-08 16:52:24 +000059 m_function_return_qual_type(return_qualtype),
Greg Clayton54e7afa2010-07-09 20:39:50 +000060 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000061 m_wrapper_function_name ("__lldb_caller_function"),
62 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000063 m_wrapper_function_addr (),
64 m_wrapper_args_addrs (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000065 m_arg_values (arg_value_list),
Chris Lattner24943d22010-06-08 16:52:24 +000066 m_compiled (false),
67 m_JITted (false)
68{
69}
70
Greg Clayton8de27c72010-10-15 22:48:33 +000071ClangFunction::ClangFunction
72(
73 const char *target_triple,
74 Function &function,
75 ClangASTContext *ast_context,
76 const ValueList &arg_value_list
77) :
Sean Callanan65dafa82010-08-27 01:01:44 +000078 m_target_triple (target_triple),
Chris Lattner24943d22010-06-08 16:52:24 +000079 m_function_ptr (&function),
Greg Clayton54e7afa2010-07-09 20:39:50 +000080 m_function_addr (),
81 m_function_return_qual_type (),
Chris Lattner24943d22010-06-08 16:52:24 +000082 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000083 m_wrapper_function_name ("__lldb_function_caller"),
84 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000085 m_wrapper_function_addr (),
86 m_wrapper_args_addrs (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000087 m_arg_values (arg_value_list),
Chris Lattner24943d22010-06-08 16:52:24 +000088 m_compiled (false),
89 m_JITted (false)
90{
91 m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
Greg Clayton462d4142010-09-29 01:12:09 +000092 m_function_return_qual_type = m_function_ptr->GetReturnType().GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +000093}
94
95//----------------------------------------------------------------------
96// Destructor
97//----------------------------------------------------------------------
98ClangFunction::~ClangFunction()
99{
100}
101
102unsigned
103ClangFunction::CompileFunction (Stream &errors)
104{
Sean Callanan65dafa82010-08-27 01:01:44 +0000105 if (m_compiled)
106 return 0;
107
Chris Lattner24943d22010-06-08 16:52:24 +0000108 // FIXME: How does clang tell us there's no return value? We need to handle that case.
109 unsigned num_errors = 0;
110
Sean Callanan65dafa82010-08-27 01:01:44 +0000111 std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type);
112
113 // Cons up the function we're going to wrap our call in, then compile it...
114 // We declare the function "extern "C"" because the compiler might be in C++
115 // mode which would mangle the name and then we couldn't find it again...
116 m_wrapper_function_text.clear();
117 m_wrapper_function_text.append ("extern \"C\" void ");
118 m_wrapper_function_text.append (m_wrapper_function_name);
119 m_wrapper_function_text.append (" (void *input)\n{\n struct ");
120 m_wrapper_function_text.append (m_wrapper_struct_name);
121 m_wrapper_function_text.append (" \n {\n");
122 m_wrapper_function_text.append (" ");
123 m_wrapper_function_text.append (return_type_str);
124 m_wrapper_function_text.append (" (*fn_ptr) (");
125
126 // Get the number of arguments. If we have a function type and it is prototyped,
127 // trust that, otherwise use the values we were given.
128
129 // FIXME: This will need to be extended to handle Variadic functions. We'll need
130 // to pull the defined arguments out of the function, then add the types from the
131 // arguments list for the variable arguments.
132
133 uint32_t num_args = UINT32_MAX;
134 bool trust_function = false;
135 // GetArgumentCount returns -1 for an unprototyped function.
136 if (m_function_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000137 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000138 int num_func_args = m_function_ptr->GetArgumentCount();
139 if (num_func_args >= 0)
140 trust_function = true;
141 else
142 num_args = num_func_args;
143 }
Chris Lattner24943d22010-06-08 16:52:24 +0000144
Sean Callanan65dafa82010-08-27 01:01:44 +0000145 if (num_args == UINT32_MAX)
146 num_args = m_arg_values.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000147
Sean Callanan65dafa82010-08-27 01:01:44 +0000148 std::string args_buffer; // This one stores the definition of all the args in "struct caller".
149 std::string args_list_buffer; // This one stores the argument list called from the structure.
150 for (size_t i = 0; i < num_args; i++)
151 {
152 const char *type_string;
153 std::string type_stdstr;
Chris Lattner24943d22010-06-08 16:52:24 +0000154
Sean Callanan65dafa82010-08-27 01:01:44 +0000155 if (trust_function)
Chris Lattner24943d22010-06-08 16:52:24 +0000156 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000157 type_string = m_function_ptr->GetArgumentTypeAtIndex(i).GetName().AsCString();
Chris Lattner24943d22010-06-08 16:52:24 +0000158 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000159 else
Chris Lattner24943d22010-06-08 16:52:24 +0000160 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000161 Value *arg_value = m_arg_values.GetValueAtIndex(i);
Greg Clayton462d4142010-09-29 01:12:09 +0000162 void *clang_qual_type = arg_value->GetClangType ();
Sean Callanan65dafa82010-08-27 01:01:44 +0000163 if (clang_qual_type != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000164 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000165 type_stdstr = ClangASTContext::GetTypeName(clang_qual_type);
166 type_string = type_stdstr.c_str();
Chris Lattner24943d22010-06-08 16:52:24 +0000167 }
168 else
Sean Callanan65dafa82010-08-27 01:01:44 +0000169 {
170 errors.Printf("Could not determine type of input value %d.", i);
Chris Lattner24943d22010-06-08 16:52:24 +0000171 return 1;
172 }
Chris Lattner24943d22010-06-08 16:52:24 +0000173 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000174
175 m_wrapper_function_text.append (type_string);
176 if (i < num_args - 1)
177 m_wrapper_function_text.append (", ");
178
179 char arg_buf[32];
180 args_buffer.append (" ");
181 args_buffer.append (type_string);
182 snprintf(arg_buf, 31, "arg_%zd", i);
183 args_buffer.push_back (' ');
184 args_buffer.append (arg_buf);
185 args_buffer.append (";\n");
186
187 args_list_buffer.append ("__lldb_fn_data->");
188 args_list_buffer.append (arg_buf);
189 if (i < num_args - 1)
190 args_list_buffer.append (", ");
191
Chris Lattner24943d22010-06-08 16:52:24 +0000192 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000193 m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
194
195 m_wrapper_function_text.append (args_buffer);
196
197 m_wrapper_function_text.append (" ");
198 m_wrapper_function_text.append (return_type_str);
199 m_wrapper_function_text.append (" return_value;");
200 m_wrapper_function_text.append ("\n };\n struct ");
201 m_wrapper_function_text.append (m_wrapper_struct_name);
202 m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
203 m_wrapper_function_text.append (m_wrapper_struct_name);
204 m_wrapper_function_text.append (" *) input;\n");
205
206 m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
207 m_wrapper_function_text.append (args_list_buffer);
208 m_wrapper_function_text.append (");\n}\n");
209
210 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
211 if (log)
212 log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
213
214 // Okay, now compile this expression
215
216 m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), *this));
217
218 num_errors = m_parser->Parse (errors);
219
220 m_compiled = (num_errors == 0);
221
222 if (!m_compiled)
223 return num_errors;
Chris Lattner24943d22010-06-08 16:52:24 +0000224
225 return num_errors;
226}
227
228bool
Sean Callananc78d6482010-07-26 22:14:36 +0000229ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000230{
Sean Callananc78d6482010-07-26 22:14:36 +0000231 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000232
Sean Callanan65dafa82010-08-27 01:01:44 +0000233 if (!process)
234 return false;
235
236 if (!m_compiled)
Chris Lattner24943d22010-06-08 16:52:24 +0000237 return false;
238
Sean Callanan65dafa82010-08-27 01:01:44 +0000239 if (m_JITted)
240 return true;
241
Sean Callanan830a9032010-08-27 23:31:21 +0000242 lldb::addr_t wrapper_function_end;
243
244 Error jit_error = m_parser->MakeJIT(m_wrapper_function_addr, wrapper_function_end, exe_ctx);
Sean Callanan65dafa82010-08-27 01:01:44 +0000245
246 if (!jit_error.Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000247 return false;
248
249 return true;
250}
251
252bool
Sean Callananc78d6482010-07-26 22:14:36 +0000253ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000254{
Sean Callananc78d6482010-07-26 22:14:36 +0000255 return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);
Chris Lattner24943d22010-06-08 16:52:24 +0000256}
257
258// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
259
260bool
Jim Ingham681778e2010-09-10 23:07:48 +0000261ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx,
262 lldb::addr_t &args_addr_ref,
263 Address function_address,
264 ValueList &arg_values,
265 Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000266{
Sean Callanan65dafa82010-08-27 01:01:44 +0000267 // All the information to reconstruct the struct is provided by the
268 // StructExtractor.
269 if (!m_struct_valid)
270 {
271 errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
272 return false;
273 }
274
Chris Lattner24943d22010-06-08 16:52:24 +0000275 Error error;
276 using namespace clang;
277 ExecutionResults return_value = eExecutionSetupError;
278
Sean Callananc78d6482010-07-26 22:14:36 +0000279 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000280
281 if (process == NULL)
282 return return_value;
Sean Callanan65dafa82010-08-27 01:01:44 +0000283
Chris Lattner24943d22010-06-08 16:52:24 +0000284 if (args_addr_ref == LLDB_INVALID_ADDRESS)
285 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000286 args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000287 if (args_addr_ref == LLDB_INVALID_ADDRESS)
288 return false;
289 m_wrapper_args_addrs.push_back (args_addr_ref);
290 }
291 else
292 {
293 // Make sure this is an address that we've already handed out.
294 if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
295 {
296 return false;
297 }
298 }
299
300 // FIXME: This is fake, and just assumes that it matches that architecture.
301 // Make a data extractor and put the address into the right byte order & size.
302
Greg Claytoneea26402010-09-14 23:36:40 +0000303 uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.target);
Sean Callanan65dafa82010-08-27 01:01:44 +0000304 int first_offset = m_member_offsets[0];
Chris Lattner24943d22010-06-08 16:52:24 +0000305 process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error);
306
307 // FIXME: We will need to extend this for Variadic functions.
308
309 Error value_error;
310
311 size_t num_args = arg_values.GetSize();
312 if (num_args != m_arg_values.GetSize())
313 {
314 errors.Printf ("Wrong number of arguments - was: %d should be: %d", num_args, m_arg_values.GetSize());
315 return false;
316 }
317
Greg Clayton54e7afa2010-07-09 20:39:50 +0000318 for (size_t i = 0; i < num_args; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000319 {
320 // FIXME: We should sanity check sizes.
321
Sean Callanan65dafa82010-08-27 01:01:44 +0000322 int offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
Chris Lattner24943d22010-06-08 16:52:24 +0000323 Value *arg_value = arg_values.GetValueAtIndex(i);
324
325 // FIXME: For now just do scalars:
326
327 // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
328
329 if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
330 arg_value->GetContextType() == Value::eContextTypeOpaqueClangQualType &&
Greg Clayton462d4142010-09-29 01:12:09 +0000331 ClangASTContext::IsPointerType(arg_value->GetClangType()))
Chris Lattner24943d22010-06-08 16:52:24 +0000332 continue;
333
Sean Callananc78d6482010-07-26 22:14:36 +0000334 const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000335
336 int byte_size = arg_scalar.GetByteSize();
337 std::vector<uint8_t> buffer;
338 buffer.resize(byte_size);
339 DataExtractor value_data;
340 arg_scalar.GetData (value_data);
Greg Clayton53d68e72010-07-20 22:52:08 +0000341 value_data.ExtractBytes(0, byte_size, process->GetByteOrder(), &buffer.front());
342 process->WriteMemory(args_addr_ref + offset, &buffer.front(), byte_size, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000343 }
344
345 return true;
346}
347
348bool
Sean Callananc78d6482010-07-26 22:14:36 +0000349ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000350{
351 using namespace clang;
352
353 if (CompileFunction(errors) != 0)
354 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000355 if (!WriteFunctionWrapper(exe_ctx, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000356 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000357 if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000358 return false;
359
360 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
361 if (log)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000362 log->Printf ("Call Address: 0x%llx Struct Address: 0x%llx.\n", m_wrapper_function_addr, args_addr_ref);
Chris Lattner24943d22010-06-08 16:52:24 +0000363
364 return true;
365}
366
367ThreadPlan *
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000368ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, lldb::addr_t func_addr, lldb::addr_t &args_addr, Stream &errors, bool stop_others, bool discard_on_error, lldb::addr_t *this_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000369{
370 // FIXME: Use the errors Stream for better error reporting.
371
Sean Callananc78d6482010-07-26 22:14:36 +0000372 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000373
374 if (process == NULL)
375 {
376 errors.Printf("Can't call a function without a process.");
377 return NULL;
378 }
379
380 // Okay, now run the function:
381
Sean Callanan841026f2010-07-23 00:16:21 +0000382 Address wrapper_address (NULL, func_addr);
Sean Callananc78d6482010-07-26 22:14:36 +0000383 ThreadPlan *new_plan = new ThreadPlanCallFunction (*exe_ctx.thread,
Chris Lattner24943d22010-06-08 16:52:24 +0000384 wrapper_address,
385 args_addr,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000386 stop_others,
387 discard_on_error,
388 this_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000389 return new_plan;
390}
391
392bool
Sean Callananc78d6482010-07-26 22:14:36 +0000393ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
Chris Lattner24943d22010-06-08 16:52:24 +0000394{
395 // Read the return value - it is the last field in the struct:
396 // FIXME: How does clang tell us there's no return value? We need to handle that case.
397
398 std::vector<uint8_t> data_buffer;
399 data_buffer.resize(m_return_size);
Sean Callananc78d6482010-07-26 22:14:36 +0000400 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000401 Error error;
Sean Callanan65dafa82010-08-27 01:01:44 +0000402 size_t bytes_read = process->ReadMemory(args_addr + m_return_offset, &data_buffer.front(), m_return_size, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000403
404 if (bytes_read == 0)
405 {
406 return false;
407 }
408
409 if (bytes_read < m_return_size)
410 return false;
411
Greg Clayton53d68e72010-07-20 22:52:08 +0000412 DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000413 // FIXME: Assuming an integer scalar for now:
414
415 uint32_t offset = 0;
416 uint64_t return_integer = data.GetMaxU64(&offset, m_return_size);
417
418 ret_value.SetContext (Value::eContextTypeOpaqueClangQualType, m_function_return_qual_type);
419 ret_value.SetValueType(Value::eValueTypeScalar);
420 ret_value.GetScalar() = return_integer;
421 return true;
422}
423
424void
Sean Callananc78d6482010-07-26 22:14:36 +0000425ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000426{
427 std::list<lldb::addr_t>::iterator pos;
428 pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
429 if (pos != m_wrapper_args_addrs.end())
430 m_wrapper_args_addrs.erase(pos);
431
Sean Callananc78d6482010-07-26 22:14:36 +0000432 exe_ctx.process->DeallocateMemory(args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000433}
434
435ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000436ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000437{
Sean Callananc78d6482010-07-26 22:14:36 +0000438 return ExecuteFunction (exe_ctx, errors, 1000, true, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000439}
440
441ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000442ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000443{
Sean Callananc78d6482010-07-26 22:14:36 +0000444 return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, false, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000445}
446
447ClangFunction::ExecutionResults
448ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000449 ExecutionContext &exe_ctx,
Chris Lattner24943d22010-06-08 16:52:24 +0000450 Stream &errors,
451 uint32_t single_thread_timeout_usec,
452 bool try_all_threads,
453 Value &results)
454{
Sean Callananc78d6482010-07-26 22:14:36 +0000455 return ExecuteFunction (exe_ctx, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000456}
457
Sean Callanan841026f2010-07-23 00:16:21 +0000458// This is the static function
459ClangFunction::ExecutionResults
460ClangFunction::ExecuteFunction (
Sean Callananc78d6482010-07-26 22:14:36 +0000461 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000462 lldb::addr_t function_address,
463 lldb::addr_t &void_arg,
464 bool stop_others,
465 bool try_all_threads,
466 uint32_t single_thread_timeout_usec,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000467 Stream &errors,
468 lldb::addr_t *this_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000469{
Sean Callananc78d6482010-07-26 22:14:36 +0000470 // Save this value for restoration of the execution context after we run
Jim Ingham681778e2010-09-10 23:07:48 +0000471 uint32_t tid = exe_ctx.thread->GetIndexID();
Sean Callananc78d6482010-07-26 22:14:36 +0000472
Jim Ingham681778e2010-09-10 23:07:48 +0000473 // N.B. Running the target may unset the currently selected thread and frame. We don't want to do that either,
474 // so we should arrange to reset them as well.
475
476 lldb::ThreadSP selected_thread_sp = exe_ctx.process->GetThreadList().GetSelectedThread();
477 lldb::StackFrameSP selected_frame_sp;
478
479 uint32_t selected_tid;
480 if (selected_thread_sp != NULL)
481 {
482 selected_tid = selected_thread_sp->GetIndexID();
483 selected_frame_sp = selected_thread_sp->GetSelectedFrame();
484 }
485 else
486 {
487 selected_tid = LLDB_INVALID_THREAD_ID;
488 }
489
Sean Callanan841026f2010-07-23 00:16:21 +0000490 ClangFunction::ExecutionResults return_value = eExecutionSetupError;
Chris Lattner24943d22010-06-08 16:52:24 +0000491
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000492 lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, errors, stop_others, false, this_arg));
Chris Lattner24943d22010-06-08 16:52:24 +0000493
494 ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
495
Chris Lattner24943d22010-06-08 16:52:24 +0000496 if (call_plan_sp == NULL)
Sean Callanan841026f2010-07-23 00:16:21 +0000497 return eExecutionSetupError;
498
Sean Callanan65af7342010-09-08 20:04:08 +0000499//#define SINGLE_STEP_EXPRESSIONS
500
501#ifdef SINGLE_STEP_EXPRESSIONS
502 return eExecutionInterrupted;
503#else
Chris Lattner24943d22010-06-08 16:52:24 +0000504 call_plan_sp->SetPrivate(true);
Sean Callananc78d6482010-07-26 22:14:36 +0000505 exe_ctx.thread->QueueThreadPlan(call_plan_sp, true);
Sean Callanan65af7342010-09-08 20:04:08 +0000506#endif
Sean Callanan841026f2010-07-23 00:16:21 +0000507
Chris Lattner24943d22010-06-08 16:52:24 +0000508 // We need to call the function synchronously, so spin waiting for it to return.
509 // If we get interrupted while executing, we're going to lose our context, and
510 // won't be able to gather the result at this point.
Sean Callanan841026f2010-07-23 00:16:21 +0000511
Chris Lattner24943d22010-06-08 16:52:24 +0000512 TimeValue* timeout_ptr = NULL;
513 TimeValue real_timeout;
Sean Callanan841026f2010-07-23 00:16:21 +0000514
Chris Lattner24943d22010-06-08 16:52:24 +0000515 if (single_thread_timeout_usec != 0)
516 {
517 real_timeout = TimeValue::Now();
518 real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
519 timeout_ptr = &real_timeout;
520 }
Sean Callanan841026f2010-07-23 00:16:21 +0000521
Jim Ingham63e24d72010-10-11 23:53:14 +0000522 Listener listener("ClangFunction temporary listener");
523 exe_ctx.process->HijackProcessEvents(&listener);
524
Jim Inghama2890f42010-08-17 00:35:35 +0000525 Error resume_error = exe_ctx.process->Resume ();
526 if (!resume_error.Success())
527 {
528 errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
529 return eExecutionSetupError;
530 }
Sean Callanan841026f2010-07-23 00:16:21 +0000531
532 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Chris Lattner24943d22010-06-08 16:52:24 +0000533
534 while (1)
535 {
536 lldb::EventSP event_sp;
Jim Ingham63e24d72010-10-11 23:53:14 +0000537 lldb::StateType stop_state = lldb::eStateInvalid;
Chris Lattner24943d22010-06-08 16:52:24 +0000538 // Now wait for the process to stop again:
Jim Ingham63e24d72010-10-11 23:53:14 +0000539 bool got_event = listener.WaitForEvent (timeout_ptr, event_sp);
Sean Callanan841026f2010-07-23 00:16:21 +0000540
Sean Callanan94fb5432010-11-03 19:36:28 +0000541 if (!got_event && !call_plan_sp->IsPlanComplete())
Chris Lattner24943d22010-06-08 16:52:24 +0000542 {
543 // Right now this is the only way to tell we've timed out...
544 // We should interrupt the process here...
545 // Not really sure what to do if Halt fails here...
Caroline Tice926060e2010-10-29 21:48:37 +0000546 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Chris Lattner24943d22010-06-08 16:52:24 +0000547 if (log)
Jim Ingham681778e2010-09-10 23:07:48 +0000548 if (try_all_threads)
Jim Inghamd1686902010-10-14 23:45:03 +0000549 log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.",
550 single_thread_timeout_usec);
Jim Ingham681778e2010-09-10 23:07:48 +0000551 else
Jim Inghamd1686902010-10-14 23:45:03 +0000552 log->Printf ("Running function with timeout: %d timed out, abandoning execution.",
553 single_thread_timeout_usec);
Sean Callanan841026f2010-07-23 00:16:21 +0000554
Sean Callananc78d6482010-07-26 22:14:36 +0000555 if (exe_ctx.process->Halt().Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000556 {
557 timeout_ptr = NULL;
558
Jim Ingham63e24d72010-10-11 23:53:14 +0000559 got_event = listener.WaitForEvent (timeout_ptr, event_sp);
560 stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
561
Chris Lattner24943d22010-06-08 16:52:24 +0000562 if (stop_state == lldb::eStateInvalid)
563 {
564 errors.Printf ("Got an invalid stop state after halt.");
565 }
566 else if (stop_state != lldb::eStateStopped)
567 {
568 StreamString s;
569 event_sp->Dump (&s);
570
571 errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
572 }
573
574 if (try_all_threads)
575 {
576 // Between the time that we got the timeout and the time we halted, but target
577 // might have actually completed the plan. If so, we're done.
Sean Callananc78d6482010-07-26 22:14:36 +0000578 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000579 {
580 return_value = eExecutionCompleted;
581 break;
582 }
Sean Callanan841026f2010-07-23 00:16:21 +0000583
Chris Lattner24943d22010-06-08 16:52:24 +0000584 call_plan_ptr->SetStopOthers (false);
Sean Callananc78d6482010-07-26 22:14:36 +0000585 exe_ctx.process->Resume();
Chris Lattner24943d22010-06-08 16:52:24 +0000586 continue;
587 }
588 else
Jim Ingham63e24d72010-10-11 23:53:14 +0000589 {
590 exe_ctx.process->RestoreProcessEvents ();
Chris Lattner24943d22010-06-08 16:52:24 +0000591 return eExecutionInterrupted;
Jim Ingham63e24d72010-10-11 23:53:14 +0000592 }
Chris Lattner24943d22010-06-08 16:52:24 +0000593 }
594 }
Jim Ingham63e24d72010-10-11 23:53:14 +0000595
596 stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
597
Chris Lattner24943d22010-06-08 16:52:24 +0000598 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
599 continue;
Sean Callanan841026f2010-07-23 00:16:21 +0000600
Sean Callananc78d6482010-07-26 22:14:36 +0000601 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000602 {
603 return_value = eExecutionCompleted;
604 break;
605 }
Sean Callananc78d6482010-07-26 22:14:36 +0000606 else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000607 {
608 return_value = eExecutionDiscarded;
609 break;
610 }
611 else
612 {
Caroline Tice926060e2010-10-29 21:48:37 +0000613 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Sean Callanan841026f2010-07-23 00:16:21 +0000614 if (log)
615 {
616 StreamString s;
617 event_sp->Dump (&s);
618 StreamString ts;
619
620 const char *event_explanation;
621
622 do
623 {
624 const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
625
626 if (!event_data)
627 {
628 event_explanation = "<no event data>";
629 break;
630 }
631
632 Process *process = event_data->GetProcessSP().get();
633
634 if (!process)
635 {
636 event_explanation = "<no process>";
637 break;
638 }
639
640 ThreadList &thread_list = process->GetThreadList();
641
642 uint32_t num_threads = thread_list.GetSize();
643 uint32_t thread_index;
644
645 ts.Printf("<%u threads> ", num_threads);
646
647 for (thread_index = 0;
648 thread_index < num_threads;
649 ++thread_index)
650 {
651 Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
652
653 if (!thread)
654 {
655 ts.Printf("<?> ");
656 continue;
657 }
658
Sean Callanan841026f2010-07-23 00:16:21 +0000659 ts.Printf("<");
660 RegisterContext *register_context = thread->GetRegisterContext();
661
662 if (register_context)
663 ts.Printf("[ip 0x%llx] ", register_context->GetPC());
664 else
665 ts.Printf("[ip unknown] ");
666
Jim Ingham6297a3a2010-10-20 00:39:53 +0000667 lldb::StopInfoSP stop_info_sp = thread->GetStopInfo();
668 if (stop_info_sp)
Greg Clayton643ee732010-08-04 01:40:35 +0000669 {
Jim Ingham6297a3a2010-10-20 00:39:53 +0000670 const char *stop_desc = stop_info_sp->GetDescription();
Greg Clayton643ee732010-08-04 01:40:35 +0000671 if (stop_desc)
672 ts.PutCString (stop_desc);
673 }
Sean Callanan841026f2010-07-23 00:16:21 +0000674 ts.Printf(">");
675 }
676
677 event_explanation = ts.GetData();
678 } while (0);
679
Caroline Tice926060e2010-10-29 21:48:37 +0000680 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
681 if (log)
682 log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
Sean Callanan841026f2010-07-23 00:16:21 +0000683 }
684
Chris Lattner24943d22010-06-08 16:52:24 +0000685 return_value = eExecutionInterrupted;
686 break;
687 }
Chris Lattner24943d22010-06-08 16:52:24 +0000688 }
Sean Callanan841026f2010-07-23 00:16:21 +0000689
Jim Ingham63e24d72010-10-11 23:53:14 +0000690 if (exe_ctx.process)
691 exe_ctx.process->RestoreProcessEvents ();
692
Sean Callananc78d6482010-07-26 22:14:36 +0000693 // Thread we ran the function in may have gone away because we ran the target
694 // Check that it's still there.
Jim Ingham681778e2010-09-10 23:07:48 +0000695 exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByIndexID(tid, true).get();
Jim Ingham324067b2010-09-30 00:54:27 +0000696 if (exe_ctx.thread)
697 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
Sean Callananc78d6482010-07-26 22:14:36 +0000698
Jim Ingham681778e2010-09-10 23:07:48 +0000699 // Also restore the current process'es selected frame & thread, since this function calling may
700 // be done behind the user's back.
701
702 if (selected_tid != LLDB_INVALID_THREAD_ID)
703 {
704 if (exe_ctx.process->GetThreadList().SetSelectedThreadByIndexID (selected_tid))
705 {
706 // We were able to restore the selected thread, now restore the frame:
707 exe_ctx.process->GetThreadList().GetSelectedThread()->SetSelectedFrame(selected_frame_sp.get());
708 }
709 }
710
Sean Callanan841026f2010-07-23 00:16:21 +0000711 return return_value;
712}
Chris Lattner24943d22010-06-08 16:52:24 +0000713
Sean Callanan841026f2010-07-23 00:16:21 +0000714ClangFunction::ExecutionResults
715ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000716 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000717 lldb::addr_t *args_addr_ptr,
718 Stream &errors,
719 bool stop_others,
720 uint32_t single_thread_timeout_usec,
721 bool try_all_threads,
722 Value &results)
723{
724 using namespace clang;
725 ExecutionResults return_value = eExecutionSetupError;
726
727 lldb::addr_t args_addr;
728
729 if (args_addr_ptr != NULL)
730 args_addr = *args_addr_ptr;
731 else
732 args_addr = LLDB_INVALID_ADDRESS;
733
734 if (CompileFunction(errors) != 0)
735 return eExecutionSetupError;
736
737 if (args_addr == LLDB_INVALID_ADDRESS)
738 {
Sean Callananc78d6482010-07-26 22:14:36 +0000739 if (!InsertFunction(exe_ctx, args_addr, errors))
Sean Callanan841026f2010-07-23 00:16:21 +0000740 return eExecutionSetupError;
741 }
742
Jim Ingham681778e2010-09-10 23:07:48 +0000743 return_value = ClangFunction::ExecuteFunction(exe_ctx, m_wrapper_function_addr, args_addr, stop_others,
744 try_all_threads, single_thread_timeout_usec, errors);
Sean Callanan841026f2010-07-23 00:16:21 +0000745
746 if (args_addr_ptr != NULL)
747 *args_addr_ptr = args_addr;
748
Chris Lattner24943d22010-06-08 16:52:24 +0000749 if (return_value != eExecutionCompleted)
750 return return_value;
751
Sean Callananc78d6482010-07-26 22:14:36 +0000752 FetchFunctionResults(exe_ctx, args_addr, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000753
754 if (args_addr_ptr == NULL)
Sean Callananc78d6482010-07-26 22:14:36 +0000755 DeallocateFunctionResults(exe_ctx, args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000756
757 return eExecutionCompleted;
758}
759
Sean Callanan65dafa82010-08-27 01:01:44 +0000760clang::ASTConsumer *
761ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
Chris Lattner24943d22010-06-08 16:52:24 +0000762{
Sean Callanan65dafa82010-08-27 01:01:44 +0000763 return new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this);
Chris Lattner24943d22010-06-08 16:52:24 +0000764}