blob: 3044d51ed695c746cd046330234909db0b7d66ee [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/ExecutionEngine/JIT.h"
22#include "llvm/Module.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023
24// Project includes
Sean Callanan65dafa82010-08-27 01:01:44 +000025#include "lldb/Expression/ASTStructExtractor.h"
26#include "lldb/Expression/ClangExpressionParser.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Expression/ClangFunction.h"
28#include "lldb/Symbol/Type.h"
29#include "lldb/Core/DataExtractor.h"
30#include "lldb/Core/ValueObject.h"
31#include "lldb/Core/ValueObjectList.h"
32#include "lldb/Interpreter/CommandReturnObject.h"
33#include "lldb/Symbol/ClangASTContext.h"
34#include "lldb/Symbol/Function.h"
35#include "lldb/Target/ExecutionContext.h"
36#include "lldb/Target/Process.h"
Sean Callanan841026f2010-07-23 00:16:21 +000037#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000038#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000039#include "lldb/Target/Thread.h"
40#include "lldb/Target/ThreadPlan.h"
41#include "lldb/Target/ThreadPlanCallFunction.h"
42#include "lldb/Core/Log.h"
43
44using namespace lldb_private;
Sean Callanan65dafa82010-08-27 01:01:44 +000045
Chris Lattner24943d22010-06-08 16:52:24 +000046//----------------------------------------------------------------------
47// ClangFunction constructor
48//----------------------------------------------------------------------
49ClangFunction::ClangFunction(const char *target_triple, ClangASTContext *ast_context, void *return_qualtype, const Address& functionAddress, const ValueList &arg_value_list) :
Sean Callanan65dafa82010-08-27 01:01:44 +000050 m_target_triple (target_triple),
Chris Lattner24943d22010-06-08 16:52:24 +000051 m_function_ptr (NULL),
Greg Clayton54e7afa2010-07-09 20:39:50 +000052 m_function_addr (functionAddress),
Chris Lattner24943d22010-06-08 16:52:24 +000053 m_function_return_qual_type(return_qualtype),
Greg Clayton54e7afa2010-07-09 20:39:50 +000054 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000055 m_wrapper_function_name ("__lldb_caller_function"),
56 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000057 m_wrapper_function_addr (),
58 m_wrapper_args_addrs (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000059 m_arg_values (arg_value_list),
Chris Lattner24943d22010-06-08 16:52:24 +000060 m_compiled (false),
61 m_JITted (false)
62{
63}
64
65ClangFunction::ClangFunction(const char *target_triple, Function &function, ClangASTContext *ast_context, const ValueList &arg_value_list) :
Sean Callanan65dafa82010-08-27 01:01:44 +000066 m_target_triple (target_triple),
Chris Lattner24943d22010-06-08 16:52:24 +000067 m_function_ptr (&function),
Greg Clayton54e7afa2010-07-09 20:39:50 +000068 m_function_addr (),
69 m_function_return_qual_type (),
Chris Lattner24943d22010-06-08 16:52:24 +000070 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000071 m_wrapper_function_name ("__lldb_function_caller"),
72 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000073 m_wrapper_function_addr (),
74 m_wrapper_args_addrs (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000075 m_arg_values (arg_value_list),
Chris Lattner24943d22010-06-08 16:52:24 +000076 m_compiled (false),
77 m_JITted (false)
78{
79 m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
80 m_function_return_qual_type = m_function_ptr->GetReturnType().GetOpaqueClangQualType();
81}
82
83//----------------------------------------------------------------------
84// Destructor
85//----------------------------------------------------------------------
86ClangFunction::~ClangFunction()
87{
88}
89
90unsigned
91ClangFunction::CompileFunction (Stream &errors)
92{
Sean Callanan65dafa82010-08-27 01:01:44 +000093 if (m_compiled)
94 return 0;
95
Chris Lattner24943d22010-06-08 16:52:24 +000096 // FIXME: How does clang tell us there's no return value? We need to handle that case.
97 unsigned num_errors = 0;
98
Sean Callanan65dafa82010-08-27 01:01:44 +000099 std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type);
100
101 // Cons up the function we're going to wrap our call in, then compile it...
102 // We declare the function "extern "C"" because the compiler might be in C++
103 // mode which would mangle the name and then we couldn't find it again...
104 m_wrapper_function_text.clear();
105 m_wrapper_function_text.append ("extern \"C\" void ");
106 m_wrapper_function_text.append (m_wrapper_function_name);
107 m_wrapper_function_text.append (" (void *input)\n{\n struct ");
108 m_wrapper_function_text.append (m_wrapper_struct_name);
109 m_wrapper_function_text.append (" \n {\n");
110 m_wrapper_function_text.append (" ");
111 m_wrapper_function_text.append (return_type_str);
112 m_wrapper_function_text.append (" (*fn_ptr) (");
113
114 // Get the number of arguments. If we have a function type and it is prototyped,
115 // trust that, otherwise use the values we were given.
116
117 // FIXME: This will need to be extended to handle Variadic functions. We'll need
118 // to pull the defined arguments out of the function, then add the types from the
119 // arguments list for the variable arguments.
120
121 uint32_t num_args = UINT32_MAX;
122 bool trust_function = false;
123 // GetArgumentCount returns -1 for an unprototyped function.
124 if (m_function_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000125 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000126 int num_func_args = m_function_ptr->GetArgumentCount();
127 if (num_func_args >= 0)
128 trust_function = true;
129 else
130 num_args = num_func_args;
131 }
Chris Lattner24943d22010-06-08 16:52:24 +0000132
Sean Callanan65dafa82010-08-27 01:01:44 +0000133 if (num_args == UINT32_MAX)
134 num_args = m_arg_values.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000135
Sean Callanan65dafa82010-08-27 01:01:44 +0000136 std::string args_buffer; // This one stores the definition of all the args in "struct caller".
137 std::string args_list_buffer; // This one stores the argument list called from the structure.
138 for (size_t i = 0; i < num_args; i++)
139 {
140 const char *type_string;
141 std::string type_stdstr;
Chris Lattner24943d22010-06-08 16:52:24 +0000142
Sean Callanan65dafa82010-08-27 01:01:44 +0000143 if (trust_function)
Chris Lattner24943d22010-06-08 16:52:24 +0000144 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000145 type_string = m_function_ptr->GetArgumentTypeAtIndex(i).GetName().AsCString();
Chris Lattner24943d22010-06-08 16:52:24 +0000146 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000147 else
Chris Lattner24943d22010-06-08 16:52:24 +0000148 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000149 Value *arg_value = m_arg_values.GetValueAtIndex(i);
150 void *clang_qual_type = arg_value->GetOpaqueClangQualType ();
151 if (clang_qual_type != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000152 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000153 type_stdstr = ClangASTContext::GetTypeName(clang_qual_type);
154 type_string = type_stdstr.c_str();
Chris Lattner24943d22010-06-08 16:52:24 +0000155 }
156 else
Sean Callanan65dafa82010-08-27 01:01:44 +0000157 {
158 errors.Printf("Could not determine type of input value %d.", i);
Chris Lattner24943d22010-06-08 16:52:24 +0000159 return 1;
160 }
Chris Lattner24943d22010-06-08 16:52:24 +0000161 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000162
163 m_wrapper_function_text.append (type_string);
164 if (i < num_args - 1)
165 m_wrapper_function_text.append (", ");
166
167 char arg_buf[32];
168 args_buffer.append (" ");
169 args_buffer.append (type_string);
170 snprintf(arg_buf, 31, "arg_%zd", i);
171 args_buffer.push_back (' ');
172 args_buffer.append (arg_buf);
173 args_buffer.append (";\n");
174
175 args_list_buffer.append ("__lldb_fn_data->");
176 args_list_buffer.append (arg_buf);
177 if (i < num_args - 1)
178 args_list_buffer.append (", ");
179
Chris Lattner24943d22010-06-08 16:52:24 +0000180 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000181 m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
182
183 m_wrapper_function_text.append (args_buffer);
184
185 m_wrapper_function_text.append (" ");
186 m_wrapper_function_text.append (return_type_str);
187 m_wrapper_function_text.append (" return_value;");
188 m_wrapper_function_text.append ("\n };\n struct ");
189 m_wrapper_function_text.append (m_wrapper_struct_name);
190 m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
191 m_wrapper_function_text.append (m_wrapper_struct_name);
192 m_wrapper_function_text.append (" *) input;\n");
193
194 m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
195 m_wrapper_function_text.append (args_list_buffer);
196 m_wrapper_function_text.append (");\n}\n");
197
198 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
199 if (log)
200 log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
201
202 // Okay, now compile this expression
203
204 m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), *this));
205
206 num_errors = m_parser->Parse (errors);
207
208 m_compiled = (num_errors == 0);
209
210 if (!m_compiled)
211 return num_errors;
Chris Lattner24943d22010-06-08 16:52:24 +0000212
213 return num_errors;
214}
215
216bool
Sean Callananc78d6482010-07-26 22:14:36 +0000217ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000218{
Sean Callananc78d6482010-07-26 22:14:36 +0000219 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000220
Sean Callanan65dafa82010-08-27 01:01:44 +0000221 if (!process)
222 return false;
223
224 if (!m_compiled)
Chris Lattner24943d22010-06-08 16:52:24 +0000225 return false;
226
Sean Callanan65dafa82010-08-27 01:01:44 +0000227 if (m_JITted)
228 return true;
229
Sean Callanan830a9032010-08-27 23:31:21 +0000230 lldb::addr_t wrapper_function_end;
231
232 Error jit_error = m_parser->MakeJIT(m_wrapper_function_addr, wrapper_function_end, exe_ctx);
Sean Callanan65dafa82010-08-27 01:01:44 +0000233
234 if (!jit_error.Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000235 return false;
236
237 return true;
238}
239
240bool
Sean Callananc78d6482010-07-26 22:14:36 +0000241ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000242{
Sean Callananc78d6482010-07-26 22:14:36 +0000243 return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);
Chris Lattner24943d22010-06-08 16:52:24 +0000244}
245
246// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
247
248bool
Sean Callananc78d6482010-07-26 22:14:36 +0000249ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000250{
Sean Callanan65dafa82010-08-27 01:01:44 +0000251 // All the information to reconstruct the struct is provided by the
252 // StructExtractor.
253 if (!m_struct_valid)
254 {
255 errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
256 return false;
257 }
258
Chris Lattner24943d22010-06-08 16:52:24 +0000259 Error error;
260 using namespace clang;
261 ExecutionResults return_value = eExecutionSetupError;
262
Sean Callananc78d6482010-07-26 22:14:36 +0000263 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000264
265 if (process == NULL)
266 return return_value;
Sean Callanan65dafa82010-08-27 01:01:44 +0000267
Chris Lattner24943d22010-06-08 16:52:24 +0000268 if (args_addr_ref == LLDB_INVALID_ADDRESS)
269 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000270 args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000271 if (args_addr_ref == LLDB_INVALID_ADDRESS)
272 return false;
273 m_wrapper_args_addrs.push_back (args_addr_ref);
274 }
275 else
276 {
277 // Make sure this is an address that we've already handed out.
278 if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
279 {
280 return false;
281 }
282 }
283
284 // FIXME: This is fake, and just assumes that it matches that architecture.
285 // Make a data extractor and put the address into the right byte order & size.
286
Sean Callananc78d6482010-07-26 22:14:36 +0000287 uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.process);
Sean Callanan65dafa82010-08-27 01:01:44 +0000288 int first_offset = m_member_offsets[0];
Chris Lattner24943d22010-06-08 16:52:24 +0000289 process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error);
290
291 // FIXME: We will need to extend this for Variadic functions.
292
293 Error value_error;
294
295 size_t num_args = arg_values.GetSize();
296 if (num_args != m_arg_values.GetSize())
297 {
298 errors.Printf ("Wrong number of arguments - was: %d should be: %d", num_args, m_arg_values.GetSize());
299 return false;
300 }
301
Greg Clayton54e7afa2010-07-09 20:39:50 +0000302 for (size_t i = 0; i < num_args; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000303 {
304 // FIXME: We should sanity check sizes.
305
Sean Callanan65dafa82010-08-27 01:01:44 +0000306 int offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
Chris Lattner24943d22010-06-08 16:52:24 +0000307 Value *arg_value = arg_values.GetValueAtIndex(i);
308
309 // FIXME: For now just do scalars:
310
311 // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
312
313 if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
314 arg_value->GetContextType() == Value::eContextTypeOpaqueClangQualType &&
315 ClangASTContext::IsPointerType(arg_value->GetValueOpaqueClangQualType()))
316 continue;
317
Sean Callananc78d6482010-07-26 22:14:36 +0000318 const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000319
320 int byte_size = arg_scalar.GetByteSize();
321 std::vector<uint8_t> buffer;
322 buffer.resize(byte_size);
323 DataExtractor value_data;
324 arg_scalar.GetData (value_data);
Greg Clayton53d68e72010-07-20 22:52:08 +0000325 value_data.ExtractBytes(0, byte_size, process->GetByteOrder(), &buffer.front());
326 process->WriteMemory(args_addr_ref + offset, &buffer.front(), byte_size, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000327 }
328
329 return true;
330}
331
332bool
Sean Callananc78d6482010-07-26 22:14:36 +0000333ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000334{
335 using namespace clang;
336
337 if (CompileFunction(errors) != 0)
338 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000339 if (!WriteFunctionWrapper(exe_ctx, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000340 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000341 if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000342 return false;
343
344 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
345 if (log)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000346 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 +0000347
348 return true;
349}
350
351ThreadPlan *
Sean Callananc78d6482010-07-26 22:14:36 +0000352ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, lldb::addr_t func_addr, lldb::addr_t &args_addr, Stream &errors, bool stop_others, bool discard_on_error)
Chris Lattner24943d22010-06-08 16:52:24 +0000353{
354 // FIXME: Use the errors Stream for better error reporting.
355
Sean Callananc78d6482010-07-26 22:14:36 +0000356 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000357
358 if (process == NULL)
359 {
360 errors.Printf("Can't call a function without a process.");
361 return NULL;
362 }
363
364 // Okay, now run the function:
365
Sean Callanan841026f2010-07-23 00:16:21 +0000366 Address wrapper_address (NULL, func_addr);
Sean Callananc78d6482010-07-26 22:14:36 +0000367 ThreadPlan *new_plan = new ThreadPlanCallFunction (*exe_ctx.thread,
Chris Lattner24943d22010-06-08 16:52:24 +0000368 wrapper_address,
369 args_addr,
370 stop_others, discard_on_error);
371 return new_plan;
372}
373
374bool
Sean Callananc78d6482010-07-26 22:14:36 +0000375ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
Chris Lattner24943d22010-06-08 16:52:24 +0000376{
377 // Read the return value - it is the last field in the struct:
378 // FIXME: How does clang tell us there's no return value? We need to handle that case.
379
380 std::vector<uint8_t> data_buffer;
381 data_buffer.resize(m_return_size);
Sean Callananc78d6482010-07-26 22:14:36 +0000382 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000383 Error error;
Sean Callanan65dafa82010-08-27 01:01:44 +0000384 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 +0000385
386 if (bytes_read == 0)
387 {
388 return false;
389 }
390
391 if (bytes_read < m_return_size)
392 return false;
393
Greg Clayton53d68e72010-07-20 22:52:08 +0000394 DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000395 // FIXME: Assuming an integer scalar for now:
396
397 uint32_t offset = 0;
398 uint64_t return_integer = data.GetMaxU64(&offset, m_return_size);
399
400 ret_value.SetContext (Value::eContextTypeOpaqueClangQualType, m_function_return_qual_type);
401 ret_value.SetValueType(Value::eValueTypeScalar);
402 ret_value.GetScalar() = return_integer;
403 return true;
404}
405
406void
Sean Callananc78d6482010-07-26 22:14:36 +0000407ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000408{
409 std::list<lldb::addr_t>::iterator pos;
410 pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
411 if (pos != m_wrapper_args_addrs.end())
412 m_wrapper_args_addrs.erase(pos);
413
Sean Callananc78d6482010-07-26 22:14:36 +0000414 exe_ctx.process->DeallocateMemory(args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000415}
416
417ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000418ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000419{
Sean Callananc78d6482010-07-26 22:14:36 +0000420 return ExecuteFunction (exe_ctx, errors, 1000, true, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000421}
422
423ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000424ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000425{
Sean Callananc78d6482010-07-26 22:14:36 +0000426 return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, false, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000427}
428
429ClangFunction::ExecutionResults
430ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000431 ExecutionContext &exe_ctx,
Chris Lattner24943d22010-06-08 16:52:24 +0000432 Stream &errors,
433 uint32_t single_thread_timeout_usec,
434 bool try_all_threads,
435 Value &results)
436{
Sean Callananc78d6482010-07-26 22:14:36 +0000437 return ExecuteFunction (exe_ctx, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000438}
439
Sean Callanan841026f2010-07-23 00:16:21 +0000440// This is the static function
441ClangFunction::ExecutionResults
442ClangFunction::ExecuteFunction (
Sean Callananc78d6482010-07-26 22:14:36 +0000443 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000444 lldb::addr_t function_address,
445 lldb::addr_t &void_arg,
446 bool stop_others,
447 bool try_all_threads,
448 uint32_t single_thread_timeout_usec,
449 Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000450{
Sean Callananc78d6482010-07-26 22:14:36 +0000451 // Save this value for restoration of the execution context after we run
452 uint32_t tid = exe_ctx.thread->GetID();
453
Sean Callanan841026f2010-07-23 00:16:21 +0000454 ClangFunction::ExecutionResults return_value = eExecutionSetupError;
Chris Lattner24943d22010-06-08 16:52:24 +0000455
Sean Callananc78d6482010-07-26 22:14:36 +0000456 lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, errors, stop_others, false));
Chris Lattner24943d22010-06-08 16:52:24 +0000457
458 ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
459
Chris Lattner24943d22010-06-08 16:52:24 +0000460 if (call_plan_sp == NULL)
Sean Callanan841026f2010-07-23 00:16:21 +0000461 return eExecutionSetupError;
462
Chris Lattner24943d22010-06-08 16:52:24 +0000463 call_plan_sp->SetPrivate(true);
Sean Callananc78d6482010-07-26 22:14:36 +0000464 exe_ctx.thread->QueueThreadPlan(call_plan_sp, true);
Sean Callanan841026f2010-07-23 00:16:21 +0000465
Chris Lattner24943d22010-06-08 16:52:24 +0000466 // We need to call the function synchronously, so spin waiting for it to return.
467 // If we get interrupted while executing, we're going to lose our context, and
468 // won't be able to gather the result at this point.
Sean Callanan841026f2010-07-23 00:16:21 +0000469
Chris Lattner24943d22010-06-08 16:52:24 +0000470 TimeValue* timeout_ptr = NULL;
471 TimeValue real_timeout;
Sean Callanan841026f2010-07-23 00:16:21 +0000472
Chris Lattner24943d22010-06-08 16:52:24 +0000473 if (single_thread_timeout_usec != 0)
474 {
475 real_timeout = TimeValue::Now();
476 real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
477 timeout_ptr = &real_timeout;
478 }
Sean Callanan841026f2010-07-23 00:16:21 +0000479
Jim Inghama2890f42010-08-17 00:35:35 +0000480 Error resume_error = exe_ctx.process->Resume ();
481 if (!resume_error.Success())
482 {
483 errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
484 return eExecutionSetupError;
485 }
Sean Callanan841026f2010-07-23 00:16:21 +0000486
487 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Chris Lattner24943d22010-06-08 16:52:24 +0000488
489 while (1)
490 {
491 lldb::EventSP event_sp;
Sean Callanan841026f2010-07-23 00:16:21 +0000492
Chris Lattner24943d22010-06-08 16:52:24 +0000493 // Now wait for the process to stop again:
494 // FIXME: Probably want a time out.
Sean Callananc78d6482010-07-26 22:14:36 +0000495 lldb::StateType stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Sean Callanan841026f2010-07-23 00:16:21 +0000496
Chris Lattner24943d22010-06-08 16:52:24 +0000497 if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL)
498 {
499 // Right now this is the only way to tell we've timed out...
500 // We should interrupt the process here...
501 // Not really sure what to do if Halt fails here...
Chris Lattner24943d22010-06-08 16:52:24 +0000502 if (log)
503 log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.", single_thread_timeout_usec);
Sean Callanan841026f2010-07-23 00:16:21 +0000504
Sean Callananc78d6482010-07-26 22:14:36 +0000505 if (exe_ctx.process->Halt().Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000506 {
507 timeout_ptr = NULL;
508
Sean Callananc78d6482010-07-26 22:14:36 +0000509 stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000510 if (stop_state == lldb::eStateInvalid)
511 {
512 errors.Printf ("Got an invalid stop state after halt.");
513 }
514 else if (stop_state != lldb::eStateStopped)
515 {
516 StreamString s;
517 event_sp->Dump (&s);
518
519 errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
520 }
521
522 if (try_all_threads)
523 {
524 // Between the time that we got the timeout and the time we halted, but target
525 // might have actually completed the plan. If so, we're done.
Sean Callananc78d6482010-07-26 22:14:36 +0000526 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000527 {
528 return_value = eExecutionCompleted;
529 break;
530 }
Sean Callanan841026f2010-07-23 00:16:21 +0000531
Chris Lattner24943d22010-06-08 16:52:24 +0000532 call_plan_ptr->SetStopOthers (false);
Sean Callananc78d6482010-07-26 22:14:36 +0000533 exe_ctx.process->Resume();
Chris Lattner24943d22010-06-08 16:52:24 +0000534 continue;
535 }
536 else
537 return eExecutionInterrupted;
538 }
539 }
540 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
541 continue;
Sean Callanan841026f2010-07-23 00:16:21 +0000542
Sean Callananc78d6482010-07-26 22:14:36 +0000543 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000544 {
545 return_value = eExecutionCompleted;
546 break;
547 }
Sean Callananc78d6482010-07-26 22:14:36 +0000548 else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000549 {
550 return_value = eExecutionDiscarded;
551 break;
552 }
553 else
554 {
Sean Callanan841026f2010-07-23 00:16:21 +0000555 if (log)
556 {
557 StreamString s;
558 event_sp->Dump (&s);
559 StreamString ts;
560
561 const char *event_explanation;
562
563 do
564 {
565 const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
566
567 if (!event_data)
568 {
569 event_explanation = "<no event data>";
570 break;
571 }
572
573 Process *process = event_data->GetProcessSP().get();
574
575 if (!process)
576 {
577 event_explanation = "<no process>";
578 break;
579 }
580
581 ThreadList &thread_list = process->GetThreadList();
582
583 uint32_t num_threads = thread_list.GetSize();
584 uint32_t thread_index;
585
586 ts.Printf("<%u threads> ", num_threads);
587
588 for (thread_index = 0;
589 thread_index < num_threads;
590 ++thread_index)
591 {
592 Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
593
594 if (!thread)
595 {
596 ts.Printf("<?> ");
597 continue;
598 }
599
Sean Callanan841026f2010-07-23 00:16:21 +0000600 ts.Printf("<");
601 RegisterContext *register_context = thread->GetRegisterContext();
602
603 if (register_context)
604 ts.Printf("[ip 0x%llx] ", register_context->GetPC());
605 else
606 ts.Printf("[ip unknown] ");
607
Greg Clayton643ee732010-08-04 01:40:35 +0000608 StopInfo *stop_info = thread->GetStopInfo();
609 if (stop_info)
610 {
611 const char *stop_desc = stop_info->GetDescription();
612 if (stop_desc)
613 ts.PutCString (stop_desc);
614 }
Sean Callanan841026f2010-07-23 00:16:21 +0000615 ts.Printf(">");
616 }
617
618 event_explanation = ts.GetData();
619 } while (0);
620
621 log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
622 }
623
Chris Lattner24943d22010-06-08 16:52:24 +0000624 return_value = eExecutionInterrupted;
625 break;
626 }
Chris Lattner24943d22010-06-08 16:52:24 +0000627 }
Sean Callanan841026f2010-07-23 00:16:21 +0000628
Sean Callananc78d6482010-07-26 22:14:36 +0000629 // Thread we ran the function in may have gone away because we ran the target
630 // Check that it's still there.
631 exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByID(tid, true).get();
632 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
633
Sean Callanan841026f2010-07-23 00:16:21 +0000634 return return_value;
635}
Chris Lattner24943d22010-06-08 16:52:24 +0000636
Sean Callanan841026f2010-07-23 00:16:21 +0000637ClangFunction::ExecutionResults
638ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000639 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000640 lldb::addr_t *args_addr_ptr,
641 Stream &errors,
642 bool stop_others,
643 uint32_t single_thread_timeout_usec,
644 bool try_all_threads,
645 Value &results)
646{
647 using namespace clang;
648 ExecutionResults return_value = eExecutionSetupError;
649
650 lldb::addr_t args_addr;
651
652 if (args_addr_ptr != NULL)
653 args_addr = *args_addr_ptr;
654 else
655 args_addr = LLDB_INVALID_ADDRESS;
656
657 if (CompileFunction(errors) != 0)
658 return eExecutionSetupError;
659
660 if (args_addr == LLDB_INVALID_ADDRESS)
661 {
Sean Callananc78d6482010-07-26 22:14:36 +0000662 if (!InsertFunction(exe_ctx, args_addr, errors))
Sean Callanan841026f2010-07-23 00:16:21 +0000663 return eExecutionSetupError;
664 }
665
Sean Callananc78d6482010-07-26 22:14:36 +0000666 return_value = ClangFunction::ExecuteFunction(exe_ctx, m_wrapper_function_addr, args_addr, stop_others, try_all_threads, single_thread_timeout_usec, errors);
Sean Callanan841026f2010-07-23 00:16:21 +0000667
668 if (args_addr_ptr != NULL)
669 *args_addr_ptr = args_addr;
670
Chris Lattner24943d22010-06-08 16:52:24 +0000671 if (return_value != eExecutionCompleted)
672 return return_value;
673
Sean Callananc78d6482010-07-26 22:14:36 +0000674 FetchFunctionResults(exe_ctx, args_addr, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000675
676 if (args_addr_ptr == NULL)
Sean Callananc78d6482010-07-26 22:14:36 +0000677 DeallocateFunctionResults(exe_ctx, args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000678
679 return eExecutionCompleted;
680}
681
Sean Callanan65dafa82010-08-27 01:01:44 +0000682clang::ASTConsumer *
683ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
Chris Lattner24943d22010-06-08 16:52:24 +0000684{
Sean Callanan65dafa82010-08-27 01:01:44 +0000685 return new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this);
Chris Lattner24943d22010-06-08 16:52:24 +0000686}