blob: be107ca8eb074886f89bd3dcba44ad040354bb93 [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
Sean Callanan65dafa82010-08-27 01:01:44 +000025#include "lldb/Expression/ASTStructExtractor.h"
26#include "lldb/Expression/ClangExpressionParser.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Expression/ClangFunction.h"
28#include "lldb/Symbol/Type.h"
29#include "lldb/Core/DataExtractor.h"
30#include "lldb/Core/ValueObject.h"
31#include "lldb/Core/ValueObjectList.h"
32#include "lldb/Interpreter/CommandReturnObject.h"
33#include "lldb/Symbol/ClangASTContext.h"
34#include "lldb/Symbol/Function.h"
35#include "lldb/Target/ExecutionContext.h"
36#include "lldb/Target/Process.h"
Sean Callanan841026f2010-07-23 00:16:21 +000037#include "lldb/Target/RegisterContext.h"
Greg Clayton643ee732010-08-04 01:40:35 +000038#include "lldb/Target/StopInfo.h"
Chris Lattner24943d22010-06-08 16:52:24 +000039#include "lldb/Target/Thread.h"
40#include "lldb/Target/ThreadPlan.h"
41#include "lldb/Target/ThreadPlanCallFunction.h"
42#include "lldb/Core/Log.h"
43
44using namespace lldb_private;
Sean Callanan65dafa82010-08-27 01:01:44 +000045
Chris Lattner24943d22010-06-08 16:52:24 +000046//----------------------------------------------------------------------
47// ClangFunction constructor
48//----------------------------------------------------------------------
49ClangFunction::ClangFunction(const char *target_triple, ClangASTContext *ast_context, void *return_qualtype, const Address& functionAddress, const ValueList &arg_value_list) :
Sean Callanan65dafa82010-08-27 01:01:44 +000050 m_target_triple (target_triple),
Chris Lattner24943d22010-06-08 16:52:24 +000051 m_function_ptr (NULL),
Greg Clayton54e7afa2010-07-09 20:39:50 +000052 m_function_addr (functionAddress),
Chris Lattner24943d22010-06-08 16:52:24 +000053 m_function_return_qual_type(return_qualtype),
Greg Clayton54e7afa2010-07-09 20:39:50 +000054 m_clang_ast_context (ast_context),
Chris Lattner24943d22010-06-08 16:52:24 +000055 m_wrapper_function_name ("__lldb_caller_function"),
56 m_wrapper_struct_name ("__lldb_caller_struct"),
Greg Clayton54e7afa2010-07-09 20:39:50 +000057 m_wrapper_function_addr (),
58 m_wrapper_args_addrs (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000059 m_arg_values (arg_value_list),
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) :
Sean Callanan65dafa82010-08-27 01:01:44 +000066 m_target_triple (target_triple),
Chris Lattner24943d22010-06-08 16:52:24 +000067 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 (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000075 m_arg_values (arg_value_list),
Chris Lattner24943d22010-06-08 16:52:24 +000076 m_compiled (false),
77 m_JITted (false)
78{
79 m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
80 m_function_return_qual_type = m_function_ptr->GetReturnType().GetOpaqueClangQualType();
81}
82
83//----------------------------------------------------------------------
84// Destructor
85//----------------------------------------------------------------------
86ClangFunction::~ClangFunction()
87{
88}
89
90unsigned
91ClangFunction::CompileFunction (Stream &errors)
92{
Sean Callanan65dafa82010-08-27 01:01:44 +000093 if (m_compiled)
94 return 0;
95
Chris Lattner24943d22010-06-08 16:52:24 +000096 // FIXME: How does clang tell us there's no return value? We need to handle that case.
97 unsigned num_errors = 0;
98
Sean Callanan65dafa82010-08-27 01:01:44 +000099 std::string return_type_str = ClangASTContext::GetTypeName(m_function_return_qual_type);
100
101 // Cons up the function we're going to wrap our call in, then compile it...
102 // We declare the function "extern "C"" because the compiler might be in C++
103 // mode which would mangle the name and then we couldn't find it again...
104 m_wrapper_function_text.clear();
105 m_wrapper_function_text.append ("extern \"C\" void ");
106 m_wrapper_function_text.append (m_wrapper_function_name);
107 m_wrapper_function_text.append (" (void *input)\n{\n struct ");
108 m_wrapper_function_text.append (m_wrapper_struct_name);
109 m_wrapper_function_text.append (" \n {\n");
110 m_wrapper_function_text.append (" ");
111 m_wrapper_function_text.append (return_type_str);
112 m_wrapper_function_text.append (" (*fn_ptr) (");
113
114 // Get the number of arguments. If we have a function type and it is prototyped,
115 // trust that, otherwise use the values we were given.
116
117 // FIXME: This will need to be extended to handle Variadic functions. We'll need
118 // to pull the defined arguments out of the function, then add the types from the
119 // arguments list for the variable arguments.
120
121 uint32_t num_args = UINT32_MAX;
122 bool trust_function = false;
123 // GetArgumentCount returns -1 for an unprototyped function.
124 if (m_function_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000125 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000126 int num_func_args = m_function_ptr->GetArgumentCount();
127 if (num_func_args >= 0)
128 trust_function = true;
129 else
130 num_args = num_func_args;
131 }
Chris Lattner24943d22010-06-08 16:52:24 +0000132
Sean Callanan65dafa82010-08-27 01:01:44 +0000133 if (num_args == UINT32_MAX)
134 num_args = m_arg_values.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000135
Sean Callanan65dafa82010-08-27 01:01:44 +0000136 std::string args_buffer; // This one stores the definition of all the args in "struct caller".
137 std::string args_list_buffer; // This one stores the argument list called from the structure.
138 for (size_t i = 0; i < num_args; i++)
139 {
140 const char *type_string;
141 std::string type_stdstr;
Chris Lattner24943d22010-06-08 16:52:24 +0000142
Sean Callanan65dafa82010-08-27 01:01:44 +0000143 if (trust_function)
Chris Lattner24943d22010-06-08 16:52:24 +0000144 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000145 type_string = m_function_ptr->GetArgumentTypeAtIndex(i).GetName().AsCString();
Chris Lattner24943d22010-06-08 16:52:24 +0000146 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000147 else
Chris Lattner24943d22010-06-08 16:52:24 +0000148 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000149 Value *arg_value = m_arg_values.GetValueAtIndex(i);
150 void *clang_qual_type = arg_value->GetOpaqueClangQualType ();
151 if (clang_qual_type != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000152 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000153 type_stdstr = ClangASTContext::GetTypeName(clang_qual_type);
154 type_string = type_stdstr.c_str();
Chris Lattner24943d22010-06-08 16:52:24 +0000155 }
156 else
Sean Callanan65dafa82010-08-27 01:01:44 +0000157 {
158 errors.Printf("Could not determine type of input value %d.", i);
Chris Lattner24943d22010-06-08 16:52:24 +0000159 return 1;
160 }
Chris Lattner24943d22010-06-08 16:52:24 +0000161 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000162
163 m_wrapper_function_text.append (type_string);
164 if (i < num_args - 1)
165 m_wrapper_function_text.append (", ");
166
167 char arg_buf[32];
168 args_buffer.append (" ");
169 args_buffer.append (type_string);
170 snprintf(arg_buf, 31, "arg_%zd", i);
171 args_buffer.push_back (' ');
172 args_buffer.append (arg_buf);
173 args_buffer.append (";\n");
174
175 args_list_buffer.append ("__lldb_fn_data->");
176 args_list_buffer.append (arg_buf);
177 if (i < num_args - 1)
178 args_list_buffer.append (", ");
179
Chris Lattner24943d22010-06-08 16:52:24 +0000180 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000181 m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
182
183 m_wrapper_function_text.append (args_buffer);
184
185 m_wrapper_function_text.append (" ");
186 m_wrapper_function_text.append (return_type_str);
187 m_wrapper_function_text.append (" return_value;");
188 m_wrapper_function_text.append ("\n };\n struct ");
189 m_wrapper_function_text.append (m_wrapper_struct_name);
190 m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
191 m_wrapper_function_text.append (m_wrapper_struct_name);
192 m_wrapper_function_text.append (" *) input;\n");
193
194 m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
195 m_wrapper_function_text.append (args_list_buffer);
196 m_wrapper_function_text.append (");\n}\n");
197
198 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
199 if (log)
200 log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
201
202 // Okay, now compile this expression
203
204 m_parser.reset(new ClangExpressionParser(m_target_triple.c_str(), *this));
205
206 num_errors = m_parser->Parse (errors);
207
208 m_compiled = (num_errors == 0);
209
210 if (!m_compiled)
211 return num_errors;
Chris Lattner24943d22010-06-08 16:52:24 +0000212
213 return num_errors;
214}
215
216bool
Sean Callananc78d6482010-07-26 22:14:36 +0000217ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000218{
Sean Callananc78d6482010-07-26 22:14:36 +0000219 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000220
Sean Callanan65dafa82010-08-27 01:01:44 +0000221 if (!process)
222 return false;
223
224 if (!m_compiled)
Chris Lattner24943d22010-06-08 16:52:24 +0000225 return false;
226
Sean Callanan65dafa82010-08-27 01:01:44 +0000227 if (m_JITted)
228 return true;
229
230 Error jit_error = m_parser->MakeJIT(m_wrapper_function_addr, exe_ctx);
231
232 if (!jit_error.Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000233 return false;
234
235 return true;
236}
237
238bool
Sean Callananc78d6482010-07-26 22:14:36 +0000239ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000240{
Sean Callananc78d6482010-07-26 22:14:36 +0000241 return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);
Chris Lattner24943d22010-06-08 16:52:24 +0000242}
243
244// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
245
246bool
Sean Callananc78d6482010-07-26 22:14:36 +0000247ClangFunction::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 +0000248{
Sean Callanan65dafa82010-08-27 01:01:44 +0000249 // All the information to reconstruct the struct is provided by the
250 // StructExtractor.
251 if (!m_struct_valid)
252 {
253 errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
254 return false;
255 }
256
Chris Lattner24943d22010-06-08 16:52:24 +0000257 Error error;
258 using namespace clang;
259 ExecutionResults return_value = eExecutionSetupError;
260
Sean Callananc78d6482010-07-26 22:14:36 +0000261 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000262
263 if (process == NULL)
264 return return_value;
Sean Callanan65dafa82010-08-27 01:01:44 +0000265
Chris Lattner24943d22010-06-08 16:52:24 +0000266 if (args_addr_ref == LLDB_INVALID_ADDRESS)
267 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000268 args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000269 if (args_addr_ref == LLDB_INVALID_ADDRESS)
270 return false;
271 m_wrapper_args_addrs.push_back (args_addr_ref);
272 }
273 else
274 {
275 // Make sure this is an address that we've already handed out.
276 if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
277 {
278 return false;
279 }
280 }
281
282 // FIXME: This is fake, and just assumes that it matches that architecture.
283 // Make a data extractor and put the address into the right byte order & size.
284
Sean Callananc78d6482010-07-26 22:14:36 +0000285 uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.process);
Sean Callanan65dafa82010-08-27 01:01:44 +0000286 int first_offset = m_member_offsets[0];
Chris Lattner24943d22010-06-08 16:52:24 +0000287 process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error);
288
289 // FIXME: We will need to extend this for Variadic functions.
290
291 Error value_error;
292
293 size_t num_args = arg_values.GetSize();
294 if (num_args != m_arg_values.GetSize())
295 {
296 errors.Printf ("Wrong number of arguments - was: %d should be: %d", num_args, m_arg_values.GetSize());
297 return false;
298 }
299
Greg Clayton54e7afa2010-07-09 20:39:50 +0000300 for (size_t i = 0; i < num_args; i++)
Chris Lattner24943d22010-06-08 16:52:24 +0000301 {
302 // FIXME: We should sanity check sizes.
303
Sean Callanan65dafa82010-08-27 01:01:44 +0000304 int offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
Chris Lattner24943d22010-06-08 16:52:24 +0000305 Value *arg_value = arg_values.GetValueAtIndex(i);
306
307 // FIXME: For now just do scalars:
308
309 // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
310
311 if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
312 arg_value->GetContextType() == Value::eContextTypeOpaqueClangQualType &&
313 ClangASTContext::IsPointerType(arg_value->GetValueOpaqueClangQualType()))
314 continue;
315
Sean Callananc78d6482010-07-26 22:14:36 +0000316 const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000317
318 int byte_size = arg_scalar.GetByteSize();
319 std::vector<uint8_t> buffer;
320 buffer.resize(byte_size);
321 DataExtractor value_data;
322 arg_scalar.GetData (value_data);
Greg Clayton53d68e72010-07-20 22:52:08 +0000323 value_data.ExtractBytes(0, byte_size, process->GetByteOrder(), &buffer.front());
324 process->WriteMemory(args_addr_ref + offset, &buffer.front(), byte_size, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000325 }
326
327 return true;
328}
329
330bool
Sean Callananc78d6482010-07-26 22:14:36 +0000331ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000332{
333 using namespace clang;
334
335 if (CompileFunction(errors) != 0)
336 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000337 if (!WriteFunctionWrapper(exe_ctx, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000338 return false;
Sean Callananc78d6482010-07-26 22:14:36 +0000339 if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
Chris Lattner24943d22010-06-08 16:52:24 +0000340 return false;
341
342 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
343 if (log)
Greg Clayton54e7afa2010-07-09 20:39:50 +0000344 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 +0000345
346 return true;
347}
348
349ThreadPlan *
Sean Callananc78d6482010-07-26 22:14:36 +0000350ClangFunction::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 +0000351{
352 // FIXME: Use the errors Stream for better error reporting.
353
Sean Callananc78d6482010-07-26 22:14:36 +0000354 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000355
356 if (process == NULL)
357 {
358 errors.Printf("Can't call a function without a process.");
359 return NULL;
360 }
361
362 // Okay, now run the function:
363
Sean Callanan841026f2010-07-23 00:16:21 +0000364 Address wrapper_address (NULL, func_addr);
Sean Callananc78d6482010-07-26 22:14:36 +0000365 ThreadPlan *new_plan = new ThreadPlanCallFunction (*exe_ctx.thread,
Chris Lattner24943d22010-06-08 16:52:24 +0000366 wrapper_address,
367 args_addr,
368 stop_others, discard_on_error);
369 return new_plan;
370}
371
372bool
Sean Callananc78d6482010-07-26 22:14:36 +0000373ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
Chris Lattner24943d22010-06-08 16:52:24 +0000374{
375 // Read the return value - it is the last field in the struct:
376 // FIXME: How does clang tell us there's no return value? We need to handle that case.
377
378 std::vector<uint8_t> data_buffer;
379 data_buffer.resize(m_return_size);
Sean Callananc78d6482010-07-26 22:14:36 +0000380 Process *process = exe_ctx.process;
Chris Lattner24943d22010-06-08 16:52:24 +0000381 Error error;
Sean Callanan65dafa82010-08-27 01:01:44 +0000382 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 +0000383
384 if (bytes_read == 0)
385 {
386 return false;
387 }
388
389 if (bytes_read < m_return_size)
390 return false;
391
Greg Clayton53d68e72010-07-20 22:52:08 +0000392 DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000393 // FIXME: Assuming an integer scalar for now:
394
395 uint32_t offset = 0;
396 uint64_t return_integer = data.GetMaxU64(&offset, m_return_size);
397
398 ret_value.SetContext (Value::eContextTypeOpaqueClangQualType, m_function_return_qual_type);
399 ret_value.SetValueType(Value::eValueTypeScalar);
400 ret_value.GetScalar() = return_integer;
401 return true;
402}
403
404void
Sean Callananc78d6482010-07-26 22:14:36 +0000405ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Chris Lattner24943d22010-06-08 16:52:24 +0000406{
407 std::list<lldb::addr_t>::iterator pos;
408 pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
409 if (pos != m_wrapper_args_addrs.end())
410 m_wrapper_args_addrs.erase(pos);
411
Sean Callananc78d6482010-07-26 22:14:36 +0000412 exe_ctx.process->DeallocateMemory(args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000413}
414
415ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000416ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000417{
Sean Callananc78d6482010-07-26 22:14:36 +0000418 return ExecuteFunction (exe_ctx, errors, 1000, true, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000419}
420
421ClangFunction::ExecutionResults
Sean Callananc78d6482010-07-26 22:14:36 +0000422ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
Chris Lattner24943d22010-06-08 16:52:24 +0000423{
Sean Callananc78d6482010-07-26 22:14:36 +0000424 return ExecuteFunction (exe_ctx, NULL, errors, stop_others, NULL, false, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000425}
426
427ClangFunction::ExecutionResults
428ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000429 ExecutionContext &exe_ctx,
Chris Lattner24943d22010-06-08 16:52:24 +0000430 Stream &errors,
431 uint32_t single_thread_timeout_usec,
432 bool try_all_threads,
433 Value &results)
434{
Sean Callananc78d6482010-07-26 22:14:36 +0000435 return ExecuteFunction (exe_ctx, NULL, errors, true, single_thread_timeout_usec, try_all_threads, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000436}
437
Sean Callanan841026f2010-07-23 00:16:21 +0000438// This is the static function
439ClangFunction::ExecutionResults
440ClangFunction::ExecuteFunction (
Sean Callananc78d6482010-07-26 22:14:36 +0000441 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000442 lldb::addr_t function_address,
443 lldb::addr_t &void_arg,
444 bool stop_others,
445 bool try_all_threads,
446 uint32_t single_thread_timeout_usec,
447 Stream &errors)
Chris Lattner24943d22010-06-08 16:52:24 +0000448{
Sean Callananc78d6482010-07-26 22:14:36 +0000449 // Save this value for restoration of the execution context after we run
450 uint32_t tid = exe_ctx.thread->GetID();
451
Sean Callanan841026f2010-07-23 00:16:21 +0000452 ClangFunction::ExecutionResults return_value = eExecutionSetupError;
Chris Lattner24943d22010-06-08 16:52:24 +0000453
Sean Callananc78d6482010-07-26 22:14:36 +0000454 lldb::ThreadPlanSP call_plan_sp(ClangFunction::GetThreadPlanToCallFunction(exe_ctx, function_address, void_arg, errors, stop_others, false));
Chris Lattner24943d22010-06-08 16:52:24 +0000455
456 ThreadPlanCallFunction *call_plan_ptr = static_cast<ThreadPlanCallFunction *> (call_plan_sp.get());
457
Chris Lattner24943d22010-06-08 16:52:24 +0000458 if (call_plan_sp == NULL)
Sean Callanan841026f2010-07-23 00:16:21 +0000459 return eExecutionSetupError;
460
Chris Lattner24943d22010-06-08 16:52:24 +0000461 call_plan_sp->SetPrivate(true);
Sean Callananc78d6482010-07-26 22:14:36 +0000462 exe_ctx.thread->QueueThreadPlan(call_plan_sp, true);
Sean Callanan841026f2010-07-23 00:16:21 +0000463
Chris Lattner24943d22010-06-08 16:52:24 +0000464 // We need to call the function synchronously, so spin waiting for it to return.
465 // If we get interrupted while executing, we're going to lose our context, and
466 // won't be able to gather the result at this point.
Sean Callanan841026f2010-07-23 00:16:21 +0000467
Chris Lattner24943d22010-06-08 16:52:24 +0000468 TimeValue* timeout_ptr = NULL;
469 TimeValue real_timeout;
Sean Callanan841026f2010-07-23 00:16:21 +0000470
Chris Lattner24943d22010-06-08 16:52:24 +0000471 if (single_thread_timeout_usec != 0)
472 {
473 real_timeout = TimeValue::Now();
474 real_timeout.OffsetWithMicroSeconds(single_thread_timeout_usec);
475 timeout_ptr = &real_timeout;
476 }
Sean Callanan841026f2010-07-23 00:16:21 +0000477
Jim Inghama2890f42010-08-17 00:35:35 +0000478 Error resume_error = exe_ctx.process->Resume ();
479 if (!resume_error.Success())
480 {
481 errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
482 return eExecutionSetupError;
483 }
Sean Callanan841026f2010-07-23 00:16:21 +0000484
485 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
Chris Lattner24943d22010-06-08 16:52:24 +0000486
487 while (1)
488 {
489 lldb::EventSP event_sp;
Sean Callanan841026f2010-07-23 00:16:21 +0000490
Chris Lattner24943d22010-06-08 16:52:24 +0000491 // Now wait for the process to stop again:
492 // FIXME: Probably want a time out.
Sean Callananc78d6482010-07-26 22:14:36 +0000493 lldb::StateType stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Sean Callanan841026f2010-07-23 00:16:21 +0000494
Chris Lattner24943d22010-06-08 16:52:24 +0000495 if (stop_state == lldb::eStateInvalid && timeout_ptr != NULL)
496 {
497 // Right now this is the only way to tell we've timed out...
498 // We should interrupt the process here...
499 // Not really sure what to do if Halt fails here...
Chris Lattner24943d22010-06-08 16:52:24 +0000500 if (log)
501 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 +0000502
Sean Callananc78d6482010-07-26 22:14:36 +0000503 if (exe_ctx.process->Halt().Success())
Chris Lattner24943d22010-06-08 16:52:24 +0000504 {
505 timeout_ptr = NULL;
506
Sean Callananc78d6482010-07-26 22:14:36 +0000507 stop_state = exe_ctx.process->WaitForStateChangedEvents (timeout_ptr, event_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000508 if (stop_state == lldb::eStateInvalid)
509 {
510 errors.Printf ("Got an invalid stop state after halt.");
511 }
512 else if (stop_state != lldb::eStateStopped)
513 {
514 StreamString s;
515 event_sp->Dump (&s);
516
517 errors.Printf("Didn't get a stopped event after Halting the target, got: \"%s\"", s.GetData());
518 }
519
520 if (try_all_threads)
521 {
522 // Between the time that we got the timeout and the time we halted, but target
523 // might have actually completed the plan. If so, we're done.
Sean Callananc78d6482010-07-26 22:14:36 +0000524 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000525 {
526 return_value = eExecutionCompleted;
527 break;
528 }
Sean Callanan841026f2010-07-23 00:16:21 +0000529
Chris Lattner24943d22010-06-08 16:52:24 +0000530 call_plan_ptr->SetStopOthers (false);
Sean Callananc78d6482010-07-26 22:14:36 +0000531 exe_ctx.process->Resume();
Chris Lattner24943d22010-06-08 16:52:24 +0000532 continue;
533 }
534 else
535 return eExecutionInterrupted;
536 }
537 }
538 if (stop_state == lldb::eStateRunning || stop_state == lldb::eStateStepping)
539 continue;
Sean Callanan841026f2010-07-23 00:16:21 +0000540
Sean Callananc78d6482010-07-26 22:14:36 +0000541 if (exe_ctx.thread->IsThreadPlanDone (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000542 {
543 return_value = eExecutionCompleted;
544 break;
545 }
Sean Callananc78d6482010-07-26 22:14:36 +0000546 else if (exe_ctx.thread->WasThreadPlanDiscarded (call_plan_sp.get()))
Chris Lattner24943d22010-06-08 16:52:24 +0000547 {
548 return_value = eExecutionDiscarded;
549 break;
550 }
551 else
552 {
Sean Callanan841026f2010-07-23 00:16:21 +0000553 if (log)
554 {
555 StreamString s;
556 event_sp->Dump (&s);
557 StreamString ts;
558
559 const char *event_explanation;
560
561 do
562 {
563 const Process::ProcessEventData *event_data = Process::ProcessEventData::GetEventDataFromEvent (event_sp.get());
564
565 if (!event_data)
566 {
567 event_explanation = "<no event data>";
568 break;
569 }
570
571 Process *process = event_data->GetProcessSP().get();
572
573 if (!process)
574 {
575 event_explanation = "<no process>";
576 break;
577 }
578
579 ThreadList &thread_list = process->GetThreadList();
580
581 uint32_t num_threads = thread_list.GetSize();
582 uint32_t thread_index;
583
584 ts.Printf("<%u threads> ", num_threads);
585
586 for (thread_index = 0;
587 thread_index < num_threads;
588 ++thread_index)
589 {
590 Thread *thread = thread_list.GetThreadAtIndex(thread_index).get();
591
592 if (!thread)
593 {
594 ts.Printf("<?> ");
595 continue;
596 }
597
Sean Callanan841026f2010-07-23 00:16:21 +0000598 ts.Printf("<");
599 RegisterContext *register_context = thread->GetRegisterContext();
600
601 if (register_context)
602 ts.Printf("[ip 0x%llx] ", register_context->GetPC());
603 else
604 ts.Printf("[ip unknown] ");
605
Greg Clayton643ee732010-08-04 01:40:35 +0000606 StopInfo *stop_info = thread->GetStopInfo();
607 if (stop_info)
608 {
609 const char *stop_desc = stop_info->GetDescription();
610 if (stop_desc)
611 ts.PutCString (stop_desc);
612 }
Sean Callanan841026f2010-07-23 00:16:21 +0000613 ts.Printf(">");
614 }
615
616 event_explanation = ts.GetData();
617 } while (0);
618
619 log->Printf("Execution interrupted: %s %s", s.GetData(), event_explanation);
620 }
621
Chris Lattner24943d22010-06-08 16:52:24 +0000622 return_value = eExecutionInterrupted;
623 break;
624 }
Chris Lattner24943d22010-06-08 16:52:24 +0000625 }
Sean Callanan841026f2010-07-23 00:16:21 +0000626
Sean Callananc78d6482010-07-26 22:14:36 +0000627 // Thread we ran the function in may have gone away because we ran the target
628 // Check that it's still there.
629 exe_ctx.thread = exe_ctx.process->GetThreadList().FindThreadByID(tid, true).get();
630 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex(0).get();
631
Sean Callanan841026f2010-07-23 00:16:21 +0000632 return return_value;
633}
Chris Lattner24943d22010-06-08 16:52:24 +0000634
Sean Callanan841026f2010-07-23 00:16:21 +0000635ClangFunction::ExecutionResults
636ClangFunction::ExecuteFunction(
Sean Callananc78d6482010-07-26 22:14:36 +0000637 ExecutionContext &exe_ctx,
Sean Callanan841026f2010-07-23 00:16:21 +0000638 lldb::addr_t *args_addr_ptr,
639 Stream &errors,
640 bool stop_others,
641 uint32_t single_thread_timeout_usec,
642 bool try_all_threads,
643 Value &results)
644{
645 using namespace clang;
646 ExecutionResults return_value = eExecutionSetupError;
647
648 lldb::addr_t args_addr;
649
650 if (args_addr_ptr != NULL)
651 args_addr = *args_addr_ptr;
652 else
653 args_addr = LLDB_INVALID_ADDRESS;
654
655 if (CompileFunction(errors) != 0)
656 return eExecutionSetupError;
657
658 if (args_addr == LLDB_INVALID_ADDRESS)
659 {
Sean Callananc78d6482010-07-26 22:14:36 +0000660 if (!InsertFunction(exe_ctx, args_addr, errors))
Sean Callanan841026f2010-07-23 00:16:21 +0000661 return eExecutionSetupError;
662 }
663
Sean Callananc78d6482010-07-26 22:14:36 +0000664 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 +0000665
666 if (args_addr_ptr != NULL)
667 *args_addr_ptr = args_addr;
668
Chris Lattner24943d22010-06-08 16:52:24 +0000669 if (return_value != eExecutionCompleted)
670 return return_value;
671
Sean Callananc78d6482010-07-26 22:14:36 +0000672 FetchFunctionResults(exe_ctx, args_addr, results);
Chris Lattner24943d22010-06-08 16:52:24 +0000673
674 if (args_addr_ptr == NULL)
Sean Callananc78d6482010-07-26 22:14:36 +0000675 DeallocateFunctionResults(exe_ctx, args_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000676
677 return eExecutionCompleted;
678}
679
Sean Callanan65dafa82010-08-27 01:01:44 +0000680clang::ASTConsumer *
681ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
Chris Lattner24943d22010-06-08 16:52:24 +0000682{
Sean Callanan65dafa82010-08-27 01:01:44 +0000683 return new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this);
Chris Lattner24943d22010-06-08 16:52:24 +0000684}