blob: 7e1160dfbefd9615a5833fb594c90ea78c353c79 [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"
35#include "lldb/Target/Thread.h"
36#include "lldb/Target/ThreadPlan.h"
37#include "lldb/Target/ThreadPlanCallFunction.h"
38#include "lldb/Core/Log.h"
39
40using namespace lldb_private;
41//----------------------------------------------------------------------
42// ClangFunction constructor
43//----------------------------------------------------------------------
44ClangFunction::ClangFunction(const char *target_triple, ClangASTContext *ast_context, void *return_qualtype, const Address& functionAddress, const ValueList &arg_value_list) :
45 ClangExpression (target_triple, NULL),
Chris Lattner24943d22010-06-08 16:52:24 +000046 m_function_ptr (NULL),
Greg Clayton54e7afa2010-07-09 20:39:50 +000047 m_function_addr (functionAddress),
Chris Lattner24943d22010-06-08 16:52:24 +000048 m_function_return_qual_type(return_qualtype),
Greg Clayton54e7afa2010-07-09 20:39:50 +000049 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000050 m_wrapper_function_name ("__lldb_caller_function"),
51 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000052 m_wrapper_function_addr (),
53 m_wrapper_args_addrs (),
54 m_struct_layout (NULL),
55 m_arg_values (arg_value_list),
56 m_value_struct_size (0),
Chris Lattner24943d22010-06-08 16:52:24 +000057 m_return_offset(0),
Greg Clayton54e7afa2010-07-09 20:39:50 +000058 m_return_size (0),
Chris Lattner24943d22010-06-08 16:52:24 +000059 m_compiled (false),
60 m_JITted (false)
61{
62}
63
64ClangFunction::ClangFunction(const char *target_triple, Function &function, ClangASTContext *ast_context, const ValueList &arg_value_list) :
65 ClangExpression (target_triple, NULL),
66 m_function_ptr (&function),
Greg Clayton54e7afa2010-07-09 20:39:50 +000067 m_function_addr (),
68 m_function_return_qual_type (),
Chris Lattner24943d22010-06-08 16:52:24 +000069 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000070 m_wrapper_function_name ("__lldb_function_caller"),
71 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000072 m_wrapper_function_addr (),
73 m_wrapper_args_addrs (),
74 m_struct_layout (NULL),
75 m_arg_values (arg_value_list),
76 m_value_struct_size (0),
77 m_return_offset (0),
78 m_return_size (0),
Chris Lattner24943d22010-06-08 16:52:24 +000079 m_compiled (false),
80 m_JITted (false)
81{
82 m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
83 m_function_return_qual_type = m_function_ptr->GetReturnType().GetOpaqueClangQualType();
84}
85
86//----------------------------------------------------------------------
87// Destructor
88//----------------------------------------------------------------------
89ClangFunction::~ClangFunction()
90{
91}
92
93unsigned
94ClangFunction::CompileFunction (Stream &errors)
95{
96 // FIXME: How does clang tell us there's no return value? We need to handle that case.
97 unsigned num_errors = 0;
98
99 if (!m_compiled)
100 {
101 std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type);
102
103 // Cons up the function we're going to wrap our call in, then compile it...
104 // We declare the function "extern "C"" because the compiler might be in C++
105 // mode which would mangle the name and then we couldn't find it again...
106 std::string expression;
107 expression.append ("extern \"C\" void ");
108 expression.append (m_wrapper_function_name);
109 expression.append (" (void *input)\n{\n struct ");
110 expression.append (m_wrapper_struct_name);
111 expression.append (" \n {\n");
112 expression.append (" ");
113 expression.append (return_type_str);
114 expression.append (" (*fn_ptr) (");
115
116 // Get the number of arguments. If we have a function type and it is prototyped,
117 // trust that, otherwise use the values we were given.
118
119 // FIXME: This will need to be extended to handle Variadic functions. We'll need
120 // to pull the defined arguments out of the function, then add the types from the
121 // arguments list for the variable arguments.
122
Greg Clayton54e7afa2010-07-09 20:39:50 +0000123 uint32_t num_args = UINT32_MAX;
Chris Lattner24943d22010-06-08 16:52:24 +0000124 bool trust_function = false;
125 // GetArgumentCount returns -1 for an unprototyped function.
126 if (m_function_ptr)
127 {
Greg Clayton54e7afa2010-07-09 20:39:50 +0000128 int num_func_args = m_function_ptr->GetArgumentCount();
129 if (num_func_args >= 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000130 trust_function = true;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000131 else
132 num_args = num_func_args;
Chris Lattner24943d22010-06-08 16:52:24 +0000133 }
134
Greg Clayton54e7afa2010-07-09 20:39:50 +0000135 if (num_args == UINT32_MAX)
Chris Lattner24943d22010-06-08 16:52:24 +0000136 num_args = m_arg_values.GetSize();
137
138 std::string args_buffer; // This one stores the definition of all the args in "struct caller".
139 std::string args_list_buffer; // This one stores the argument list called from the structure.
Greg Clayton54e7afa2010-07-09 20:39:50 +0000140 for (size_t i = 0; i < num_args; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000141 {
142 const char *type_string;
143 std::string type_stdstr;
144
145 if (trust_function)
146 {
147 type_string = m_function_ptr->GetArgumentTypeAtIndex(i).GetName().AsCString();
148 }
149 else
150 {
151 Value *arg_value = m_arg_values.GetValueAtIndex(i);
152 void *clang_qual_type = arg_value->GetOpaqueClangQualType ();
153 if (clang_qual_type != NULL)
154 {
155 type_stdstr = ClangASTContext::GetTypeName(clang_qual_type);
156 type_string = type_stdstr.c_str();
157 }
158 else
159 {
160 errors.Printf("Could not determine type of input value %d.", i);
161 return 1;
162 }
163 }
164
165
166 expression.append (type_string);
167 if (i < num_args - 1)
168 expression.append (", ");
169
170 char arg_buf[32];
171 args_buffer.append (" ");
172 args_buffer.append (type_string);
Greg Clayton54e7afa2010-07-09 20:39:50 +0000173 snprintf(arg_buf, 31, "arg_%zd", i);
Chris Lattner24943d22010-06-08 16:52:24 +0000174 args_buffer.push_back (' ');
175 args_buffer.append (arg_buf);
176 args_buffer.append (";\n");
177
178 args_list_buffer.append ("__lldb_fn_data->");
179 args_list_buffer.append (arg_buf);
180 if (i < num_args - 1)
181 args_list_buffer.append (", ");
182
183 }
184 expression.append (");\n"); // Close off the function calling prototype.
185
186 expression.append (args_buffer);
187
188 expression.append (" ");
189 expression.append (return_type_str);
190 expression.append (" return_value;");
191 expression.append ("\n };\n struct ");
192 expression.append (m_wrapper_struct_name);
193 expression.append ("* __lldb_fn_data = (struct ");
194 expression.append (m_wrapper_struct_name);
195 expression.append (" *) input;\n");
196
197 expression.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
198 expression.append (args_list_buffer);
199 expression.append (");\n}\n");
200
201 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
202 if (log)
203 log->Printf ("Expression: \n\n%s\n\n", expression.c_str());
204
205 // Okay, now compile this expression:
206 num_errors = ParseBareExpression (expression.c_str(), errors);
207 m_compiled = (num_errors == 0);
208
209 if (m_compiled)
210 {
211 using namespace clang;
212 CompilerInstance *compiler_instance = GetCompilerInstance();
213 ASTContext &ast_context = compiler_instance->getASTContext();
214
215 DeclarationName wrapper_func_name(&ast_context.Idents.get(m_wrapper_function_name.c_str()));
216 FunctionDecl::lookup_result func_lookup = ast_context.getTranslationUnitDecl()->lookup(wrapper_func_name);
217 if (func_lookup.first == func_lookup.second)
218 return false;
219
220 FunctionDecl *wrapper_func = dyn_cast<FunctionDecl> (*(func_lookup.first));
221 if (!wrapper_func)
222 return false;
223
224 DeclarationName wrapper_struct_name(&ast_context.Idents.get(m_wrapper_struct_name.c_str()));
225 RecordDecl::lookup_result struct_lookup = wrapper_func->lookup(wrapper_struct_name);
226 if (struct_lookup.first == struct_lookup.second)
227 return false;
228
229 RecordDecl *wrapper_struct = dyn_cast<RecordDecl>(*(struct_lookup.first));
230
231 if (!wrapper_struct)
232 return false;
233
234 m_struct_layout = &ast_context.getASTRecordLayout (wrapper_struct);
235 if (!m_struct_layout)
236 {
237 m_compiled = false;
238 return 1;
239 }
240 m_return_offset = m_struct_layout->getFieldOffset(m_struct_layout->getFieldCount() - 1);
241 m_return_size = (m_struct_layout->getDataSize() - m_return_offset)/8;
242 }
243 }
244
245 return num_errors;
246}
247
248bool
249ClangFunction::WriteFunctionWrapper (ExecutionContext &exc_context, Stream &errors)
250{
251 Process *process = exc_context.process;
252
253 if (process == NULL)
254 return false;
255
256 if (!m_JITted)
257 {
258 // Next we should JIT it and insert the result into the target program.
259 if (!JITFunction (exc_context, m_wrapper_function_name.c_str()))
260 return false;
261
262 if (!WriteJITCode (exc_context))
263 return false;
264
265 m_JITted = true;
266 }
267
268 // Next get the call address for the function:
Greg Clayton54e7afa2010-07-09 20:39:50 +0000269 m_wrapper_function_addr = GetFunctionAddress (m_wrapper_function_name.c_str());
270 if (m_wrapper_function_addr == LLDB_INVALID_ADDRESS)
Chris Lattner24943d22010-06-08 16:52:24 +0000271 return false;
272
273 return true;
274}
275
276bool
277ClangFunction::WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors)
278{
279 return WriteFunctionArguments(exc_context, args_addr_ref, m_function_addr, m_arg_values, errors);
280}
281
282// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
283
284bool
285ClangFunction::WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors)
286{
287 // Otherwise, allocate space for the argument passing struct, and write it.
288 // We use the information in the expression parser AST to
289 // figure out how to do this...
290 // We should probably transcode this in this object so we can ditch the compiler instance
291 // and all its associated data, and just keep the JITTed bytes.
292
293 Error error;
294 using namespace clang;
295 ExecutionResults return_value = eExecutionSetupError;
296
297 Process *process = exc_context.process;
298
299 if (process == NULL)
300 return return_value;
301
302 uint64_t struct_size = m_struct_layout->getSize()/8; // Clang returns sizes in bytes.
303
304 if (args_addr_ref == LLDB_INVALID_ADDRESS)
305 {
306 args_addr_ref = process->AllocateMemory(struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
307 if (args_addr_ref == LLDB_INVALID_ADDRESS)
308 return false;
309 m_wrapper_args_addrs.push_back (args_addr_ref);
310 }
311 else
312 {
313 // Make sure this is an address that we've already handed out.
314 if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
315 {
316 return false;
317 }
318 }
319
320 // FIXME: This is fake, and just assumes that it matches that architecture.
321 // Make a data extractor and put the address into the right byte order & size.
322
323 uint64_t fun_addr = function_address.GetLoadAddress(exc_context.process);
324 int first_offset = m_struct_layout->getFieldOffset(0)/8;
325 process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error);
326
327 // FIXME: We will need to extend this for Variadic functions.
328
329 Error value_error;
330
331 size_t num_args = arg_values.GetSize();
332 if (num_args != m_arg_values.GetSize())
333 {
334 errors.Printf ("Wrong number of arguments - was: %d should be: %d", num_args, m_arg_values.GetSize());
335 return false;
336 }
337
Greg Clayton54e7afa2010-07-09 20:39:50 +0000338 for (size_t i = 0; i < num_args; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000339 {
340 // FIXME: We should sanity check sizes.
341
342 int offset = m_struct_layout->getFieldOffset(i+1)/8; // Clang sizes are in bytes.
343 Value *arg_value = arg_values.GetValueAtIndex(i);
344
345 // FIXME: For now just do scalars:
346
347 // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
348
349 if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
350 arg_value->GetContextType() == Value::eContextTypeOpaqueClangQualType &&
351 ClangASTContext::IsPointerType(arg_value->GetValueOpaqueClangQualType()))
352 continue;
353
354 const Scalar &arg_scalar = arg_value->ResolveValue(&exc_context, m_clang_ast_context->getASTContext());
355
356 int byte_size = arg_scalar.GetByteSize();
357 std::vector<uint8_t> buffer;
358 buffer.resize(byte_size);
359 DataExtractor value_data;
360 arg_scalar.GetData (value_data);
Greg Clayton53d68e72010-07-20 22:52:08 +0000361 value_data.ExtractBytes(0, byte_size, process->GetByteOrder(), &buffer.front());
362 process->WriteMemory(args_addr_ref + offset, &buffer.front(), byte_size, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000363 }
364
365 return true;
366}
367
368bool
369ClangFunction::InsertFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors)
370{
371 using namespace clang;
372
373 if (CompileFunction(errors) != 0)
374 return false;
375 if (!WriteFunctionWrapper(exc_context, errors))
376 return false;
377 if (!WriteFunctionArguments(exc_context, args_addr_ref, errors))
378 return false;
379
380 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
381 if (log)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000382 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 +0000383
384 return true;
385}
386
387ThreadPlan *
388ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr, Stream &errors, bool stop_others, bool discard_on_error)
389{
390 // FIXME: Use the errors Stream for better error reporting.
391
392 Process *process = exc_context.process;
393
394 if (process == NULL)
395 {
396 errors.Printf("Can't call a function without a process.");
397 return NULL;
398 }
399
400 // Okay, now run the function:
401
Greg Clayton54e7afa2010-07-09 20:39:50 +0000402 Address wrapper_address (NULL, m_wrapper_function_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000403 ThreadPlan *new_plan = new ThreadPlanCallFunction (*exc_context.thread,
404 wrapper_address,
405 args_addr,
406 stop_others, discard_on_error);
407 return new_plan;
408}
409
410bool
411ClangFunction::FetchFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr, Value &ret_value)
412{
413 // Read the return value - it is the last field in the struct:
414 // FIXME: How does clang tell us there's no return value? We need to handle that case.
415
416 std::vector<uint8_t> data_buffer;
417 data_buffer.resize(m_return_size);
418 Process *process = exc_context.process;
419 Error error;
Greg Clayton53d68e72010-07-20 22:52:08 +0000420 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 +0000421
422 if (bytes_read == 0)
423 {
424 return false;
425 }
426
427 if (bytes_read < m_return_size)
428 return false;
429
Greg Clayton53d68e72010-07-20 22:52:08 +0000430 DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000431 // FIXME: Assuming an integer scalar for now:
432
433 uint32_t offset = 0;
434 uint64_t return_integer = data.GetMaxU64(&offset, m_return_size);
435
436 ret_value.SetContext (Value::eContextTypeOpaqueClangQualType, m_function_return_qual_type);
437 ret_value.SetValueType(Value::eValueTypeScalar);
438 ret_value.GetScalar() = return_integer;
439 return true;
440}
441
442void
443ClangFunction::DeallocateFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr)
444{
445 std::list<lldb::addr_t>::iterator pos;
446 pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
447 if (pos != m_wrapper_args_addrs.end())
448 m_wrapper_args_addrs.erase(pos);
449
450 exc_context.process->DeallocateMemory(args_addr);
451}
452
453ClangFunction::ExecutionResults
454ClangFunction::ExecuteFunction(ExecutionContext &exc_context, Stream &errors, Value &results)
455{
456 return ExecuteFunction (exc_context, errors, 1000, true, results);
457}
458
459ClangFunction::ExecutionResults
460ClangFunction::ExecuteFunction(ExecutionContext &exc_context, Stream &errors, bool stop_others, Value &results)
461{
462 return ExecuteFunction (exc_context, NULL, errors, stop_others, NULL, false, results);
463}
464
465ClangFunction::ExecutionResults
466ClangFunction::ExecuteFunction(
467 ExecutionContext &exc_context,
468 Stream &errors,
469 uint32_t single_thread_timeout_usec,
470 bool try_all_threads,
471 Value &results)
472{
473 return ExecuteFunction (exc_context, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
474}
475
476ClangFunction::ExecutionResults
477ClangFunction::ExecuteFunction(
478 ExecutionContext &exc_context,
479 lldb::addr_t *args_addr_ptr,
480 Stream &errors,
481 bool stop_others,
482 uint32_t single_thread_timeout_usec,
483 bool try_all_threads,
484 Value &results)
485{
486 using namespace clang;
487 ExecutionResults return_value = eExecutionSetupError;
488 Process *process = exc_context.process;
489
490 lldb::addr_t args_addr;
491
492 if (args_addr_ptr != NULL)
493 args_addr = *args_addr_ptr;
494 else
495 args_addr = LLDB_INVALID_ADDRESS;
496
497 if (CompileFunction(errors) != 0)
498 return eExecutionSetupError;
499
500 if (args_addr == LLDB_INVALID_ADDRESS)
501 {
502 if (!InsertFunction(exc_context, args_addr, errors))
503 return eExecutionSetupError;
504 }
505
506
507 lldb::ThreadPlanSP call_plan_sp(GetThreadPlanToCallFunction(exc_context, args_addr, errors, stop_others, false));
508
509 ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
510
511 if (args_addr_ptr != NULL)
512 *args_addr_ptr = args_addr;
513
514 if (call_plan_sp == NULL)
515 return return_value;
516
517 call_plan_sp->SetPrivate(true);
518 exc_context.thread->QueueThreadPlan(call_plan_sp, true);
519
520 // We need to call the function synchronously, so spin waiting for it to return.
521 // If we get interrupted while executing, we're going to lose our context, and
522 // won't be able to gather the result at this point.
523
524 TimeValue* timeout_ptr = NULL;
525 TimeValue real_timeout;
526 if (single_thread_timeout_usec != 0)
527 {
528 real_timeout = TimeValue::Now();
529 real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
530 timeout_ptr = &real_timeout;
531 }
532 process->Resume ();
533
534
535 while (1)
536 {
537 lldb::EventSP event_sp;
538
539 // Now wait for the process to stop again:
540 // FIXME: Probably want a time out.
541 lldb::StateType stop_state = process->WaitForStateChangedEvents (timeout_ptr, event_sp);
542 if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL)
543 {
544 // Right now this is the only way to tell we've timed out...
545 // We should interrupt the process here...
546 // Not really sure what to do if Halt fails here...
547 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
548 if (log)
549 log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.", single_thread_timeout_usec);
550
551 if (process->Halt().Success())
552 {
553 timeout_ptr = NULL;
554
Greg Claytonbef15832010-07-14 00:18:15 +0000555 stop_state = process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000556 if (stop_state == lldb::eStateInvalid)
557 {
558 errors.Printf ("Got an invalid stop state after halt.");
559 }
560 else if (stop_state != lldb::eStateStopped)
561 {
562 StreamString s;
563 event_sp->Dump (&s);
564
565 errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
566 }
567
568 if (try_all_threads)
569 {
570 // Between the time that we got the timeout and the time we halted, but target
571 // might have actually completed the plan. If so, we're done.
572 if (exc_context.thread->IsThreadPlanDone (call_plan_sp.get()))
573 {
574 return_value = eExecutionCompleted;
575 break;
576 }
577
578
579 call_plan_ptr->SetStopOthers (false);
580 process->Resume();
581 continue;
582 }
583 else
584 return eExecutionInterrupted;
585 }
586 }
587 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
588 continue;
589
590 if (exc_context.thread->IsThreadPlanDone (call_plan_sp.get()))
591 {
592 return_value = eExecutionCompleted;
593 break;
594 }
595 else if (exc_context.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
596 {
597 return_value = eExecutionDiscarded;
598 break;
599 }
600 else
601 {
602 return_value = eExecutionInterrupted;
603 break;
604 }
605
606 }
607
608 if (return_value != eExecutionCompleted)
609 return return_value;
610
611 FetchFunctionResults(exc_context, args_addr, results);
612
613 if (args_addr_ptr == NULL)
614 DeallocateFunctionResults(exc_context, args_addr);
615
616 return eExecutionCompleted;
617}
618
619ClangFunction::ExecutionResults
620ClangFunction::ExecuteFunctionWithABI(ExecutionContext &exc_context, Stream &errors, Value &results)
621{
622 // FIXME: Use the errors Stream for better error reporting.
623 using namespace clang;
624 ExecutionResults return_value = eExecutionSetupError;
625
626 Process *process = exc_context.process;
627
628 if (process == NULL)
629 {
630 errors.Printf("Can't call a function without a process.");
631 return return_value;
632 }
633
634 //unsigned int num_args = m_arg_values.GetSize();
635 //unsigned int arg_index;
636
637 //for (arg_index = 0; arg_index < num_args; ++arg_index)
638 // m_arg_values.GetValueAtIndex(arg_index)->ResolveValue(&exc_context, GetASTContext());
639
640 ThreadPlan *call_plan = exc_context.thread->QueueThreadPlanForCallFunction (false,
641 m_function_addr,
642 m_arg_values,
643 true);
644 if (call_plan == NULL)
645 return return_value;
646
647 call_plan->SetPrivate(true);
648
649 // We need to call the function synchronously, so spin waiting for it to return.
650 // If we get interrupted while executing, we're going to lose our context, and
651 // won't be able to gather the result at this point.
652
653 process->Resume ();
654
655 while (1)
656 {
657 lldb::EventSP event_sp;
658
659 // Now wait for the process to stop again:
660 // FIXME: Probably want a time out.
661 lldb::StateType stop_state = process->WaitForStateChangedEvents (NULL, event_sp);
662 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
663 continue;
664
665 if (exc_context.thread->IsThreadPlanDone (call_plan))
666 {
667 return_value = eExecutionCompleted;
668 break;
669 }
670 else if (exc_context.thread->WasThreadPlanDiscarded (call_plan))
671 {
672 return_value = eExecutionDiscarded;
673 break;
674 }
675 else
676 {
677 return_value = eExecutionInterrupted;
678 break;
679 }
680
681 }
682
683 return eExecutionCompleted;
684}