/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- AppleThreadPlanStepThroughObjCTrampoline.h --------------*- C++ -*-===// |
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 | | #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H |
10 | | #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H |
11 | | |
12 | | #include "AppleObjCTrampolineHandler.h" |
13 | | #include "lldb/Core/Value.h" |
14 | | #include "lldb/Target/ThreadPlan.h" |
15 | | #include "lldb/Target/ThreadPlanStepInRange.h" |
16 | | #include "lldb/Target/ThreadPlanStepOut.h" |
17 | | #include "lldb/Target/ThreadPlanShouldStopHere.h" |
18 | | #include "lldb/lldb-enumerations.h" |
19 | | #include "lldb/lldb-types.h" |
20 | | |
21 | | namespace lldb_private { |
22 | | |
23 | | class AppleThreadPlanStepThroughObjCTrampoline : public ThreadPlan { |
24 | | public: |
25 | | AppleThreadPlanStepThroughObjCTrampoline( |
26 | | Thread &thread, AppleObjCTrampolineHandler &trampoline_handler, |
27 | | ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr, |
28 | | lldb::addr_t sel_str_addr, llvm::StringRef sel_str); |
29 | | |
30 | | ~AppleThreadPlanStepThroughObjCTrampoline() override; |
31 | | |
32 | | static bool PreResumeInitializeFunctionCaller(void *myself); |
33 | | |
34 | | void GetDescription(Stream *s, lldb::DescriptionLevel level) override; |
35 | | |
36 | | bool ValidatePlan(Stream *error) override; |
37 | | |
38 | | lldb::StateType GetPlanRunState() override; |
39 | | |
40 | | bool ShouldStop(Event *event_ptr) override; |
41 | | |
42 | | // The step through code might have to fill in the cache, so it is not safe |
43 | | // to run only one thread. |
44 | 54 | bool StopOthers() override { return false; } |
45 | | |
46 | | // The base class MischiefManaged does some cleanup - so you have to call it |
47 | | // in your MischiefManaged derived class. |
48 | | bool MischiefManaged() override; |
49 | | |
50 | | void DidPush() override; |
51 | | |
52 | | bool WillStop() override; |
53 | | |
54 | | protected: |
55 | | bool DoPlanExplainsStop(Event *event_ptr) override; |
56 | | |
57 | | private: |
58 | | bool InitializeFunctionCaller(); |
59 | | |
60 | | AppleObjCTrampolineHandler &m_trampoline_handler; /// The handler itself. |
61 | | lldb::addr_t m_args_addr; /// Stores the address for our step through function |
62 | | /// result structure. |
63 | | ValueList m_input_values; |
64 | | lldb::addr_t m_isa_addr; /// isa_addr and sel_addr are the keys we will use to |
65 | | /// cache the implementation. |
66 | | lldb::addr_t m_sel_addr; |
67 | | lldb::ThreadPlanSP m_func_sp; /// This is the function call plan. We fill it |
68 | | /// at start, then set it to NULL when this plan |
69 | | /// is done. That way we know to go on to: |
70 | | lldb::ThreadPlanSP m_run_to_sp; /// The plan that runs to the target. |
71 | | FunctionCaller *m_impl_function; /// This is a pointer to a impl function that |
72 | | /// is owned by the client that pushes this |
73 | | /// plan. |
74 | | lldb::addr_t m_sel_str_addr; /// If this is not LLDB_INVALID_ADDRESS then it |
75 | | /// is the address we wrote the selector string |
76 | | /// to. We need to deallocate it when the |
77 | | /// function call is done. |
78 | | std::string m_sel_str; /// This is the string we wrote to memory - we |
79 | | /// use it for caching, but only if |
80 | | /// m_sel_str_addr is non-null. |
81 | | }; |
82 | | |
83 | | class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut { |
84 | | public: |
85 | | AppleThreadPlanStepThroughDirectDispatch(Thread &thread, |
86 | | AppleObjCTrampolineHandler &handler, |
87 | | llvm::StringRef dispatch_func_name); |
88 | | |
89 | | ~AppleThreadPlanStepThroughDirectDispatch() override; |
90 | | |
91 | | void GetDescription(Stream *s, lldb::DescriptionLevel level) override; |
92 | | |
93 | | bool ShouldStop(Event *event_ptr) override; |
94 | | |
95 | 22 | bool StopOthers() override { return false; } |
96 | | |
97 | | bool MischiefManaged() override; |
98 | | |
99 | | bool DoWillResume(lldb::StateType resume_state, bool current_plan) override; |
100 | | |
101 | 0 | void SetFlagsToDefault() override { |
102 | 0 | GetFlags().Set(ThreadPlanStepInRange::GetDefaultFlagsValue()); |
103 | 0 | } |
104 | | |
105 | | protected: |
106 | | bool DoPlanExplainsStop(Event *event_ptr) override; |
107 | | |
108 | | AppleObjCTrampolineHandler &m_trampoline_handler; |
109 | | std::string m_dispatch_func_name; /// Which dispatch function we're stepping |
110 | | /// through. |
111 | | lldb::ThreadPlanSP m_objc_step_through_sp; /// When we hit an objc_msgSend, |
112 | | /// we'll use this plan to get to |
113 | | /// its target. |
114 | | std::vector<lldb::BreakpointSP> m_msgSend_bkpts; /// Breakpoints on the objc |
115 | | /// dispatch functions. |
116 | | bool m_at_msg_send; /// Are we currently handling an msg_send |
117 | | |
118 | | }; |
119 | | |
120 | | } // namespace lldb_private |
121 | | |
122 | | #endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLETHREADPLANSTEPTHROUGHOBJCTRAMPOLINE_H |