gdb: stop trying to prepare displaced steps for an inferior when it returns _UNAVAILABLE
[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;
d6864985
SM
70
71 bool unavailable = false;
e088209c
SM
72};
73
74/* Per-thread displaced stepping state. */
75
76struct displaced_step_thread_state
77{
78 /* Return true if this thread is currently executing a displaced step. */
79 bool in_progress () const
80 { return m_original_gdbarch != nullptr; }
81
82 /* Return the gdbarch of the thread prior to the step. */
83 gdbarch *get_original_gdbarch () const
84 { return m_original_gdbarch; }
85
86 /* Mark this thread as currently executing a displaced step.
87
88 ORIGINAL_GDBARCH is the current gdbarch of the thread (before the step
89 is executed). */
90 void set (gdbarch *original_gdbarch)
91 { m_original_gdbarch = original_gdbarch; }
92
93 /* mark this thread as no longer executing a displaced step. */
94 void reset ()
95 { m_original_gdbarch = nullptr; }
96
97private:
98 gdbarch *m_original_gdbarch = nullptr;
99};
100
101/* Manage access to a single displaced stepping buffer, without any
102 sharing. */
103
104struct single_displaced_buffer_manager
105{
106 single_displaced_buffer_manager (CORE_ADDR buffer_addr)
107 : m_buffer_addr (buffer_addr)
108 {}
109
110 displaced_step_prepare_status prepare (thread_info *thread);
111
112 displaced_step_finish_status finish (gdbarch *arch, thread_info *thread,
113 gdb_signal sig);
114
115private:
116
117 CORE_ADDR m_original_pc;
118 CORE_ADDR m_buffer_addr;
119
120 /* If set, the thread currently using the buffer. */
121 thread_info *m_current_thread = nullptr;
122
123 gdb::byte_vector m_saved_copy;
124 displaced_step_copy_insn_closure_up m_copy_insn_closure;
125};
126
127
128#endif /* DISPLACED_STEPPING_H */
This page took 0.027883 seconds and 4 git commands to generate.