1 | //===-- ThreadPlanStepRange.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_TARGET_THREADPLANSTEPRANGE_H |
10 | #define LLDB_TARGET_THREADPLANSTEPRANGE_H |
11 | |
12 | #include "lldb/Core/AddressRange.h" |
13 | #include "lldb/Target/StackID.h" |
14 | #include "lldb/Target/Thread.h" |
15 | #include "lldb/Target/ThreadPlan.h" |
16 | #include "lldb/Target/ThreadPlanShouldStopHere.h" |
17 | |
18 | namespace lldb_private { |
19 | |
20 | class ThreadPlanStepRange : public ThreadPlan { |
21 | public: |
22 | ThreadPlanStepRange(ThreadPlanKind kind, const char *name, Thread &thread, |
23 | const AddressRange &range, |
24 | const SymbolContext &addr_context, |
25 | lldb::RunMode stop_others, |
26 | bool given_ranges_only = false); |
27 | |
28 | ~ThreadPlanStepRange() override; |
29 | |
30 | void GetDescription(Stream *s, lldb::DescriptionLevel level) override = 0; |
31 | bool ValidatePlan(Stream *error) override; |
32 | bool ShouldStop(Event *event_ptr) override = 0; |
33 | Vote ShouldReportStop(Event *event_ptr) override; |
34 | bool StopOthers() override; |
35 | lldb::StateType GetPlanRunState() override; |
36 | bool WillStop() override; |
37 | bool MischiefManaged() override; |
38 | void DidPush() override; |
39 | bool IsPlanStale() override; |
40 | |
41 | void AddRange(const AddressRange &new_range); |
42 | |
43 | protected: |
44 | bool InRange(); |
45 | lldb::FrameComparison CompareCurrentFrameToStartFrame(); |
46 | bool InSymbol(); |
47 | void DumpRanges(Stream *s); |
48 | |
49 | Disassembler *GetDisassembler(); |
50 | |
51 | InstructionList *GetInstructionsForAddress(lldb::addr_t addr, |
52 | size_t &range_index, |
53 | size_t &insn_offset); |
54 | |
55 | // Pushes a plan to proceed through the next section of instructions in the |
56 | // range - usually just a RunToAddress plan to run to the next branch. |
57 | // Returns true if it pushed such a plan. If there was no available 'quick |
58 | // run' plan, then just single step. |
59 | bool SetNextBranchBreakpoint(); |
60 | |
61 | void ClearNextBranchBreakpoint(); |
62 | |
63 | bool (lldb::StopInfoSP stop_info_sp); |
64 | |
65 | SymbolContext m_addr_context; |
66 | std::vector<AddressRange> m_address_ranges; |
67 | lldb::RunMode m_stop_others; |
68 | StackID m_stack_id; // Use the stack ID so we can tell step out from step in. |
69 | StackID m_parent_stack_id; // Use the parent stack ID so we can identify tail |
70 | // calls and the like. |
71 | bool m_no_more_plans; // Need this one so we can tell if we stepped into a |
72 | // call, |
73 | // but can't continue, in which case we are done. |
74 | bool m_first_run_event; // We want to broadcast only one running event, our |
75 | // first. |
76 | lldb::BreakpointSP m_next_branch_bp_sp; |
77 | bool m_use_fast_step; |
78 | bool m_given_ranges_only; |
79 | bool m_found_calls = false; // When we set the next branch breakpoint for |
80 | // step over, we now extend them past call insns |
81 | // that directly return. But if we do that we |
82 | // need to run all threads, or we might cause |
83 | // deadlocks. This tells us whether we found |
84 | // any calls in setting the next branch breakpoint. |
85 | |
86 | private: |
87 | std::vector<lldb::DisassemblerSP> m_instruction_ranges; |
88 | |
89 | ThreadPlanStepRange(const ThreadPlanStepRange &) = delete; |
90 | const ThreadPlanStepRange &operator=(const ThreadPlanStepRange &) = delete; |
91 | }; |
92 | |
93 | } // namespace lldb_private |
94 | |
95 | #endif // LLDB_TARGET_THREADPLANSTEPRANGE_H |
96 | |