aboutsummaryrefslogtreecommitdiff
path: root/gdb/frame-unwind.h
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/frame-unwind.h')
-rw-r--r--gdb/frame-unwind.h184
1 files changed, 167 insertions, 17 deletions
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index 53fcd68..a967b7c 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -1,6 +1,6 @@
/* Definitions for a frame unwinder, for GDB, the GNU debugger.
- Copyright (C) 2003-2024 Free Software Foundation, Inc.
+ Copyright (C) 2003-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -17,8 +17,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#if !defined (FRAME_UNWIND_H)
-#define FRAME_UNWIND_H 1
+#ifndef GDB_FRAME_UNWIND_H
+#define GDB_FRAME_UNWIND_H
struct frame_data;
class frame_info_ptr;
@@ -156,21 +156,171 @@ typedef void (frame_dealloc_cache_ftype) (frame_info *self,
typedef gdbarch *(frame_prev_arch_ftype) (const frame_info_ptr &this_frame,
void **this_prologue_cache);
-struct frame_unwind
+/* Unwinders are classified by what part of GDB code created it. */
+enum frame_unwind_class
{
- const char *name;
+ /* This is mostly handled by core GDB code. */
+ FRAME_UNWIND_GDB,
+ /* This unwinder was added by one of GDB's extension languages. */
+ FRAME_UNWIND_EXTENSION,
+ /* The unwinder was created and mostly handles debug information. */
+ FRAME_UNWIND_DEBUGINFO,
+ /* The unwinder was created and handles target dependent things. */
+ FRAME_UNWIND_ARCH,
+ /* Meta enum value, to ensure we're always sent a valid unwinder class. */
+ UNWIND_CLASS_NUMBER,
+};
+
+class frame_unwind
+{
+public:
+ frame_unwind (const char *name, frame_type type, frame_unwind_class uclass,
+ const frame_data *data)
+ : m_name (name), m_type (type), m_unwinder_class (uclass),
+ m_unwind_data (data)
+ { }
+
+ const char *name () const
+ { return m_name; }
+
+ frame_type type () const
+ { return m_type; }
+
+ frame_unwind_class unwinder_class () const
+ { return m_unwinder_class; }
+
+ const frame_data *unwind_data () const
+ { return m_unwind_data; }
+
+ bool enabled () const
+ { return m_enabled; }
+
+ void set_enabled (bool state) const
+ { m_enabled = state; }
+
+ /* Default stop_reason implementation. It reports NO_REASON, unless the
+ frame is the outermost. */
+
+ virtual unwind_stop_reason stop_reason (const frame_info_ptr &this_frame,
+ void **this_prologue_cache) const
+ {
+ return default_frame_unwind_stop_reason (this_frame, this_prologue_cache);
+ }
+
+ /* Default frame sniffer. Will always return that the unwinder
+ is able to unwind the frame. */
+
+ virtual int sniff (const frame_info_ptr &this_frame,
+ void **this_prologue_cache) const
+ { return 1; }
+
+ /* Calculate the ID of the given frame using this unwinder. */
+
+ virtual void this_id (const frame_info_ptr &this_frame,
+ void **this_prologue_cache,
+ struct frame_id *id) const = 0;
+
+ /* Get the value of a register in a previous frame. */
+
+ virtual struct value *prev_register (const frame_info_ptr &this_frame,
+ void **this_prologue_cache,
+ int regnum) const = 0;
+
+ /* Properly deallocate the cache. */
+
+ virtual void dealloc_cache (frame_info *self, void *this_cache) const
+ { }
+
+ /* Get the previous architecture. */
+
+ virtual gdbarch *prev_arch (const frame_info_ptr &this_frame,
+ void **this_prologue_cache) const
+ { return get_frame_arch (this_frame); }
+
+private:
+
+ /* Name of the unwinder. Used to uniquely identify unwinders. */
+ const char *m_name;
+
/* The frame's type. Should this instead be a collection of
predicates that test the frame for various attributes? */
- enum frame_type type;
- /* Should an attribute indicating the frame's address-in-block go
- here? */
- frame_unwind_stop_reason_ftype *stop_reason;
- frame_this_id_ftype *this_id;
- frame_prev_register_ftype *prev_register;
- const struct frame_data *unwind_data;
- frame_sniffer_ftype *sniffer;
- frame_dealloc_cache_ftype *dealloc_cache;
- frame_prev_arch_ftype *prev_arch;
+ frame_type m_type;
+
+ /* What kind of unwinder is this. It generally follows from where
+ the unwinder was added or where it looks for information to do the
+ unwinding. */
+ frame_unwind_class m_unwinder_class;
+
+ /* Additional data used by the trampoline and python frame unwinders. */
+ const frame_data *m_unwind_data;
+
+ /* Whether this unwinder can be used when sniffing. */
+ mutable bool m_enabled = true;
+};
+
+/* This is a legacy version of the frame unwinder. The original struct
+ used function pointers for callbacks, this updated version has a
+ method that just passes the parameters along to the callback
+ pointer.
+ Do not use this class for new unwinders. Instead, see other classes
+ that inherit from frame_unwind, such as the python unwinder. */
+struct frame_unwind_legacy : public frame_unwind
+{
+ frame_unwind_legacy (const char *name, frame_type type,
+ frame_unwind_class uclass,
+ frame_unwind_stop_reason_ftype *stop_reason_func,
+ frame_this_id_ftype *this_id_func,
+ frame_prev_register_ftype *prev_register_func,
+ const struct frame_data *data,
+ frame_sniffer_ftype *sniffer_func,
+ frame_dealloc_cache_ftype *dealloc_cache_func = nullptr,
+ frame_prev_arch_ftype *prev_arch_func = nullptr)
+ : frame_unwind (name, type, uclass, data), m_stop_reason (stop_reason_func),
+ m_this_id (this_id_func), m_prev_register (prev_register_func),
+ m_sniffer (sniffer_func), m_dealloc_cache (dealloc_cache_func),
+ m_prev_arch (prev_arch_func)
+ { }
+
+ /* This method just passes the parameters to the callback pointer. */
+
+ enum unwind_stop_reason stop_reason (const frame_info_ptr &this_frame,
+ void **this_prologue_cache) const override;
+
+ /* This method just passes the parameters to the callback pointer. */
+
+ void this_id (const frame_info_ptr &this_frame, void **this_prologue_cache,
+ struct frame_id *id) const override;
+
+ /* This method just passes the parameters to the callback pointer. */
+
+ struct value *prev_register (const frame_info_ptr &this_frame,
+ void **this_prologue_cache,
+ int regnum) const override;
+
+ /* This method just passes the parameters to the callback pointer. */
+
+ int sniff (const frame_info_ptr &this_frame,
+ void **this_prologue_cache) const override;
+
+ /* This method just passes the parameters to the callback pointer.
+ It is safe to call this method if no callback is installed, it
+ just turns into a noop. */
+
+ void dealloc_cache (frame_info *self, void *this_cache) const override;
+
+ /* This method just passes the parameters to the callback pointer. */
+
+ struct gdbarch *prev_arch (const frame_info_ptr &this_frame,
+ void **this_prologue_cache) const override;
+
+private:
+
+ frame_unwind_stop_reason_ftype *m_stop_reason;
+ frame_this_id_ftype *m_this_id;
+ frame_prev_register_ftype *m_prev_register;
+ frame_sniffer_ftype *m_sniffer;
+ frame_dealloc_cache_ftype *m_dealloc_cache;
+ frame_prev_arch_ftype *m_prev_arch;
};
/* Register a frame unwinder, _prepending_ it to the front of the
@@ -226,7 +376,7 @@ value *frame_unwind_got_constant (const frame_info_ptr &frame, int regnum,
inside BUF. */
value *frame_unwind_got_bytes (const frame_info_ptr &frame, int regnum,
- const gdb_byte *buf);
+ gdb::array_view<const gdb_byte> buf);
/* Return a value which indicates that FRAME's saved version of REGNUM
has a known constant (computed) value of ADDR. Convert the
@@ -235,4 +385,4 @@ value *frame_unwind_got_bytes (const frame_info_ptr &frame, int regnum,
value *frame_unwind_got_address (const frame_info_ptr &frame, int regnum,
CORE_ADDR addr);
-#endif
+#endif /* GDB_FRAME_UNWIND_H */