blob: b5a580c5935f3103fd67676fc76233963fa3f0aa [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
25#include "lldb/Expression/ClangFunction.h"
26#include "lldb/Symbol/Type.h"
27#include "lldb/Core/DataExtractor.h"
28#include "lldb/Core/ValueObject.h"
29#include "lldb/Core/ValueObjectList.h"
30#include "lldb/Interpreter/CommandReturnObject.h"
31#include "lldb/Symbol/ClangASTContext.h"
32#include "lldb/Symbol/Function.h"
33#include "lldb/Target/ExecutionContext.h"
34#include "lldb/Target/Process.h"
Sean Callanan841026f2010-07-23 00:16:21 +000035#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036#include "lldb/Target/Thread.h"
37#include "lldb/Target/ThreadPlan.h"
38#include "lldb/Target/ThreadPlanCallFunction.h"
39#include "lldb/Core/Log.h"
40
41using namespace lldb_private;
42//----------------------------------------------------------------------
43// ClangFunction constructor
44//----------------------------------------------------------------------
45ClangFunction::ClangFunction(const char *target_triple, ClangASTContext *ast_context, void *return_qualtype, const Address& functionAddress, const ValueList &arg_value_list) :
46 ClangExpression (target_triple, NULL),
Chris Lattner24943d22010-06-08 16:52:24 +000047 m_function_ptr (NULL),
Greg Clayton54e7afa2010-07-09 20:39:50 +000048 m_function_addr (functionAddress),
Chris Lattner24943d22010-06-08 16:52:24 +000049 m_function_return_qual_type(return_qualtype),
Greg Clayton54e7afa2010-07-09 20:39:50 +000050 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000051 m_wrapper_function_name ("__lldb_caller_function"),
52 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000053 m_wrapper_function_addr (),
54 m_wrapper_args_addrs (),
55 m_struct_layout (NULL),
56 m_arg_values (arg_value_list),
57 m_value_struct_size (0),
Chris Lattner24943d22010-06-08 16:52:24 +000058 m_return_offset(0),
Greg Clayton54e7afa2010-07-09 20:39:50 +000059 m_return_size (0),
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) :
66 ClangExpression (target_triple, NULL),
67 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 (),
75 m_struct_layout (NULL),
76 m_arg_values (arg_value_list),
77 m_value_struct_size (0),
78 m_return_offset (0),
79 m_return_size (0),
Chris Lattner24943d22010-06-08 16:52:24 +000080 m_compiled (false),
81 m_JITted (false)
82{
83 m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
84 m_function_return_qual_type = m_function_ptr->GetReturnType().GetOpaqueClangQualType();
85}
86
87//----------------------------------------------------------------------
88// Destructor
89//----------------------------------------------------------------------
90ClangFunction::~ClangFunction()
91{
92}
93
94unsigned
95ClangFunction::CompileFunction (Stream &errors)
96{
97 // FIXME: How does clang tell us there's no return value? We need to handle that case.
98 unsigned num_errors = 0;
99
100 if (!m_compiled)
101 {
102 std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type);
103
104 // Cons up the function we're going to wrap our call in, then compile it...
105 // We declare the function "extern "C"" because the compiler might be in C++
106 // mode which would mangle the name and then we couldn't find it again...
107 std::string expression;
108 expression.append ("extern \"C\" void ");
109 expression.append (m_wrapper_function_name);
110 expression.append (" (void *input)\n{\n struct ");
111 expression.append (m_wrapper_struct_name);
112 expression.append (" \n {\n");
113 expression.append (" ");
114 expression.append (return_type_str);
115 expression.append (" (*fn_ptr) (");
116
117 // Get the number of arguments. If we have a function type and it is prototyped,
118 // trust that, otherwise use the values we were given.
119
120 // FIXME: This will need to be extended to handle Variadic functions. We'll need
121 // to pull the defined arguments out of the function, then add the types from the
122 // arguments list for the variable arguments.
123
Greg Clayton54e7afa2010-07-09 20:39:50 +0000124 uint32_t num_args = UINT32_MAX;
Chris Lattner24943d22010-06-08 16:52:24 +0000125 bool trust_function = false;
126 // GetArgumentCount returns -1 for an unprototyped function.
127 if (m_function_ptr)
128 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000129 int num_func_args = m_function_ptr->GetArgumentCount();
130 if (num_func_args >= 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000131 trust_function = true;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000132 else
133 num_args = num_func_args;
Chris Lattner24943d22010-06-08 16:52:24 +0000134 }
135
Greg Clayton54e7afa2010-07-09 20:39:50 +0000136 if (num_args == UINT32_MAX)
Chris Lattner24943d22010-06-08 16:52:24 +0000137 num_args = m_arg_values.GetSize();
138
139 std::string args_buffer; // This one stores the definition of all the args in "struct caller".
140 std::string args_list_buffer; // This one stores the argument list called from the structure.
Greg Clayton54e7afa2010-07-09 20:39:50 +0000141 for (size_t i = 0; i < num_args; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000142 {
143 const char *type_string;
144 std::string type_stdstr;
145
146 if (trust_function)
147 {
148 type_string = m_function_ptr->GetArgumentTypeAtIndex(i).GetName().AsCString();
149 }
150 else
151 {
152 Value *arg_value = m_arg_values.GetValueAtIndex(i);
153 void *clang_qual_type = arg_value->GetOpaqueClangQualType ();
154 if (clang_qual_type != NULL)
155 {
156 type_stdstr = ClangASTContext::GetTypeName(clang_qual_type);
157 type_string = type_stdstr.c_str();
158 }
159 else
160 {
161 errors.Printf("Could not determine type of input value %d.", i);
162 return 1;
163 }
164 }
165
166
167 expression.append (type_string);
168 if (i < num_args - 1)
169 expression.append (", ");
170
171 char arg_buf[32];
172 args_buffer.append (" ");
173 args_buffer.append (type_string);
Greg Clayton54e7afa2010-07-09 20:39:50 +0000174 snprintf(arg_buf, 31, "arg_%zd", i);
Chris Lattner24943d22010-06-08 16:52:24 +0000175 args_buffer.push_back (' ');
176 args_buffer.append (arg_buf);
177 args_buffer.append (";\n");
178
179 args_list_buffer.append ("__lldb_fn_data->");
180 args_list_buffer.append (arg_buf);
181 if (i < num_args - 1)
182 args_list_buffer.append (", ");
183
184 }
185 expression.append (");\n"); // Close off the function calling prototype.
186
187 expression.append (args_buffer);
188
189 expression.append (" ");
190 expression.append (return_type_str);
191 expression.append (" return_value;");
192 expression.append ("\n };\n struct ");
193 expression.append (m_wrapper_struct_name);
194 expression.append ("* __lldb_fn_data = (struct ");
195 expression.append (m_wrapper_struct_name);
196 expression.append (" *) input;\n");
197
198 expression.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
199 expression.append (args_list_buffer);
200 expression.append (");\n}\n");
201
202 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
203 if (log)
204 log->Printf ("Expression: \n\n%s\n\n", expression.c_str());
205
206 // Okay, now compile this expression:
207 num_errors = ParseBareExpression (expression.c_str(), errors);
208 m_compiled = (num_errors == 0);
209
210 if (m_compiled)
211 {
212 using namespace clang;
213 CompilerInstance *compiler_instance = GetCompilerInstance();
214 ASTContext &ast_context = compiler_instance->getASTContext();
215
216 DeclarationName wrapper_func_name(&ast_context.Idents.get(m_wrapper_function_name.c_str()));
217 FunctionDecl::lookup_result func_lookup = ast_context.getTranslationUnitDecl()->lookup(wrapper_func_name);
218 if (func_lookup.first == func_lookup.second)
219 return false;
220
221 FunctionDecl *wrapper_func = dyn_cast<FunctionDecl> (*(func_lookup.first));
222 if (!wrapper_func)
223 return false;
224
225 DeclarationName wrapper_struct_name(&ast_context.Idents.get(m_wrapper_struct_name.c_str()));
226 RecordDecl::lookup_result struct_lookup = wrapper_func->lookup(wrapper_struct_name);
227 if (struct_lookup.first == struct_lookup.second)
228 return false;
229
230 RecordDecl *wrapper_struct = dyn_cast<RecordDecl>(*(struct_lookup.first));
231
232 if (!wrapper_struct)
233 return false;
234
235 m_struct_layout = &ast_context.getASTRecordLayout (wrapper_struct);
236 if (!m_struct_layout)
237 {
238 m_compiled = false;
239 return 1;
240 }
241 m_return_offset = m_struct_layout->getFieldOffset(m_struct_layout->getFieldCount() - 1);
242 m_return_size = (m_struct_layout->getDataSize() - m_return_offset)/8;
243 }
244 }
245
246 return num_errors;
247}
248
249bool
250ClangFunction::WriteFunctionWrapper (ExecutionContext &exc_context, Stream &errors)
251{
252 Process *process = exc_context.process;
253
254 if (process == NULL)
255 return false;
256
257 if (!m_JITted)
258 {
259 // Next we should JIT it and insert the result into the target program.
260 if (!JITFunction (exc_context, m_wrapper_function_name.c_str()))
261 return false;
262
263 if (!WriteJITCode (exc_context))
264 return false;
265
266 m_JITted = true;
267 }
268
269 // Next get the call address for the function:
Greg Clayton54e7afa2010-07-09 20:39:50 +0000270 m_wrapper_function_addr = GetFunctionAddress (m_wrapper_function_name.c_str());
271 if (m_wrapper_function_addr == LLDB_INVALID_ADDRESS)
Chris Lattner24943d22010-06-08 16:52:24 +0000272 return false;
273
274 return true;
275}
276
277bool
278ClangFunction::WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors)
279{
280 return WriteFunctionArguments(exc_context, args_addr_ref, m_function_addr, m_arg_values, errors);
281}
282
283// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
284
285bool
286ClangFunction::WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors)
287{
288 // Otherwise, allocate space for the argument passing struct, and write it.
289 // We use the information in the expression parser AST to
290 // figure out how to do this...
291 // We should probably transcode this in this object so we can ditch the compiler instance
292 // and all its associated data, and just keep the JITTed bytes.
293
294 Error error;
295 using namespace clang;
296 ExecutionResults return_value = eExecutionSetupError;
297
298 Process *process = exc_context.process;
299
300 if (process == NULL)
301 return return_value;
302
303 uint64_t struct_size = m_struct_layout->getSize()/8; // Clang returns sizes in bytes.
304
305 if (args_addr_ref == LLDB_INVALID_ADDRESS)
306 {
307 args_addr_ref = process->AllocateMemory(struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
308 if (args_addr_ref == LLDB_INVALID_ADDRESS)
309 return false;
310 m_wrapper_args_addrs.push_back (args_addr_ref);
311 }
312 else
313 {
314 // Make sure this is an address that we've already handed out.
315 if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
316 {
317 return false;
318 }
319 }
320
321 // FIXME: This is fake, and just assumes that it matches that architecture.
322 // Make a data extractor and put the address into the right byte order & size.
323
324 uint64_t fun_addr = function_address.GetLoadAddress(exc_context.process);
325 int first_offset = m_struct_layout->getFieldOffset(0)/8;
326 process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error);
327
328 // FIXME: We will need to extend this for Variadic functions.
329
330 Error value_error;
331
332 size_t num_args = arg_values.GetSize();
333 if (num_args != m_arg_values.GetSize())
334 {
335 errors.Printf ("Wrong number of arguments - was: %d should be: %d", num_args, m_arg_values.GetSize());
336 return false;
337 }
338
Greg Clayton54e7afa2010-07-09 20:39:50 +0000339 for (size_t i = 0; i < num_args; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000340 {
341 // FIXME: We should sanity check sizes.
342
343 int offset = m_struct_layout->getFieldOffset(i+1)/8; // Clang sizes are in bytes.
344 Value *arg_value = arg_values.GetValueAtIndex(i);
345
346 // FIXME: For now just do scalars:
347
348 // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
349
350 if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
351 arg_value->GetContextType() == Value::eContextTypeOpaqueClangQualType &&
352 ClangASTContext::IsPointerType(arg_value->GetValueOpaqueClangQualType()))
353 continue;
354
355 const Scalar &arg_scalar = arg_value->ResolveValue(&exc_context, m_clang_ast_context->getASTContext());
356
357 int byte_size = arg_scalar.GetByteSize();
358 std::vector<uint8_t> buffer;
359 buffer.resize(byte_size);
360 DataExtractor value_data;
361 arg_scalar.GetData (value_data);
Greg Clayton53d68e72010-07-20 22:52:08 +0000362 value_data.ExtractBytes(0, byte_size, process->GetByteOrder(), &buffer.front());
363 process->WriteMemory(args_addr_ref + offset, &buffer.front(), byte_size, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000364 }
365
366 return true;
367}
368
369bool
370ClangFunction::InsertFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors)
371{
372 using namespace clang;
373
374 if (CompileFunction(errors) != 0)
375 return false;
376 if (!WriteFunctionWrapper(exc_context, errors))
377 return false;
378 if (!WriteFunctionArguments(exc_context, args_addr_ref, errors))
379 return false;
380
381 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
382 if (log)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000383 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 +0000384
385 return true;
386}
387
388ThreadPlan *
Sean Callanan841026f2010-07-23 00:16:21 +0000389ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exc_context, 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 +0000390{
391 // FIXME: Use the errors Stream for better error reporting.
392
393 Process *process = exc_context.process;
394
395 if (process == NULL)
396 {
397 errors.Printf("Can't call a function without a process.");
398 return NULL;
399 }
400
401 // Okay, now run the function:
402
Sean Callanan841026f2010-07-23 00:16:21 +0000403 Address wrapper_address (NULL, func_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000404 ThreadPlan *new_plan = new ThreadPlanCallFunction (*exc_context.thread,
405 wrapper_address,
406 args_addr,
407 stop_others, discard_on_error);
408 return new_plan;
409}
410
411bool
412ClangFunction::FetchFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr, Value &ret_value)
413{
414 // Read the return value - it is the last field in the struct:
415 // FIXME: How does clang tell us there's no return value? We need to handle that case.
416
417 std::vector<uint8_t> data_buffer;
418 data_buffer.resize(m_return_size);
419 Process *process = exc_context.process;
420 Error error;
Greg Clayton53d68e72010-07-20 22:52:08 +0000421 size_t bytes_read = process->ReadMemory(args_addr + m_return_offset/8, &data_buffer.front(), m_return_size, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000422
423 if (bytes_read == 0)
424 {
425 return false;
426 }
427
428 if (bytes_read < m_return_size)
429 return false;
430
Greg Clayton53d68e72010-07-20 22:52:08 +0000431 DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000432 // FIXME: Assuming an integer scalar for now:
433
434 uint32_t offset = 0;
435 uint64_t return_integer = data.GetMaxU64(&offset, m_return_size);
436
437 ret_value.SetContext (Value::eContextTypeOpaqueClangQualType, m_function_return_qual_type);
438 ret_value.SetValueType(Value::eValueTypeScalar);
439 ret_value.GetScalar() = return_integer;
440 return true;
441}
442
443void
444ClangFunction::DeallocateFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr)
445{
446 std::list<lldb::addr_t>::iterator pos;
447 pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
448 if (pos != m_wrapper_args_addrs.end())
449 m_wrapper_args_addrs.erase(pos);
450
451 exc_context.process->DeallocateMemory(args_addr);
452}
453
454ClangFunction::ExecutionResults
455ClangFunction::ExecuteFunction(ExecutionContext &exc_context, Stream &errors, Value &results)
456{
457 return ExecuteFunction (exc_context, errors, 1000, true, results);
458}
459
460ClangFunction::ExecutionResults
461ClangFunction::ExecuteFunction(ExecutionContext &exc_context, Stream &errors, bool stop_others, Value &results)
462{
463 return ExecuteFunction (exc_context, NULL, errors, stop_others, NULL, false, results);
464}
465
466ClangFunction::ExecutionResults
467ClangFunction::ExecuteFunction(
468 ExecutionContext &exc_context,
469 Stream &errors,
470 uint32_t single_thread_timeout_usec,
471 bool try_all_threads,
472 Value &results)
473{
474 return ExecuteFunction (exc_context, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
475}
476
Sean Callanan841026f2010-07-23 00:16:21 +0000477// This is the static function
478ClangFunction::ExecutionResults
479ClangFunction::ExecuteFunction (
Chris Lattner24943d22010-06-08 16:52:24 +0000480 ExecutionContext &exc_context,
Sean Callanan841026f2010-07-23 00:16:21 +0000481 lldb::addr_t function_address,
482 lldb::addr_t &void_arg,
483 bool stop_others,
484 bool try_all_threads,
485 uint32_t single_thread_timeout_usec,
486 Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000487{
Sean Callanan841026f2010-07-23 00:16:21 +0000488 ClangFunction::ExecutionResults return_value = eExecutionSetupError;
Chris Lattner24943d22010-06-08 16:52:24 +0000489
Sean Callanan841026f2010-07-23 00:16:21 +0000490 lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exc_context, function_address, void_arg, errors, stop_others, false));
Chris Lattner24943d22010-06-08 16:52:24 +0000491
492 ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
493
Chris Lattner24943d22010-06-08 16:52:24 +0000494 if (call_plan_sp == NULL)
Sean Callanan841026f2010-07-23 00:16:21 +0000495 return eExecutionSetupError;
496
Chris Lattner24943d22010-06-08 16:52:24 +0000497 call_plan_sp->SetPrivate(true);
498 exc_context.thread->QueueThreadPlan(call_plan_sp, true);
Sean Callanan841026f2010-07-23 00:16:21 +0000499
Chris Lattner24943d22010-06-08 16:52:24 +0000500 // We need to call the function synchronously, so spin waiting for it to return.
501 // If we get interrupted while executing, we're going to lose our context, and
502 // won't be able to gather the result at this point.
Sean Callanan841026f2010-07-23 00:16:21 +0000503
Chris Lattner24943d22010-06-08 16:52:24 +0000504 TimeValue* timeout_ptr = NULL;
505 TimeValue real_timeout;
Sean Callanan841026f2010-07-23 00:16:21 +0000506
Chris Lattner24943d22010-06-08 16:52:24 +0000507 if (single_thread_timeout_usec != 0)
508 {
509 real_timeout = TimeValue::Now();
510 real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
511 timeout_ptr = &real_timeout;
512 }
Sean Callanan841026f2010-07-23 00:16:21 +0000513
514 exc_context.process->Resume ();
515
516 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Chris Lattner24943d22010-06-08 16:52:24 +0000517
518 while (1)
519 {
520 lldb::EventSP event_sp;
Sean Callanan841026f2010-07-23 00:16:21 +0000521
Chris Lattner24943d22010-06-08 16:52:24 +0000522 // Now wait for the process to stop again:
523 // FIXME: Probably want a time out.
Sean Callanan841026f2010-07-23 00:16:21 +0000524 lldb::StateType stop_state = exc_context.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
525
Chris Lattner24943d22010-06-08 16:52:24 +0000526 if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL)
527 {
528 // Right now this is the only way to tell we've timed out...
529 // We should interrupt the process here...
530 // Not really sure what to do if Halt fails here...
Chris Lattner24943d22010-06-08 16:52:24 +0000531 if (log)
532 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 +0000533
534 if (exc_context.process->Halt().Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000535 {
536 timeout_ptr = NULL;
537
Sean Callanan841026f2010-07-23 00:16:21 +0000538 stop_state = exc_context.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000539 if (stop_state == lldb::eStateInvalid)
540 {
541 errors.Printf ("Got an invalid stop state after halt.");
542 }
543 else if (stop_state != lldb::eStateStopped)
544 {
545 StreamString s;
546 event_sp->Dump (&s);
547
548 errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
549 }
550
551 if (try_all_threads)
552 {
553 // Between the time that we got the timeout and the time we halted, but target
554 // might have actually completed the plan. If so, we're done.
555 if (exc_context.thread->IsThreadPlanDone (call_plan_sp.get()))
556 {
557 return_value = eExecutionCompleted;
558 break;
559 }
Sean Callanan841026f2010-07-23 00:16:21 +0000560
Chris Lattner24943d22010-06-08 16:52:24 +0000561 call_plan_ptr->SetStopOthers (false);
Sean Callanan841026f2010-07-23 00:16:21 +0000562 exc_context.process->Resume();
Chris Lattner24943d22010-06-08 16:52:24 +0000563 continue;
564 }
565 else
566 return eExecutionInterrupted;
567 }
568 }
569 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
570 continue;
Sean Callanan841026f2010-07-23 00:16:21 +0000571
Chris Lattner24943d22010-06-08 16:52:24 +0000572 if (exc_context.thread->IsThreadPlanDone (call_plan_sp.get()))
573 {
574 return_value = eExecutionCompleted;
575 break;
576 }
577 else if (exc_context.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
578 {
579 return_value = eExecutionDiscarded;
580 break;
581 }
582 else
583 {
Sean Callanan841026f2010-07-23 00:16:21 +0000584 if (log)
585 {
586 StreamString s;
587 event_sp->Dump (&s);
588 StreamString ts;
589
590 const char *event_explanation;
591
592 do
593 {
594 const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
595
596 if (!event_data)
597 {
598 event_explanation = "<no event data>";
599 break;
600 }
601
602 Process *process = event_data->GetProcessSP().get();
603
604 if (!process)
605 {
606 event_explanation = "<no process>";
607 break;
608 }
609
610 ThreadList &thread_list = process->GetThreadList();
611
612 uint32_t num_threads = thread_list.GetSize();
613 uint32_t thread_index;
614
615 ts.Printf("<%u threads> ", num_threads);
616
617 for (thread_index = 0;
618 thread_index < num_threads;
619 ++thread_index)
620 {
621 Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
622
623 if (!thread)
624 {
625 ts.Printf("<?> ");
626 continue;
627 }
628
629 Thread::StopInfo stop_info;
630 thread->GetStopInfo(&stop_info);
631
632 ts.Printf("<");
633 RegisterContext *register_context = thread->GetRegisterContext();
634
635 if (register_context)
636 ts.Printf("[ip 0x%llx] ", register_context->GetPC());
637 else
638 ts.Printf("[ip unknown] ");
639
640 stop_info.Dump(&ts);
641 ts.Printf(">");
642 }
643
644 event_explanation = ts.GetData();
645 } while (0);
646
647 log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
648 }
649
Chris Lattner24943d22010-06-08 16:52:24 +0000650 return_value = eExecutionInterrupted;
651 break;
652 }
Chris Lattner24943d22010-06-08 16:52:24 +0000653 }
Sean Callanan841026f2010-07-23 00:16:21 +0000654
655 return return_value;
656}
Chris Lattner24943d22010-06-08 16:52:24 +0000657
Sean Callanan841026f2010-07-23 00:16:21 +0000658ClangFunction::ExecutionResults
659ClangFunction::ExecuteFunction(
660 ExecutionContext &exc_context,
661 lldb::addr_t *args_addr_ptr,
662 Stream &errors,
663 bool stop_others,
664 uint32_t single_thread_timeout_usec,
665 bool try_all_threads,
666 Value &results)
667{
668 using namespace clang;
669 ExecutionResults return_value = eExecutionSetupError;
670
671 lldb::addr_t args_addr;
672
673 if (args_addr_ptr != NULL)
674 args_addr = *args_addr_ptr;
675 else
676 args_addr = LLDB_INVALID_ADDRESS;
677
678 if (CompileFunction(errors) != 0)
679 return eExecutionSetupError;
680
681 if (args_addr == LLDB_INVALID_ADDRESS)
682 {
683 if (!InsertFunction(exc_context, args_addr, errors))
684 return eExecutionSetupError;
685 }
686
687 return_value = ClangFunction::ExecuteFunction(exc_context, m_wrapper_function_addr, args_addr, stop_others, try_all_threads, single_thread_timeout_usec, errors);
688
689 if (args_addr_ptr != NULL)
690 *args_addr_ptr = args_addr;
691
Chris Lattner24943d22010-06-08 16:52:24 +0000692 if (return_value != eExecutionCompleted)
693 return return_value;
694
695 FetchFunctionResults(exc_context, args_addr, results);
696
697 if (args_addr_ptr == NULL)
698 DeallocateFunctionResults(exc_context, args_addr);
699
700 return eExecutionCompleted;
701}
702
703ClangFunction::ExecutionResults
704ClangFunction::ExecuteFunctionWithABI(ExecutionContext &exc_context, Stream &errors, Value &results)
705{
706 // FIXME: Use the errors Stream for better error reporting.
707 using namespace clang;
708 ExecutionResults return_value = eExecutionSetupError;
709
710 Process *process = exc_context.process;
711
712 if (process == NULL)
713 {
714 errors.Printf("Can't call a function without a process.");
715 return return_value;
716 }
717
718 //unsigned int num_args = m_arg_values.GetSize();
719 //unsigned int arg_index;
720
721 //for (arg_index = 0; arg_index < num_args; ++arg_index)
722 // m_arg_values.GetValueAtIndex(arg_index)->ResolveValue(&exc_context, GetASTContext());
723
724 ThreadPlan *call_plan = exc_context.thread->QueueThreadPlanForCallFunction (false,
725 m_function_addr,
726 m_arg_values,
727 true);
728 if (call_plan == NULL)
729 return return_value;
730
731 call_plan->SetPrivate(true);
732
733 // We need to call the function synchronously, so spin waiting for it to return.
734 // If we get interrupted while executing, we're going to lose our context, and
735 // won't be able to gather the result at this point.
736
737 process->Resume ();
738
739 while (1)
740 {
741 lldb::EventSP event_sp;
742
743 // Now wait for the process to stop again:
744 // FIXME: Probably want a time out.
745 lldb::StateType stop_state = process->WaitForStateChangedEvents (NULL, event_sp);
746 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
747 continue;
748
749 if (exc_context.thread->IsThreadPlanDone (call_plan))
750 {
751 return_value = eExecutionCompleted;
752 break;
753 }
754 else if (exc_context.thread->WasThreadPlanDiscarded (call_plan))
755 {
756 return_value = eExecutionDiscarded;
757 break;
758 }
759 else
760 {
761 return_value = eExecutionInterrupted;
762 break;
763 }
764
765 }
766
767 return eExecutionCompleted;
768}