0cb2d8c97071e97b0afb692de5afa89cf2a3ed61
[deliverable/binutils-gdb.git] / gdb / displaced-stepping.h
1 #ifndef DISPLACED_STEPPING_H
2 #define DISPLACED_STEPPING_H
3
4 #include "gdbsupport/byte-vector.h"
5
6 struct gdbarch;
7 struct thread_info;
8
9 enum displaced_step_prepare_status
10 {
11 /* A displaced stepping buffer was successfully allocated and prepared. */
12 DISPLACED_STEP_PREPARE_STATUS_OK,
13
14 /* Something bad happened. */
15 DISPLACED_STEP_PREPARE_STATUS_ERROR,
16
17 /* Not enough resources are available at this time, try again later. */
18 DISPLACED_STEP_PREPARE_STATUS_UNAVAILABLE,
19 };
20
21 enum displaced_step_finish_status
22 {
23 /* The instruction was stepped and fixed up. */
24 DISPLACED_STEP_FINISH_STATUS_OK,
25
26 /* The instruction was not stepped. */
27 DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED,
28 };
29
30 /* Data returned by a gdbarch displaced_step_copy_insn method, to be passed to
31 the matching displaced_step_fixup method. */
32
33 struct displaced_step_copy_insn_closure
34 {
35 virtual ~displaced_step_copy_insn_closure () = 0;
36 };
37
38 typedef std::unique_ptr<displaced_step_copy_insn_closure>
39 displaced_step_copy_insn_closure_up;
40
41 /* A simple displaced step closure that contains only a byte buffer. */
42
43 struct buf_displaced_step_copy_insn_closure : displaced_step_copy_insn_closure
44 {
45 buf_displaced_step_copy_insn_closure (int buf_size)
46 : buf (buf_size)
47 {}
48
49 gdb::byte_vector buf;
50 };
51
52 /* Per-inferior displaced stepping state. */
53
54 struct displaced_step_inferior_state
55 {
56 displaced_step_inferior_state ()
57 {
58 reset ();
59 }
60
61 /* Put this object back in its original state. */
62 void reset ()
63 {
64 failed_before = false;
65 }
66
67 /* True if preparing a displaced step ever failed. If so, we won't
68 try displaced stepping for this inferior again. */
69 bool failed_before;
70 };
71
72 /* Per-thread displaced stepping state. */
73
74 struct displaced_step_thread_state
75 {
76 /* Return true if this thread is currently executing a displaced step. */
77 bool in_progress () const
78 { return m_original_gdbarch != nullptr; }
79
80 /* Return the gdbarch of the thread prior to the step. */
81 gdbarch *get_original_gdbarch () const
82 { return m_original_gdbarch; }
83
84 /* Mark this thread as currently executing a displaced step.
85
86 ORIGINAL_GDBARCH is the current gdbarch of the thread (before the step
87 is executed). */
88 void set (gdbarch *original_gdbarch)
89 { m_original_gdbarch = original_gdbarch; }
90
91 /* mark this thread as no longer executing a displaced step. */
92 void reset ()
93 { m_original_gdbarch = nullptr; }
94
95 private:
96 gdbarch *m_original_gdbarch = nullptr;
97 };
98
99 /* Manage access to a single displaced stepping buffer, without any
100 sharing. */
101
102 struct single_displaced_buffer_manager
103 {
104 single_displaced_buffer_manager (CORE_ADDR buffer_addr)
105 : m_buffer_addr (buffer_addr)
106 {}
107
108 displaced_step_prepare_status prepare (thread_info *thread);
109
110 displaced_step_finish_status finish (gdbarch *arch, thread_info *thread,
111 gdb_signal sig);
112
113 private:
114
115 CORE_ADDR m_original_pc;
116 CORE_ADDR m_buffer_addr;
117
118 /* If set, the thread currently using the buffer. */
119 thread_info *m_current_thread = nullptr;
120
121 gdb::byte_vector m_saved_copy;
122 displaced_step_copy_insn_closure_up m_copy_insn_closure;
123 };
124
125
126 #endif /* DISPLACED_STEPPING_H */
This page took 0.030882 seconds and 3 git commands to generate.