blob: 83b8270813c31dd8df8f64a272bb7b2aa27d18f8 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:241//===-- ThreadPlanCallFunction.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#include "lldb/Target/ThreadPlanCallFunction.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
Sean Callanan6db73ca2010-11-03 01:37:5215#include "llvm/Support/MachO.h"
Chris Lattner30fdc8d2010-06-08 16:52:2416// Project includes
17#include "lldb/lldb-private-log.h"
Jim Ingham40d871f2010-10-26 00:27:4518#include "lldb/Breakpoint/Breakpoint.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
Chris Lattner30fdc8d2010-06-08 16:52:2420#include "lldb/Core/Address.h"
21#include "lldb/Core/Log.h"
22#include "lldb/Core/Stream.h"
Sean Callananf2115102010-11-03 22:19:3823#include "lldb/Target/LanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:2424#include "lldb/Target/Process.h"
25#include "lldb/Target/RegisterContext.h"
Jim Ingham40d871f2010-10-26 00:27:4526#include "lldb/Target/StopInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:2427#include "lldb/Target/Target.h"
28#include "lldb/Target/Thread.h"
29#include "lldb/Target/ThreadPlanRunToAddress.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34//----------------------------------------------------------------------
35// ThreadPlanCallFunction: Plan to call a single function
36//----------------------------------------------------------------------
37
38ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
39 Address &function,
40 lldb::addr_t arg,
41 bool stop_other_threads,
Sean Callananfc55f5d2010-09-21 00:44:1242 bool discard_on_error,
Sean Callanan17827832010-12-13 22:46:1543 lldb::addr_t *this_arg,
44 lldb::addr_t *cmd_arg) :
Jim Inghamb01e742a2010-06-19 04:45:3245 ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
Benjamin Kramer1ee0d4f2010-07-16 12:32:3346 m_valid (false),
47 m_stop_other_threads (stop_other_threads),
Chris Lattner30fdc8d2010-06-08 16:52:2448 m_arg_addr (arg),
49 m_args (NULL),
Benjamin Kramer1ee0d4f2010-07-16 12:32:3350 m_process (thread.GetProcess()),
Jim Ingham9da36832011-01-22 01:27:2351 m_thread (thread),
Sean Callanane359d9b2011-05-09 22:04:3652 m_takedown_done (false),
53 m_function_sp(NULL)
Chris Lattner30fdc8d2010-06-08 16:52:2454{
Chris Lattner30fdc8d2010-06-08 16:52:2455 SetOkayToDiscard (discard_on_error);
56
57 Process& process = thread.GetProcess();
58 Target& target = process.GetTarget();
59 const ABI *abi = process.GetABI();
Sean Callanan6db73ca2010-11-03 01:37:5260
Chris Lattner30fdc8d2010-06-08 16:52:2461 if (!abi)
62 return;
Sean Callanan6db73ca2010-11-03 01:37:5263
Jim Ingham77787032011-01-20 02:03:1864 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
65
Sean Callanan6db73ca2010-11-03 01:37:5266 SetBreakpoints();
67
Sean Callanane359d9b2011-05-09 22:04:3668 m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
Chris Lattner30fdc8d2010-06-08 16:52:2469
Chris Lattner30fdc8d2010-06-08 16:52:2470 ModuleSP executableModuleSP (target.GetExecutableModule());
71
Jim Ingham672e6f52011-03-07 23:44:0872 if (!executableModuleSP)
73 {
74 log->Printf ("Can't execute code without an executable module.");
Chris Lattner30fdc8d2010-06-08 16:52:2475 return;
Jim Ingham672e6f52011-03-07 23:44:0876 }
77 else
78 {
79 ObjectFile *objectFile = executableModuleSP->GetObjectFile();
80 if (!objectFile)
81 {
82 log->Printf ("Could not find object file for module \"%s\".",
83 executableModuleSP->GetFileSpec().GetFilename().AsCString());
84 return;
85 }
86 m_start_addr = objectFile->GetEntryPointAddress();
87 if (!m_start_addr.IsValid())
88 {
89 log->Printf ("Could not find entry point address for executable module \"%s\".",
90 executableModuleSP->GetFileSpec().GetFilename().AsCString());
91 return;
92 }
93 }
Chris Lattner30fdc8d2010-06-08 16:52:2494
Greg Claytonf5e56de2010-09-14 23:36:4095 lldb::addr_t StartLoadAddr = m_start_addr.GetLoadAddress(&target);
Jim Ingham672e6f52011-03-07 23:44:0896
Jim Ingham77787032011-01-20 02:03:1897 // Checkpoint the thread state so we can restore it later.
Jim Ingham9da36832011-01-22 01:27:2398 if (log && log->GetVerbose())
99 ReportRegisterState ("About to checkpoint thread before function call. Original register state was:");
100
Jim Ingham77787032011-01-20 02:03:18101 if (!thread.CheckpointThreadState (m_stored_thread_state))
102 {
103 if (log)
104 log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
Chris Lattner30fdc8d2010-06-08 16:52:24105 return;
Jim Ingham77787032011-01-20 02:03:18106 }
107 // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
108 thread.SetStopInfoToNothing();
109
Chris Lattner30fdc8d2010-06-08 16:52:24110 m_function_addr = function;
Greg Claytonf5e56de2010-09-14 23:36:40111 lldb::addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target);
Chris Lattner30fdc8d2010-06-08 16:52:24112
113 if (!abi->PrepareTrivialCall(thread,
Sean Callanane359d9b2011-05-09 22:04:36114 m_function_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24115 FunctionLoadAddr,
116 StartLoadAddr,
Sean Callananfc55f5d2010-09-21 00:44:12117 m_arg_addr,
Sean Callanan17827832010-12-13 22:46:15118 this_arg,
119 cmd_arg))
Chris Lattner30fdc8d2010-06-08 16:52:24120 return;
121
Jim Ingham9da36832011-01-22 01:27:23122 ReportRegisterState ("Function call was set up. Register state was:");
123
124 m_valid = true;
125}
126
127ThreadPlanCallFunction::~ThreadPlanCallFunction ()
128{
129}
130
131void
132ThreadPlanCallFunction::ReportRegisterState (const char *message)
133{
134 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Sean Callananece96492010-11-08 03:49:50135 if (log)
136 {
Greg Clayton5ccbd292011-01-06 22:15:06137 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
Jim Ingham9da36832011-01-22 01:27:23138
139 log->PutCString(message);
140
Sean Callananece96492010-11-08 03:49:50141 for (uint32_t register_index = 0, num_registers = reg_ctx->GetRegisterCount();
142 register_index < num_registers;
143 ++register_index)
144 {
145 const char *register_name = reg_ctx->GetRegisterName(register_index);
146 uint64_t register_value = reg_ctx->ReadRegisterAsUnsigned(register_index, LLDB_INVALID_ADDRESS);
147
148 log->Printf(" %s = 0x%llx", register_name, register_value);
149 }
150 }
Sean Callanan10af7c42010-11-04 01:51:38151}
152
153void
154ThreadPlanCallFunction::DoTakedown ()
155{
Jim Ingham9da36832011-01-22 01:27:23156 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
157 if (!m_takedown_done)
Jim Ingham77787032011-01-20 02:03:18158 {
Jim Ingham9da36832011-01-22 01:27:23159 if (log)
160 log->Printf ("DoTakedown called for thread 0x%4.4x, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete());
161 m_takedown_done = true;
Jim Ingham77787032011-01-20 02:03:18162 m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state);
163 SetPlanComplete();
164 ClearBreakpoints();
Jim Ingham9da36832011-01-22 01:27:23165 if (log && log->GetVerbose())
166 ReportRegisterState ("Restoring thread state after function call. Restored register state:");
Jim Ingham2c364392011-01-26 19:13:09167
Jim Ingham9da36832011-01-22 01:27:23168 }
169 else
170 {
171 if (log)
172 log->Printf ("DoTakedown called as no-op for thread 0x%4.4x, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete());
Jim Ingham77787032011-01-20 02:03:18173 }
Chris Lattner30fdc8d2010-06-08 16:52:24174}
175
176void
Jim Inghambda4e5eb2011-01-18 01:58:06177ThreadPlanCallFunction::WillPop ()
178{
Jim Ingham77787032011-01-20 02:03:18179 DoTakedown();
Jim Inghambda4e5eb2011-01-18 01:58:06180}
181
182void
Chris Lattner30fdc8d2010-06-08 16:52:24183ThreadPlanCallFunction::GetDescription (Stream *s, lldb::DescriptionLevel level)
184{
185 if (level == lldb::eDescriptionLevelBrief)
186 {
187 s->Printf("Function call thread plan");
188 }
189 else
190 {
191 if (m_args)
Greg Claytonf5e56de2010-09-14 23:36:40192 s->Printf("Thread plan to call 0x%llx with parsed arguments", m_function_addr.GetLoadAddress(&m_process.GetTarget()), m_arg_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24193 else
Greg Claytonf5e56de2010-09-14 23:36:40194 s->Printf("Thread plan to call 0x%llx void * argument at: 0x%llx", m_function_addr.GetLoadAddress(&m_process.GetTarget()), m_arg_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24195 }
196}
197
198bool
199ThreadPlanCallFunction::ValidatePlan (Stream *error)
200{
201 if (!m_valid)
202 return false;
203
204 return true;
205}
206
207bool
208ThreadPlanCallFunction::PlanExplainsStop ()
Sean Callanan6db73ca2010-11-03 01:37:52209{
Jim Ingham40d871f2010-10-26 00:27:45210 // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
211 // we answer yes.
212 if(m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop())
213 return true;
Sean Callanan3e6fedc2010-10-19 22:24:06214
Sean Callananc98aca62010-11-03 19:36:28215 // Check if the breakpoint is one of ours.
216
217 if (BreakpointsExplainStop())
218 return true;
219
Jim Ingham40d871f2010-10-26 00:27:45220 // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
221 if (!OkayToDiscard())
222 return false;
223
224 // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on.
225 // If it is not an internal breakpoint, consult OkayToDiscard.
226 lldb::StopInfoSP stop_info_sp = GetPrivateStopReason();
Sean Callanan6db73ca2010-11-03 01:37:52227
Jim Ingham40d871f2010-10-26 00:27:45228 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
229 {
230 uint64_t break_site_id = stop_info_sp->GetValue();
231 lldb::BreakpointSiteSP bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(break_site_id);
232 if (bp_site_sp)
233 {
234 uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
235 bool is_internal = true;
236 for (uint32_t i = 0; i < num_owners; i++)
237 {
Sean Callanan6db73ca2010-11-03 01:37:52238 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
Sean Callanan6db73ca2010-11-03 01:37:52239
240 if (!bp.IsInternal())
Jim Ingham40d871f2010-10-26 00:27:45241 {
242 is_internal = false;
243 break;
244 }
245 }
246 if (is_internal)
247 return false;
248 }
249
250 return OkayToDiscard();
251 }
252 else
253 {
254 // If the subplan is running, any crashes are attributable to us.
Jim Ingham2c364392011-01-26 19:13:09255 // If we want to discard the plan, then we say we explain the stop
256 // but if we are going to be discarded, let whoever is above us
257 // explain the stop.
258 return ((m_subplan_sp.get() != NULL) && !OkayToDiscard());
Jim Ingham40d871f2010-10-26 00:27:45259 }
Chris Lattner30fdc8d2010-06-08 16:52:24260}
261
262bool
263ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
264{
265 if (PlanExplainsStop())
266 {
Jim Ingham9da36832011-01-22 01:27:23267 ReportRegisterState ("Function completed. Register state was:");
Sean Callanan5300d372010-07-31 01:32:05268
Sean Callanan10af7c42010-11-04 01:51:38269 DoTakedown();
Sean Callanan6db73ca2010-11-03 01:37:52270
Chris Lattner30fdc8d2010-06-08 16:52:24271 return true;
272 }
273 else
274 {
275 return false;
276 }
277}
278
279bool
280ThreadPlanCallFunction::StopOthers ()
281{
282 return m_stop_other_threads;
283}
284
285void
286ThreadPlanCallFunction::SetStopOthers (bool new_value)
287{
288 if (m_subplan_sp)
289 {
290 ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
291 address_plan->SetStopOthers(new_value);
292 }
293 m_stop_other_threads = new_value;
294}
295
296StateType
Jim Ingham06e827c2010-11-11 19:26:09297ThreadPlanCallFunction::GetPlanRunState ()
Chris Lattner30fdc8d2010-06-08 16:52:24298{
299 return eStateRunning;
300}
301
302void
303ThreadPlanCallFunction::DidPush ()
304{
Sean Callananbe3a1b12010-10-26 00:31:56305//#define SINGLE_STEP_EXPRESSIONS
306
307#ifndef SINGLE_STEP_EXPRESSIONS
Chris Lattner30fdc8d2010-06-08 16:52:24308 m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
309
310 m_thread.QueueThreadPlan(m_subplan_sp, false);
Jim Ingham77787032011-01-20 02:03:18311 m_subplan_sp->SetPrivate (true);
Sean Callananbe3a1b12010-10-26 00:31:56312#endif
Chris Lattner30fdc8d2010-06-08 16:52:24313}
314
315bool
316ThreadPlanCallFunction::WillStop ()
317{
318 return true;
319}
320
321bool
322ThreadPlanCallFunction::MischiefManaged ()
323{
324 if (IsPlanComplete())
325 {
Greg Clayton2d4edfb2010-11-06 01:53:30326 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner30fdc8d2010-06-08 16:52:24327
328 if (log)
329 log->Printf("Completed call function plan.");
330
331 ThreadPlan::MischiefManaged ();
332 return true;
333 }
334 else
335 {
336 return false;
337 }
338}
Sean Callanan6db73ca2010-11-03 01:37:52339
340void
341ThreadPlanCallFunction::SetBreakpoints ()
342{
Sean Callananf2115102010-11-03 22:19:38343 m_cxx_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeC_plus_plus);
344 m_objc_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeObjC);
Sean Callanan6db73ca2010-11-03 01:37:52345
Sean Callananf2115102010-11-03 22:19:38346 if (m_cxx_language_runtime)
347 m_cxx_language_runtime->SetExceptionBreakpoints();
348 if (m_objc_language_runtime)
349 m_objc_language_runtime->SetExceptionBreakpoints();
Sean Callanan6db73ca2010-11-03 01:37:52350}
351
352void
353ThreadPlanCallFunction::ClearBreakpoints ()
354{
Sean Callananf2115102010-11-03 22:19:38355 if (m_cxx_language_runtime)
356 m_cxx_language_runtime->ClearExceptionBreakpoints();
357 if (m_objc_language_runtime)
358 m_objc_language_runtime->ClearExceptionBreakpoints();
Sean Callanan6db73ca2010-11-03 01:37:52359}
Sean Callananc98aca62010-11-03 19:36:28360
361bool
362ThreadPlanCallFunction::BreakpointsExplainStop()
363{
Sean Callananc98aca62010-11-03 19:36:28364 lldb::StopInfoSP stop_info_sp = GetPrivateStopReason();
365
Sean Callananf2115102010-11-03 22:19:38366 if (m_cxx_language_runtime &&
367 m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
368 return true;
Sean Callananc98aca62010-11-03 19:36:28369
Sean Callananf2115102010-11-03 22:19:38370 if (m_objc_language_runtime &&
371 m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
372 return true;
Sean Callananc98aca62010-11-03 19:36:28373
374 return false;
375}