aboutsummaryrefslogtreecommitdiff
path: root/gdb/trad-frame.h
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/trad-frame.h')
-rw-r--r--gdb/trad-frame.h173
1 files changed, 131 insertions, 42 deletions
diff --git a/gdb/trad-frame.h b/gdb/trad-frame.h
index 2df10dc..cdc937c 100644
--- a/gdb/trad-frame.h
+++ b/gdb/trad-frame.h
@@ -62,88 +62,177 @@ struct value *trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
struct frame_info *this_frame,
int regnum);
-/* A traditional saved regs table, indexed by REGNUM, encoding where
- the value of REGNUM for the previous frame can be found in this
- frame.
-
- The table is initialized with an identity encoding (ADDR == -1,
- REALREG == REGNUM) indicating that the value of REGNUM in the
- previous frame can be found in register REGNUM (== REALREG) in this
- frame.
-
- The initial encoding can then be changed:
-
- Modify ADDR (REALREG >= 0, ADDR != -1) to indicate that the value
- of register REGNUM in the previous frame can be found in memory at
- ADDR in this frame (addr_p, !realreg_p, !value_p).
-
- Modify REALREG (REALREG >= 0, ADDR == -1) to indicate that the
- value of register REGNUM in the previous frame is found in register
- REALREG in this frame (!addr_p, realreg_p, !value_p).
-
- Call trad_frame_set_value (REALREG == -1) to indicate that the
- value of register REGNUM in the previous frame is found in ADDR
- (!addr_p, !realreg_p, value_p).
+/* Describes the kind of encoding a stored register has. */
+enum class trad_frame_saved_reg_kind
+{
+ /* Register value is unknown. */
+ UNKNOWN = 0,
+ /* Register value is a constant. */
+ VALUE,
+ /* Register value is in another register. */
+ REALREG,
+ /* Register value is at an address. */
+ ADDR,
+ /* Register value is a sequence of bytes. */
+ VALUE_BYTES
+};
- Call trad_frame_set_unknown (REALREG == -2) to indicate that the
- register's value is not known. */
+/* A struct that describes a saved register in a frame. */
struct trad_frame_saved_reg
{
- LONGEST addr; /* A CORE_ADDR fits in a longest. */
- int realreg;
- /* Register data (for values that don't fit in ADDR). */
- gdb_byte *data;
+ /* Setters */
+
+ /* Encode that the saved register's value is constant VAL in the
+ trad-frame. */
+ void set_value (LONGEST val)
+ {
+ m_kind = trad_frame_saved_reg_kind::VALUE;
+ m_reg.value = val;
+ }
+
+ /* Encode that the saved register's value is stored in register REALREG. */
+ void set_realreg (int realreg)
+ {
+ m_kind = trad_frame_saved_reg_kind::REALREG;
+ m_reg.realreg = realreg;
+ }
+
+ /* Encode that the saved register's value is stored in memory at ADDR. */
+ void set_addr (LONGEST addr)
+ {
+ m_kind = trad_frame_saved_reg_kind::ADDR;
+ m_reg.addr = addr;
+ }
+
+ /* Encode that the saved register's value is unknown. */
+ void set_unknown ()
+ {
+ m_kind = trad_frame_saved_reg_kind::UNKNOWN;
+ }
+
+ /* Encode that the saved register's value is stored as a sequence of bytes.
+ This is useful when the value is larger than what primitive types
+ can hold. */
+ void set_value_bytes (const gdb_byte *value_bytes)
+ {
+ m_kind = trad_frame_saved_reg_kind::VALUE_BYTES;
+ m_reg.value_bytes = value_bytes;
+ }
+
+ /* Getters */
+
+ LONGEST value () const
+ {
+ gdb_assert (m_kind == trad_frame_saved_reg_kind::VALUE);
+ return m_reg.value;
+ }
+
+ int realreg () const
+ {
+ gdb_assert (m_kind == trad_frame_saved_reg_kind::REALREG);
+ return m_reg.realreg;
+ }
+
+ LONGEST addr () const
+ {
+ gdb_assert (m_kind == trad_frame_saved_reg_kind::ADDR);
+ return m_reg.addr;
+ }
+
+ const gdb_byte *value_bytes () const
+ {
+ gdb_assert (m_kind == trad_frame_saved_reg_kind::VALUE_BYTES);
+ return m_reg.value_bytes;
+ }
+
+ /* Convenience functions, return true if the register has been
+ encoded as specified. Return false otherwise. */
+ bool is_value () const
+ {
+ return m_kind == trad_frame_saved_reg_kind::VALUE;
+ }
+
+ bool is_realreg () const
+ {
+ return m_kind == trad_frame_saved_reg_kind::REALREG;
+ }
+
+ bool is_addr () const
+ {
+ return m_kind == trad_frame_saved_reg_kind::ADDR;
+ }
+
+ bool is_unknown () const
+ {
+ return m_kind == trad_frame_saved_reg_kind::UNKNOWN;
+ }
+
+ bool is_value_bytes () const
+ {
+ return m_kind == trad_frame_saved_reg_kind::VALUE_BYTES;
+ }
+
+private:
+
+ trad_frame_saved_reg_kind m_kind;
+
+ union {
+ LONGEST value;
+ int realreg;
+ LONGEST addr;
+ const gdb_byte *value_bytes;
+ } m_reg;
};
/* Encode REGNUM value in the trad-frame. */
-void trad_frame_set_value (struct trad_frame_saved_reg this_saved_regs[],
+void trad_frame_set_value (trad_frame_saved_reg this_saved_regs[],
int regnum, LONGEST val);
/* Encode REGNUM is in REALREG in the trad-frame. */
-void trad_frame_set_realreg (struct trad_frame_saved_reg this_saved_regs[],
+void trad_frame_set_realreg (trad_frame_saved_reg this_saved_regs[],
int regnum, int realreg);
/* Encode REGNUM is at address ADDR in the trad-frame. */
-void trad_frame_set_addr (struct trad_frame_saved_reg this_trad_cache[],
+void trad_frame_set_addr (trad_frame_saved_reg this_trad_cache[],
int regnum, CORE_ADDR addr);
/* Mark REGNUM as unknown. */
-void trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[],
+void trad_frame_set_unknown (trad_frame_saved_reg this_saved_regs[],
int regnum);
/* Encode REGNUM value in the trad-frame as a sequence of bytes. This is
useful when the value is larger than what primitive types can hold. */
-void trad_frame_set_value_bytes (struct trad_frame_saved_reg this_saved_regs[],
+void trad_frame_set_value_bytes (trad_frame_saved_reg this_saved_regs[],
int regnum, const gdb_byte *bytes,
size_t size);
/* Convenience functions, return non-zero if the register has been
encoded as specified. */
-int trad_frame_value_p (struct trad_frame_saved_reg this_saved_regs[],
+int trad_frame_value_p (trad_frame_saved_reg this_saved_regs[],
int regnum);
-int trad_frame_addr_p (struct trad_frame_saved_reg this_saved_regs[],
+int trad_frame_addr_p (trad_frame_saved_reg this_saved_regs[],
int regnum);
-int trad_frame_realreg_p (struct trad_frame_saved_reg this_saved_regs[],
+int trad_frame_realreg_p (trad_frame_saved_reg this_saved_regs[],
int regnum);
/* Return TRUE if REGNUM is stored as a sequence of bytes, and FALSE
otherwise. */
-bool trad_frame_value_bytes_p (struct trad_frame_saved_reg this_saved_regs[],
+bool trad_frame_value_bytes_p (trad_frame_saved_reg this_saved_regs[],
int regnum);
-/* Reset the save regs cache, setting register values to -1. */
+/* Reset the saved regs cache, setting register values to -1. */
void trad_frame_reset_saved_regs (struct gdbarch *gdbarch,
- struct trad_frame_saved_reg *regs);
+ trad_frame_saved_reg *regs);
/* Return a freshly allocated (and initialized) trad_frame array. */
-struct trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct frame_info *);
-struct trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct gdbarch *);
+trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct frame_info *);
+trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct gdbarch *);
/* Given the trad_frame info, return the location of the specified
register. */
struct value *trad_frame_get_prev_register (struct frame_info *this_frame,
- struct trad_frame_saved_reg this_saved_regs[],
+ trad_frame_saved_reg this_saved_regs[],
int regnum);
#endif