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                                                 addr_t arg,
41                                                 bool stop_other_threads,
42                                                 bool discard_on_error,
43                                                 addr_t *this_arg,
44                                                 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_function_addr (function),
49     m_function_sp (NULL),
50     m_takedown_done (false),
51     m_stop_address (LLDB_INVALID_ADDRESS)
52 {
53     SetOkayToDiscard (discard_on_error);
54 
55     Process& process = thread.GetProcess();
56     Target& target = process.GetTarget();
57     const ABI *abi = process.GetABI().get();
58 
59     if (!abi)
60         return;
61 
62     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
63 
64     SetBreakpoints();
65 
66     m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
67 
68     Module *exe_module = target.GetExecutableModulePointer();
69 
70     if (exe_module == NULL)
71     {
72         if (log)
73             log->Printf ("Can't execute code without an executable module.");
74         return;
75     }
76     else
77     {
78         ObjectFile *objectFile = exe_module->GetObjectFile();
79         if (!objectFile)
80         {
81             if (log)
82                 log->Printf ("Could not find object file for module \"%s\".",
83                              exe_module->GetFileSpec().GetFilename().AsCString());
84             return;
85         }
86         m_start_addr = objectFile->GetEntryPointAddress();
87         if (!m_start_addr.IsValid())
88         {
89             if (log)
90                 log->Printf ("Could not find entry point address for executable module \"%s\".",
91                              exe_module->GetFileSpec().GetFilename().AsCString());
92             return;
93         }
94     }
95 
96     addr_t start_load_addr = m_start_addr.GetLoadAddress(&target);
97 
98     // Checkpoint the thread state so we can restore it later.
99     if (log && log->GetVerbose())
100         ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
101 
102     if (!thread.CheckpointThreadState (m_stored_thread_state))
103     {
104         if (log)
105             log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
106         return;
107     }
108     // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
109     thread.SetStopInfoToNothing();
110 
111     addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target);
112 
113     if (this_arg && cmd_arg)
114     {
115         if (!abi->PrepareTrivialCall (thread,
116                                       m_function_sp,
117                                       FunctionLoadAddr,
118                                       start_load_addr,
119                                       this_arg,
120                                       cmd_arg,
121                                       &arg))
122             return;
123     }
124     else if (this_arg)
125     {
126         if (!abi->PrepareTrivialCall (thread,
127                                       m_function_sp,
128                                       FunctionLoadAddr,
129                                       start_load_addr,
130                                       this_arg,
131                                       &arg))
132             return;
133     }
134     else
135     {
136         if (!abi->PrepareTrivialCall (thread,
137                                       m_function_sp,
138                                       FunctionLoadAddr,
139                                       start_load_addr,
140                                       &arg))
141             return;
142     }
143 
144     ReportRegisterState ("Function call was set up.  Register state was:");
145 
146     m_valid = true;
147 }
148 
149 
150 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
151                                                 Address &function,
152                                                 bool stop_other_threads,
153                                                 bool discard_on_error,
154                                                 addr_t *arg1_ptr,
155                                                 addr_t *arg2_ptr,
156                                                 addr_t *arg3_ptr,
157                                                 addr_t *arg4_ptr,
158                                                 addr_t *arg5_ptr,
159                                                 addr_t *arg6_ptr) :
160     ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
161     m_valid (false),
162     m_stop_other_threads (stop_other_threads),
163     m_function_addr (function),
164     m_function_sp(NULL),
165     m_takedown_done (false)
166 {
167     SetOkayToDiscard (discard_on_error);
168 
169     Process& process = thread.GetProcess();
170     Target& target = process.GetTarget();
171     const ABI *abi = process.GetABI().get();
172 
173     if (!abi)
174         return;
175 
176     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
177 
178     SetBreakpoints();
179 
180     m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
181 
182     Module *exe_module = target.GetExecutableModulePointer();
183 
184     if (exe_module == NULL)
185     {
186         if (log)
187             log->Printf ("Can't execute code without an executable module.");
188         return;
189     }
190     else
191     {
192         ObjectFile *objectFile = exe_module->GetObjectFile();
193         if (!objectFile)
194         {
195             if (log)
196                 log->Printf ("Could not find object file for module \"%s\".",
197                              exe_module->GetFileSpec().GetFilename().AsCString());
198             return;
199         }
200         m_start_addr = objectFile->GetEntryPointAddress();
201         if (!m_start_addr.IsValid())
202         {
203             if (log)
204                 log->Printf ("Could not find entry point address for executable module \"%s\".",
205                              exe_module->GetFileSpec().GetFilename().AsCString());
206             return;
207         }
208     }
209 
210     addr_t start_load_addr = m_start_addr.GetLoadAddress(&target);
211 
212     // Checkpoint the thread state so we can restore it later.
213     if (log && log->GetVerbose())
214         ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
215 
216     if (!thread.CheckpointThreadState (m_stored_thread_state))
217     {
218         if (log)
219             log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
220         return;
221     }
222     // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
223     thread.SetStopInfoToNothing();
224 
225     addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target);
226 
227     if (!abi->PrepareTrivialCall (thread,
228                                   m_function_sp,
229                                   FunctionLoadAddr,
230                                   start_load_addr,
231                                   arg1_ptr,
232                                   arg2_ptr,
233                                   arg3_ptr,
234                                   arg4_ptr,
235                                   arg5_ptr,
236                                   arg6_ptr))
237     {
238             return;
239     }
240 
241     ReportRegisterState ("Function call was set up.  Register state was:");
242 
243     m_valid = true;
244 }
245 
246 ThreadPlanCallFunction::~ThreadPlanCallFunction ()
247 {
248 }
249 
250 void
251 ThreadPlanCallFunction::ReportRegisterState (const char *message)
252 {
253     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE));
254     if (log)
255     {
256         StreamString strm;
257         RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
258 
259         log->PutCString(message);
260 
261         RegisterValue reg_value;
262 
263         for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
264              reg_idx < num_registers;
265              ++reg_idx)
266         {
267             const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
268             if (reg_ctx->ReadRegister(reg_info, reg_value))
269             {
270                 reg_value.Dump(&strm, reg_info, true, false, eFormatDefault);
271                 strm.EOL();
272             }
273         }
274         log->PutCString(strm.GetData());
275     }
276 }
277 
278 void
279 ThreadPlanCallFunction::DoTakedown ()
280 {
281     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
282     if (!m_takedown_done)
283     {
284         // TODO: how do we tell if all went well?
285         if (m_return_value_sp)
286         {
287             const ABI *abi = m_thread.GetProcess().GetABI().get();
288             if (abi)
289                 abi->GetReturnValue(m_thread, *m_return_value_sp);
290         }
291         if (log)
292             log->Printf ("DoTakedown called for thread 0x%4.4llx, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete());
293         m_takedown_done = true;
294         m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
295         m_real_stop_info_sp = GetPrivateStopReason();
296         m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state);
297         SetPlanComplete();
298         ClearBreakpoints();
299         if (log && log->GetVerbose())
300             ReportRegisterState ("Restoring thread state after function call.  Restored register state:");
301 
302     }
303     else
304     {
305         if (log)
306             log->Printf ("DoTakedown called as no-op for thread 0x%4.4llx, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete());
307     }
308 }
309 
310 void
311 ThreadPlanCallFunction::WillPop ()
312 {
313     DoTakedown();
314 }
315 
316 void
317 ThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level)
318 {
319     if (level == eDescriptionLevelBrief)
320     {
321         s->Printf("Function call thread plan");
322     }
323     else
324     {
325         s->Printf("Thread plan to call 0x%llx", m_function_addr.GetLoadAddress(&m_thread.GetProcess().GetTarget()));
326     }
327 }
328 
329 bool
330 ThreadPlanCallFunction::ValidatePlan (Stream *error)
331 {
332     if (!m_valid)
333         return false;
334 
335     return true;
336 }
337 
338 bool
339 ThreadPlanCallFunction::PlanExplainsStop ()
340 {
341     m_real_stop_info_sp = GetPrivateStopReason();
342 
343     // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
344     // we answer yes.
345     if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop())
346         return true;
347 
348     // Check if the breakpoint is one of ours.
349 
350     if (BreakpointsExplainStop())
351         return true;
352 
353     // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
354     if (!OkayToDiscard())
355         return false;
356 
357     // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on.
358     // If it is not an internal breakpoint, consult OkayToDiscard.
359 
360     if (m_real_stop_info_sp && m_real_stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
361     {
362         uint64_t break_site_id = m_real_stop_info_sp->GetValue();
363         BreakpointSiteSP bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(break_site_id);
364         if (bp_site_sp)
365         {
366             uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
367             bool is_internal = true;
368             for (uint32_t i = 0; i < num_owners; i++)
369             {
370                 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
371 
372                 if (!bp.IsInternal())
373                 {
374                     is_internal = false;
375                     break;
376                 }
377             }
378             if (is_internal)
379                 return false;
380         }
381 
382         return OkayToDiscard();
383     }
384     else
385     {
386         // If the subplan is running, any crashes are attributable to us.
387         // If we want to discard the plan, then we say we explain the stop
388         // but if we are going to be discarded, let whoever is above us
389         // explain the stop.
390         return ((m_subplan_sp.get() != NULL) && !OkayToDiscard());
391     }
392 }
393 
394 bool
395 ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
396 {
397     if (PlanExplainsStop())
398     {
399         ReportRegisterState ("Function completed.  Register state was:");
400 
401         DoTakedown();
402 
403         return true;
404     }
405     else
406     {
407         return false;
408     }
409 }
410 
411 bool
412 ThreadPlanCallFunction::StopOthers ()
413 {
414     return m_stop_other_threads;
415 }
416 
417 void
418 ThreadPlanCallFunction::SetStopOthers (bool new_value)
419 {
420     if (m_subplan_sp)
421     {
422         ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
423         address_plan->SetStopOthers(new_value);
424     }
425     m_stop_other_threads = new_value;
426 }
427 
428 StateType
429 ThreadPlanCallFunction::GetPlanRunState ()
430 {
431     return eStateRunning;
432 }
433 
434 void
435 ThreadPlanCallFunction::DidPush ()
436 {
437 //#define SINGLE_STEP_EXPRESSIONS
438 
439 #ifndef SINGLE_STEP_EXPRESSIONS
440     m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
441 
442     m_thread.QueueThreadPlan(m_subplan_sp, false);
443     m_subplan_sp->SetPrivate (true);
444 #endif
445 }
446 
447 bool
448 ThreadPlanCallFunction::WillStop ()
449 {
450     return true;
451 }
452 
453 bool
454 ThreadPlanCallFunction::MischiefManaged ()
455 {
456     if (IsPlanComplete())
457     {
458         LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
459 
460         if (log)
461             log->Printf("Completed call function plan.");
462 
463         ThreadPlan::MischiefManaged ();
464         return true;
465     }
466     else
467     {
468         return false;
469     }
470 }
471 
472 void
473 ThreadPlanCallFunction::SetBreakpoints ()
474 {
475     m_cxx_language_runtime = m_thread.GetProcess().GetLanguageRuntime(eLanguageTypeC_plus_plus);
476     m_objc_language_runtime = m_thread.GetProcess().GetLanguageRuntime(eLanguageTypeObjC);
477 
478     if (m_cxx_language_runtime)
479         m_cxx_language_runtime->SetExceptionBreakpoints();
480     if (m_objc_language_runtime)
481         m_objc_language_runtime->SetExceptionBreakpoints();
482 }
483 
484 void
485 ThreadPlanCallFunction::ClearBreakpoints ()
486 {
487     if (m_cxx_language_runtime)
488         m_cxx_language_runtime->ClearExceptionBreakpoints();
489     if (m_objc_language_runtime)
490         m_objc_language_runtime->ClearExceptionBreakpoints();
491 }
492 
493 bool
494 ThreadPlanCallFunction::BreakpointsExplainStop()
495 {
496     StopInfoSP stop_info_sp = GetPrivateStopReason();
497 
498     if (m_cxx_language_runtime &&
499         m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
500         return true;
501 
502     if (m_objc_language_runtime &&
503         m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
504         return true;
505 
506     return false;
507 }
508