gdb: move displaced stepping logic to gdbarch, allow starting concurrent displaced...
[deliverable/binutils-gdb.git] / gdb / displaced-stepping.h
CommitLineData
e088209c
SM
1#ifndef DISPLACED_STEPPING_H
2#define DISPLACED_STEPPING_H
3
4#include "gdbsupport/byte-vector.h"
5
6struct gdbarch;
7struct thread_info;
8
9enum 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
21enum 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
33struct displaced_step_copy_insn_closure
34{
35 virtual ~displaced_step_copy_insn_closure () = 0;
36};
37
38typedef 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
43struct 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
54struct 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
74struct 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
95private:
96 gdbarch *m_original_gdbarch = nullptr;
97};
98
99/* Manage access to a single displaced stepping buffer, without any
100 sharing. */
101
102struct 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
113private:
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.027569 seconds and 4 git commands to generate.