1 //===-- 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
15 #include "llvm/Support/MachO.h"
16 // Project includes
17 #include "lldb/lldb-private-log.h"
18 #include "lldb/Breakpoint/Breakpoint.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Core/Address.h"
21 #include "lldb/Core/Log.h"
22 #include "lldb/Core/Stream.h"
23 #include "lldb/Target/LanguageRuntime.h"
24 #include "lldb/Target/Process.h"
25 #include "lldb/Target/RegisterContext.h"
26 #include "lldb/Target/StopInfo.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadPlanRunToAddress.h"
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 //----------------------------------------------------------------------
35 // ThreadPlanCallFunction: Plan to call a single function
36 //----------------------------------------------------------------------
37 
38 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
39                                                 Address &function,
40                                                 lldb::addr_t arg,
41                                                 bool stop_other_threads,
42                                                 bool discard_on_error,
43                                                 lldb::addr_t *this_arg,
44                                                 lldb::addr_t *cmd_arg) :
45     ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
46     m_valid (false),
47     m_stop_other_threads (stop_other_threads),
48     m_arg_addr (arg),
49     m_args (NULL),
50     m_process (thread.GetProcess()),
51     m_thread (thread),
52     m_takedown_done (false)
53 {
54     SetOkayToDiscard (discard_on_error);
55 
56     Process& process = thread.GetProcess();
57     Target& target = process.GetTarget();
58     const ABI *abi = process.GetABI();
59 
60     if (!abi)
61         return;
62 
63     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
64 
65     SetBreakpoints();
66 
67     lldb::addr_t spBelowRedZone = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
68 
69     ModuleSP executableModuleSP (target.GetExecutableModule());
70 
71     if (!executableModuleSP)
72     {
73         log->Printf ("Can't execute code without an executable module.");
74         return;
75     }
76     else
77     {
78         ObjectFile *objectFile = executableModuleSP->GetObjectFile();
79         if (!objectFile)
80         {
81             log->Printf ("Could not find object file for module \"%s\".",
82                          executableModuleSP->GetFileSpec().GetFilename().AsCString());
83             return;
84         }
85         m_start_addr = objectFile->GetEntryPointAddress();
86         if (!m_start_addr.IsValid())
87         {
88             log->Printf ("Could not find entry point address for executable module \"%s\".",
89                          executableModuleSP->GetFileSpec().GetFilename().AsCString());
90             return;
91         }
92     }
93 
94     lldb::addr_t StartLoadAddr = m_start_addr.GetLoadAddress(&target);
95 
96     // Checkpoint the thread state so we can restore it later.
97     if (log && log->GetVerbose())
98         ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
99 
100     if (!thread.CheckpointThreadState (m_stored_thread_state))
101     {
102         if (log)
103             log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
104         return;
105     }
106     // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
107     thread.SetStopInfoToNothing();
108 
109     m_function_addr = function;
110     lldb::addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target);
111 
112     if (!abi->PrepareTrivialCall(thread,
113                                  spBelowRedZone,
114                                  FunctionLoadAddr,
115                                  StartLoadAddr,
116                                  m_arg_addr,
117                                  this_arg,
118                                  cmd_arg))
119         return;
120 
121     ReportRegisterState ("Function call was set up.  Register state was:");
122 
123     m_valid = true;
124 }
125 
126 ThreadPlanCallFunction::~ThreadPlanCallFunction ()
127 {
128 }
129 
130 void
131 ThreadPlanCallFunction::ReportRegisterState (const char *message)
132 {
133     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
134     if (log)
135     {
136         RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
137 
138         log->PutCString(message);
139 
140         for (uint32_t register_index = 0, num_registers = reg_ctx->GetRegisterCount();
141              register_index < num_registers;
142              ++register_index)
143         {
144             const char *register_name = reg_ctx->GetRegisterName(register_index);
145             uint64_t register_value = reg_ctx->ReadRegisterAsUnsigned(register_index, LLDB_INVALID_ADDRESS);
146 
147             log->Printf("  %s = 0x%llx", register_name, register_value);
148         }
149     }
150 }
151 
152 void
153 ThreadPlanCallFunction::DoTakedown ()
154 {
155     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
156     if (!m_takedown_done)
157     {
158         if (log)
159             log->Printf ("DoTakedown called for thread 0x%4.4x, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete());
160         m_takedown_done = true;
161         m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state);
162         SetPlanComplete();
163         ClearBreakpoints();
164         if (log && log->GetVerbose())
165             ReportRegisterState ("Restoring thread state after function call.  Restored register state:");
166 
167     }
168     else
169     {
170         if (log)
171             log->Printf ("DoTakedown called as no-op for thread 0x%4.4x, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete());
172     }
173 }
174 
175 void
176 ThreadPlanCallFunction::WillPop ()
177 {
178     DoTakedown();
179 }
180 
181 void
182 ThreadPlanCallFunction::GetDescription (Stream *s, lldb::DescriptionLevel level)
183 {
184     if (level == lldb::eDescriptionLevelBrief)
185     {
186         s->Printf("Function call thread plan");
187     }
188     else
189     {
190         if (m_args)
191             s->Printf("Thread plan to call 0x%llx with parsed arguments", m_function_addr.GetLoadAddress(&m_process.GetTarget()), m_arg_addr);
192         else
193             s->Printf("Thread plan to call 0x%llx void * argument at: 0x%llx", m_function_addr.GetLoadAddress(&m_process.GetTarget()), m_arg_addr);
194     }
195 }
196 
197 bool
198 ThreadPlanCallFunction::ValidatePlan (Stream *error)
199 {
200     if (!m_valid)
201         return false;
202 
203     return true;
204 }
205 
206 bool
207 ThreadPlanCallFunction::PlanExplainsStop ()
208 {
209     // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
210     // we answer yes.
211     if(m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop())
212         return true;
213 
214     // Check if the breakpoint is one of ours.
215 
216     if (BreakpointsExplainStop())
217         return true;
218 
219     // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
220     if (!OkayToDiscard())
221         return false;
222 
223     // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on.
224     // If it is not an internal breakpoint, consult OkayToDiscard.
225     lldb::StopInfoSP stop_info_sp = GetPrivateStopReason();
226 
227     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
228     {
229         uint64_t break_site_id = stop_info_sp->GetValue();
230         lldb::BreakpointSiteSP bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(break_site_id);
231         if (bp_site_sp)
232         {
233             uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
234             bool is_internal = true;
235             for (uint32_t i = 0; i < num_owners; i++)
236             {
237                 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
238 
239                 if (!bp.IsInternal())
240                 {
241                     is_internal = false;
242                     break;
243                 }
244             }
245             if (is_internal)
246                 return false;
247         }
248 
249         return OkayToDiscard();
250     }
251     else
252     {
253         // If the subplan is running, any crashes are attributable to us.
254         // If we want to discard the plan, then we say we explain the stop
255         // but if we are going to be discarded, let whoever is above us
256         // explain the stop.
257         return ((m_subplan_sp.get() != NULL) && !OkayToDiscard());
258     }
259 }
260 
261 bool
262 ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
263 {
264     if (PlanExplainsStop())
265     {
266         ReportRegisterState ("Function completed.  Register state was:");
267 
268         DoTakedown();
269 
270         return true;
271     }
272     else
273     {
274         return false;
275     }
276 }
277 
278 bool
279 ThreadPlanCallFunction::StopOthers ()
280 {
281     return m_stop_other_threads;
282 }
283 
284 void
285 ThreadPlanCallFunction::SetStopOthers (bool new_value)
286 {
287     if (m_subplan_sp)
288     {
289         ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
290         address_plan->SetStopOthers(new_value);
291     }
292     m_stop_other_threads = new_value;
293 }
294 
295 StateType
296 ThreadPlanCallFunction::GetPlanRunState ()
297 {
298     return eStateRunning;
299 }
300 
301 void
302 ThreadPlanCallFunction::DidPush ()
303 {
304 //#define SINGLE_STEP_EXPRESSIONS
305 
306 #ifndef SINGLE_STEP_EXPRESSIONS
307     m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
308 
309     m_thread.QueueThreadPlan(m_subplan_sp, false);
310     m_subplan_sp->SetPrivate (true);
311 #endif
312 }
313 
314 bool
315 ThreadPlanCallFunction::WillStop ()
316 {
317     return true;
318 }
319 
320 bool
321 ThreadPlanCallFunction::MischiefManaged ()
322 {
323     if (IsPlanComplete())
324     {
325         LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
326 
327         if (log)
328             log->Printf("Completed call function plan.");
329 
330         ThreadPlan::MischiefManaged ();
331         return true;
332     }
333     else
334     {
335         return false;
336     }
337 }
338 
339 void
340 ThreadPlanCallFunction::SetBreakpoints ()
341 {
342     m_cxx_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeC_plus_plus);
343     m_objc_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeObjC);
344 
345     if (m_cxx_language_runtime)
346         m_cxx_language_runtime->SetExceptionBreakpoints();
347     if (m_objc_language_runtime)
348         m_objc_language_runtime->SetExceptionBreakpoints();
349 }
350 
351 void
352 ThreadPlanCallFunction::ClearBreakpoints ()
353 {
354     if (m_cxx_language_runtime)
355         m_cxx_language_runtime->ClearExceptionBreakpoints();
356     if (m_objc_language_runtime)
357         m_objc_language_runtime->ClearExceptionBreakpoints();
358 }
359 
360 bool
361 ThreadPlanCallFunction::BreakpointsExplainStop()
362 {
363     lldb::StopInfoSP stop_info_sp = GetPrivateStopReason();
364 
365     if (m_cxx_language_runtime &&
366         m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
367         return true;
368 
369     if (m_objc_language_runtime &&
370         m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
371         return true;
372 
373     return false;
374 }
375