blob: 5401b1c134332db56b8f6499c7f87318f1e8ad4d [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
Sean Callananc78d6482010-07-26 22:14:36 +0000250ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000251{
Sean Callananc78d6482010-07-26 22:14:36 +0000252 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000253
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.
Sean Callananc78d6482010-07-26 22:14:36 +0000260 if (!JITFunction (exe_ctx, m_wrapper_function_name.c_str()))
Chris Lattner24943d22010-06-08 16:52:24 +0000261 return false;
262
Sean Callananc78d6482010-07-26 22:14:36 +0000263 if (!WriteJITCode (exe_ctx))
Chris Lattner24943d22010-06-08 16:52:24 +0000264 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
Sean Callananc78d6482010-07-26 22:14:36 +0000278ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000279{
Sean Callananc78d6482010-07-26 22:14:36 +0000280 return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);
Chris Lattner24943d22010-06-08 16:52:24 +0000281}
282
283// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
284
285bool
Sean Callananc78d6482010-07-26 22:14:36 +0000286ClangFunction::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 +0000287{
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
Sean Callananc78d6482010-07-26 22:14:36 +0000298 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000299
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
Sean Callananc78d6482010-07-26 22:14:36 +0000324 uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.process);
Chris Lattner24943d22010-06-08 16:52:24 +0000325 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
Sean Callananc78d6482010-07-26 22:14:36 +0000355 const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000356
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
Sean Callananc78d6482010-07-26 22:14:36 +0000370ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000371{
372 using namespace clang;
373
374 if (CompileFunction(errors) != 0)
375 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000376 if (!WriteFunctionWrapper(exe_ctx, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000377 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000378 if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000379 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 Callananc78d6482010-07-26 22:14:36 +0000389ClangFunction::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 +0000390{
391 // FIXME: Use the errors Stream for better error reporting.
392
Sean Callananc78d6482010-07-26 22:14:36 +0000393 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000394
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);
Sean Callananc78d6482010-07-26 22:14:36 +0000404 ThreadPlan *new_plan = new ThreadPlanCallFunction (*exe_ctx.thread,
Chris Lattner24943d22010-06-08 16:52:24 +0000405 wrapper_address,
406 args_addr,
407 stop_others, discard_on_error);
408 return new_plan;
409}
410
411bool
Sean Callananc78d6482010-07-26 22:14:36 +0000412ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
Chris Lattner24943d22010-06-08 16:52:24 +0000413{
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);
Sean Callananc78d6482010-07-26 22:14:36 +0000419 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000420 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
Sean Callananc78d6482010-07-26 22:14:36 +0000444ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000445{
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
Sean Callananc78d6482010-07-26 22:14:36 +0000451 exe_ctx.process->DeallocateMemory(args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000452}
453
454ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000455ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000456{
Sean Callananc78d6482010-07-26 22:14:36 +0000457 return ExecuteFunction (exe_ctx, errors, 1000, true, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000458}
459
460ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000461ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000462{
Sean Callananc78d6482010-07-26 22:14:36 +0000463 return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, false, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000464}
465
466ClangFunction::ExecutionResults
467ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000468 ExecutionContext &exe_ctx,
Chris Lattner24943d22010-06-08 16:52:24 +0000469 Stream &errors,
470 uint32_t single_thread_timeout_usec,
471 bool try_all_threads,
472 Value &results)
473{
Sean Callananc78d6482010-07-26 22:14:36 +0000474 return ExecuteFunction (exe_ctx, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000475}
476
Sean Callanan841026f2010-07-23 00:16:21 +0000477// This is the static function
478ClangFunction::ExecutionResults
479ClangFunction::ExecuteFunction (
Sean Callananc78d6482010-07-26 22:14:36 +0000480 ExecutionContext &exe_ctx,
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 Callananc78d6482010-07-26 22:14:36 +0000488 // Save this value for restoration of the execution context after we run
489 uint32_t tid = exe_ctx.thread->GetID();
490
Sean Callanan841026f2010-07-23 00:16:21 +0000491 ClangFunction::ExecutionResults return_value = eExecutionSetupError;
Chris Lattner24943d22010-06-08 16:52:24 +0000492
Sean Callananc78d6482010-07-26 22:14:36 +0000493 lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, errors, stop_others, false));
Chris Lattner24943d22010-06-08 16:52:24 +0000494
495 ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
496
Chris Lattner24943d22010-06-08 16:52:24 +0000497 if (call_plan_sp == NULL)
Sean Callanan841026f2010-07-23 00:16:21 +0000498 return eExecutionSetupError;
499
Chris Lattner24943d22010-06-08 16:52:24 +0000500 call_plan_sp->SetPrivate(true);
Sean Callananc78d6482010-07-26 22:14:36 +0000501 exe_ctx.thread->QueueThreadPlan(call_plan_sp, true);
Sean Callanan841026f2010-07-23 00:16:21 +0000502
Chris Lattner24943d22010-06-08 16:52:24 +0000503 // We need to call the function synchronously, so spin waiting for it to return.
504 // If we get interrupted while executing, we're going to lose our context, and
505 // won't be able to gather the result at this point.
Sean Callanan841026f2010-07-23 00:16:21 +0000506
Chris Lattner24943d22010-06-08 16:52:24 +0000507 TimeValue* timeout_ptr = NULL;
508 TimeValue real_timeout;
Sean Callanan841026f2010-07-23 00:16:21 +0000509
Chris Lattner24943d22010-06-08 16:52:24 +0000510 if (single_thread_timeout_usec != 0)
511 {
512 real_timeout = TimeValue::Now();
513 real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
514 timeout_ptr = &real_timeout;
515 }
Sean Callanan841026f2010-07-23 00:16:21 +0000516
Sean Callananc78d6482010-07-26 22:14:36 +0000517 exe_ctx.process->Resume ();
Sean Callanan841026f2010-07-23 00:16:21 +0000518
519 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Chris Lattner24943d22010-06-08 16:52:24 +0000520
521 while (1)
522 {
523 lldb::EventSP event_sp;
Sean Callanan841026f2010-07-23 00:16:21 +0000524
Chris Lattner24943d22010-06-08 16:52:24 +0000525 // Now wait for the process to stop again:
526 // FIXME: Probably want a time out.
Sean Callananc78d6482010-07-26 22:14:36 +0000527 lldb::StateType stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Sean Callanan841026f2010-07-23 00:16:21 +0000528
Chris Lattner24943d22010-06-08 16:52:24 +0000529 if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL)
530 {
531 // Right now this is the only way to tell we've timed out...
532 // We should interrupt the process here...
533 // Not really sure what to do if Halt fails here...
Chris Lattner24943d22010-06-08 16:52:24 +0000534 if (log)
535 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 +0000536
Sean Callananc78d6482010-07-26 22:14:36 +0000537 if (exe_ctx.process->Halt().Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000538 {
539 timeout_ptr = NULL;
540
Sean Callananc78d6482010-07-26 22:14:36 +0000541 stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000542 if (stop_state == lldb::eStateInvalid)
543 {
544 errors.Printf ("Got an invalid stop state after halt.");
545 }
546 else if (stop_state != lldb::eStateStopped)
547 {
548 StreamString s;
549 event_sp->Dump (&s);
550
551 errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
552 }
553
554 if (try_all_threads)
555 {
556 // Between the time that we got the timeout and the time we halted, but target
557 // might have actually completed the plan. If so, we're done.
Sean Callananc78d6482010-07-26 22:14:36 +0000558 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000559 {
560 return_value = eExecutionCompleted;
561 break;
562 }
Sean Callanan841026f2010-07-23 00:16:21 +0000563
Chris Lattner24943d22010-06-08 16:52:24 +0000564 call_plan_ptr->SetStopOthers (false);
Sean Callananc78d6482010-07-26 22:14:36 +0000565 exe_ctx.process->Resume();
Chris Lattner24943d22010-06-08 16:52:24 +0000566 continue;
567 }
568 else
569 return eExecutionInterrupted;
570 }
571 }
572 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
573 continue;
Sean Callanan841026f2010-07-23 00:16:21 +0000574
Sean Callananc78d6482010-07-26 22:14:36 +0000575 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000576 {
577 return_value = eExecutionCompleted;
578 break;
579 }
Sean Callananc78d6482010-07-26 22:14:36 +0000580 else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000581 {
582 return_value = eExecutionDiscarded;
583 break;
584 }
585 else
586 {
Sean Callanan841026f2010-07-23 00:16:21 +0000587 if (log)
588 {
589 StreamString s;
590 event_sp->Dump (&s);
591 StreamString ts;
592
593 const char *event_explanation;
594
595 do
596 {
597 const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
598
599 if (!event_data)
600 {
601 event_explanation = "<no event data>";
602 break;
603 }
604
605 Process *process = event_data->GetProcessSP().get();
606
607 if (!process)
608 {
609 event_explanation = "<no process>";
610 break;
611 }
612
613 ThreadList &thread_list = process->GetThreadList();
614
615 uint32_t num_threads = thread_list.GetSize();
616 uint32_t thread_index;
617
618 ts.Printf("<%u threads> ", num_threads);
619
620 for (thread_index = 0;
621 thread_index < num_threads;
622 ++thread_index)
623 {
624 Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
625
626 if (!thread)
627 {
628 ts.Printf("<?> ");
629 continue;
630 }
631
632 Thread::StopInfo stop_info;
633 thread->GetStopInfo(&stop_info);
634
635 ts.Printf("<");
636 RegisterContext *register_context = thread->GetRegisterContext();
637
638 if (register_context)
639 ts.Printf("[ip 0x%llx] ", register_context->GetPC());
640 else
641 ts.Printf("[ip unknown] ");
642
643 stop_info.Dump(&ts);
644 ts.Printf(">");
645 }
646
647 event_explanation = ts.GetData();
648 } while (0);
649
650 log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
651 }
652
Chris Lattner24943d22010-06-08 16:52:24 +0000653 return_value = eExecutionInterrupted;
654 break;
655 }
Chris Lattner24943d22010-06-08 16:52:24 +0000656 }
Sean Callanan841026f2010-07-23 00:16:21 +0000657
Sean Callananc78d6482010-07-26 22:14:36 +0000658 // Thread we ran the function in may have gone away because we ran the target
659 // Check that it's still there.
660 exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByID(tid, true).get();
661 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
662
Sean Callanan841026f2010-07-23 00:16:21 +0000663 return return_value;
664}
Chris Lattner24943d22010-06-08 16:52:24 +0000665
Sean Callanan841026f2010-07-23 00:16:21 +0000666ClangFunction::ExecutionResults
667ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000668 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000669 lldb::addr_t *args_addr_ptr,
670 Stream &errors,
671 bool stop_others,
672 uint32_t single_thread_timeout_usec,
673 bool try_all_threads,
674 Value &results)
675{
676 using namespace clang;
677 ExecutionResults return_value = eExecutionSetupError;
678
679 lldb::addr_t args_addr;
680
681 if (args_addr_ptr != NULL)
682 args_addr = *args_addr_ptr;
683 else
684 args_addr = LLDB_INVALID_ADDRESS;
685
686 if (CompileFunction(errors) != 0)
687 return eExecutionSetupError;
688
689 if (args_addr == LLDB_INVALID_ADDRESS)
690 {
Sean Callananc78d6482010-07-26 22:14:36 +0000691 if (!InsertFunction(exe_ctx, args_addr, errors))
Sean Callanan841026f2010-07-23 00:16:21 +0000692 return eExecutionSetupError;
693 }
694
Sean Callananc78d6482010-07-26 22:14:36 +0000695 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 +0000696
697 if (args_addr_ptr != NULL)
698 *args_addr_ptr = args_addr;
699
Chris Lattner24943d22010-06-08 16:52:24 +0000700 if (return_value != eExecutionCompleted)
701 return return_value;
702
Sean Callananc78d6482010-07-26 22:14:36 +0000703 FetchFunctionResults(exe_ctx, args_addr, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000704
705 if (args_addr_ptr == NULL)
Sean Callananc78d6482010-07-26 22:14:36 +0000706 DeallocateFunctionResults(exe_ctx, args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000707
708 return eExecutionCompleted;
709}
710
711ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000712ClangFunction::ExecuteFunctionWithABI(ExecutionContext &exe_ctx, Stream &errors, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000713{
714 // FIXME: Use the errors Stream for better error reporting.
715 using namespace clang;
716 ExecutionResults return_value = eExecutionSetupError;
717
Sean Callananc78d6482010-07-26 22:14:36 +0000718 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000719
720 if (process == NULL)
721 {
722 errors.Printf("Can't call a function without a process.");
723 return return_value;
724 }
725
726 //unsigned int num_args = m_arg_values.GetSize();
727 //unsigned int arg_index;
728
729 //for (arg_index = 0; arg_index < num_args; ++arg_index)
Sean Callananc78d6482010-07-26 22:14:36 +0000730 // m_arg_values.GetValueAtIndex(arg_index)->ResolveValue(&exe_ctx, GetASTContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000731
Sean Callananc78d6482010-07-26 22:14:36 +0000732 ThreadPlan *call_plan = exe_ctx.thread->QueueThreadPlanForCallFunction (false,
Chris Lattner24943d22010-06-08 16:52:24 +0000733 m_function_addr,
734 m_arg_values,
735 true);
736 if (call_plan == NULL)
737 return return_value;
738
739 call_plan->SetPrivate(true);
740
741 // We need to call the function synchronously, so spin waiting for it to return.
742 // If we get interrupted while executing, we're going to lose our context, and
743 // won't be able to gather the result at this point.
744
745 process->Resume ();
746
747 while (1)
748 {
749 lldb::EventSP event_sp;
750
751 // Now wait for the process to stop again:
752 // FIXME: Probably want a time out.
753 lldb::StateType stop_state = process->WaitForStateChangedEvents (NULL, event_sp);
754 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
755 continue;
756
Sean Callananc78d6482010-07-26 22:14:36 +0000757 if (exe_ctx.thread->IsThreadPlanDone (call_plan))
Chris Lattner24943d22010-06-08 16:52:24 +0000758 {
759 return_value = eExecutionCompleted;
760 break;
761 }
Sean Callananc78d6482010-07-26 22:14:36 +0000762 else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan))
Chris Lattner24943d22010-06-08 16:52:24 +0000763 {
764 return_value = eExecutionDiscarded;
765 break;
766 }
767 else
768 {
769 return_value = eExecutionInterrupted;
770 break;
771 }
772
773 }
774
775 return eExecutionCompleted;
776}