gdb/riscv: Add command to switch between numeric & abi register names
[binutils-gdb.git] / gdb / target / waitstatus.h
blob0ba5b9cecbfc591897d1cd0fa03573fec43bca1e
1 /* Target waitstatus definitions and prototypes.
3 Copyright (C) 1990-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #ifndef GDB_TARGET_WAITSTATUS_H
21 #define GDB_TARGET_WAITSTATUS_H
23 #include "diagnostics.h"
24 #include "gdb/signals.h"
26 /* Stuff for target_wait. */
28 /* Generally, what has the program done? */
29 enum target_waitkind
31 /* The program has exited. The exit status is in value.integer. */
32 TARGET_WAITKIND_EXITED,
34 /* The program has stopped with a signal. Which signal is in
35 value.sig. */
36 TARGET_WAITKIND_STOPPED,
38 /* The program has terminated with a signal. Which signal is in
39 value.sig. */
40 TARGET_WAITKIND_SIGNALLED,
42 /* The program is letting us know that it dynamically loaded
43 something (e.g. it called load(2) on AIX). */
44 TARGET_WAITKIND_LOADED,
46 /* The program has forked. A "related" process' PTID is in
47 value.related_pid. I.e., if the child forks, value.related_pid
48 is the parent's ID. */
49 TARGET_WAITKIND_FORKED,
51 /* The program has vforked. A "related" process's PTID is in
52 value.related_pid. */
53 TARGET_WAITKIND_VFORKED,
55 /* The program has exec'ed a new executable file. The new file's
56 pathname is pointed to by value.execd_pathname. */
57 TARGET_WAITKIND_EXECD,
59 /* The program had previously vforked, and now the child is done
60 with the shared memory region, because it exec'ed or exited.
61 Note that the event is reported to the vfork parent. This is
62 only used if GDB did not stay attached to the vfork child,
63 otherwise, a TARGET_WAITKIND_EXECD or
64 TARGET_WAITKIND_EXIT|SIGNALLED event associated with the child
65 has the same effect. */
66 TARGET_WAITKIND_VFORK_DONE,
68 /* The program has entered or returned from a system call. On
69 HP-UX, this is used in the hardware watchpoint implementation.
70 The syscall's unique integer ID number is in
71 value.syscall_id. */
72 TARGET_WAITKIND_SYSCALL_ENTRY,
73 TARGET_WAITKIND_SYSCALL_RETURN,
75 /* Nothing happened, but we stopped anyway. This perhaps should
76 be handled within target_wait, but I'm not sure target_wait
77 should be resuming the inferior. */
78 TARGET_WAITKIND_SPURIOUS,
80 /* An event has occurred, but we should wait again.
81 Remote_async_wait() returns this when there is an event
82 on the inferior, but the rest of the world is not interested in
83 it. The inferior has not stopped, but has just sent some output
84 to the console, for instance. In this case, we want to go back
85 to the event loop and wait there for another event from the
86 inferior, rather than being stuck in the remote_async_wait()
87 function. This way the event loop is responsive to other events,
88 like for instance the user typing. */
89 TARGET_WAITKIND_IGNORE,
91 /* The target has run out of history information,
92 and cannot run backward any further. */
93 TARGET_WAITKIND_NO_HISTORY,
95 /* There are no resumed children left in the program. */
96 TARGET_WAITKIND_NO_RESUMED,
98 /* The thread was cloned. The event's ptid corresponds to the
99 cloned parent. The cloned child is held stopped at its entry
100 point, and its ptid is in the event's m_child_ptid. The target
101 must not add the cloned child to GDB's thread list until
102 target_ops::follow_clone() is called. */
103 TARGET_WAITKIND_THREAD_CLONED,
105 /* The thread was created. */
106 TARGET_WAITKIND_THREAD_CREATED,
108 /* The thread has exited. The exit status is in value.integer. */
109 TARGET_WAITKIND_THREAD_EXITED,
112 /* Determine if KIND represents an event with a new child - a fork,
113 vfork, or clone. */
115 static inline bool
116 is_new_child_status (target_waitkind kind)
118 return (kind == TARGET_WAITKIND_FORKED
119 || kind == TARGET_WAITKIND_VFORKED
120 || kind == TARGET_WAITKIND_THREAD_CLONED);
123 /* Return KIND as a string. */
125 static inline const char *
126 target_waitkind_str (target_waitkind kind)
128 /* Make sure the compiler warns if a new TARGET_WAITKIND enumerator is added
129 but not handled here. */
130 DIAGNOSTIC_PUSH
131 DIAGNOSTIC_ERROR_SWITCH
132 switch (kind)
134 case TARGET_WAITKIND_EXITED:
135 return "EXITED";
136 case TARGET_WAITKIND_STOPPED:
137 return "STOPPED";
138 case TARGET_WAITKIND_SIGNALLED:
139 return "SIGNALLED";
140 case TARGET_WAITKIND_LOADED:
141 return "LOADED";
142 case TARGET_WAITKIND_FORKED:
143 return "FORKED";
144 case TARGET_WAITKIND_VFORKED:
145 return "VFORKED";
146 case TARGET_WAITKIND_THREAD_CLONED:
147 return "THREAD_CLONED";
148 case TARGET_WAITKIND_EXECD:
149 return "EXECD";
150 case TARGET_WAITKIND_VFORK_DONE:
151 return "VFORK_DONE";
152 case TARGET_WAITKIND_SYSCALL_ENTRY:
153 return "SYSCALL_ENTRY";
154 case TARGET_WAITKIND_SYSCALL_RETURN:
155 return "SYSCALL_RETURN";
156 case TARGET_WAITKIND_SPURIOUS:
157 return "SPURIOUS";
158 case TARGET_WAITKIND_IGNORE:
159 return "IGNORE";
160 case TARGET_WAITKIND_NO_HISTORY:
161 return "NO_HISTORY";
162 case TARGET_WAITKIND_NO_RESUMED:
163 return "NO_RESUMED";
164 case TARGET_WAITKIND_THREAD_CREATED:
165 return "THREAD_CREATED";
166 case TARGET_WAITKIND_THREAD_EXITED:
167 return "THREAD_EXITED";
169 DIAGNOSTIC_POP
171 gdb_assert_not_reached ("invalid target_waitkind value: %d\n", (int) kind);
174 struct target_waitstatus
176 /* Default constructor. */
177 target_waitstatus () = default;
179 /* Copy constructor. */
181 target_waitstatus (const target_waitstatus &other)
183 m_kind = other.m_kind;
184 m_value = other.m_value;
186 if (m_kind == TARGET_WAITKIND_EXECD)
187 m_value.execd_pathname = xstrdup (m_value.execd_pathname);
190 /* Move constructor. */
192 target_waitstatus (target_waitstatus &&other)
194 m_kind = other.m_kind;
195 m_value = other.m_value;
197 if (m_kind == TARGET_WAITKIND_EXECD)
198 other.m_value.execd_pathname = nullptr;
200 other.reset ();
203 /* Copy assignment operator. */
205 target_waitstatus &operator= (const target_waitstatus &rhs)
207 this->reset ();
208 m_kind = rhs.m_kind;
209 m_value = rhs.m_value;
211 if (m_kind == TARGET_WAITKIND_EXECD)
212 m_value.execd_pathname = xstrdup (m_value.execd_pathname);
214 return *this;
217 /* Move assignment operator. */
219 target_waitstatus &operator= (target_waitstatus &&rhs)
221 this->reset ();
222 m_kind = rhs.m_kind;
223 m_value = rhs.m_value;
225 if (m_kind == TARGET_WAITKIND_EXECD)
226 rhs.m_value.execd_pathname = nullptr;
228 rhs.reset ();
230 return *this;
233 /* Destructor. */
235 ~target_waitstatus ()
237 this->reset ();
240 /* Setters: set the wait status kind plus any associated data. */
242 target_waitstatus &set_exited (int exit_status)
244 this->reset ();
245 m_kind = TARGET_WAITKIND_EXITED;
246 m_value.exit_status = exit_status;
247 return *this;
250 target_waitstatus &set_stopped (gdb_signal sig)
252 this->reset ();
253 m_kind = TARGET_WAITKIND_STOPPED;
254 m_value.sig = sig;
255 return *this;
258 target_waitstatus &set_signalled (gdb_signal sig)
260 this->reset ();
261 m_kind = TARGET_WAITKIND_SIGNALLED;
262 m_value.sig = sig;
263 return *this;
266 target_waitstatus &set_loaded ()
268 this->reset ();
269 m_kind = TARGET_WAITKIND_LOADED;
270 return *this;
273 target_waitstatus &set_forked (ptid_t child_ptid)
275 this->reset ();
276 m_kind = TARGET_WAITKIND_FORKED;
277 m_value.child_ptid = child_ptid;
278 return *this;
281 target_waitstatus &set_vforked (ptid_t child_ptid)
283 this->reset ();
284 m_kind = TARGET_WAITKIND_VFORKED;
285 m_value.child_ptid = child_ptid;
286 return *this;
289 target_waitstatus &set_execd (gdb::unique_xmalloc_ptr<char> execd_pathname)
291 this->reset ();
292 m_kind = TARGET_WAITKIND_EXECD;
293 m_value.execd_pathname = execd_pathname.release ();
294 return *this;
297 target_waitstatus &set_vfork_done ()
299 this->reset ();
300 m_kind = TARGET_WAITKIND_VFORK_DONE;
301 return *this;
304 target_waitstatus &set_syscall_entry (int syscall_number)
306 this->reset ();
307 m_kind = TARGET_WAITKIND_SYSCALL_ENTRY;
308 m_value.syscall_number = syscall_number;
309 return *this;
312 target_waitstatus &set_syscall_return (int syscall_number)
314 this->reset ();
315 m_kind = TARGET_WAITKIND_SYSCALL_RETURN;
316 m_value.syscall_number = syscall_number;
317 return *this;
320 target_waitstatus &set_spurious ()
322 this->reset ();
323 m_kind = TARGET_WAITKIND_SPURIOUS;
324 return *this;
327 target_waitstatus &set_ignore ()
329 this->reset ();
330 m_kind = TARGET_WAITKIND_IGNORE;
331 return *this;
334 target_waitstatus &set_no_history ()
336 this->reset ();
337 m_kind = TARGET_WAITKIND_NO_HISTORY;
338 return *this;
341 target_waitstatus &set_no_resumed ()
343 this->reset ();
344 m_kind = TARGET_WAITKIND_NO_RESUMED;
345 return *this;
348 target_waitstatus &set_thread_cloned (ptid_t child_ptid)
350 this->reset ();
351 m_kind = TARGET_WAITKIND_THREAD_CLONED;
352 m_value.child_ptid = child_ptid;
353 return *this;
356 target_waitstatus &set_thread_created ()
358 this->reset ();
359 m_kind = TARGET_WAITKIND_THREAD_CREATED;
360 return *this;
363 target_waitstatus &set_thread_exited (int exit_status)
365 this->reset ();
366 m_kind = TARGET_WAITKIND_THREAD_EXITED;
367 m_value.exit_status = exit_status;
368 return *this;
371 /* Get the kind of this wait status. */
373 target_waitkind kind () const
375 return m_kind;
378 /* Getters for the associated data.
380 Getters can only be used if the wait status is of the appropriate kind.
381 See the setters above or the assertions below to know which data is
382 associated to which kind. */
384 int exit_status () const
386 gdb_assert (m_kind == TARGET_WAITKIND_EXITED
387 || m_kind == TARGET_WAITKIND_THREAD_EXITED);
388 return m_value.exit_status;
391 gdb_signal sig () const
393 gdb_assert (m_kind == TARGET_WAITKIND_STOPPED
394 || m_kind == TARGET_WAITKIND_SIGNALLED);
395 return m_value.sig;
398 ptid_t child_ptid () const
400 gdb_assert (is_new_child_status (m_kind));
401 return m_value.child_ptid;
404 const char *execd_pathname () const
406 gdb_assert (m_kind == TARGET_WAITKIND_EXECD);
407 return m_value.execd_pathname;
410 int syscall_number () const
412 gdb_assert (m_kind == TARGET_WAITKIND_SYSCALL_ENTRY
413 || m_kind == TARGET_WAITKIND_SYSCALL_RETURN);
414 return m_value.syscall_number;
417 /* Return a pretty printed form of target_waitstatus.
419 This is only meant to be used in debug messages, not for user-visible
420 messages. */
421 std::string to_string () const;
423 private:
424 /* Reset the wait status to its original state. */
425 void reset ()
427 if (m_kind == TARGET_WAITKIND_EXECD)
428 xfree (m_value.execd_pathname);
430 m_kind = TARGET_WAITKIND_IGNORE;
433 target_waitkind m_kind = TARGET_WAITKIND_IGNORE;
435 /* Additional information about the event. */
436 union
438 /* Exit status */
439 int exit_status;
440 /* Signal number */
441 enum gdb_signal sig;
442 /* Forked child pid */
443 ptid_t child_ptid;
444 /* execd pathname */
445 char *execd_pathname;
446 /* Syscall number */
447 int syscall_number;
448 } m_value {};
451 /* Extended reasons that can explain why a target/thread stopped for a
452 trap signal. */
454 enum target_stop_reason
456 /* Either not stopped, or stopped for a reason that doesn't require
457 special tracking. */
458 TARGET_STOPPED_BY_NO_REASON,
460 /* Stopped by a software breakpoint. */
461 TARGET_STOPPED_BY_SW_BREAKPOINT,
463 /* Stopped by a hardware breakpoint. */
464 TARGET_STOPPED_BY_HW_BREAKPOINT,
466 /* Stopped by a watchpoint. */
467 TARGET_STOPPED_BY_WATCHPOINT,
469 /* Stopped by a single step finishing. */
470 TARGET_STOPPED_BY_SINGLE_STEP
473 #endif /* GDB_TARGET_WAITSTATUS_H */