1 #ifndef DISPLACED_STEPPING_H
2 #define DISPLACED_STEPPING_H
4 #include "gdbsupport/byte-vector.h"
9 enum displaced_step_prepare_status
11 /* A displaced stepping buffer was successfully allocated and prepared. */
12 DISPLACED_STEP_PREPARE_STATUS_OK
,
14 /* Something bad happened. */
15 DISPLACED_STEP_PREPARE_STATUS_ERROR
,
17 /* Not enough resources are available at this time, try again later. */
18 DISPLACED_STEP_PREPARE_STATUS_UNAVAILABLE
,
21 enum displaced_step_finish_status
23 /* The instruction was stepped and fixed up. */
24 DISPLACED_STEP_FINISH_STATUS_OK
,
26 /* The instruction was not stepped. */
27 DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED
,
30 /* Data returned by a gdbarch displaced_step_copy_insn method, to be passed to
31 the matching displaced_step_fixup method. */
33 struct displaced_step_copy_insn_closure
35 virtual ~displaced_step_copy_insn_closure () = 0;
38 typedef std::unique_ptr
<displaced_step_copy_insn_closure
>
39 displaced_step_copy_insn_closure_up
;
41 /* A simple displaced step closure that contains only a byte buffer. */
43 struct buf_displaced_step_copy_insn_closure
: displaced_step_copy_insn_closure
45 buf_displaced_step_copy_insn_closure (int buf_size
)
52 /* Per-inferior displaced stepping state. */
54 struct displaced_step_inferior_state
56 displaced_step_inferior_state ()
61 /* Put this object back in its original state. */
64 failed_before
= false;
67 /* True if preparing a displaced step ever failed. If so, we won't
68 try displaced stepping for this inferior again. */
72 /* Per-thread displaced stepping state. */
74 struct displaced_step_thread_state
76 /* Return true if this thread is currently executing a displaced step. */
77 bool in_progress () const
78 { return m_original_gdbarch
!= nullptr; }
80 /* Return the gdbarch of the thread prior to the step. */
81 gdbarch
*get_original_gdbarch () const
82 { return m_original_gdbarch
; }
84 /* Mark this thread as currently executing a displaced step.
86 ORIGINAL_GDBARCH is the current gdbarch of the thread (before the step
88 void set (gdbarch
*original_gdbarch
)
89 { m_original_gdbarch
= original_gdbarch
; }
91 /* mark this thread as no longer executing a displaced step. */
93 { m_original_gdbarch
= nullptr; }
96 gdbarch
*m_original_gdbarch
= nullptr;
99 /* Manage access to a single displaced stepping buffer, without any
102 struct single_displaced_buffer_manager
104 single_displaced_buffer_manager (CORE_ADDR buffer_addr
)
105 : m_buffer_addr (buffer_addr
)
108 displaced_step_prepare_status
prepare (thread_info
*thread
);
110 displaced_step_finish_status
finish (gdbarch
*arch
, thread_info
*thread
,
115 CORE_ADDR m_original_pc
;
116 CORE_ADDR m_buffer_addr
;
118 /* If set, the thread currently using the buffer. */
119 thread_info
*m_current_thread
= nullptr;
121 gdb::byte_vector m_saved_copy
;
122 displaced_step_copy_insn_closure_up m_copy_insn_closure
;
126 #endif /* DISPLACED_STEPPING_H */