blob: c418fabbbd6d5612191722d679e3ea083799a6ac [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangFunction.cpp ---------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10
11// C Includes
12// C++ Includes
13// Other libraries and framework includes
Chris Lattner24943d22010-06-08 16:52:24 +000014#include "clang/AST/ASTContext.h"
15#include "clang/AST/RecordLayout.h"
Greg Claytonc4f51102010-07-02 18:39:06 +000016#include "clang/CodeGen/CodeGenAction.h"
17#include "clang/CodeGen/ModuleBuilder.h"
18#include "clang/Frontend/CompilerInstance.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ExecutionEngine/ExecutionEngine.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "llvm/Module.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022
23// Project includes
Sean Callanan65dafa82010-08-27 01:01:44 +000024#include "lldb/Expression/ASTStructExtractor.h"
25#include "lldb/Expression/ClangExpressionParser.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026#include "lldb/Expression/ClangFunction.h"
27#include "lldb/Symbol/Type.h"
28#include "lldb/Core/DataExtractor.h"
29#include "lldb/Core/ValueObject.h"
30#include "lldb/Core/ValueObjectList.h"
31#include "lldb/Interpreter/CommandReturnObject.h"
32#include "lldb/Symbol/ClangASTContext.h"
33#include "lldb/Symbol/Function.h"
34#include "lldb/Target/ExecutionContext.h"
35#include "lldb/Target/Process.h"
Sean Callanan841026f2010-07-23 00:16:21 +000036#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000037#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038#include "lldb/Target/Thread.h"
39#include "lldb/Target/ThreadPlan.h"
40#include "lldb/Target/ThreadPlanCallFunction.h"
41#include "lldb/Core/Log.h"
42
43using namespace lldb_private;
Sean Callanan65dafa82010-08-27 01:01:44 +000044
Chris Lattner24943d22010-06-08 16:52:24 +000045//----------------------------------------------------------------------
46// ClangFunction constructor
47//----------------------------------------------------------------------
Jim Ingham681778e2010-09-10 23:07:48 +000048ClangFunction::ClangFunction(const char *target_triple,
49 ClangASTContext *ast_context,
50 void *return_qualtype,
51 const Address& functionAddress,
52 const ValueList &arg_value_list) :
Sean Callanan65dafa82010-08-27 01:01:44 +000053 m_target_triple (target_triple),
Chris Lattner24943d22010-06-08 16:52:24 +000054 m_function_ptr (NULL),
Greg Clayton54e7afa2010-07-09 20:39:50 +000055 m_function_addr (functionAddress),
Chris Lattner24943d22010-06-08 16:52:24 +000056 m_function_return_qual_type(return_qualtype),
Greg Clayton54e7afa2010-07-09 20:39:50 +000057 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000058 m_wrapper_function_name ("__lldb_caller_function"),
59 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000060 m_wrapper_function_addr (),
61 m_wrapper_args_addrs (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000062 m_arg_values (arg_value_list),
Chris Lattner24943d22010-06-08 16:52:24 +000063 m_compiled (false),
64 m_JITted (false)
65{
66}
67
Jim Ingham681778e2010-09-10 23:07:48 +000068ClangFunction::ClangFunction(const char *target_triple,
69 Function &function,
70 ClangASTContext *ast_context,
71 const ValueList &arg_value_list) :
Sean Callanan65dafa82010-08-27 01:01:44 +000072 m_target_triple (target_triple),
Chris Lattner24943d22010-06-08 16:52:24 +000073 m_function_ptr (&function),
Greg Clayton54e7afa2010-07-09 20:39:50 +000074 m_function_addr (),
75 m_function_return_qual_type (),
Chris Lattner24943d22010-06-08 16:52:24 +000076 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000077 m_wrapper_function_name ("__lldb_function_caller"),
78 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000079 m_wrapper_function_addr (),
80 m_wrapper_args_addrs (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000081 m_arg_values (arg_value_list),
Chris Lattner24943d22010-06-08 16:52:24 +000082 m_compiled (false),
83 m_JITted (false)
84{
85 m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
86 m_function_return_qual_type = m_function_ptr->GetReturnType().GetOpaqueClangQualType();
87}
88
89//----------------------------------------------------------------------
90// Destructor
91//----------------------------------------------------------------------
92ClangFunction::~ClangFunction()
93{
94}
95
96unsigned
97ClangFunction::CompileFunction (Stream &errors)
98{
Sean Callanan65dafa82010-08-27 01:01:44 +000099 if (m_compiled)
100 return 0;
101
Chris Lattner24943d22010-06-08 16:52:24 +0000102 // FIXME: How does clang tell us there's no return value? We need to handle that case.
103 unsigned num_errors = 0;
104
Sean Callanan65dafa82010-08-27 01:01:44 +0000105 std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type);
106
107 // Cons up the function we're going to wrap our call in, then compile it...
108 // We declare the function "extern "C"" because the compiler might be in C++
109 // mode which would mangle the name and then we couldn't find it again...
110 m_wrapper_function_text.clear();
111 m_wrapper_function_text.append ("extern \"C\" void ");
112 m_wrapper_function_text.append (m_wrapper_function_name);
113 m_wrapper_function_text.append (" (void *input)\n{\n struct ");
114 m_wrapper_function_text.append (m_wrapper_struct_name);
115 m_wrapper_function_text.append (" \n {\n");
116 m_wrapper_function_text.append (" ");
117 m_wrapper_function_text.append (return_type_str);
118 m_wrapper_function_text.append (" (*fn_ptr) (");
119
120 // Get the number of arguments. If we have a function type and it is prototyped,
121 // trust that, otherwise use the values we were given.
122
123 // FIXME: This will need to be extended to handle Variadic functions. We'll need
124 // to pull the defined arguments out of the function, then add the types from the
125 // arguments list for the variable arguments.
126
127 uint32_t num_args = UINT32_MAX;
128 bool trust_function = false;
129 // GetArgumentCount returns -1 for an unprototyped function.
130 if (m_function_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000131 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000132 int num_func_args = m_function_ptr->GetArgumentCount();
133 if (num_func_args >= 0)
134 trust_function = true;
135 else
136 num_args = num_func_args;
137 }
Chris Lattner24943d22010-06-08 16:52:24 +0000138
Sean Callanan65dafa82010-08-27 01:01:44 +0000139 if (num_args == UINT32_MAX)
140 num_args = m_arg_values.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000141
Sean Callanan65dafa82010-08-27 01:01:44 +0000142 std::string args_buffer; // This one stores the definition of all the args in "struct caller".
143 std::string args_list_buffer; // This one stores the argument list called from the structure.
144 for (size_t i = 0; i < num_args; i++)
145 {
146 const char *type_string;
147 std::string type_stdstr;
Chris Lattner24943d22010-06-08 16:52:24 +0000148
Sean Callanan65dafa82010-08-27 01:01:44 +0000149 if (trust_function)
Chris Lattner24943d22010-06-08 16:52:24 +0000150 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000151 type_string = m_function_ptr->GetArgumentTypeAtIndex(i).GetName().AsCString();
Chris Lattner24943d22010-06-08 16:52:24 +0000152 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000153 else
Chris Lattner24943d22010-06-08 16:52:24 +0000154 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000155 Value *arg_value = m_arg_values.GetValueAtIndex(i);
156 void *clang_qual_type = arg_value->GetOpaqueClangQualType ();
157 if (clang_qual_type != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000158 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000159 type_stdstr = ClangASTContext::GetTypeName(clang_qual_type);
160 type_string = type_stdstr.c_str();
Chris Lattner24943d22010-06-08 16:52:24 +0000161 }
162 else
Sean Callanan65dafa82010-08-27 01:01:44 +0000163 {
164 errors.Printf("Could not determine type of input value %d.", i);
Chris Lattner24943d22010-06-08 16:52:24 +0000165 return 1;
166 }
Chris Lattner24943d22010-06-08 16:52:24 +0000167 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000168
169 m_wrapper_function_text.append (type_string);
170 if (i < num_args - 1)
171 m_wrapper_function_text.append (", ");
172
173 char arg_buf[32];
174 args_buffer.append (" ");
175 args_buffer.append (type_string);
176 snprintf(arg_buf, 31, "arg_%zd", i);
177 args_buffer.push_back (' ');
178 args_buffer.append (arg_buf);
179 args_buffer.append (";\n");
180
181 args_list_buffer.append ("__lldb_fn_data->");
182 args_list_buffer.append (arg_buf);
183 if (i < num_args - 1)
184 args_list_buffer.append (", ");
185
Chris Lattner24943d22010-06-08 16:52:24 +0000186 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000187 m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
188
189 m_wrapper_function_text.append (args_buffer);
190
191 m_wrapper_function_text.append (" ");
192 m_wrapper_function_text.append (return_type_str);
193 m_wrapper_function_text.append (" return_value;");
194 m_wrapper_function_text.append ("\n };\n struct ");
195 m_wrapper_function_text.append (m_wrapper_struct_name);
196 m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
197 m_wrapper_function_text.append (m_wrapper_struct_name);
198 m_wrapper_function_text.append (" *) input;\n");
199
200 m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
201 m_wrapper_function_text.append (args_list_buffer);
202 m_wrapper_function_text.append (");\n}\n");
203
204 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
205 if (log)
206 log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
207
208 // Okay, now compile this expression
209
210 m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), *this));
211
212 num_errors = m_parser->Parse (errors);
213
214 m_compiled = (num_errors == 0);
215
216 if (!m_compiled)
217 return num_errors;
Chris Lattner24943d22010-06-08 16:52:24 +0000218
219 return num_errors;
220}
221
222bool
Sean Callananc78d6482010-07-26 22:14:36 +0000223ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000224{
Sean Callananc78d6482010-07-26 22:14:36 +0000225 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000226
Sean Callanan65dafa82010-08-27 01:01:44 +0000227 if (!process)
228 return false;
229
230 if (!m_compiled)
Chris Lattner24943d22010-06-08 16:52:24 +0000231 return false;
232
Sean Callanan65dafa82010-08-27 01:01:44 +0000233 if (m_JITted)
234 return true;
235
Sean Callanan830a9032010-08-27 23:31:21 +0000236 lldb::addr_t wrapper_function_end;
237
238 Error jit_error = m_parser->MakeJIT(m_wrapper_function_addr, wrapper_function_end, exe_ctx);
Sean Callanan65dafa82010-08-27 01:01:44 +0000239
240 if (!jit_error.Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000241 return false;
242
243 return true;
244}
245
246bool
Sean Callananc78d6482010-07-26 22:14:36 +0000247ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000248{
Sean Callananc78d6482010-07-26 22:14:36 +0000249 return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);
Chris Lattner24943d22010-06-08 16:52:24 +0000250}
251
252// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
253
254bool
Jim Ingham681778e2010-09-10 23:07:48 +0000255ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx,
256 lldb::addr_t &args_addr_ref,
257 Address function_address,
258 ValueList &arg_values,
259 Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000260{
Sean Callanan65dafa82010-08-27 01:01:44 +0000261 // All the information to reconstruct the struct is provided by the
262 // StructExtractor.
263 if (!m_struct_valid)
264 {
265 errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
266 return false;
267 }
268
Chris Lattner24943d22010-06-08 16:52:24 +0000269 Error error;
270 using namespace clang;
271 ExecutionResults return_value = eExecutionSetupError;
272
Sean Callananc78d6482010-07-26 22:14:36 +0000273 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000274
275 if (process == NULL)
276 return return_value;
Sean Callanan65dafa82010-08-27 01:01:44 +0000277
Chris Lattner24943d22010-06-08 16:52:24 +0000278 if (args_addr_ref == LLDB_INVALID_ADDRESS)
279 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000280 args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000281 if (args_addr_ref == LLDB_INVALID_ADDRESS)
282 return false;
283 m_wrapper_args_addrs.push_back (args_addr_ref);
284 }
285 else
286 {
287 // Make sure this is an address that we've already handed out.
288 if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
289 {
290 return false;
291 }
292 }
293
294 // FIXME: This is fake, and just assumes that it matches that architecture.
295 // Make a data extractor and put the address into the right byte order & size.
296
Sean Callananc78d6482010-07-26 22:14:36 +0000297 uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.process);
Sean Callanan65dafa82010-08-27 01:01:44 +0000298 int first_offset = m_member_offsets[0];
Chris Lattner24943d22010-06-08 16:52:24 +0000299 process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error);
300
301 // FIXME: We will need to extend this for Variadic functions.
302
303 Error value_error;
304
305 size_t num_args = arg_values.GetSize();
306 if (num_args != m_arg_values.GetSize())
307 {
308 errors.Printf ("Wrong number of arguments - was: %d should be: %d", num_args, m_arg_values.GetSize());
309 return false;
310 }
311
Greg Clayton54e7afa2010-07-09 20:39:50 +0000312 for (size_t i = 0; i < num_args; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000313 {
314 // FIXME: We should sanity check sizes.
315
Sean Callanan65dafa82010-08-27 01:01:44 +0000316 int offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
Chris Lattner24943d22010-06-08 16:52:24 +0000317 Value *arg_value = arg_values.GetValueAtIndex(i);
318
319 // FIXME: For now just do scalars:
320
321 // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
322
323 if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
324 arg_value->GetContextType() == Value::eContextTypeOpaqueClangQualType &&
325 ClangASTContext::IsPointerType(arg_value->GetValueOpaqueClangQualType()))
326 continue;
327
Sean Callananc78d6482010-07-26 22:14:36 +0000328 const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000329
330 int byte_size = arg_scalar.GetByteSize();
331 std::vector<uint8_t> buffer;
332 buffer.resize(byte_size);
333 DataExtractor value_data;
334 arg_scalar.GetData (value_data);
Greg Clayton53d68e72010-07-20 22:52:08 +0000335 value_data.ExtractBytes(0, byte_size, process->GetByteOrder(), &buffer.front());
336 process->WriteMemory(args_addr_ref + offset, &buffer.front(), byte_size, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000337 }
338
339 return true;
340}
341
342bool
Sean Callananc78d6482010-07-26 22:14:36 +0000343ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000344{
345 using namespace clang;
346
347 if (CompileFunction(errors) != 0)
348 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000349 if (!WriteFunctionWrapper(exe_ctx, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000350 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000351 if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000352 return false;
353
354 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
355 if (log)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000356 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 +0000357
358 return true;
359}
360
361ThreadPlan *
Sean Callananc78d6482010-07-26 22:14:36 +0000362ClangFunction::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 +0000363{
364 // FIXME: Use the errors Stream for better error reporting.
365
Sean Callananc78d6482010-07-26 22:14:36 +0000366 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000367
368 if (process == NULL)
369 {
370 errors.Printf("Can't call a function without a process.");
371 return NULL;
372 }
373
374 // Okay, now run the function:
375
Sean Callanan841026f2010-07-23 00:16:21 +0000376 Address wrapper_address (NULL, func_addr);
Sean Callananc78d6482010-07-26 22:14:36 +0000377 ThreadPlan *new_plan = new ThreadPlanCallFunction (*exe_ctx.thread,
Chris Lattner24943d22010-06-08 16:52:24 +0000378 wrapper_address,
379 args_addr,
380 stop_others, discard_on_error);
381 return new_plan;
382}
383
384bool
Sean Callananc78d6482010-07-26 22:14:36 +0000385ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
Chris Lattner24943d22010-06-08 16:52:24 +0000386{
387 // Read the return value - it is the last field in the struct:
388 // FIXME: How does clang tell us there's no return value? We need to handle that case.
389
390 std::vector<uint8_t> data_buffer;
391 data_buffer.resize(m_return_size);
Sean Callananc78d6482010-07-26 22:14:36 +0000392 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000393 Error error;
Sean Callanan65dafa82010-08-27 01:01:44 +0000394 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 +0000395
396 if (bytes_read == 0)
397 {
398 return false;
399 }
400
401 if (bytes_read < m_return_size)
402 return false;
403
Greg Clayton53d68e72010-07-20 22:52:08 +0000404 DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000405 // FIXME: Assuming an integer scalar for now:
406
407 uint32_t offset = 0;
408 uint64_t return_integer = data.GetMaxU64(&offset, m_return_size);
409
410 ret_value.SetContext (Value::eContextTypeOpaqueClangQualType, m_function_return_qual_type);
411 ret_value.SetValueType(Value::eValueTypeScalar);
412 ret_value.GetScalar() = return_integer;
413 return true;
414}
415
416void
Sean Callananc78d6482010-07-26 22:14:36 +0000417ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000418{
419 std::list<lldb::addr_t>::iterator pos;
420 pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
421 if (pos != m_wrapper_args_addrs.end())
422 m_wrapper_args_addrs.erase(pos);
423
Sean Callananc78d6482010-07-26 22:14:36 +0000424 exe_ctx.process->DeallocateMemory(args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000425}
426
427ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000428ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000429{
Sean Callananc78d6482010-07-26 22:14:36 +0000430 return ExecuteFunction (exe_ctx, errors, 1000, true, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000431}
432
433ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000434ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000435{
Sean Callananc78d6482010-07-26 22:14:36 +0000436 return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, false, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000437}
438
439ClangFunction::ExecutionResults
440ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000441 ExecutionContext &exe_ctx,
Chris Lattner24943d22010-06-08 16:52:24 +0000442 Stream &errors,
443 uint32_t single_thread_timeout_usec,
444 bool try_all_threads,
445 Value &results)
446{
Sean Callananc78d6482010-07-26 22:14:36 +0000447 return ExecuteFunction (exe_ctx, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000448}
449
Sean Callanan841026f2010-07-23 00:16:21 +0000450// This is the static function
451ClangFunction::ExecutionResults
452ClangFunction::ExecuteFunction (
Sean Callananc78d6482010-07-26 22:14:36 +0000453 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000454 lldb::addr_t function_address,
455 lldb::addr_t &void_arg,
456 bool stop_others,
457 bool try_all_threads,
458 uint32_t single_thread_timeout_usec,
459 Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000460{
Sean Callananc78d6482010-07-26 22:14:36 +0000461 // Save this value for restoration of the execution context after we run
Jim Ingham681778e2010-09-10 23:07:48 +0000462 uint32_t tid = exe_ctx.thread->GetIndexID();
Sean Callananc78d6482010-07-26 22:14:36 +0000463
Jim Ingham681778e2010-09-10 23:07:48 +0000464 // N.B. Running the target may unset the currently selected thread and frame. We don't want to do that either,
465 // so we should arrange to reset them as well.
466
467 lldb::ThreadSP selected_thread_sp = exe_ctx.process->GetThreadList().GetSelectedThread();
468 lldb::StackFrameSP selected_frame_sp;
469
470 uint32_t selected_tid;
471 if (selected_thread_sp != NULL)
472 {
473 selected_tid = selected_thread_sp->GetIndexID();
474 selected_frame_sp = selected_thread_sp->GetSelectedFrame();
475 }
476 else
477 {
478 selected_tid = LLDB_INVALID_THREAD_ID;
479 }
480
Sean Callanan841026f2010-07-23 00:16:21 +0000481 ClangFunction::ExecutionResults return_value = eExecutionSetupError;
Chris Lattner24943d22010-06-08 16:52:24 +0000482
Sean Callananc78d6482010-07-26 22:14:36 +0000483 lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, errors, stop_others, false));
Chris Lattner24943d22010-06-08 16:52:24 +0000484
485 ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
486
Chris Lattner24943d22010-06-08 16:52:24 +0000487 if (call_plan_sp == NULL)
Sean Callanan841026f2010-07-23 00:16:21 +0000488 return eExecutionSetupError;
489
Sean Callanan65af7342010-09-08 20:04:08 +0000490//#define SINGLE_STEP_EXPRESSIONS
491
492#ifdef SINGLE_STEP_EXPRESSIONS
493 return eExecutionInterrupted;
494#else
Chris Lattner24943d22010-06-08 16:52:24 +0000495 call_plan_sp->SetPrivate(true);
Sean Callananc78d6482010-07-26 22:14:36 +0000496 exe_ctx.thread->QueueThreadPlan(call_plan_sp, true);
Sean Callanan65af7342010-09-08 20:04:08 +0000497#endif
Sean Callanan841026f2010-07-23 00:16:21 +0000498
Chris Lattner24943d22010-06-08 16:52:24 +0000499 // We need to call the function synchronously, so spin waiting for it to return.
500 // If we get interrupted while executing, we're going to lose our context, and
501 // won't be able to gather the result at this point.
Sean Callanan841026f2010-07-23 00:16:21 +0000502
Chris Lattner24943d22010-06-08 16:52:24 +0000503 TimeValue* timeout_ptr = NULL;
504 TimeValue real_timeout;
Sean Callanan841026f2010-07-23 00:16:21 +0000505
Chris Lattner24943d22010-06-08 16:52:24 +0000506 if (single_thread_timeout_usec != 0)
507 {
508 real_timeout = TimeValue::Now();
509 real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
510 timeout_ptr = &real_timeout;
511 }
Sean Callanan841026f2010-07-23 00:16:21 +0000512
Jim Inghama2890f42010-08-17 00:35:35 +0000513 Error resume_error = exe_ctx.process->Resume ();
514 if (!resume_error.Success())
515 {
516 errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
517 return eExecutionSetupError;
518 }
Sean Callanan841026f2010-07-23 00:16:21 +0000519
520 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Chris Lattner24943d22010-06-08 16:52:24 +0000521
522 while (1)
523 {
524 lldb::EventSP event_sp;
Sean Callanan841026f2010-07-23 00:16:21 +0000525
Chris Lattner24943d22010-06-08 16:52:24 +0000526 // Now wait for the process to stop again:
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)
Jim Ingham681778e2010-09-10 23:07:48 +0000535 if (try_all_threads)
536 log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.", single_thread_timeout_usec);
537 else
538 log->Printf ("Running function with timeout: %d timed out, abandoning execution.", single_thread_timeout_usec);
Sean Callanan841026f2010-07-23 00:16:21 +0000539
Sean Callananc78d6482010-07-26 22:14:36 +0000540 if (exe_ctx.process->Halt().Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000541 {
542 timeout_ptr = NULL;
543
Sean Callananc78d6482010-07-26 22:14:36 +0000544 stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000545 if (stop_state == lldb::eStateInvalid)
546 {
547 errors.Printf ("Got an invalid stop state after halt.");
548 }
549 else if (stop_state != lldb::eStateStopped)
550 {
551 StreamString s;
552 event_sp->Dump (&s);
553
554 errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
555 }
556
557 if (try_all_threads)
558 {
559 // Between the time that we got the timeout and the time we halted, but target
560 // might have actually completed the plan. If so, we're done.
Sean Callananc78d6482010-07-26 22:14:36 +0000561 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000562 {
563 return_value = eExecutionCompleted;
564 break;
565 }
Sean Callanan841026f2010-07-23 00:16:21 +0000566
Chris Lattner24943d22010-06-08 16:52:24 +0000567 call_plan_ptr->SetStopOthers (false);
Sean Callananc78d6482010-07-26 22:14:36 +0000568 exe_ctx.process->Resume();
Chris Lattner24943d22010-06-08 16:52:24 +0000569 continue;
570 }
571 else
572 return eExecutionInterrupted;
573 }
574 }
575 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
576 continue;
Sean Callanan841026f2010-07-23 00:16:21 +0000577
Sean Callananc78d6482010-07-26 22:14:36 +0000578 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000579 {
580 return_value = eExecutionCompleted;
581 break;
582 }
Sean Callananc78d6482010-07-26 22:14:36 +0000583 else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000584 {
585 return_value = eExecutionDiscarded;
586 break;
587 }
588 else
589 {
Sean Callanan841026f2010-07-23 00:16:21 +0000590 if (log)
591 {
592 StreamString s;
593 event_sp->Dump (&s);
594 StreamString ts;
595
596 const char *event_explanation;
597
598 do
599 {
600 const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
601
602 if (!event_data)
603 {
604 event_explanation = "<no event data>";
605 break;
606 }
607
608 Process *process = event_data->GetProcessSP().get();
609
610 if (!process)
611 {
612 event_explanation = "<no process>";
613 break;
614 }
615
616 ThreadList &thread_list = process->GetThreadList();
617
618 uint32_t num_threads = thread_list.GetSize();
619 uint32_t thread_index;
620
621 ts.Printf("<%u threads> ", num_threads);
622
623 for (thread_index = 0;
624 thread_index < num_threads;
625 ++thread_index)
626 {
627 Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
628
629 if (!thread)
630 {
631 ts.Printf("<?> ");
632 continue;
633 }
634
Sean Callanan841026f2010-07-23 00:16:21 +0000635 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
Greg Clayton643ee732010-08-04 01:40:35 +0000643 StopInfo *stop_info = thread->GetStopInfo();
644 if (stop_info)
645 {
646 const char *stop_desc = stop_info->GetDescription();
647 if (stop_desc)
648 ts.PutCString (stop_desc);
649 }
Sean Callanan841026f2010-07-23 00:16:21 +0000650 ts.Printf(">");
651 }
652
653 event_explanation = ts.GetData();
654 } while (0);
655
656 log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
657 }
658
Chris Lattner24943d22010-06-08 16:52:24 +0000659 return_value = eExecutionInterrupted;
660 break;
661 }
Chris Lattner24943d22010-06-08 16:52:24 +0000662 }
Sean Callanan841026f2010-07-23 00:16:21 +0000663
Sean Callananc78d6482010-07-26 22:14:36 +0000664 // Thread we ran the function in may have gone away because we ran the target
665 // Check that it's still there.
Jim Ingham681778e2010-09-10 23:07:48 +0000666 exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByIndexID(tid, true).get();
Sean Callananc78d6482010-07-26 22:14:36 +0000667 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
668
Jim Ingham681778e2010-09-10 23:07:48 +0000669 // Also restore the current process'es selected frame & thread, since this function calling may
670 // be done behind the user's back.
671
672 if (selected_tid != LLDB_INVALID_THREAD_ID)
673 {
674 if (exe_ctx.process->GetThreadList().SetSelectedThreadByIndexID (selected_tid))
675 {
676 // We were able to restore the selected thread, now restore the frame:
677 exe_ctx.process->GetThreadList().GetSelectedThread()->SetSelectedFrame(selected_frame_sp.get());
678 }
679 }
680
Sean Callanan841026f2010-07-23 00:16:21 +0000681 return return_value;
682}
Chris Lattner24943d22010-06-08 16:52:24 +0000683
Sean Callanan841026f2010-07-23 00:16:21 +0000684ClangFunction::ExecutionResults
685ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000686 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000687 lldb::addr_t *args_addr_ptr,
688 Stream &errors,
689 bool stop_others,
690 uint32_t single_thread_timeout_usec,
691 bool try_all_threads,
692 Value &results)
693{
694 using namespace clang;
695 ExecutionResults return_value = eExecutionSetupError;
696
697 lldb::addr_t args_addr;
698
699 if (args_addr_ptr != NULL)
700 args_addr = *args_addr_ptr;
701 else
702 args_addr = LLDB_INVALID_ADDRESS;
703
704 if (CompileFunction(errors) != 0)
705 return eExecutionSetupError;
706
707 if (args_addr == LLDB_INVALID_ADDRESS)
708 {
Sean Callananc78d6482010-07-26 22:14:36 +0000709 if (!InsertFunction(exe_ctx, args_addr, errors))
Sean Callanan841026f2010-07-23 00:16:21 +0000710 return eExecutionSetupError;
711 }
712
Jim Ingham681778e2010-09-10 23:07:48 +0000713 return_value = ClangFunction::ExecuteFunction(exe_ctx, m_wrapper_function_addr, args_addr, stop_others,
714 try_all_threads, single_thread_timeout_usec, errors);
Sean Callanan841026f2010-07-23 00:16:21 +0000715
716 if (args_addr_ptr != NULL)
717 *args_addr_ptr = args_addr;
718
Chris Lattner24943d22010-06-08 16:52:24 +0000719 if (return_value != eExecutionCompleted)
720 return return_value;
721
Sean Callananc78d6482010-07-26 22:14:36 +0000722 FetchFunctionResults(exe_ctx, args_addr, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000723
724 if (args_addr_ptr == NULL)
Sean Callananc78d6482010-07-26 22:14:36 +0000725 DeallocateFunctionResults(exe_ctx, args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000726
727 return eExecutionCompleted;
728}
729
Sean Callanan65dafa82010-08-27 01:01:44 +0000730clang::ASTConsumer *
731ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
Chris Lattner24943d22010-06-08 16:52:24 +0000732{
Sean Callanan65dafa82010-08-27 01:01:44 +0000733 return new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this);
Chris Lattner24943d22010-06-08 16:52:24 +0000734}