blob: e6606a2296cb3cf3ce79185f5efaff318f870de1 [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
Greg Claytoneea26402010-09-14 23:36:40 +0000297 uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.target);
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 Callanan3c9c5eb2010-09-21 00:44:12 +0000362ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, lldb::addr_t func_addr, lldb::addr_t &args_addr, Stream &errors, bool stop_others, bool discard_on_error, lldb::addr_t *this_arg)
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,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000380 stop_others,
381 discard_on_error,
382 this_arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000383 return new_plan;
384}
385
386bool
Sean Callananc78d6482010-07-26 22:14:36 +0000387ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
Chris Lattner24943d22010-06-08 16:52:24 +0000388{
389 // Read the return value - it is the last field in the struct:
390 // FIXME: How does clang tell us there's no return value? We need to handle that case.
391
392 std::vector<uint8_t> data_buffer;
393 data_buffer.resize(m_return_size);
Sean Callananc78d6482010-07-26 22:14:36 +0000394 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000395 Error error;
Sean Callanan65dafa82010-08-27 01:01:44 +0000396 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 +0000397
398 if (bytes_read == 0)
399 {
400 return false;
401 }
402
403 if (bytes_read < m_return_size)
404 return false;
405
Greg Clayton53d68e72010-07-20 22:52:08 +0000406 DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000407 // FIXME: Assuming an integer scalar for now:
408
409 uint32_t offset = 0;
410 uint64_t return_integer = data.GetMaxU64(&offset, m_return_size);
411
412 ret_value.SetContext (Value::eContextTypeOpaqueClangQualType, m_function_return_qual_type);
413 ret_value.SetValueType(Value::eValueTypeScalar);
414 ret_value.GetScalar() = return_integer;
415 return true;
416}
417
418void
Sean Callananc78d6482010-07-26 22:14:36 +0000419ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000420{
421 std::list<lldb::addr_t>::iterator pos;
422 pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
423 if (pos != m_wrapper_args_addrs.end())
424 m_wrapper_args_addrs.erase(pos);
425
Sean Callananc78d6482010-07-26 22:14:36 +0000426 exe_ctx.process->DeallocateMemory(args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000427}
428
429ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000430ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000431{
Sean Callananc78d6482010-07-26 22:14:36 +0000432 return ExecuteFunction (exe_ctx, errors, 1000, true, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000433}
434
435ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000436ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000437{
Sean Callananc78d6482010-07-26 22:14:36 +0000438 return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, false, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000439}
440
441ClangFunction::ExecutionResults
442ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000443 ExecutionContext &exe_ctx,
Chris Lattner24943d22010-06-08 16:52:24 +0000444 Stream &errors,
445 uint32_t single_thread_timeout_usec,
446 bool try_all_threads,
447 Value &results)
448{
Sean Callananc78d6482010-07-26 22:14:36 +0000449 return ExecuteFunction (exe_ctx, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000450}
451
Sean Callanan841026f2010-07-23 00:16:21 +0000452// This is the static function
453ClangFunction::ExecutionResults
454ClangFunction::ExecuteFunction (
Sean Callananc78d6482010-07-26 22:14:36 +0000455 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000456 lldb::addr_t function_address,
457 lldb::addr_t &void_arg,
458 bool stop_others,
459 bool try_all_threads,
460 uint32_t single_thread_timeout_usec,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000461 Stream &errors,
462 lldb::addr_t *this_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000463{
Sean Callananc78d6482010-07-26 22:14:36 +0000464 // Save this value for restoration of the execution context after we run
Jim Ingham681778e2010-09-10 23:07:48 +0000465 uint32_t tid = exe_ctx.thread->GetIndexID();
Sean Callananc78d6482010-07-26 22:14:36 +0000466
Jim Ingham681778e2010-09-10 23:07:48 +0000467 // N.B. Running the target may unset the currently selected thread and frame. We don't want to do that either,
468 // so we should arrange to reset them as well.
469
470 lldb::ThreadSP selected_thread_sp = exe_ctx.process->GetThreadList().GetSelectedThread();
471 lldb::StackFrameSP selected_frame_sp;
472
473 uint32_t selected_tid;
474 if (selected_thread_sp != NULL)
475 {
476 selected_tid = selected_thread_sp->GetIndexID();
477 selected_frame_sp = selected_thread_sp->GetSelectedFrame();
478 }
479 else
480 {
481 selected_tid = LLDB_INVALID_THREAD_ID;
482 }
483
Sean Callanan841026f2010-07-23 00:16:21 +0000484 ClangFunction::ExecutionResults return_value = eExecutionSetupError;
Chris Lattner24943d22010-06-08 16:52:24 +0000485
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000486 lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, errors, stop_others, false, this_arg));
Chris Lattner24943d22010-06-08 16:52:24 +0000487
488 ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
489
Chris Lattner24943d22010-06-08 16:52:24 +0000490 if (call_plan_sp == NULL)
Sean Callanan841026f2010-07-23 00:16:21 +0000491 return eExecutionSetupError;
492
Sean Callanan65af7342010-09-08 20:04:08 +0000493//#define SINGLE_STEP_EXPRESSIONS
494
495#ifdef SINGLE_STEP_EXPRESSIONS
496 return eExecutionInterrupted;
497#else
Chris Lattner24943d22010-06-08 16:52:24 +0000498 call_plan_sp->SetPrivate(true);
Sean Callananc78d6482010-07-26 22:14:36 +0000499 exe_ctx.thread->QueueThreadPlan(call_plan_sp, true);
Sean Callanan65af7342010-09-08 20:04:08 +0000500#endif
Sean Callanan841026f2010-07-23 00:16:21 +0000501
Chris Lattner24943d22010-06-08 16:52:24 +0000502 // We need to call the function synchronously, so spin waiting for it to return.
503 // If we get interrupted while executing, we're going to lose our context, and
504 // won't be able to gather the result at this point.
Sean Callanan841026f2010-07-23 00:16:21 +0000505
Chris Lattner24943d22010-06-08 16:52:24 +0000506 TimeValue* timeout_ptr = NULL;
507 TimeValue real_timeout;
Sean Callanan841026f2010-07-23 00:16:21 +0000508
Chris Lattner24943d22010-06-08 16:52:24 +0000509 if (single_thread_timeout_usec != 0)
510 {
511 real_timeout = TimeValue::Now();
512 real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
513 timeout_ptr = &real_timeout;
514 }
Sean Callanan841026f2010-07-23 00:16:21 +0000515
Jim Inghama2890f42010-08-17 00:35:35 +0000516 Error resume_error = exe_ctx.process->Resume ();
517 if (!resume_error.Success())
518 {
519 errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
520 return eExecutionSetupError;
521 }
Sean Callanan841026f2010-07-23 00:16:21 +0000522
523 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Chris Lattner24943d22010-06-08 16:52:24 +0000524
525 while (1)
526 {
527 lldb::EventSP event_sp;
Sean Callanan841026f2010-07-23 00:16:21 +0000528
Chris Lattner24943d22010-06-08 16:52:24 +0000529 // Now wait for the process to stop again:
Sean Callananc78d6482010-07-26 22:14:36 +0000530 lldb::StateType stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Sean Callanan841026f2010-07-23 00:16:21 +0000531
Chris Lattner24943d22010-06-08 16:52:24 +0000532 if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL)
533 {
534 // Right now this is the only way to tell we've timed out...
535 // We should interrupt the process here...
536 // Not really sure what to do if Halt fails here...
Chris Lattner24943d22010-06-08 16:52:24 +0000537 if (log)
Jim Ingham681778e2010-09-10 23:07:48 +0000538 if (try_all_threads)
539 log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.", single_thread_timeout_usec);
540 else
541 log->Printf ("Running function with timeout: %d timed out, abandoning execution.", single_thread_timeout_usec);
Sean Callanan841026f2010-07-23 00:16:21 +0000542
Sean Callananc78d6482010-07-26 22:14:36 +0000543 if (exe_ctx.process->Halt().Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000544 {
545 timeout_ptr = NULL;
546
Sean Callananc78d6482010-07-26 22:14:36 +0000547 stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000548 if (stop_state == lldb::eStateInvalid)
549 {
550 errors.Printf ("Got an invalid stop state after halt.");
551 }
552 else if (stop_state != lldb::eStateStopped)
553 {
554 StreamString s;
555 event_sp->Dump (&s);
556
557 errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
558 }
559
560 if (try_all_threads)
561 {
562 // Between the time that we got the timeout and the time we halted, but target
563 // might have actually completed the plan. If so, we're done.
Sean Callananc78d6482010-07-26 22:14:36 +0000564 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000565 {
566 return_value = eExecutionCompleted;
567 break;
568 }
Sean Callanan841026f2010-07-23 00:16:21 +0000569
Chris Lattner24943d22010-06-08 16:52:24 +0000570 call_plan_ptr->SetStopOthers (false);
Sean Callananc78d6482010-07-26 22:14:36 +0000571 exe_ctx.process->Resume();
Chris Lattner24943d22010-06-08 16:52:24 +0000572 continue;
573 }
574 else
575 return eExecutionInterrupted;
576 }
577 }
578 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
579 continue;
Sean Callanan841026f2010-07-23 00:16:21 +0000580
Sean Callananc78d6482010-07-26 22:14:36 +0000581 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000582 {
583 return_value = eExecutionCompleted;
584 break;
585 }
Sean Callananc78d6482010-07-26 22:14:36 +0000586 else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000587 {
588 return_value = eExecutionDiscarded;
589 break;
590 }
591 else
592 {
Sean Callanan841026f2010-07-23 00:16:21 +0000593 if (log)
594 {
595 StreamString s;
596 event_sp->Dump (&s);
597 StreamString ts;
598
599 const char *event_explanation;
600
601 do
602 {
603 const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
604
605 if (!event_data)
606 {
607 event_explanation = "<no event data>";
608 break;
609 }
610
611 Process *process = event_data->GetProcessSP().get();
612
613 if (!process)
614 {
615 event_explanation = "<no process>";
616 break;
617 }
618
619 ThreadList &thread_list = process->GetThreadList();
620
621 uint32_t num_threads = thread_list.GetSize();
622 uint32_t thread_index;
623
624 ts.Printf("<%u threads> ", num_threads);
625
626 for (thread_index = 0;
627 thread_index < num_threads;
628 ++thread_index)
629 {
630 Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
631
632 if (!thread)
633 {
634 ts.Printf("<?> ");
635 continue;
636 }
637
Sean Callanan841026f2010-07-23 00:16:21 +0000638 ts.Printf("<");
639 RegisterContext *register_context = thread->GetRegisterContext();
640
641 if (register_context)
642 ts.Printf("[ip 0x%llx] ", register_context->GetPC());
643 else
644 ts.Printf("[ip unknown] ");
645
Greg Clayton643ee732010-08-04 01:40:35 +0000646 StopInfo *stop_info = thread->GetStopInfo();
647 if (stop_info)
648 {
649 const char *stop_desc = stop_info->GetDescription();
650 if (stop_desc)
651 ts.PutCString (stop_desc);
652 }
Sean Callanan841026f2010-07-23 00:16:21 +0000653 ts.Printf(">");
654 }
655
656 event_explanation = ts.GetData();
657 } while (0);
658
659 log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
660 }
661
Chris Lattner24943d22010-06-08 16:52:24 +0000662 return_value = eExecutionInterrupted;
663 break;
664 }
Chris Lattner24943d22010-06-08 16:52:24 +0000665 }
Sean Callanan841026f2010-07-23 00:16:21 +0000666
Sean Callananc78d6482010-07-26 22:14:36 +0000667 // Thread we ran the function in may have gone away because we ran the target
668 // Check that it's still there.
Jim Ingham681778e2010-09-10 23:07:48 +0000669 exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByIndexID(tid, true).get();
Sean Callananc78d6482010-07-26 22:14:36 +0000670 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
671
Jim Ingham681778e2010-09-10 23:07:48 +0000672 // Also restore the current process'es selected frame & thread, since this function calling may
673 // be done behind the user's back.
674
675 if (selected_tid != LLDB_INVALID_THREAD_ID)
676 {
677 if (exe_ctx.process->GetThreadList().SetSelectedThreadByIndexID (selected_tid))
678 {
679 // We were able to restore the selected thread, now restore the frame:
680 exe_ctx.process->GetThreadList().GetSelectedThread()->SetSelectedFrame(selected_frame_sp.get());
681 }
682 }
683
Sean Callanan841026f2010-07-23 00:16:21 +0000684 return return_value;
685}
Chris Lattner24943d22010-06-08 16:52:24 +0000686
Sean Callanan841026f2010-07-23 00:16:21 +0000687ClangFunction::ExecutionResults
688ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000689 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000690 lldb::addr_t *args_addr_ptr,
691 Stream &errors,
692 bool stop_others,
693 uint32_t single_thread_timeout_usec,
694 bool try_all_threads,
695 Value &results)
696{
697 using namespace clang;
698 ExecutionResults return_value = eExecutionSetupError;
699
700 lldb::addr_t args_addr;
701
702 if (args_addr_ptr != NULL)
703 args_addr = *args_addr_ptr;
704 else
705 args_addr = LLDB_INVALID_ADDRESS;
706
707 if (CompileFunction(errors) != 0)
708 return eExecutionSetupError;
709
710 if (args_addr == LLDB_INVALID_ADDRESS)
711 {
Sean Callananc78d6482010-07-26 22:14:36 +0000712 if (!InsertFunction(exe_ctx, args_addr, errors))
Sean Callanan841026f2010-07-23 00:16:21 +0000713 return eExecutionSetupError;
714 }
715
Jim Ingham681778e2010-09-10 23:07:48 +0000716 return_value = ClangFunction::ExecuteFunction(exe_ctx, m_wrapper_function_addr, args_addr, stop_others,
717 try_all_threads, single_thread_timeout_usec, errors);
Sean Callanan841026f2010-07-23 00:16:21 +0000718
719 if (args_addr_ptr != NULL)
720 *args_addr_ptr = args_addr;
721
Chris Lattner24943d22010-06-08 16:52:24 +0000722 if (return_value != eExecutionCompleted)
723 return return_value;
724
Sean Callananc78d6482010-07-26 22:14:36 +0000725 FetchFunctionResults(exe_ctx, args_addr, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000726
727 if (args_addr_ptr == NULL)
Sean Callananc78d6482010-07-26 22:14:36 +0000728 DeallocateFunctionResults(exe_ctx, args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000729
730 return eExecutionCompleted;
731}
732
Sean Callanan65dafa82010-08-27 01:01:44 +0000733clang::ASTConsumer *
734ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
Chris Lattner24943d22010-06-08 16:52:24 +0000735{
Sean Callanan65dafa82010-08-27 01:01:44 +0000736 return new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this);
Chris Lattner24943d22010-06-08 16:52:24 +0000737}