diff options
Diffstat (limited to 'gdb/trad-frame.h')
-rw-r--r-- | gdb/trad-frame.h | 173 |
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 |