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