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_sp (NULL),
49     m_process (thread.GetProcess()),
50     m_thread (thread),
51     m_takedown_done (false)
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                              executableModuleSP->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                              executableModuleSP->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     m_function_addr = function;
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_sp(NULL),
165     m_process (thread.GetProcess()),
166     m_thread (thread),
167     m_takedown_done (false)
168 {
169     SetOkayToDiscard (discard_on_error);
170 
171     Process& process = thread.GetProcess();
172     Target& target = process.GetTarget();
173     const ABI *abi = process.GetABI().get();
174 
175     if (!abi)
176         return;
177 
178     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
179 
180     SetBreakpoints();
181 
182     m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
183 
184     Module *exe_module = target.GetExecutableModulePointer();
185 
186     if (exe_module == NULL)
187     {
188         if (log)
189             log->Printf ("Can't execute code without an executable module.");
190         return;
191     }
192     else
193     {
194         ObjectFile *objectFile = exe_module->GetObjectFile();
195         if (!objectFile)
196         {
197             if (log)
198                 log->Printf ("Could not find object file for module \"%s\".",
199                              executableModuleSP->GetFileSpec().GetFilename().AsCString());
200             return;
201         }
202         m_start_addr = objectFile->GetEntryPointAddress();
203         if (!m_start_addr.IsValid())
204         {
205             if (log)
206                 log->Printf ("Could not find entry point address for executable module \"%s\".",
207                              exe_module->GetFileSpec().GetFilename().AsCString());
208             return;
209         }
210     }
211 
212     addr_t start_load_addr = m_start_addr.GetLoadAddress(&target);
213 
214     // Checkpoint the thread state so we can restore it later.
215     if (log && log->GetVerbose())
216         ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
217 
218     if (!thread.CheckpointThreadState (m_stored_thread_state))
219     {
220         if (log)
221             log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
222         return;
223     }
224     // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
225     thread.SetStopInfoToNothing();
226 
227     m_function_addr = function;
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