aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp')
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp334
1 files changed, 153 insertions, 181 deletions
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index a2101c927b4d..e49269532329 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -1,4 +1,5 @@
-//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp --------------------------*- C++ -*-===//
+//===-- AppleThreadPlanStepThroughObjCTrampoline.cpp
+//--------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -30,212 +31,183 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// ThreadPlanStepThroughObjCTrampoline constructor
//----------------------------------------------------------------------
-AppleThreadPlanStepThroughObjCTrampoline::AppleThreadPlanStepThroughObjCTrampoline
-(
- Thread &thread,
- AppleObjCTrampolineHandler *trampoline_handler,
- ValueList &input_values,
- lldb::addr_t isa_addr,
- lldb::addr_t sel_addr,
- bool stop_others
-) :
- ThreadPlan (ThreadPlan::eKindGeneric,
- "MacOSX Step through ObjC Trampoline",
- thread,
- eVoteNoOpinion,
- eVoteNoOpinion),
- m_trampoline_handler (trampoline_handler),
- m_args_addr (LLDB_INVALID_ADDRESS),
- m_input_values (input_values),
- m_isa_addr(isa_addr),
- m_sel_addr(sel_addr),
- m_impl_function (NULL),
- m_stop_others (stop_others)
-{
-
-}
+AppleThreadPlanStepThroughObjCTrampoline::
+ AppleThreadPlanStepThroughObjCTrampoline(
+ Thread &thread, AppleObjCTrampolineHandler *trampoline_handler,
+ ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
+ bool stop_others)
+ : ThreadPlan(ThreadPlan::eKindGeneric,
+ "MacOSX Step through ObjC Trampoline", thread, eVoteNoOpinion,
+ eVoteNoOpinion),
+ m_trampoline_handler(trampoline_handler),
+ m_args_addr(LLDB_INVALID_ADDRESS), m_input_values(input_values),
+ m_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(NULL),
+ m_stop_others(stop_others) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-AppleThreadPlanStepThroughObjCTrampoline::~AppleThreadPlanStepThroughObjCTrampoline()
-{
+AppleThreadPlanStepThroughObjCTrampoline::
+ ~AppleThreadPlanStepThroughObjCTrampoline() {}
+
+void AppleThreadPlanStepThroughObjCTrampoline::DidPush() {
+ // Setting up the memory space for the called function text might require
+ // allocations,
+ // i.e. a nested function call. This needs to be done as a PreResumeAction.
+ m_thread.GetProcess()->AddPreResumeAction(PreResumeInitializeFunctionCaller,
+ (void *)this);
}
-void
-AppleThreadPlanStepThroughObjCTrampoline::DidPush ()
-{
- // Setting up the memory space for the called function text might require allocations,
- // i.e. a nested function call. This needs to be done as a PreResumeAction.
- m_thread.GetProcess()->AddPreResumeAction (PreResumeInitializeFunctionCaller, (void *) this);
-}
+bool AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller() {
+ if (!m_func_sp) {
+ DiagnosticManager diagnostics;
+ m_args_addr =
+ m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values);
-bool
-AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller ()
-{
- if (!m_func_sp)
- {
- DiagnosticManager diagnostics;
- m_args_addr = m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values);
-
- if (m_args_addr == LLDB_INVALID_ADDRESS)
- {
- return false;
- }
- m_impl_function = m_trampoline_handler->GetLookupImplementationFunctionCaller();
- ExecutionContext exc_ctx;
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetIgnoreBreakpoints(true);
- options.SetStopOthers(m_stop_others);
- m_thread.CalculateExecutionContext(exc_ctx);
- m_func_sp = m_impl_function->GetThreadPlanToCallFunction(exc_ctx, m_args_addr, options, diagnostics);
- m_func_sp->SetOkayToDiscard(true);
- m_thread.QueueThreadPlan(m_func_sp, false);
+ if (m_args_addr == LLDB_INVALID_ADDRESS) {
+ return false;
}
- return true;
+ m_impl_function =
+ m_trampoline_handler->GetLookupImplementationFunctionCaller();
+ ExecutionContext exc_ctx;
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(m_stop_others);
+ m_thread.CalculateExecutionContext(exc_ctx);
+ m_func_sp = m_impl_function->GetThreadPlanToCallFunction(
+ exc_ctx, m_args_addr, options, diagnostics);
+ m_func_sp->SetOkayToDiscard(true);
+ m_thread.QueueThreadPlan(m_func_sp, false);
+ }
+ return true;
}
-bool
-AppleThreadPlanStepThroughObjCTrampoline::PreResumeInitializeFunctionCaller(void *void_myself)
-{
- AppleThreadPlanStepThroughObjCTrampoline *myself = static_cast<AppleThreadPlanStepThroughObjCTrampoline *>(void_myself);
- return myself->InitializeFunctionCaller();
+bool AppleThreadPlanStepThroughObjCTrampoline::
+ PreResumeInitializeFunctionCaller(void *void_myself) {
+ AppleThreadPlanStepThroughObjCTrampoline *myself =
+ static_cast<AppleThreadPlanStepThroughObjCTrampoline *>(void_myself);
+ return myself->InitializeFunctionCaller();
}
-void
-AppleThreadPlanStepThroughObjCTrampoline::GetDescription (Stream *s,
- lldb::DescriptionLevel level)
-{
- if (level == lldb::eDescriptionLevelBrief)
- s->Printf("Step through ObjC trampoline");
- else
- {
- s->Printf ("Stepping to implementation of ObjC method - obj: 0x%llx, isa: 0x%" PRIx64 ", sel: 0x%" PRIx64,
- m_input_values.GetValueAtIndex(0)->GetScalar().ULongLong(), m_isa_addr, m_sel_addr);
- }
+void AppleThreadPlanStepThroughObjCTrampoline::GetDescription(
+ Stream *s, lldb::DescriptionLevel level) {
+ if (level == lldb::eDescriptionLevelBrief)
+ s->Printf("Step through ObjC trampoline");
+ else {
+ s->Printf("Stepping to implementation of ObjC method - obj: 0x%llx, isa: "
+ "0x%" PRIx64 ", sel: 0x%" PRIx64,
+ m_input_values.GetValueAtIndex(0)->GetScalar().ULongLong(),
+ m_isa_addr, m_sel_addr);
+ }
}
-
-bool
-AppleThreadPlanStepThroughObjCTrampoline::ValidatePlan (Stream *error)
-{
- return true;
+
+bool AppleThreadPlanStepThroughObjCTrampoline::ValidatePlan(Stream *error) {
+ return true;
}
-bool
-AppleThreadPlanStepThroughObjCTrampoline::DoPlanExplainsStop (Event *event_ptr)
-{
- // If we get asked to explain the stop it will be because something went
- // wrong (like the implementation for selector function crashed... We're going
- // to figure out what to do about that, so we do explain the stop.
- return true;
+bool AppleThreadPlanStepThroughObjCTrampoline::DoPlanExplainsStop(
+ Event *event_ptr) {
+ // If we get asked to explain the stop it will be because something went
+ // wrong (like the implementation for selector function crashed... We're
+ // going
+ // to figure out what to do about that, so we do explain the stop.
+ return true;
}
-lldb::StateType
-AppleThreadPlanStepThroughObjCTrampoline::GetPlanRunState ()
-{
- return eStateRunning;
+lldb::StateType AppleThreadPlanStepThroughObjCTrampoline::GetPlanRunState() {
+ return eStateRunning;
}
-bool
-AppleThreadPlanStepThroughObjCTrampoline::ShouldStop (Event *event_ptr)
-{
- // First stage: we are still handling the "call a function to get the target of the dispatch"
- if (m_func_sp)
- {
- if (!m_func_sp->IsPlanComplete())
- {
- return false;
- }
- else
- {
- if (!m_func_sp->PlanSucceeded())
- {
- SetPlanComplete(false);
- return true;
- }
- m_func_sp.reset();
- }
+bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
+ // First stage: we are still handling the "call a function to get the target
+ // of the dispatch"
+ if (m_func_sp) {
+ if (!m_func_sp->IsPlanComplete()) {
+ return false;
+ } else {
+ if (!m_func_sp->PlanSucceeded()) {
+ SetPlanComplete(false);
+ return true;
+ }
+ m_func_sp.reset();
}
-
- // Second stage, if all went well with the function calling, then fetch the target address, and
- // queue up a "run to that address" plan.
- if (!m_run_to_sp)
- {
- Value target_addr_value;
- ExecutionContext exc_ctx;
- m_thread.CalculateExecutionContext(exc_ctx);
- m_impl_function->FetchFunctionResults (exc_ctx, m_args_addr, target_addr_value);
- m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr);
- lldb::addr_t target_addr = target_addr_value.GetScalar().ULongLong();
- Address target_so_addr;
- target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr());
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (target_addr == 0)
- {
- if (log)
- log->Printf("Got target implementation of 0x0, stopping.");
- SetPlanComplete();
- return true;
- }
- if (m_trampoline_handler->AddrIsMsgForward(target_addr))
- {
- if (log)
- log->Printf ("Implementation lookup returned msgForward function: 0x%" PRIx64 ", stopping.", target_addr);
-
- SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(eSymbolContextEverything);
- const bool abort_other_plans = false;
- const bool first_insn = true;
- const uint32_t frame_idx = 0;
- m_run_to_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop (abort_other_plans,
- &sc,
- first_insn,
- m_stop_others,
- eVoteNoOpinion,
- eVoteNoOpinion,
- frame_idx);
- m_run_to_sp->SetPrivate(true);
- return false;
- }
-
- if (log)
- log->Printf("Running to ObjC method implementation: 0x%" PRIx64, target_addr);
-
- ObjCLanguageRuntime *objc_runtime = GetThread().GetProcess()->GetObjCLanguageRuntime();
- assert (objc_runtime != NULL);
- objc_runtime->AddToMethodCache (m_isa_addr, m_sel_addr, target_addr);
- if (log)
- log->Printf("Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64 "} = addr=0x%" PRIx64 " to cache.", m_isa_addr, m_sel_addr, target_addr);
-
- // Extract the target address from the value:
-
- m_run_to_sp.reset(new ThreadPlanRunToAddress(m_thread, target_so_addr, m_stop_others));
- m_thread.QueueThreadPlan(m_run_to_sp, false);
- m_run_to_sp->SetPrivate(true);
- return false;
+ }
+
+ // Second stage, if all went well with the function calling, then fetch the
+ // target address, and
+ // queue up a "run to that address" plan.
+ if (!m_run_to_sp) {
+ Value target_addr_value;
+ ExecutionContext exc_ctx;
+ m_thread.CalculateExecutionContext(exc_ctx);
+ m_impl_function->FetchFunctionResults(exc_ctx, m_args_addr,
+ target_addr_value);
+ m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr);
+ lldb::addr_t target_addr = target_addr_value.GetScalar().ULongLong();
+ Address target_so_addr;
+ target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr());
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (target_addr == 0) {
+ if (log)
+ log->Printf("Got target implementation of 0x0, stopping.");
+ SetPlanComplete();
+ return true;
}
- else if (m_thread.IsThreadPlanDone(m_run_to_sp.get()))
- {
- // Third stage, work the run to target plan.
- SetPlanComplete();
- return true;
+ if (m_trampoline_handler->AddrIsMsgForward(target_addr)) {
+ if (log)
+ log->Printf(
+ "Implementation lookup returned msgForward function: 0x%" PRIx64
+ ", stopping.",
+ target_addr);
+
+ SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(
+ eSymbolContextEverything);
+ const bool abort_other_plans = false;
+ const bool first_insn = true;
+ const uint32_t frame_idx = 0;
+ m_run_to_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop(
+ abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion,
+ eVoteNoOpinion, frame_idx);
+ m_run_to_sp->SetPrivate(true);
+ return false;
}
+
+ if (log)
+ log->Printf("Running to ObjC method implementation: 0x%" PRIx64,
+ target_addr);
+
+ ObjCLanguageRuntime *objc_runtime =
+ GetThread().GetProcess()->GetObjCLanguageRuntime();
+ assert(objc_runtime != NULL);
+ objc_runtime->AddToMethodCache(m_isa_addr, m_sel_addr, target_addr);
+ if (log)
+ log->Printf("Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64
+ "} = addr=0x%" PRIx64 " to cache.",
+ m_isa_addr, m_sel_addr, target_addr);
+
+ // Extract the target address from the value:
+
+ m_run_to_sp.reset(
+ new ThreadPlanRunToAddress(m_thread, target_so_addr, m_stop_others));
+ m_thread.QueueThreadPlan(m_run_to_sp, false);
+ m_run_to_sp->SetPrivate(true);
return false;
+ } else if (m_thread.IsThreadPlanDone(m_run_to_sp.get())) {
+ // Third stage, work the run to target plan.
+ SetPlanComplete();
+ return true;
+ }
+ return false;
}
// The base class MischiefManaged does some cleanup - so you have to call it
// in your MischiefManaged derived class.
-bool
-AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged ()
-{
- if (IsPlanComplete())
- return true;
- else
- return false;
-}
-
-bool
-AppleThreadPlanStepThroughObjCTrampoline::WillStop()
-{
+bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() {
+ if (IsPlanComplete())
return true;
+ else
+ return false;
}
+
+bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; }