1061da546Spatrick //===-- AppleThreadPlanStepThroughObjCTrampoline.h --------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H 11061da546Spatrick 12061da546Spatrick #include "AppleObjCTrampolineHandler.h" 13061da546Spatrick #include "lldb/Core/Value.h" 14061da546Spatrick #include "lldb/Target/ThreadPlan.h" 15dda28197Spatrick #include "lldb/Target/ThreadPlanStepInRange.h" 16dda28197Spatrick #include "lldb/Target/ThreadPlanStepOut.h" 17dda28197Spatrick #include "lldb/Target/ThreadPlanShouldStopHere.h" 18061da546Spatrick #include "lldb/lldb-enumerations.h" 19061da546Spatrick #include "lldb/lldb-types.h" 20061da546Spatrick 21061da546Spatrick namespace lldb_private { 22061da546Spatrick 23061da546Spatrick class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan { 24061da546Spatrick public: 25061da546Spatrick AppleThreadPlanStepThroughObjCTrampoline( 26dda28197Spatrick Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, 27*f6aab3d8Srobert ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, 28*f6aab3d8Srobert lldb::addr_t sel_str_addr, llvm::StringRef sel_str); 29061da546Spatrick 30061da546Spatrick ~AppleThreadPlanStepThroughObjCTrampoline() override; 31061da546Spatrick 32061da546Spatrick static bool PreResumeInitializeFunctionCaller(void *myself); 33061da546Spatrick 34061da546Spatrick void GetDescription(Stream *s, lldb::DescriptionLevel level) override; 35061da546Spatrick 36061da546Spatrick bool ValidatePlan(Stream *error) override; 37061da546Spatrick 38061da546Spatrick lldb::StateType GetPlanRunState() override; 39061da546Spatrick 40061da546Spatrick bool ShouldStop(Event *event_ptr) override; 41061da546Spatrick 42be691f3bSpatrick // The step through code might have to fill in the cache, so it is not safe 43be691f3bSpatrick // to run only one thread. StopOthers()44be691f3bSpatrick bool StopOthers() override { return false; } 45061da546Spatrick 46061da546Spatrick // The base class MischiefManaged does some cleanup - so you have to call it 47061da546Spatrick // in your MischiefManaged derived class. 48061da546Spatrick bool MischiefManaged() override; 49061da546Spatrick 50061da546Spatrick void DidPush() override; 51061da546Spatrick 52061da546Spatrick bool WillStop() override; 53061da546Spatrick 54061da546Spatrick protected: 55061da546Spatrick bool DoPlanExplainsStop(Event *event_ptr) override; 56061da546Spatrick 57061da546Spatrick private: 58061da546Spatrick bool InitializeFunctionCaller(); 59061da546Spatrick 60dda28197Spatrick AppleObjCTrampolineHandler &m_trampoline_handler; /// The handler itself. 61dda28197Spatrick lldb::addr_t m_args_addr; /// Stores the address for our step through function 62dda28197Spatrick /// result structure. 63061da546Spatrick ValueList m_input_values; 64dda28197Spatrick lldb::addr_t m_isa_addr; /// isa_addr and sel_addr are the keys we will use to 65dda28197Spatrick /// cache the implementation. 66061da546Spatrick lldb::addr_t m_sel_addr; 67dda28197Spatrick lldb::ThreadPlanSP m_func_sp; /// This is the function call plan. We fill it 68dda28197Spatrick /// at start, then set it to NULL when this plan 69dda28197Spatrick /// is done. That way we know to go on to: 70dda28197Spatrick lldb::ThreadPlanSP m_run_to_sp; /// The plan that runs to the target. 71dda28197Spatrick FunctionCaller *m_impl_function; /// This is a pointer to a impl function that 72dda28197Spatrick /// is owned by the client that pushes this 73dda28197Spatrick /// plan. 74*f6aab3d8Srobert lldb::addr_t m_sel_str_addr; /// If this is not LLDB_INVALID_ADDRESS then it 75*f6aab3d8Srobert /// is the address we wrote the selector string 76*f6aab3d8Srobert /// to. We need to deallocate it when the 77*f6aab3d8Srobert /// function call is done. 78*f6aab3d8Srobert std::string m_sel_str; /// This is the string we wrote to memory - we 79*f6aab3d8Srobert /// use it for caching, but only if 80*f6aab3d8Srobert /// m_sel_str_addr is non-null. 81dda28197Spatrick }; 82dda28197Spatrick 83dda28197Spatrick class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut { 84dda28197Spatrick public: 85be691f3bSpatrick AppleThreadPlanStepThroughDirectDispatch(Thread &thread, 86be691f3bSpatrick AppleObjCTrampolineHandler &handler, 87be691f3bSpatrick llvm::StringRef dispatch_func_name); 88dda28197Spatrick 89dda28197Spatrick ~AppleThreadPlanStepThroughDirectDispatch() override; 90dda28197Spatrick 91dda28197Spatrick void GetDescription(Stream *s, lldb::DescriptionLevel level) override; 92dda28197Spatrick 93dda28197Spatrick bool ShouldStop(Event *event_ptr) override; 94dda28197Spatrick StopOthers()95be691f3bSpatrick bool StopOthers() override { return false; } 96dda28197Spatrick 97dda28197Spatrick bool MischiefManaged() override; 98dda28197Spatrick 99dda28197Spatrick bool DoWillResume(lldb::StateType resume_state, bool current_plan) override; 100dda28197Spatrick SetFlagsToDefault()101dda28197Spatrick void SetFlagsToDefault() override { 102dda28197Spatrick GetFlags().Set(ThreadPlanStepInRange::GetDefaultFlagsValue()); 103dda28197Spatrick } 104dda28197Spatrick 105dda28197Spatrick protected: 106dda28197Spatrick bool DoPlanExplainsStop(Event *event_ptr) override; 107dda28197Spatrick 108dda28197Spatrick AppleObjCTrampolineHandler &m_trampoline_handler; 109dda28197Spatrick std::string m_dispatch_func_name; /// Which dispatch function we're stepping 110dda28197Spatrick /// through. 111dda28197Spatrick lldb::ThreadPlanSP m_objc_step_through_sp; /// When we hit an objc_msgSend, 112dda28197Spatrick /// we'll use this plan to get to 113dda28197Spatrick /// its target. 114dda28197Spatrick std::vector<lldb::BreakpointSP> m_msgSend_bkpts; /// Breakpoints on the objc 115dda28197Spatrick /// dispatch functions. 116dda28197Spatrick bool m_at_msg_send; /// Are we currently handling an msg_send 117dda28197Spatrick 118061da546Spatrick }; 119061da546Spatrick 120061da546Spatrick } // namespace lldb_private 121061da546Spatrick 122dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H 123