1 //===-- ThreadPlanCallFunction.cpp ----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Target/ThreadPlanCallFunction.h"
10 #include "lldb/Breakpoint/Breakpoint.h"
11 #include "lldb/Breakpoint/BreakpointLocation.h"
12 #include "lldb/Core/Address.h"
13 #include "lldb/Core/DumpRegisterValue.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Symbol/ObjectFile.h"
16 #include "lldb/Target/ABI.h"
17 #include "lldb/Target/LanguageRuntime.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/RegisterContext.h"
20 #include "lldb/Target/StopInfo.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/Thread.h"
23 #include "lldb/Target/ThreadPlanRunToAddress.h"
24 #include "lldb/Utility/Log.h"
25 #include "lldb/Utility/Stream.h"
26 
27 #include <memory>
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 // ThreadPlanCallFunction: Plan to call a single function
33 bool ThreadPlanCallFunction::ConstructorSetup(
34     Thread &thread, ABI *&abi, lldb::addr_t &start_load_addr,
35     lldb::addr_t &function_load_addr) {
36   SetIsMasterPlan(true);
37   SetOkayToDiscard(false);
38   SetPrivate(true);
39 
40   ProcessSP process_sp(thread.GetProcess());
41   if (!process_sp)
42     return false;
43 
44   abi = process_sp->GetABI().get();
45 
46   if (!abi)
47     return false;
48 
49   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
50 
51   SetBreakpoints();
52 
53   m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
54   // If we can't read memory at the point of the process where we are planning
55   // to put our function, we're not going to get any further...
56   Status error;
57   process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
58   if (!error.Success()) {
59     m_constructor_errors.Printf(
60         "Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".",
61         m_function_sp);
62     LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
63               m_constructor_errors.GetData());
64     return false;
65   }
66 
67   llvm::Expected<Address> start_address = GetTarget().GetEntryPointAddress();
68   if (!start_address) {
69     m_constructor_errors.Printf(
70         "%s", llvm::toString(start_address.takeError()).c_str());
71     LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
72               m_constructor_errors.GetData());
73     return false;
74   }
75 
76   m_start_addr = *start_address;
77   start_load_addr = m_start_addr.GetLoadAddress(&GetTarget());
78 
79   // Checkpoint the thread state so we can restore it later.
80   if (log && log->GetVerbose())
81     ReportRegisterState("About to checkpoint thread before function call.  "
82                         "Original register state was:");
83 
84   if (!thread.CheckpointThreadState(m_stored_thread_state)) {
85     m_constructor_errors.Printf("Setting up ThreadPlanCallFunction, failed to "
86                                 "checkpoint thread state.");
87     LLDB_LOGF(log, "ThreadPlanCallFunction(%p): %s.", static_cast<void *>(this),
88               m_constructor_errors.GetData());
89     return false;
90   }
91   function_load_addr = m_function_addr.GetLoadAddress(&GetTarget());
92 
93   return true;
94 }
95 
96 ThreadPlanCallFunction::ThreadPlanCallFunction(
97     Thread &thread, const Address &function, const CompilerType &return_type,
98     llvm::ArrayRef<addr_t> args, const EvaluateExpressionOptions &options)
99     : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
100                  eVoteNoOpinion, eVoteNoOpinion),
101       m_valid(false), m_stop_other_threads(options.GetStopOthers()),
102       m_unwind_on_error(options.DoesUnwindOnError()),
103       m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
104       m_debug_execution(options.GetDebug()),
105       m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
106       m_function_sp(0), m_takedown_done(false),
107       m_should_clear_objc_exception_bp(false),
108       m_should_clear_cxx_exception_bp(false),
109       m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(return_type) {
110   lldb::addr_t start_load_addr = LLDB_INVALID_ADDRESS;
111   lldb::addr_t function_load_addr = LLDB_INVALID_ADDRESS;
112   ABI *abi = nullptr;
113 
114   if (!ConstructorSetup(thread, abi, start_load_addr, function_load_addr))
115     return;
116 
117   if (!abi->PrepareTrivialCall(thread, m_function_sp, function_load_addr,
118                                start_load_addr, args))
119     return;
120 
121   ReportRegisterState("Function call was set up.  Register state was:");
122 
123   m_valid = true;
124 }
125 
126 ThreadPlanCallFunction::ThreadPlanCallFunction(
127     Thread &thread, const Address &function,
128     const EvaluateExpressionOptions &options)
129     : ThreadPlan(ThreadPlan::eKindCallFunction, "Call function plan", thread,
130                  eVoteNoOpinion, eVoteNoOpinion),
131       m_valid(false), m_stop_other_threads(options.GetStopOthers()),
132       m_unwind_on_error(options.DoesUnwindOnError()),
133       m_ignore_breakpoints(options.DoesIgnoreBreakpoints()),
134       m_debug_execution(options.GetDebug()),
135       m_trap_exceptions(options.GetTrapExceptions()), m_function_addr(function),
136       m_function_sp(0), m_takedown_done(false),
137       m_should_clear_objc_exception_bp(false),
138       m_should_clear_cxx_exception_bp(false),
139       m_stop_address(LLDB_INVALID_ADDRESS), m_return_type(CompilerType()) {}
140 
141 ThreadPlanCallFunction::~ThreadPlanCallFunction() {
142   DoTakedown(PlanSucceeded());
143 }
144 
145 void ThreadPlanCallFunction::ReportRegisterState(const char *message) {
146   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
147   if (log && log->GetVerbose()) {
148     StreamString strm;
149     RegisterContext *reg_ctx = GetThread().GetRegisterContext().get();
150 
151     log->PutCString(message);
152 
153     RegisterValue reg_value;
154 
155     for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
156          reg_idx < num_registers; ++reg_idx) {
157       const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx);
158       if (reg_ctx->ReadRegister(reg_info, reg_value)) {
159         DumpRegisterValue(reg_value, &strm, reg_info, true, false,
160                           eFormatDefault);
161         strm.EOL();
162       }
163     }
164     log->PutString(strm.GetString());
165   }
166 }
167 
168 void ThreadPlanCallFunction::DoTakedown(bool success) {
169   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
170 
171   if (!m_valid) {
172     // Don't call DoTakedown if we were never valid to begin with.
173     LLDB_LOGF(log,
174               "ThreadPlanCallFunction(%p): Log called on "
175               "ThreadPlanCallFunction that was never valid.",
176               static_cast<void *>(this));
177     return;
178   }
179 
180   if (!m_takedown_done) {
181     Thread &thread = GetThread();
182     if (success) {
183       SetReturnValue();
184     }
185     LLDB_LOGF(log,
186               "ThreadPlanCallFunction(%p): DoTakedown called for thread "
187               "0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
188               static_cast<void *>(this), m_tid, m_valid, IsPlanComplete());
189     m_takedown_done = true;
190     m_stop_address =
191         thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
192     m_real_stop_info_sp = GetPrivateStopInfo();
193     if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state)) {
194       LLDB_LOGF(log,
195                 "ThreadPlanCallFunction(%p): DoTakedown failed to restore "
196                 "register state",
197                 static_cast<void *>(this));
198     }
199     SetPlanComplete(success);
200     ClearBreakpoints();
201     if (log && log->GetVerbose())
202       ReportRegisterState("Restoring thread state after function call.  "
203                           "Restored register state:");
204   } else {
205     LLDB_LOGF(log,
206               "ThreadPlanCallFunction(%p): DoTakedown called as no-op for "
207               "thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n",
208               static_cast<void *>(this), m_tid, m_valid, IsPlanComplete());
209   }
210 }
211 
212 void ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); }
213 
214 void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) {
215   if (level == eDescriptionLevelBrief) {
216     s->Printf("Function call thread plan");
217   } else {
218     s->Printf("Thread plan to call 0x%" PRIx64,
219               m_function_addr.GetLoadAddress(&GetTarget()));
220   }
221 }
222 
223 bool ThreadPlanCallFunction::ValidatePlan(Stream *error) {
224   if (!m_valid) {
225     if (error) {
226       if (m_constructor_errors.GetSize() > 0)
227         error->PutCString(m_constructor_errors.GetString());
228       else
229         error->PutCString("Unknown error");
230     }
231     return false;
232   }
233 
234   return true;
235 }
236 
237 Vote ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) {
238   if (m_takedown_done || IsPlanComplete())
239     return eVoteYes;
240   else
241     return ThreadPlan::ShouldReportStop(event_ptr);
242 }
243 
244 bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
245   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP |
246                                                   LIBLLDB_LOG_PROCESS));
247   m_real_stop_info_sp = GetPrivateStopInfo();
248 
249   // If our subplan knows why we stopped, even if it's done (which would
250   // forward the question to us) we answer yes.
251   if (m_subplan_sp && m_subplan_sp->PlanExplainsStop(event_ptr)) {
252     SetPlanComplete();
253     return true;
254   }
255 
256   // Check if the breakpoint is one of ours.
257 
258   StopReason stop_reason;
259   if (!m_real_stop_info_sp)
260     stop_reason = eStopReasonNone;
261   else
262     stop_reason = m_real_stop_info_sp->GetStopReason();
263   LLDB_LOG(log,
264            "ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - {0}.",
265            Thread::StopReasonAsString(stop_reason));
266 
267   if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
268     return true;
269 
270   // One more quirk here.  If this event was from Halt interrupting the target,
271   // then we should not consider ourselves complete.  Return true to
272   // acknowledge the stop.
273   if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
274     LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: The event is an "
275                    "Interrupt, returning true.");
276     return true;
277   }
278   // We control breakpoints separately from other "stop reasons."  So first,
279   // check the case where we stopped for an internal breakpoint, in that case,
280   // continue on. If it is not an internal breakpoint, consult
281   // m_ignore_breakpoints.
282 
283   if (stop_reason == eStopReasonBreakpoint) {
284     uint64_t break_site_id = m_real_stop_info_sp->GetValue();
285     BreakpointSiteSP bp_site_sp;
286     bp_site_sp = m_process.GetBreakpointSiteList().FindByID(break_site_id);
287     if (bp_site_sp) {
288       uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
289       bool is_internal = true;
290       for (uint32_t i = 0; i < num_owners; i++) {
291         Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
292         LLDB_LOGF(log,
293                   "ThreadPlanCallFunction::PlanExplainsStop: hit "
294                   "breakpoint %d while calling function",
295                   bp.GetID());
296 
297         if (!bp.IsInternal()) {
298           is_internal = false;
299           break;
300         }
301       }
302       if (is_internal) {
303         LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop hit an "
304                        "internal breakpoint, not stopping.");
305         return false;
306       }
307     }
308 
309     if (m_ignore_breakpoints) {
310       LLDB_LOGF(log,
311                 "ThreadPlanCallFunction::PlanExplainsStop: we are ignoring "
312                 "breakpoints, overriding breakpoint stop info ShouldStop, "
313                 "returning true");
314       m_real_stop_info_sp->OverrideShouldStop(false);
315       return true;
316     } else {
317       LLDB_LOGF(log, "ThreadPlanCallFunction::PlanExplainsStop: we are not "
318                      "ignoring breakpoints, overriding breakpoint stop info "
319                      "ShouldStop, returning true");
320       m_real_stop_info_sp->OverrideShouldStop(true);
321       return false;
322     }
323   } else if (!m_unwind_on_error) {
324     // If we don't want to discard this plan, than any stop we don't understand
325     // should be propagated up the stack.
326     return false;
327   } else {
328     // If the subplan is running, any crashes are attributable to us. If we
329     // want to discard the plan, then we say we explain the stop but if we are
330     // going to be discarded, let whoever is above us explain the stop. But
331     // don't discard the plan if the stop would restart itself (for instance if
332     // it is a signal that is set not to stop.  Check that here first.  We just
333     // say we explain the stop but aren't done and everything will continue on
334     // from there.
335 
336     if (m_real_stop_info_sp &&
337         m_real_stop_info_sp->ShouldStopSynchronous(event_ptr)) {
338       SetPlanComplete(false);
339       return m_subplan_sp ? m_unwind_on_error : false;
340     } else
341       return true;
342   }
343 }
344 
345 bool ThreadPlanCallFunction::ShouldStop(Event *event_ptr) {
346   // We do some computation in DoPlanExplainsStop that may or may not set the
347   // plan as complete. We need to do that here to make sure our state is
348   // correct.
349   DoPlanExplainsStop(event_ptr);
350 
351   if (IsPlanComplete()) {
352     ReportRegisterState("Function completed.  Register state was:");
353     return true;
354   } else {
355     return false;
356   }
357 }
358 
359 bool ThreadPlanCallFunction::StopOthers() { return m_stop_other_threads; }
360 
361 StateType ThreadPlanCallFunction::GetPlanRunState() { return eStateRunning; }
362 
363 void ThreadPlanCallFunction::DidPush() {
364   //#define SINGLE_STEP_EXPRESSIONS
365 
366   // Now set the thread state to "no reason" so we don't run with whatever
367   // signal was outstanding... Wait till the plan is pushed so we aren't
368   // changing the stop info till we're about to run.
369 
370   GetThread().SetStopInfoToNothing();
371 
372 #ifndef SINGLE_STEP_EXPRESSIONS
373   Thread &thread = GetThread();
374   m_subplan_sp = std::make_shared<ThreadPlanRunToAddress>(thread, m_start_addr,
375                                                           m_stop_other_threads);
376 
377   thread.QueueThreadPlan(m_subplan_sp, false);
378   m_subplan_sp->SetPrivate(true);
379 #endif
380 }
381 
382 bool ThreadPlanCallFunction::WillStop() { return true; }
383 
384 bool ThreadPlanCallFunction::MischiefManaged() {
385   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
386 
387   if (IsPlanComplete()) {
388     LLDB_LOGF(log, "ThreadPlanCallFunction(%p): Completed call function plan.",
389               static_cast<void *>(this));
390 
391     ThreadPlan::MischiefManaged();
392     return true;
393   } else {
394     return false;
395   }
396 }
397 
398 void ThreadPlanCallFunction::SetBreakpoints() {
399   if (m_trap_exceptions) {
400     m_cxx_language_runtime =
401         m_process.GetLanguageRuntime(eLanguageTypeC_plus_plus);
402     m_objc_language_runtime = m_process.GetLanguageRuntime(eLanguageTypeObjC);
403 
404     if (m_cxx_language_runtime) {
405       m_should_clear_cxx_exception_bp =
406           !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
407       m_cxx_language_runtime->SetExceptionBreakpoints();
408     }
409     if (m_objc_language_runtime) {
410       m_should_clear_objc_exception_bp =
411           !m_objc_language_runtime->ExceptionBreakpointsAreSet();
412       m_objc_language_runtime->SetExceptionBreakpoints();
413     }
414   }
415 }
416 
417 void ThreadPlanCallFunction::ClearBreakpoints() {
418   if (m_trap_exceptions) {
419     if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
420       m_cxx_language_runtime->ClearExceptionBreakpoints();
421     if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
422       m_objc_language_runtime->ClearExceptionBreakpoints();
423   }
424 }
425 
426 bool ThreadPlanCallFunction::BreakpointsExplainStop() {
427   StopInfoSP stop_info_sp = GetPrivateStopInfo();
428 
429   if (m_trap_exceptions) {
430     if ((m_cxx_language_runtime &&
431          m_cxx_language_runtime->ExceptionBreakpointsExplainStop(
432              stop_info_sp)) ||
433         (m_objc_language_runtime &&
434          m_objc_language_runtime->ExceptionBreakpointsExplainStop(
435              stop_info_sp))) {
436       Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP));
437       LLDB_LOGF(log, "ThreadPlanCallFunction::BreakpointsExplainStop - Hit an "
438                      "exception breakpoint, setting plan complete.");
439 
440       SetPlanComplete(false);
441 
442       // If the user has set the ObjC language breakpoint, it would normally
443       // get priority over our internal catcher breakpoint, but in this case we
444       // can't let that happen, so force the ShouldStop here.
445       stop_info_sp->OverrideShouldStop(true);
446       return true;
447     }
448   }
449 
450   return false;
451 }
452 
453 void ThreadPlanCallFunction::SetStopOthers(bool new_value) {
454   m_subplan_sp->SetStopOthers(new_value);
455 }
456 
457 bool ThreadPlanCallFunction::RestoreThreadState() {
458   return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
459 }
460 
461 void ThreadPlanCallFunction::SetReturnValue() {
462   const ABI *abi = m_process.GetABI().get();
463   if (abi && m_return_type.IsValid()) {
464     const bool persistent = false;
465     m_return_valobj_sp =
466         abi->GetReturnValueObject(GetThread(), m_return_type, persistent);
467   }
468 }
469