Update copyright year range in all GDB files
[deliverable/binutils-gdb.git] / gdb / regcache.h
index 1e4ee86adc83b0322a5c3dfe818527ed5de0f410..9e3da8c3fc5dcab58dfbe75665fd6a10907bd16a 100644 (file)
@@ -1,7 +1,6 @@
 /* Cache and manage the values of registers for GDB, the GNU debugger.
 
-   Copyright (C) 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001,
-   2002, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 1986-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #ifndef REGCACHE_H
 #define REGCACHE_H
 
+#include "common-regcache.h"
+#include <forward_list>
+
 struct regcache;
+struct regset;
 struct gdbarch;
+struct address_space;
 
 extern struct regcache *get_current_regcache (void);
 extern struct regcache *get_thread_regcache (ptid_t ptid);
+extern struct regcache *get_thread_arch_regcache (ptid_t, struct gdbarch *);
+extern struct regcache *get_thread_arch_aspace_regcache (ptid_t,
+                                                        struct gdbarch *,
+                                                        struct address_space *);
+
+/* Return REGCACHE's ptid.  */
+
+extern ptid_t regcache_get_ptid (const struct regcache *regcache);
 
-void regcache_xfree (struct regcache *regcache);
-struct cleanup *make_cleanup_regcache_xfree (struct regcache *regcache);
-struct regcache *regcache_xmalloc (struct gdbarch *gdbarch);
+enum register_status regcache_register_status (const struct regcache *regcache,
+                                              int regnum);
 
-/* Return REGCACHE's architecture.  */
+/* Make certain that the register REGNUM in REGCACHE is up-to-date.  */
 
-extern struct gdbarch *get_regcache_arch (const struct regcache *regcache);
+void regcache_raw_update (struct regcache *regcache, int regnum);
 
 /* Transfer a raw register [0..NUM_REGS) between core-gdb and the
-   regcache. */
+   regcache.  The read variants return the status of the register.  */
 
-void regcache_raw_read (struct regcache *regcache, int rawnum, gdb_byte *buf);
+enum register_status regcache_raw_read (struct regcache *regcache,
+                                       int rawnum, gdb_byte *buf);
 void regcache_raw_write (struct regcache *regcache, int rawnum,
                         const gdb_byte *buf);
-extern void regcache_raw_read_signed (struct regcache *regcache,
-                                     int regnum, LONGEST *val);
-extern void regcache_raw_read_unsigned (struct regcache *regcache,
-                                       int regnum, ULONGEST *val);
+extern enum register_status
+  regcache_raw_read_signed (struct regcache *regcache,
+                           int regnum, LONGEST *val);
+
 extern void regcache_raw_write_signed (struct regcache *regcache,
                                       int regnum, LONGEST val);
 extern void regcache_raw_write_unsigned (struct regcache *regcache,
                                         int regnum, ULONGEST val);
 
-/* Partial transfer of a raw registers.  These perform read, modify,
-   write style operations.  */
+/* Return the register's value in signed or throw if it's not
+   available.  */
 
-void regcache_raw_read_part (struct regcache *regcache, int regnum,
-                            int offset, int len, gdb_byte *buf);
+extern LONGEST regcache_raw_get_signed (struct regcache *regcache,
+                                       int regnum);
+
+/* Set a raw register's value in the regcache's buffer.  Unlike
+   regcache_raw_write, this is not write-through.  The intention is
+   allowing to change the buffer contents of a read-only regcache
+   allocated with new.  */
+
+extern void regcache_raw_set_cached_value
+  (struct regcache *regcache, int regnum, const gdb_byte *buf);
+
+/* Partial transfer of raw registers.  These perform read, modify,
+   write style operations.  The read variant returns the status of the
+   register.  */
+
+extern enum register_status
+  regcache_raw_read_part (struct regcache *regcache, int regnum,
+                         int offset, int len, gdb_byte *buf);
 void regcache_raw_write_part (struct regcache *regcache, int regnum,
                              int offset, int len, const gdb_byte *buf);
 
-int regcache_valid_p (const struct regcache *regcache, int regnum);
-
 void regcache_invalidate (struct regcache *regcache, int regnum);
 
+/* Transfer of pseudo-registers.  The read variants return a register
+   status, as an indication of when a ``cooked'' register was
+   constructed from valid, invalid or unavailable ``raw''
+   registers.  */
+
 /* Transfer a cooked register [0..NUM_REGS+NUM_PSEUDO_REGS).  */
-void regcache_cooked_read (struct regcache *regcache, int rawnum,
-                          gdb_byte *buf);
+enum register_status regcache_cooked_read (struct regcache *regcache,
+                                          int rawnum, gdb_byte *buf);
 void regcache_cooked_write (struct regcache *regcache, int rawnum,
                            const gdb_byte *buf);
 
-/* NOTE: cagney/2002-08-13: At present GDB has no reliable mechanism
-   for indicating when a ``cooked'' register was constructed from
-   invalid or unavailable ``raw'' registers.  One fairly easy way of
-   adding such a mechanism would be for the cooked functions to return
-   a register valid indication.  Given the possibility of such a
-   change, the extract functions below use a reference parameter,
-   rather than a function result.  */
+/* Read register REGNUM from REGCACHE and return a new value.  This
+   will call mark_value_bytes_unavailable as appropriate.  */
+
+struct value *regcache_cooked_read_value (struct regcache *regcache,
+                                         int regnum);
 
 /* Read a register as a signed/unsigned quantity.  */
-extern void regcache_cooked_read_signed (struct regcache *regcache,
-                                        int regnum, LONGEST *val);
-extern void regcache_cooked_read_unsigned (struct regcache *regcache,
-                                          int regnum, ULONGEST *val);
+extern enum register_status
+  regcache_cooked_read_signed (struct regcache *regcache,
+                              int regnum, LONGEST *val);
+extern enum register_status
+  regcache_cooked_read_unsigned (struct regcache *regcache,
+                                int regnum, ULONGEST *val);
 extern void regcache_cooked_write_signed (struct regcache *regcache,
                                          int regnum, LONGEST val);
 extern void regcache_cooked_write_unsigned (struct regcache *regcache,
@@ -89,11 +120,17 @@ extern void regcache_cooked_write_unsigned (struct regcache *regcache,
 /* Partial transfer of a cooked register.  These perform read, modify,
    write style operations.  */
 
-void regcache_cooked_read_part (struct regcache *regcache, int regnum,
-                               int offset, int len, gdb_byte *buf);
+enum register_status regcache_cooked_read_part (struct regcache *regcache,
+                                               int regnum, int offset,
+                                               int len, gdb_byte *buf);
 void regcache_cooked_write_part (struct regcache *regcache, int regnum,
                                 int offset, int len, const gdb_byte *buf);
 
+/* Special routines to read/write the PC.  */
+
+/* For regcache_read_pc see common/common-regcache.h.  */
+extern void regcache_write_pc (struct regcache *regcache, CORE_ADDR pc);
+
 /* Transfer a raw register [0..NUM_REGS) between the regcache and the
    target.  These functions are called by the target in response to a
    target_fetch_registers() or target_store_registers().  */
@@ -103,6 +140,51 @@ extern void regcache_raw_supply (struct regcache *regcache,
 extern void regcache_raw_collect (const struct regcache *regcache,
                                  int regnum, void *buf);
 
+/* Mapping between register numbers and offsets in a buffer, for use
+   in the '*regset' functions below.  In an array of
+   'regcache_map_entry' each element is interpreted like follows:
+
+   - If 'regno' is a register number: Map register 'regno' to the
+     current offset (starting with 0) and increase the current offset
+     by 'size' (or the register's size, if 'size' is zero).  Repeat
+     this with consecutive register numbers up to 'regno+count-1'.
+
+   - If 'regno' is REGCACHE_MAP_SKIP: Add 'count*size' to the current
+     offset.
+
+   - If count=0: End of the map.  */
+
+struct regcache_map_entry
+{
+  int count;
+  int regno;
+  int size;
+};
+
+/* Special value for the 'regno' field in the struct above.  */
+
+enum
+  {
+    REGCACHE_MAP_SKIP = -1,
+  };
+
+/* Transfer a set of registers (as described by REGSET) between
+   REGCACHE and BUF.  If REGNUM == -1, transfer all registers
+   belonging to the regset, otherwise just the register numbered
+   REGNUM.  The REGSET's 'regmap' field must point to an array of
+   'struct regcache_map_entry'.
+
+   These functions are suitable for the 'regset_supply' and
+   'regset_collect' fields in a regset structure.  */
+
+extern void regcache_supply_regset (const struct regset *regset,
+                                   struct regcache *regcache,
+                                   int regnum, const void *buf,
+                                   size_t size);
+extern void regcache_collect_regset (const struct regset *regset,
+                                    const struct regcache *regcache,
+                                    int regnum, void *buf, size_t size);
+
 
 /* The type of a register.  This function is slightly more efficient
    then its gdbarch vector counterpart since it returns a precomputed
@@ -122,30 +204,205 @@ extern int register_size (struct gdbarch *gdbarch, int regnum);
    restore_reggroup respectively.  COOKED_READ returns zero iff the
    register's value can't be returned.  */
 
-typedef int (regcache_cooked_read_ftype) (void *src, int regnum,
-                                         gdb_byte *buf);
+typedef enum register_status (regcache_cooked_read_ftype) (void *src,
+                                                          int regnum,
+                                                          gdb_byte *buf);
 
 extern void regcache_save (struct regcache *dst,
                           regcache_cooked_read_ftype *cooked_read,
                           void *cooked_read_context);
-extern void regcache_restore (struct regcache *dst,
-                             regcache_cooked_read_ftype *cooked_read,
-                             void *cooked_read_context);
 
-/* Copy/duplicate the contents of a register cache.  By default, the
-   operation is pass-through.  Writes to DST and reads from SRC will
-   go through to the target.
+enum regcache_dump_what
+{
+  regcache_dump_none, regcache_dump_raw,
+  regcache_dump_cooked, regcache_dump_groups,
+  regcache_dump_remote
+};
+
+/* A (register_number, register_value) pair.  */
+
+typedef struct cached_reg
+{
+  int num;
+  gdb_byte *data;
+} cached_reg_t;
+
+/* The register cache for storing raw register values.  */
+
+class regcache
+{
+public:
+  regcache (gdbarch *gdbarch)
+    : regcache (gdbarch, nullptr, true)
+  {}
+
+  struct readonly_t {};
+  static constexpr readonly_t readonly {};
+
+  /* Create a readonly regcache from a non-readonly regcache.  */
+  regcache (readonly_t, const regcache &src);
+
+  DISABLE_COPY_AND_ASSIGN (regcache);
+
+  ~regcache ()
+  {
+    xfree (m_registers);
+    xfree (m_register_status);
+  }
+
+  /* Return regcache's architecture.  */
+  gdbarch *arch () const;
+
+  /* Return REGCACHE's address space.  */
+  const address_space *aspace () const
+  {
+    return m_aspace;
+  }
+
+  void save (regcache_cooked_read_ftype *cooked_read, void *src);
+
+  enum register_status cooked_read (int regnum, gdb_byte *buf);
+  void cooked_write (int regnum, const gdb_byte *buf);
+
+  enum register_status raw_read (int regnum, gdb_byte *buf);
+
+  void raw_write (int regnum, const gdb_byte *buf);
 
-   The ``cpy'' functions can not have overlapping SRC and DST buffers.
+  template<typename T, typename = RequireLongest<T>>
+  enum register_status raw_read (int regnum, T *val);
 
-   ``no passthrough'' versions do not go through to the target.  They
-   only transfer values already in the cache.  */
+  template<typename T, typename = RequireLongest<T>>
+  void raw_write (int regnum, T val);
 
+  struct value *cooked_read_value (int regnum);
+
+  template<typename T, typename = RequireLongest<T>>
+  enum register_status cooked_read (int regnum, T *val);
+
+  template<typename T, typename = RequireLongest<T>>
+  void cooked_write (int regnum, T val);
+
+  void raw_update (int regnum);
+
+  void raw_collect (int regnum, void *buf) const;
+
+  void raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
+                           bool is_signed) const;
+
+  void raw_supply (int regnum, const void *buf);
+
+  void raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
+                          bool is_signed);
+
+  void raw_supply_zeroed (int regnum);
+
+  enum register_status get_register_status (int regnum) const;
+
+  void raw_set_cached_value (int regnum, const gdb_byte *buf);
+
+  void invalidate (int regnum);
+
+  enum register_status raw_read_part (int regnum, int offset, int len,
+                                     gdb_byte *buf);
+
+  void raw_write_part (int regnum, int offset, int len, const gdb_byte *buf);
+
+  enum register_status cooked_read_part (int regnum, int offset, int len,
+                                        gdb_byte *buf);
+
+  void cooked_write_part (int regnum, int offset, int len,
+                         const gdb_byte *buf);
+
+  void supply_regset (const struct regset *regset,
+                     int regnum, const void *buf, size_t size);
+
+
+  void collect_regset (const struct regset *regset, int regnum,
+                      void *buf, size_t size) const;
+
+  void dump (ui_file *file, enum regcache_dump_what what_to_dump);
+
+  ptid_t ptid () const
+  {
+    return m_ptid;
+  }
+
+  void set_ptid (const ptid_t ptid)
+  {
+    this->m_ptid = ptid;
+  }
+
+/* Dump the contents of a register from the register cache to the target
+   debug.  */
+  void debug_print_register (const char *func, int regno);
+
+  static void regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid);
+protected:
+  regcache (gdbarch *gdbarch, const address_space *aspace_, bool readonly_p_);
+
+  int num_raw_registers () const;
+
+  static std::forward_list<regcache *> current_regcache;
+
+private:
+  gdb_byte *register_buffer (int regnum) const;
+
+  void restore (struct regcache *src);
+
+  enum register_status xfer_part (int regnum, int offset, int len, void *in,
+                                 const void *out, bool is_raw);
+
+  void transfer_regset (const struct regset *regset,
+                       struct regcache *out_regcache,
+                       int regnum, const void *in_buf,
+                       void *out_buf, size_t size) const;
+
+  /* Assert on the range of REGNUM.  */
+  void assert_regnum (int regnum) const;
+
+  struct regcache_descr *m_descr;
+
+  /* The address space of this register cache (for registers where it
+     makes sense, like PC or SP).  */
+  const address_space * const m_aspace;
+
+  /* The register buffers.  A read-only register cache can hold the
+     full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) while a read/write
+     register cache can only hold [0 .. gdbarch_num_regs).  */
+  gdb_byte *m_registers;
+  /* Register cache status.  */
+  signed char *m_register_status;
+  /* Is this a read-only cache?  A read-only cache is used for saving
+     the target's register state (e.g, across an inferior function
+     call or just before forcing a function return).  A read-only
+     cache can only be updated via the methods regcache_dup() and
+     regcache_cpy().  The actual contents are determined by the
+     reggroup_save and reggroup_restore methods.  */
+  const bool m_readonly_p;
+  /* If this is a read-write cache, which thread's registers is
+     it connected to?  */
+  ptid_t m_ptid;
+
+  friend struct regcache *
+  get_thread_arch_aspace_regcache (ptid_t ptid, struct gdbarch *gdbarch,
+                                  struct address_space *aspace);
+
+  friend void
+  registers_changed_ptid (ptid_t ptid);
+
+  friend void
+  regcache_cpy (struct regcache *dst, struct regcache *src);
+};
+
+/* Duplicate the contents of a register cache to a read-only register
+   cache.  The operation is pass-through.  */
 extern struct regcache *regcache_dup (struct regcache *regcache);
-extern struct regcache *regcache_dup_no_passthrough (struct regcache *regcache);
+
+/* Writes to DEST will go through to the target.  SRC is a read-only
+   register cache.  */
 extern void regcache_cpy (struct regcache *dest, struct regcache *src);
-extern void regcache_cpy_no_passthrough (struct regcache *dest, struct regcache *src);
 
 extern void registers_changed (void);
+extern void registers_changed_ptid (ptid_t);
 
 #endif /* REGCACHE_H */
This page took 0.029829 seconds and 4 git commands to generate.