15796c8dcSSimon Schubert /* Cache and manage the values of registers for GDB, the GNU debugger.
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn Marino Copyright (C) 1986-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert This file is part of GDB.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert (at your option) any later version.
115796c8dcSSimon Schubert
125796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155796c8dcSSimon Schubert GNU General Public License for more details.
165796c8dcSSimon Schubert
175796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
195796c8dcSSimon Schubert
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "inferior.h"
225796c8dcSSimon Schubert #include "target.h"
235796c8dcSSimon Schubert #include "gdbarch.h"
245796c8dcSSimon Schubert #include "gdbcmd.h"
255796c8dcSSimon Schubert #include "regcache.h"
265796c8dcSSimon Schubert #include "reggroups.h"
275796c8dcSSimon Schubert #include "gdb_assert.h"
285796c8dcSSimon Schubert #include "gdb_string.h"
295796c8dcSSimon Schubert #include "gdbcmd.h" /* For maintenanceprintlist. */
305796c8dcSSimon Schubert #include "observer.h"
31c50c785cSJohn Marino #include "exceptions.h"
32a45ae5f8SJohn Marino #include "remote.h"
335796c8dcSSimon Schubert
345796c8dcSSimon Schubert /*
355796c8dcSSimon Schubert * DATA STRUCTURE
365796c8dcSSimon Schubert *
375796c8dcSSimon Schubert * Here is the actual register cache.
385796c8dcSSimon Schubert */
395796c8dcSSimon Schubert
405796c8dcSSimon Schubert /* Per-architecture object describing the layout of a register cache.
41c50c785cSJohn Marino Computed once when the architecture is created. */
425796c8dcSSimon Schubert
435796c8dcSSimon Schubert struct gdbarch_data *regcache_descr_handle;
445796c8dcSSimon Schubert
455796c8dcSSimon Schubert struct regcache_descr
465796c8dcSSimon Schubert {
475796c8dcSSimon Schubert /* The architecture this descriptor belongs to. */
485796c8dcSSimon Schubert struct gdbarch *gdbarch;
495796c8dcSSimon Schubert
505796c8dcSSimon Schubert /* The raw register cache. Each raw (or hard) register is supplied
515796c8dcSSimon Schubert by the target interface. The raw cache should not contain
525796c8dcSSimon Schubert redundant information - if the PC is constructed from two
535796c8dcSSimon Schubert registers then those registers and not the PC lives in the raw
545796c8dcSSimon Schubert cache. */
555796c8dcSSimon Schubert int nr_raw_registers;
565796c8dcSSimon Schubert long sizeof_raw_registers;
57c50c785cSJohn Marino long sizeof_raw_register_status;
585796c8dcSSimon Schubert
595796c8dcSSimon Schubert /* The cooked register space. Each cooked register in the range
605796c8dcSSimon Schubert [0..NR_RAW_REGISTERS) is direct-mapped onto the corresponding raw
615796c8dcSSimon Schubert register. The remaining [NR_RAW_REGISTERS
625796c8dcSSimon Schubert .. NR_COOKED_REGISTERS) (a.k.a. pseudo registers) are mapped onto
635796c8dcSSimon Schubert both raw registers and memory by the architecture methods
645796c8dcSSimon Schubert gdbarch_pseudo_register_read and gdbarch_pseudo_register_write. */
655796c8dcSSimon Schubert int nr_cooked_registers;
665796c8dcSSimon Schubert long sizeof_cooked_registers;
67c50c785cSJohn Marino long sizeof_cooked_register_status;
685796c8dcSSimon Schubert
69a45ae5f8SJohn Marino /* Offset and size (in 8 bit bytes), of each register in the
705796c8dcSSimon Schubert register cache. All registers (including those in the range
71c50c785cSJohn Marino [NR_RAW_REGISTERS .. NR_COOKED_REGISTERS) are given an
72c50c785cSJohn Marino offset. */
735796c8dcSSimon Schubert long *register_offset;
745796c8dcSSimon Schubert long *sizeof_register;
755796c8dcSSimon Schubert
765796c8dcSSimon Schubert /* Cached table containing the type of each register. */
775796c8dcSSimon Schubert struct type **register_type;
785796c8dcSSimon Schubert };
795796c8dcSSimon Schubert
805796c8dcSSimon Schubert static void *
init_regcache_descr(struct gdbarch * gdbarch)815796c8dcSSimon Schubert init_regcache_descr (struct gdbarch *gdbarch)
825796c8dcSSimon Schubert {
835796c8dcSSimon Schubert int i;
845796c8dcSSimon Schubert struct regcache_descr *descr;
855796c8dcSSimon Schubert gdb_assert (gdbarch != NULL);
865796c8dcSSimon Schubert
875796c8dcSSimon Schubert /* Create an initial, zero filled, table. */
885796c8dcSSimon Schubert descr = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct regcache_descr);
895796c8dcSSimon Schubert descr->gdbarch = gdbarch;
905796c8dcSSimon Schubert
915796c8dcSSimon Schubert /* Total size of the register space. The raw registers are mapped
925796c8dcSSimon Schubert directly onto the raw register cache while the pseudo's are
935796c8dcSSimon Schubert either mapped onto raw-registers or memory. */
945796c8dcSSimon Schubert descr->nr_cooked_registers = gdbarch_num_regs (gdbarch)
955796c8dcSSimon Schubert + gdbarch_num_pseudo_regs (gdbarch);
96c50c785cSJohn Marino descr->sizeof_cooked_register_status
97c50c785cSJohn Marino = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
985796c8dcSSimon Schubert
995796c8dcSSimon Schubert /* Fill in a table of register types. */
1005796c8dcSSimon Schubert descr->register_type
101c50c785cSJohn Marino = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers,
102c50c785cSJohn Marino struct type *);
1035796c8dcSSimon Schubert for (i = 0; i < descr->nr_cooked_registers; i++)
1045796c8dcSSimon Schubert descr->register_type[i] = gdbarch_register_type (gdbarch, i);
1055796c8dcSSimon Schubert
1065796c8dcSSimon Schubert /* Construct a strictly RAW register cache. Don't allow pseudo's
1075796c8dcSSimon Schubert into the register cache. */
1085796c8dcSSimon Schubert descr->nr_raw_registers = gdbarch_num_regs (gdbarch);
109c50c785cSJohn Marino descr->sizeof_raw_register_status = gdbarch_num_regs (gdbarch);
1105796c8dcSSimon Schubert
1115796c8dcSSimon Schubert /* Lay out the register cache.
1125796c8dcSSimon Schubert
1135796c8dcSSimon Schubert NOTE: cagney/2002-05-22: Only register_type() is used when
1145796c8dcSSimon Schubert constructing the register cache. It is assumed that the
1155796c8dcSSimon Schubert register's raw size, virtual size and type length are all the
1165796c8dcSSimon Schubert same. */
1175796c8dcSSimon Schubert
1185796c8dcSSimon Schubert {
1195796c8dcSSimon Schubert long offset = 0;
120cf7f2e2dSJohn Marino
1215796c8dcSSimon Schubert descr->sizeof_register
1225796c8dcSSimon Schubert = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
1235796c8dcSSimon Schubert descr->register_offset
1245796c8dcSSimon Schubert = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
125c50c785cSJohn Marino for (i = 0; i < descr->nr_raw_registers; i++)
1265796c8dcSSimon Schubert {
1275796c8dcSSimon Schubert descr->sizeof_register[i] = TYPE_LENGTH (descr->register_type[i]);
1285796c8dcSSimon Schubert descr->register_offset[i] = offset;
1295796c8dcSSimon Schubert offset += descr->sizeof_register[i];
1305796c8dcSSimon Schubert gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
1315796c8dcSSimon Schubert }
132c50c785cSJohn Marino /* Set the real size of the raw register cache buffer. */
133c50c785cSJohn Marino descr->sizeof_raw_registers = offset;
134c50c785cSJohn Marino
135c50c785cSJohn Marino for (; i < descr->nr_cooked_registers; i++)
136c50c785cSJohn Marino {
137c50c785cSJohn Marino descr->sizeof_register[i] = TYPE_LENGTH (descr->register_type[i]);
138c50c785cSJohn Marino descr->register_offset[i] = offset;
139c50c785cSJohn Marino offset += descr->sizeof_register[i];
140c50c785cSJohn Marino gdb_assert (MAX_REGISTER_SIZE >= descr->sizeof_register[i]);
141c50c785cSJohn Marino }
142c50c785cSJohn Marino /* Set the real size of the readonly register cache buffer. */
1435796c8dcSSimon Schubert descr->sizeof_cooked_registers = offset;
1445796c8dcSSimon Schubert }
1455796c8dcSSimon Schubert
1465796c8dcSSimon Schubert return descr;
1475796c8dcSSimon Schubert }
1485796c8dcSSimon Schubert
1495796c8dcSSimon Schubert static struct regcache_descr *
regcache_descr(struct gdbarch * gdbarch)1505796c8dcSSimon Schubert regcache_descr (struct gdbarch *gdbarch)
1515796c8dcSSimon Schubert {
1525796c8dcSSimon Schubert return gdbarch_data (gdbarch, regcache_descr_handle);
1535796c8dcSSimon Schubert }
1545796c8dcSSimon Schubert
1555796c8dcSSimon Schubert /* Utility functions returning useful register attributes stored in
1565796c8dcSSimon Schubert the regcache descr. */
1575796c8dcSSimon Schubert
1585796c8dcSSimon Schubert struct type *
register_type(struct gdbarch * gdbarch,int regnum)1595796c8dcSSimon Schubert register_type (struct gdbarch *gdbarch, int regnum)
1605796c8dcSSimon Schubert {
1615796c8dcSSimon Schubert struct regcache_descr *descr = regcache_descr (gdbarch);
162cf7f2e2dSJohn Marino
1635796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
1645796c8dcSSimon Schubert return descr->register_type[regnum];
1655796c8dcSSimon Schubert }
1665796c8dcSSimon Schubert
1675796c8dcSSimon Schubert /* Utility functions returning useful register attributes stored in
1685796c8dcSSimon Schubert the regcache descr. */
1695796c8dcSSimon Schubert
1705796c8dcSSimon Schubert int
register_size(struct gdbarch * gdbarch,int regnum)1715796c8dcSSimon Schubert register_size (struct gdbarch *gdbarch, int regnum)
1725796c8dcSSimon Schubert {
1735796c8dcSSimon Schubert struct regcache_descr *descr = regcache_descr (gdbarch);
1745796c8dcSSimon Schubert int size;
175cf7f2e2dSJohn Marino
1765796c8dcSSimon Schubert gdb_assert (regnum >= 0
1775796c8dcSSimon Schubert && regnum < (gdbarch_num_regs (gdbarch)
1785796c8dcSSimon Schubert + gdbarch_num_pseudo_regs (gdbarch)));
1795796c8dcSSimon Schubert size = descr->sizeof_register[regnum];
1805796c8dcSSimon Schubert return size;
1815796c8dcSSimon Schubert }
1825796c8dcSSimon Schubert
1835796c8dcSSimon Schubert /* The register cache for storing raw register values. */
1845796c8dcSSimon Schubert
1855796c8dcSSimon Schubert struct regcache
1865796c8dcSSimon Schubert {
1875796c8dcSSimon Schubert struct regcache_descr *descr;
188cf7f2e2dSJohn Marino
189cf7f2e2dSJohn Marino /* The address space of this register cache (for registers where it
190cf7f2e2dSJohn Marino makes sense, like PC or SP). */
191cf7f2e2dSJohn Marino struct address_space *aspace;
192cf7f2e2dSJohn Marino
1935796c8dcSSimon Schubert /* The register buffers. A read-only register cache can hold the
1945796c8dcSSimon Schubert full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) while a read/write
1955796c8dcSSimon Schubert register cache can only hold [0 .. gdbarch_num_regs). */
1965796c8dcSSimon Schubert gdb_byte *registers;
197c50c785cSJohn Marino /* Register cache status. */
198c50c785cSJohn Marino signed char *register_status;
1995796c8dcSSimon Schubert /* Is this a read-only cache? A read-only cache is used for saving
2005796c8dcSSimon Schubert the target's register state (e.g, across an inferior function
2015796c8dcSSimon Schubert call or just before forcing a function return). A read-only
2025796c8dcSSimon Schubert cache can only be updated via the methods regcache_dup() and
2035796c8dcSSimon Schubert regcache_cpy(). The actual contents are determined by the
2045796c8dcSSimon Schubert reggroup_save and reggroup_restore methods. */
2055796c8dcSSimon Schubert int readonly_p;
2065796c8dcSSimon Schubert /* If this is a read-write cache, which thread's registers is
2075796c8dcSSimon Schubert it connected to? */
2085796c8dcSSimon Schubert ptid_t ptid;
2095796c8dcSSimon Schubert };
2105796c8dcSSimon Schubert
211c50c785cSJohn Marino static struct regcache *
regcache_xmalloc_1(struct gdbarch * gdbarch,struct address_space * aspace,int readonly_p)212c50c785cSJohn Marino regcache_xmalloc_1 (struct gdbarch *gdbarch, struct address_space *aspace,
213c50c785cSJohn Marino int readonly_p)
2145796c8dcSSimon Schubert {
2155796c8dcSSimon Schubert struct regcache_descr *descr;
2165796c8dcSSimon Schubert struct regcache *regcache;
217cf7f2e2dSJohn Marino
2185796c8dcSSimon Schubert gdb_assert (gdbarch != NULL);
2195796c8dcSSimon Schubert descr = regcache_descr (gdbarch);
2205796c8dcSSimon Schubert regcache = XMALLOC (struct regcache);
2215796c8dcSSimon Schubert regcache->descr = descr;
222c50c785cSJohn Marino regcache->readonly_p = readonly_p;
223c50c785cSJohn Marino if (readonly_p)
224c50c785cSJohn Marino {
225c50c785cSJohn Marino regcache->registers
226c50c785cSJohn Marino = XCALLOC (descr->sizeof_cooked_registers, gdb_byte);
227c50c785cSJohn Marino regcache->register_status
228*ef5ccd6cSJohn Marino = XCALLOC (descr->sizeof_cooked_register_status, signed char);
229c50c785cSJohn Marino }
230c50c785cSJohn Marino else
231c50c785cSJohn Marino {
2325796c8dcSSimon Schubert regcache->registers
2335796c8dcSSimon Schubert = XCALLOC (descr->sizeof_raw_registers, gdb_byte);
234c50c785cSJohn Marino regcache->register_status
235*ef5ccd6cSJohn Marino = XCALLOC (descr->sizeof_raw_register_status, signed char);
236c50c785cSJohn Marino }
237cf7f2e2dSJohn Marino regcache->aspace = aspace;
2385796c8dcSSimon Schubert regcache->ptid = minus_one_ptid;
2395796c8dcSSimon Schubert return regcache;
2405796c8dcSSimon Schubert }
2415796c8dcSSimon Schubert
242c50c785cSJohn Marino struct regcache *
regcache_xmalloc(struct gdbarch * gdbarch,struct address_space * aspace)243c50c785cSJohn Marino regcache_xmalloc (struct gdbarch *gdbarch, struct address_space *aspace)
244c50c785cSJohn Marino {
245c50c785cSJohn Marino return regcache_xmalloc_1 (gdbarch, aspace, 1);
246c50c785cSJohn Marino }
247c50c785cSJohn Marino
2485796c8dcSSimon Schubert void
regcache_xfree(struct regcache * regcache)2495796c8dcSSimon Schubert regcache_xfree (struct regcache *regcache)
2505796c8dcSSimon Schubert {
2515796c8dcSSimon Schubert if (regcache == NULL)
2525796c8dcSSimon Schubert return;
2535796c8dcSSimon Schubert xfree (regcache->registers);
254c50c785cSJohn Marino xfree (regcache->register_status);
2555796c8dcSSimon Schubert xfree (regcache);
2565796c8dcSSimon Schubert }
2575796c8dcSSimon Schubert
2585796c8dcSSimon Schubert static void
do_regcache_xfree(void * data)2595796c8dcSSimon Schubert do_regcache_xfree (void *data)
2605796c8dcSSimon Schubert {
2615796c8dcSSimon Schubert regcache_xfree (data);
2625796c8dcSSimon Schubert }
2635796c8dcSSimon Schubert
2645796c8dcSSimon Schubert struct cleanup *
make_cleanup_regcache_xfree(struct regcache * regcache)2655796c8dcSSimon Schubert make_cleanup_regcache_xfree (struct regcache *regcache)
2665796c8dcSSimon Schubert {
2675796c8dcSSimon Schubert return make_cleanup (do_regcache_xfree, regcache);
2685796c8dcSSimon Schubert }
2695796c8dcSSimon Schubert
2705796c8dcSSimon Schubert /* Return REGCACHE's architecture. */
2715796c8dcSSimon Schubert
2725796c8dcSSimon Schubert struct gdbarch *
get_regcache_arch(const struct regcache * regcache)2735796c8dcSSimon Schubert get_regcache_arch (const struct regcache *regcache)
2745796c8dcSSimon Schubert {
2755796c8dcSSimon Schubert return regcache->descr->gdbarch;
2765796c8dcSSimon Schubert }
2775796c8dcSSimon Schubert
278cf7f2e2dSJohn Marino struct address_space *
get_regcache_aspace(const struct regcache * regcache)279cf7f2e2dSJohn Marino get_regcache_aspace (const struct regcache *regcache)
280cf7f2e2dSJohn Marino {
281cf7f2e2dSJohn Marino return regcache->aspace;
282cf7f2e2dSJohn Marino }
283cf7f2e2dSJohn Marino
2845796c8dcSSimon Schubert /* Return a pointer to register REGNUM's buffer cache. */
2855796c8dcSSimon Schubert
2865796c8dcSSimon Schubert static gdb_byte *
register_buffer(const struct regcache * regcache,int regnum)2875796c8dcSSimon Schubert register_buffer (const struct regcache *regcache, int regnum)
2885796c8dcSSimon Schubert {
2895796c8dcSSimon Schubert return regcache->registers + regcache->descr->register_offset[regnum];
2905796c8dcSSimon Schubert }
2915796c8dcSSimon Schubert
2925796c8dcSSimon Schubert void
regcache_save(struct regcache * dst,regcache_cooked_read_ftype * cooked_read,void * src)2935796c8dcSSimon Schubert regcache_save (struct regcache *dst, regcache_cooked_read_ftype *cooked_read,
2945796c8dcSSimon Schubert void *src)
2955796c8dcSSimon Schubert {
2965796c8dcSSimon Schubert struct gdbarch *gdbarch = dst->descr->gdbarch;
2975796c8dcSSimon Schubert gdb_byte buf[MAX_REGISTER_SIZE];
2985796c8dcSSimon Schubert int regnum;
299cf7f2e2dSJohn Marino
3005796c8dcSSimon Schubert /* The DST should be `read-only', if it wasn't then the save would
3015796c8dcSSimon Schubert end up trying to write the register values back out to the
3025796c8dcSSimon Schubert target. */
3035796c8dcSSimon Schubert gdb_assert (dst->readonly_p);
3045796c8dcSSimon Schubert /* Clear the dest. */
3055796c8dcSSimon Schubert memset (dst->registers, 0, dst->descr->sizeof_cooked_registers);
306c50c785cSJohn Marino memset (dst->register_status, 0,
307c50c785cSJohn Marino dst->descr->sizeof_cooked_register_status);
3085796c8dcSSimon Schubert /* Copy over any registers (identified by their membership in the
3095796c8dcSSimon Schubert save_reggroup) and mark them as valid. The full [0 .. gdbarch_num_regs +
3105796c8dcSSimon Schubert gdbarch_num_pseudo_regs) range is checked since some architectures need
3115796c8dcSSimon Schubert to save/restore `cooked' registers that live in memory. */
3125796c8dcSSimon Schubert for (regnum = 0; regnum < dst->descr->nr_cooked_registers; regnum++)
3135796c8dcSSimon Schubert {
3145796c8dcSSimon Schubert if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
3155796c8dcSSimon Schubert {
316c50c785cSJohn Marino enum register_status status = cooked_read (src, regnum, buf);
317cf7f2e2dSJohn Marino
318c50c785cSJohn Marino if (status == REG_VALID)
3195796c8dcSSimon Schubert memcpy (register_buffer (dst, regnum), buf,
3205796c8dcSSimon Schubert register_size (gdbarch, regnum));
321c50c785cSJohn Marino else
322c50c785cSJohn Marino {
323c50c785cSJohn Marino gdb_assert (status != REG_UNKNOWN);
324c50c785cSJohn Marino
325c50c785cSJohn Marino memset (register_buffer (dst, regnum), 0,
326c50c785cSJohn Marino register_size (gdbarch, regnum));
3275796c8dcSSimon Schubert }
328c50c785cSJohn Marino dst->register_status[regnum] = status;
3295796c8dcSSimon Schubert }
3305796c8dcSSimon Schubert }
3315796c8dcSSimon Schubert }
3325796c8dcSSimon Schubert
333a45ae5f8SJohn Marino static void
regcache_restore(struct regcache * dst,regcache_cooked_read_ftype * cooked_read,void * cooked_read_context)3345796c8dcSSimon Schubert regcache_restore (struct regcache *dst,
3355796c8dcSSimon Schubert regcache_cooked_read_ftype *cooked_read,
3365796c8dcSSimon Schubert void *cooked_read_context)
3375796c8dcSSimon Schubert {
3385796c8dcSSimon Schubert struct gdbarch *gdbarch = dst->descr->gdbarch;
3395796c8dcSSimon Schubert gdb_byte buf[MAX_REGISTER_SIZE];
3405796c8dcSSimon Schubert int regnum;
341cf7f2e2dSJohn Marino
3425796c8dcSSimon Schubert /* The dst had better not be read-only. If it is, the `restore'
3435796c8dcSSimon Schubert doesn't make much sense. */
3445796c8dcSSimon Schubert gdb_assert (!dst->readonly_p);
3455796c8dcSSimon Schubert /* Copy over any registers, being careful to only restore those that
3465796c8dcSSimon Schubert were both saved and need to be restored. The full [0 .. gdbarch_num_regs
3475796c8dcSSimon Schubert + gdbarch_num_pseudo_regs) range is checked since some architectures need
3485796c8dcSSimon Schubert to save/restore `cooked' registers that live in memory. */
3495796c8dcSSimon Schubert for (regnum = 0; regnum < dst->descr->nr_cooked_registers; regnum++)
3505796c8dcSSimon Schubert {
3515796c8dcSSimon Schubert if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup))
3525796c8dcSSimon Schubert {
353a45ae5f8SJohn Marino enum register_status status;
354cf7f2e2dSJohn Marino
355a45ae5f8SJohn Marino status = cooked_read (cooked_read_context, regnum, buf);
356a45ae5f8SJohn Marino if (status == REG_VALID)
3575796c8dcSSimon Schubert regcache_cooked_write (dst, regnum, buf);
3585796c8dcSSimon Schubert }
3595796c8dcSSimon Schubert }
3605796c8dcSSimon Schubert }
3615796c8dcSSimon Schubert
362c50c785cSJohn Marino static enum register_status
do_cooked_read(void * src,int regnum,gdb_byte * buf)3635796c8dcSSimon Schubert do_cooked_read (void *src, int regnum, gdb_byte *buf)
3645796c8dcSSimon Schubert {
3655796c8dcSSimon Schubert struct regcache *regcache = src;
366cf7f2e2dSJohn Marino
367c50c785cSJohn Marino return regcache_cooked_read (regcache, regnum, buf);
3685796c8dcSSimon Schubert }
3695796c8dcSSimon Schubert
3705796c8dcSSimon Schubert void
regcache_cpy(struct regcache * dst,struct regcache * src)3715796c8dcSSimon Schubert regcache_cpy (struct regcache *dst, struct regcache *src)
3725796c8dcSSimon Schubert {
3735796c8dcSSimon Schubert gdb_assert (src != NULL && dst != NULL);
3745796c8dcSSimon Schubert gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
3755796c8dcSSimon Schubert gdb_assert (src != dst);
3765796c8dcSSimon Schubert gdb_assert (src->readonly_p || dst->readonly_p);
377cf7f2e2dSJohn Marino
3785796c8dcSSimon Schubert if (!src->readonly_p)
3795796c8dcSSimon Schubert regcache_save (dst, do_cooked_read, src);
3805796c8dcSSimon Schubert else if (!dst->readonly_p)
3815796c8dcSSimon Schubert regcache_restore (dst, do_cooked_read, src);
3825796c8dcSSimon Schubert else
3835796c8dcSSimon Schubert regcache_cpy_no_passthrough (dst, src);
3845796c8dcSSimon Schubert }
3855796c8dcSSimon Schubert
3865796c8dcSSimon Schubert void
regcache_cpy_no_passthrough(struct regcache * dst,struct regcache * src)3875796c8dcSSimon Schubert regcache_cpy_no_passthrough (struct regcache *dst, struct regcache *src)
3885796c8dcSSimon Schubert {
3895796c8dcSSimon Schubert gdb_assert (src != NULL && dst != NULL);
3905796c8dcSSimon Schubert gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
3915796c8dcSSimon Schubert /* NOTE: cagney/2002-05-17: Don't let the caller do a no-passthrough
392c50c785cSJohn Marino move of data into a thread's regcache. Doing this would be silly
393c50c785cSJohn Marino - it would mean that regcache->register_status would be
394c50c785cSJohn Marino completely invalid. */
395c50c785cSJohn Marino gdb_assert (dst->readonly_p && src->readonly_p);
396cf7f2e2dSJohn Marino
397c50c785cSJohn Marino memcpy (dst->registers, src->registers,
398c50c785cSJohn Marino dst->descr->sizeof_cooked_registers);
399c50c785cSJohn Marino memcpy (dst->register_status, src->register_status,
400c50c785cSJohn Marino dst->descr->sizeof_cooked_register_status);
4015796c8dcSSimon Schubert }
4025796c8dcSSimon Schubert
4035796c8dcSSimon Schubert struct regcache *
regcache_dup(struct regcache * src)4045796c8dcSSimon Schubert regcache_dup (struct regcache *src)
4055796c8dcSSimon Schubert {
4065796c8dcSSimon Schubert struct regcache *newbuf;
407cf7f2e2dSJohn Marino
408cf7f2e2dSJohn Marino newbuf = regcache_xmalloc (src->descr->gdbarch, get_regcache_aspace (src));
4095796c8dcSSimon Schubert regcache_cpy (newbuf, src);
4105796c8dcSSimon Schubert return newbuf;
4115796c8dcSSimon Schubert }
4125796c8dcSSimon Schubert
413*ef5ccd6cSJohn Marino enum register_status
regcache_register_status(const struct regcache * regcache,int regnum)414c50c785cSJohn Marino regcache_register_status (const struct regcache *regcache, int regnum)
4155796c8dcSSimon Schubert {
4165796c8dcSSimon Schubert gdb_assert (regcache != NULL);
4175796c8dcSSimon Schubert gdb_assert (regnum >= 0);
4185796c8dcSSimon Schubert if (regcache->readonly_p)
4195796c8dcSSimon Schubert gdb_assert (regnum < regcache->descr->nr_cooked_registers);
4205796c8dcSSimon Schubert else
4215796c8dcSSimon Schubert gdb_assert (regnum < regcache->descr->nr_raw_registers);
4225796c8dcSSimon Schubert
423c50c785cSJohn Marino return regcache->register_status[regnum];
4245796c8dcSSimon Schubert }
4255796c8dcSSimon Schubert
4265796c8dcSSimon Schubert void
regcache_invalidate(struct regcache * regcache,int regnum)4275796c8dcSSimon Schubert regcache_invalidate (struct regcache *regcache, int regnum)
4285796c8dcSSimon Schubert {
4295796c8dcSSimon Schubert gdb_assert (regcache != NULL);
4305796c8dcSSimon Schubert gdb_assert (regnum >= 0);
4315796c8dcSSimon Schubert gdb_assert (!regcache->readonly_p);
4325796c8dcSSimon Schubert gdb_assert (regnum < regcache->descr->nr_raw_registers);
433c50c785cSJohn Marino regcache->register_status[regnum] = REG_UNKNOWN;
4345796c8dcSSimon Schubert }
4355796c8dcSSimon Schubert
4365796c8dcSSimon Schubert
4375796c8dcSSimon Schubert /* Global structure containing the current regcache. */
4385796c8dcSSimon Schubert
4395796c8dcSSimon Schubert /* NOTE: this is a write-through cache. There is no "dirty" bit for
4405796c8dcSSimon Schubert recording if the register values have been changed (eg. by the
4415796c8dcSSimon Schubert user). Therefore all registers must be written back to the
4425796c8dcSSimon Schubert target when appropriate. */
4435796c8dcSSimon Schubert
4445796c8dcSSimon Schubert struct regcache_list
4455796c8dcSSimon Schubert {
4465796c8dcSSimon Schubert struct regcache *regcache;
4475796c8dcSSimon Schubert struct regcache_list *next;
4485796c8dcSSimon Schubert };
4495796c8dcSSimon Schubert
4505796c8dcSSimon Schubert static struct regcache_list *current_regcache;
4515796c8dcSSimon Schubert
4525796c8dcSSimon Schubert struct regcache *
get_thread_arch_aspace_regcache(ptid_t ptid,struct gdbarch * gdbarch,struct address_space * aspace)453a45ae5f8SJohn Marino get_thread_arch_aspace_regcache (ptid_t ptid, struct gdbarch *gdbarch,
454a45ae5f8SJohn Marino struct address_space *aspace)
4555796c8dcSSimon Schubert {
4565796c8dcSSimon Schubert struct regcache_list *list;
4575796c8dcSSimon Schubert struct regcache *new_regcache;
4585796c8dcSSimon Schubert
4595796c8dcSSimon Schubert for (list = current_regcache; list; list = list->next)
4605796c8dcSSimon Schubert if (ptid_equal (list->regcache->ptid, ptid)
4615796c8dcSSimon Schubert && get_regcache_arch (list->regcache) == gdbarch)
4625796c8dcSSimon Schubert return list->regcache;
4635796c8dcSSimon Schubert
464a45ae5f8SJohn Marino new_regcache = regcache_xmalloc_1 (gdbarch, aspace, 0);
465a45ae5f8SJohn Marino new_regcache->ptid = ptid;
466a45ae5f8SJohn Marino
467a45ae5f8SJohn Marino list = xmalloc (sizeof (struct regcache_list));
468a45ae5f8SJohn Marino list->regcache = new_regcache;
469a45ae5f8SJohn Marino list->next = current_regcache;
470a45ae5f8SJohn Marino current_regcache = list;
471a45ae5f8SJohn Marino
472a45ae5f8SJohn Marino return new_regcache;
473a45ae5f8SJohn Marino }
474a45ae5f8SJohn Marino
475a45ae5f8SJohn Marino struct regcache *
get_thread_arch_regcache(ptid_t ptid,struct gdbarch * gdbarch)476a45ae5f8SJohn Marino get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch)
477a45ae5f8SJohn Marino {
478a45ae5f8SJohn Marino struct address_space *aspace;
479a45ae5f8SJohn Marino
480c50c785cSJohn Marino /* For the benefit of "maint print registers" & co when debugging an
481c50c785cSJohn Marino executable, allow dumping the regcache even when there is no
482c50c785cSJohn Marino thread selected (target_thread_address_space internal-errors if
483c50c785cSJohn Marino no address space is found). Note that normal user commands will
484c50c785cSJohn Marino fail higher up on the call stack due to no
485c50c785cSJohn Marino target_has_registers. */
486c50c785cSJohn Marino aspace = (ptid_equal (null_ptid, ptid)
487c50c785cSJohn Marino ? NULL
488c50c785cSJohn Marino : target_thread_address_space (ptid));
489c50c785cSJohn Marino
490a45ae5f8SJohn Marino return get_thread_arch_aspace_regcache (ptid, gdbarch, aspace);
4915796c8dcSSimon Schubert }
4925796c8dcSSimon Schubert
4935796c8dcSSimon Schubert static ptid_t current_thread_ptid;
4945796c8dcSSimon Schubert static struct gdbarch *current_thread_arch;
4955796c8dcSSimon Schubert
4965796c8dcSSimon Schubert struct regcache *
get_thread_regcache(ptid_t ptid)4975796c8dcSSimon Schubert get_thread_regcache (ptid_t ptid)
4985796c8dcSSimon Schubert {
4995796c8dcSSimon Schubert if (!current_thread_arch || !ptid_equal (current_thread_ptid, ptid))
5005796c8dcSSimon Schubert {
5015796c8dcSSimon Schubert current_thread_ptid = ptid;
5025796c8dcSSimon Schubert current_thread_arch = target_thread_architecture (ptid);
5035796c8dcSSimon Schubert }
5045796c8dcSSimon Schubert
5055796c8dcSSimon Schubert return get_thread_arch_regcache (ptid, current_thread_arch);
5065796c8dcSSimon Schubert }
5075796c8dcSSimon Schubert
5085796c8dcSSimon Schubert struct regcache *
get_current_regcache(void)5095796c8dcSSimon Schubert get_current_regcache (void)
5105796c8dcSSimon Schubert {
5115796c8dcSSimon Schubert return get_thread_regcache (inferior_ptid);
5125796c8dcSSimon Schubert }
5135796c8dcSSimon Schubert
5145796c8dcSSimon Schubert
5155796c8dcSSimon Schubert /* Observer for the target_changed event. */
5165796c8dcSSimon Schubert
5175796c8dcSSimon Schubert static void
regcache_observer_target_changed(struct target_ops * target)5185796c8dcSSimon Schubert regcache_observer_target_changed (struct target_ops *target)
5195796c8dcSSimon Schubert {
5205796c8dcSSimon Schubert registers_changed ();
5215796c8dcSSimon Schubert }
5225796c8dcSSimon Schubert
5235796c8dcSSimon Schubert /* Update global variables old ptids to hold NEW_PTID if they were
5245796c8dcSSimon Schubert holding OLD_PTID. */
5255796c8dcSSimon Schubert static void
regcache_thread_ptid_changed(ptid_t old_ptid,ptid_t new_ptid)5265796c8dcSSimon Schubert regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
5275796c8dcSSimon Schubert {
5285796c8dcSSimon Schubert struct regcache_list *list;
5295796c8dcSSimon Schubert
5305796c8dcSSimon Schubert for (list = current_regcache; list; list = list->next)
5315796c8dcSSimon Schubert if (ptid_equal (list->regcache->ptid, old_ptid))
5325796c8dcSSimon Schubert list->regcache->ptid = new_ptid;
5335796c8dcSSimon Schubert }
5345796c8dcSSimon Schubert
5355796c8dcSSimon Schubert /* Low level examining and depositing of registers.
5365796c8dcSSimon Schubert
5375796c8dcSSimon Schubert The caller is responsible for making sure that the inferior is
5385796c8dcSSimon Schubert stopped before calling the fetching routines, or it will get
5395796c8dcSSimon Schubert garbage. (a change from GDB version 3, in which the caller got the
5405796c8dcSSimon Schubert value from the last stop). */
5415796c8dcSSimon Schubert
5425796c8dcSSimon Schubert /* REGISTERS_CHANGED ()
5435796c8dcSSimon Schubert
5445796c8dcSSimon Schubert Indicate that registers may have changed, so invalidate the cache. */
5455796c8dcSSimon Schubert
5465796c8dcSSimon Schubert void
registers_changed_ptid(ptid_t ptid)547cf7f2e2dSJohn Marino registers_changed_ptid (ptid_t ptid)
5485796c8dcSSimon Schubert {
549cf7f2e2dSJohn Marino struct regcache_list *list, **list_link;
5505796c8dcSSimon Schubert
551cf7f2e2dSJohn Marino list = current_regcache;
552cf7f2e2dSJohn Marino list_link = ¤t_regcache;
553cf7f2e2dSJohn Marino while (list)
5545796c8dcSSimon Schubert {
555cf7f2e2dSJohn Marino if (ptid_match (list->regcache->ptid, ptid))
556cf7f2e2dSJohn Marino {
557cf7f2e2dSJohn Marino struct regcache_list *dead = list;
558cf7f2e2dSJohn Marino
559cf7f2e2dSJohn Marino *list_link = list->next;
5605796c8dcSSimon Schubert regcache_xfree (list->regcache);
561cf7f2e2dSJohn Marino list = *list_link;
562cf7f2e2dSJohn Marino xfree (dead);
563cf7f2e2dSJohn Marino continue;
564cf7f2e2dSJohn Marino }
565cf7f2e2dSJohn Marino
566cf7f2e2dSJohn Marino list_link = &list->next;
567cf7f2e2dSJohn Marino list = *list_link;
5685796c8dcSSimon Schubert }
5695796c8dcSSimon Schubert
570a45ae5f8SJohn Marino if (ptid_match (current_thread_ptid, ptid))
571c50c785cSJohn Marino {
5725796c8dcSSimon Schubert current_thread_ptid = null_ptid;
5735796c8dcSSimon Schubert current_thread_arch = NULL;
574c50c785cSJohn Marino }
5755796c8dcSSimon Schubert
576a45ae5f8SJohn Marino if (ptid_match (inferior_ptid, ptid))
577c50c785cSJohn Marino {
578c50c785cSJohn Marino /* We just deleted the regcache of the current thread. Need to
579c50c785cSJohn Marino forget about any frames we have cached, too. */
5805796c8dcSSimon Schubert reinit_frame_cache ();
581c50c785cSJohn Marino }
582c50c785cSJohn Marino }
583c50c785cSJohn Marino
584c50c785cSJohn Marino void
registers_changed(void)585c50c785cSJohn Marino registers_changed (void)
586c50c785cSJohn Marino {
587c50c785cSJohn Marino registers_changed_ptid (minus_one_ptid);
5885796c8dcSSimon Schubert
5895796c8dcSSimon Schubert /* Force cleanup of any alloca areas if using C alloca instead of
5905796c8dcSSimon Schubert a builtin alloca. This particular call is used to clean up
5915796c8dcSSimon Schubert areas allocated by low level target code which may build up
5925796c8dcSSimon Schubert during lengthy interactions between gdb and the target before
5935796c8dcSSimon Schubert gdb gives control to the user (ie watchpoints). */
5945796c8dcSSimon Schubert alloca (0);
5955796c8dcSSimon Schubert }
5965796c8dcSSimon Schubert
597c50c785cSJohn Marino enum register_status
regcache_raw_read(struct regcache * regcache,int regnum,gdb_byte * buf)5985796c8dcSSimon Schubert regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf)
5995796c8dcSSimon Schubert {
6005796c8dcSSimon Schubert gdb_assert (regcache != NULL && buf != NULL);
6015796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
6025796c8dcSSimon Schubert /* Make certain that the register cache is up-to-date with respect
6035796c8dcSSimon Schubert to the current thread. This switching shouldn't be necessary
6045796c8dcSSimon Schubert only there is still only one target side register cache. Sigh!
6055796c8dcSSimon Schubert On the bright side, at least there is a regcache object. */
606c50c785cSJohn Marino if (!regcache->readonly_p
607c50c785cSJohn Marino && regcache_register_status (regcache, regnum) == REG_UNKNOWN)
6085796c8dcSSimon Schubert {
6095796c8dcSSimon Schubert struct cleanup *old_chain = save_inferior_ptid ();
610cf7f2e2dSJohn Marino
6115796c8dcSSimon Schubert inferior_ptid = regcache->ptid;
6125796c8dcSSimon Schubert target_fetch_registers (regcache, regnum);
6135796c8dcSSimon Schubert do_cleanups (old_chain);
614c50c785cSJohn Marino
615c50c785cSJohn Marino /* A number of targets can't access the whole set of raw
616c50c785cSJohn Marino registers (because the debug API provides no means to get at
617c50c785cSJohn Marino them). */
618c50c785cSJohn Marino if (regcache->register_status[regnum] == REG_UNKNOWN)
619c50c785cSJohn Marino regcache->register_status[regnum] = REG_UNAVAILABLE;
6205796c8dcSSimon Schubert }
6215796c8dcSSimon Schubert
622c50c785cSJohn Marino if (regcache->register_status[regnum] != REG_VALID)
623c50c785cSJohn Marino memset (buf, 0, regcache->descr->sizeof_register[regnum]);
624c50c785cSJohn Marino else
625c50c785cSJohn Marino memcpy (buf, register_buffer (regcache, regnum),
626c50c785cSJohn Marino regcache->descr->sizeof_register[regnum]);
627c50c785cSJohn Marino
628c50c785cSJohn Marino return regcache->register_status[regnum];
629c50c785cSJohn Marino }
630c50c785cSJohn Marino
631c50c785cSJohn Marino enum register_status
regcache_raw_read_signed(struct regcache * regcache,int regnum,LONGEST * val)6325796c8dcSSimon Schubert regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
6335796c8dcSSimon Schubert {
6345796c8dcSSimon Schubert gdb_byte *buf;
635c50c785cSJohn Marino enum register_status status;
636cf7f2e2dSJohn Marino
6375796c8dcSSimon Schubert gdb_assert (regcache != NULL);
6385796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
6395796c8dcSSimon Schubert buf = alloca (regcache->descr->sizeof_register[regnum]);
640c50c785cSJohn Marino status = regcache_raw_read (regcache, regnum, buf);
641c50c785cSJohn Marino if (status == REG_VALID)
642c50c785cSJohn Marino *val = extract_signed_integer
6435796c8dcSSimon Schubert (buf, regcache->descr->sizeof_register[regnum],
6445796c8dcSSimon Schubert gdbarch_byte_order (regcache->descr->gdbarch));
645c50c785cSJohn Marino else
646c50c785cSJohn Marino *val = 0;
647c50c785cSJohn Marino return status;
6485796c8dcSSimon Schubert }
6495796c8dcSSimon Schubert
650c50c785cSJohn Marino enum register_status
regcache_raw_read_unsigned(struct regcache * regcache,int regnum,ULONGEST * val)6515796c8dcSSimon Schubert regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
6525796c8dcSSimon Schubert ULONGEST *val)
6535796c8dcSSimon Schubert {
6545796c8dcSSimon Schubert gdb_byte *buf;
655c50c785cSJohn Marino enum register_status status;
656cf7f2e2dSJohn Marino
6575796c8dcSSimon Schubert gdb_assert (regcache != NULL);
6585796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
6595796c8dcSSimon Schubert buf = alloca (regcache->descr->sizeof_register[regnum]);
660c50c785cSJohn Marino status = regcache_raw_read (regcache, regnum, buf);
661c50c785cSJohn Marino if (status == REG_VALID)
662c50c785cSJohn Marino *val = extract_unsigned_integer
6635796c8dcSSimon Schubert (buf, regcache->descr->sizeof_register[regnum],
6645796c8dcSSimon Schubert gdbarch_byte_order (regcache->descr->gdbarch));
665c50c785cSJohn Marino else
666c50c785cSJohn Marino *val = 0;
667c50c785cSJohn Marino return status;
6685796c8dcSSimon Schubert }
6695796c8dcSSimon Schubert
6705796c8dcSSimon Schubert void
regcache_raw_write_signed(struct regcache * regcache,int regnum,LONGEST val)6715796c8dcSSimon Schubert regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val)
6725796c8dcSSimon Schubert {
6735796c8dcSSimon Schubert void *buf;
674cf7f2e2dSJohn Marino
6755796c8dcSSimon Schubert gdb_assert (regcache != NULL);
6765796c8dcSSimon Schubert gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers);
6775796c8dcSSimon Schubert buf = alloca (regcache->descr->sizeof_register[regnum]);
6785796c8dcSSimon Schubert store_signed_integer (buf, regcache->descr->sizeof_register[regnum],
6795796c8dcSSimon Schubert gdbarch_byte_order (regcache->descr->gdbarch), val);
6805796c8dcSSimon Schubert regcache_raw_write (regcache, regnum, buf);
6815796c8dcSSimon Schubert }
6825796c8dcSSimon Schubert
6835796c8dcSSimon Schubert void
regcache_raw_write_unsigned(struct regcache * regcache,int regnum,ULONGEST val)6845796c8dcSSimon Schubert regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
6855796c8dcSSimon Schubert ULONGEST val)
6865796c8dcSSimon Schubert {
6875796c8dcSSimon Schubert void *buf;
688cf7f2e2dSJohn Marino
6895796c8dcSSimon Schubert gdb_assert (regcache != NULL);
6905796c8dcSSimon Schubert gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers);
6915796c8dcSSimon Schubert buf = alloca (regcache->descr->sizeof_register[regnum]);
6925796c8dcSSimon Schubert store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum],
6935796c8dcSSimon Schubert gdbarch_byte_order (regcache->descr->gdbarch), val);
6945796c8dcSSimon Schubert regcache_raw_write (regcache, regnum, buf);
6955796c8dcSSimon Schubert }
6965796c8dcSSimon Schubert
697c50c785cSJohn Marino enum register_status
regcache_cooked_read(struct regcache * regcache,int regnum,gdb_byte * buf)6985796c8dcSSimon Schubert regcache_cooked_read (struct regcache *regcache, int regnum, gdb_byte *buf)
6995796c8dcSSimon Schubert {
7005796c8dcSSimon Schubert gdb_assert (regnum >= 0);
7015796c8dcSSimon Schubert gdb_assert (regnum < regcache->descr->nr_cooked_registers);
7025796c8dcSSimon Schubert if (regnum < regcache->descr->nr_raw_registers)
703c50c785cSJohn Marino return regcache_raw_read (regcache, regnum, buf);
7045796c8dcSSimon Schubert else if (regcache->readonly_p
705c50c785cSJohn Marino && regcache->register_status[regnum] != REG_UNKNOWN)
706c50c785cSJohn Marino {
707c50c785cSJohn Marino /* Read-only register cache, perhaps the cooked value was
708c50c785cSJohn Marino cached? */
709c50c785cSJohn Marino if (regcache->register_status[regnum] == REG_VALID)
7105796c8dcSSimon Schubert memcpy (buf, register_buffer (regcache, regnum),
7115796c8dcSSimon Schubert regcache->descr->sizeof_register[regnum]);
7125796c8dcSSimon Schubert else
713c50c785cSJohn Marino memset (buf, 0, regcache->descr->sizeof_register[regnum]);
714c50c785cSJohn Marino
715c50c785cSJohn Marino return regcache->register_status[regnum];
716c50c785cSJohn Marino }
717a45ae5f8SJohn Marino else if (gdbarch_pseudo_register_read_value_p (regcache->descr->gdbarch))
718a45ae5f8SJohn Marino {
719a45ae5f8SJohn Marino struct value *mark, *computed;
720a45ae5f8SJohn Marino enum register_status result = REG_VALID;
721a45ae5f8SJohn Marino
722a45ae5f8SJohn Marino mark = value_mark ();
723a45ae5f8SJohn Marino
724a45ae5f8SJohn Marino computed = gdbarch_pseudo_register_read_value (regcache->descr->gdbarch,
725a45ae5f8SJohn Marino regcache, regnum);
726a45ae5f8SJohn Marino if (value_entirely_available (computed))
727a45ae5f8SJohn Marino memcpy (buf, value_contents_raw (computed),
728a45ae5f8SJohn Marino regcache->descr->sizeof_register[regnum]);
729a45ae5f8SJohn Marino else
730a45ae5f8SJohn Marino {
731a45ae5f8SJohn Marino memset (buf, 0, regcache->descr->sizeof_register[regnum]);
732a45ae5f8SJohn Marino result = REG_UNAVAILABLE;
733a45ae5f8SJohn Marino }
734a45ae5f8SJohn Marino
735a45ae5f8SJohn Marino value_free_to_mark (mark);
736a45ae5f8SJohn Marino
737a45ae5f8SJohn Marino return result;
738a45ae5f8SJohn Marino }
739c50c785cSJohn Marino else
740c50c785cSJohn Marino return gdbarch_pseudo_register_read (regcache->descr->gdbarch, regcache,
7415796c8dcSSimon Schubert regnum, buf);
7425796c8dcSSimon Schubert }
7435796c8dcSSimon Schubert
744a45ae5f8SJohn Marino struct value *
regcache_cooked_read_value(struct regcache * regcache,int regnum)745a45ae5f8SJohn Marino regcache_cooked_read_value (struct regcache *regcache, int regnum)
746a45ae5f8SJohn Marino {
747a45ae5f8SJohn Marino gdb_assert (regnum >= 0);
748a45ae5f8SJohn Marino gdb_assert (regnum < regcache->descr->nr_cooked_registers);
749a45ae5f8SJohn Marino
750a45ae5f8SJohn Marino if (regnum < regcache->descr->nr_raw_registers
751a45ae5f8SJohn Marino || (regcache->readonly_p
752a45ae5f8SJohn Marino && regcache->register_status[regnum] != REG_UNKNOWN)
753a45ae5f8SJohn Marino || !gdbarch_pseudo_register_read_value_p (regcache->descr->gdbarch))
754a45ae5f8SJohn Marino {
755a45ae5f8SJohn Marino struct value *result;
756a45ae5f8SJohn Marino
757a45ae5f8SJohn Marino result = allocate_value (register_type (regcache->descr->gdbarch,
758a45ae5f8SJohn Marino regnum));
759a45ae5f8SJohn Marino VALUE_LVAL (result) = lval_register;
760a45ae5f8SJohn Marino VALUE_REGNUM (result) = regnum;
761a45ae5f8SJohn Marino
762a45ae5f8SJohn Marino /* It is more efficient in general to do this delegation in this
763a45ae5f8SJohn Marino direction than in the other one, even though the value-based
764a45ae5f8SJohn Marino API is preferred. */
765a45ae5f8SJohn Marino if (regcache_cooked_read (regcache, regnum,
766a45ae5f8SJohn Marino value_contents_raw (result)) == REG_UNAVAILABLE)
767a45ae5f8SJohn Marino mark_value_bytes_unavailable (result, 0,
768a45ae5f8SJohn Marino TYPE_LENGTH (value_type (result)));
769a45ae5f8SJohn Marino
770a45ae5f8SJohn Marino return result;
771a45ae5f8SJohn Marino }
772a45ae5f8SJohn Marino else
773a45ae5f8SJohn Marino return gdbarch_pseudo_register_read_value (regcache->descr->gdbarch,
774a45ae5f8SJohn Marino regcache, regnum);
775a45ae5f8SJohn Marino }
776a45ae5f8SJohn Marino
777c50c785cSJohn Marino enum register_status
regcache_cooked_read_signed(struct regcache * regcache,int regnum,LONGEST * val)7785796c8dcSSimon Schubert regcache_cooked_read_signed (struct regcache *regcache, int regnum,
7795796c8dcSSimon Schubert LONGEST *val)
7805796c8dcSSimon Schubert {
781c50c785cSJohn Marino enum register_status status;
7825796c8dcSSimon Schubert gdb_byte *buf;
783cf7f2e2dSJohn Marino
7845796c8dcSSimon Schubert gdb_assert (regcache != NULL);
7855796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
7865796c8dcSSimon Schubert buf = alloca (regcache->descr->sizeof_register[regnum]);
787c50c785cSJohn Marino status = regcache_cooked_read (regcache, regnum, buf);
788c50c785cSJohn Marino if (status == REG_VALID)
789c50c785cSJohn Marino *val = extract_signed_integer
7905796c8dcSSimon Schubert (buf, regcache->descr->sizeof_register[regnum],
7915796c8dcSSimon Schubert gdbarch_byte_order (regcache->descr->gdbarch));
792c50c785cSJohn Marino else
793c50c785cSJohn Marino *val = 0;
794c50c785cSJohn Marino return status;
7955796c8dcSSimon Schubert }
7965796c8dcSSimon Schubert
797c50c785cSJohn Marino enum register_status
regcache_cooked_read_unsigned(struct regcache * regcache,int regnum,ULONGEST * val)7985796c8dcSSimon Schubert regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
7995796c8dcSSimon Schubert ULONGEST *val)
8005796c8dcSSimon Schubert {
801c50c785cSJohn Marino enum register_status status;
8025796c8dcSSimon Schubert gdb_byte *buf;
803cf7f2e2dSJohn Marino
8045796c8dcSSimon Schubert gdb_assert (regcache != NULL);
8055796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
8065796c8dcSSimon Schubert buf = alloca (regcache->descr->sizeof_register[regnum]);
807c50c785cSJohn Marino status = regcache_cooked_read (regcache, regnum, buf);
808c50c785cSJohn Marino if (status == REG_VALID)
809c50c785cSJohn Marino *val = extract_unsigned_integer
8105796c8dcSSimon Schubert (buf, regcache->descr->sizeof_register[regnum],
8115796c8dcSSimon Schubert gdbarch_byte_order (regcache->descr->gdbarch));
812c50c785cSJohn Marino else
813c50c785cSJohn Marino *val = 0;
814c50c785cSJohn Marino return status;
8155796c8dcSSimon Schubert }
8165796c8dcSSimon Schubert
8175796c8dcSSimon Schubert void
regcache_cooked_write_signed(struct regcache * regcache,int regnum,LONGEST val)8185796c8dcSSimon Schubert regcache_cooked_write_signed (struct regcache *regcache, int regnum,
8195796c8dcSSimon Schubert LONGEST val)
8205796c8dcSSimon Schubert {
8215796c8dcSSimon Schubert void *buf;
822cf7f2e2dSJohn Marino
8235796c8dcSSimon Schubert gdb_assert (regcache != NULL);
8245796c8dcSSimon Schubert gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers);
8255796c8dcSSimon Schubert buf = alloca (regcache->descr->sizeof_register[regnum]);
8265796c8dcSSimon Schubert store_signed_integer (buf, regcache->descr->sizeof_register[regnum],
8275796c8dcSSimon Schubert gdbarch_byte_order (regcache->descr->gdbarch), val);
8285796c8dcSSimon Schubert regcache_cooked_write (regcache, regnum, buf);
8295796c8dcSSimon Schubert }
8305796c8dcSSimon Schubert
8315796c8dcSSimon Schubert void
regcache_cooked_write_unsigned(struct regcache * regcache,int regnum,ULONGEST val)8325796c8dcSSimon Schubert regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
8335796c8dcSSimon Schubert ULONGEST val)
8345796c8dcSSimon Schubert {
8355796c8dcSSimon Schubert void *buf;
836cf7f2e2dSJohn Marino
8375796c8dcSSimon Schubert gdb_assert (regcache != NULL);
8385796c8dcSSimon Schubert gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers);
8395796c8dcSSimon Schubert buf = alloca (regcache->descr->sizeof_register[regnum]);
8405796c8dcSSimon Schubert store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum],
8415796c8dcSSimon Schubert gdbarch_byte_order (regcache->descr->gdbarch), val);
8425796c8dcSSimon Schubert regcache_cooked_write (regcache, regnum, buf);
8435796c8dcSSimon Schubert }
8445796c8dcSSimon Schubert
8455796c8dcSSimon Schubert void
regcache_raw_write(struct regcache * regcache,int regnum,const gdb_byte * buf)8465796c8dcSSimon Schubert regcache_raw_write (struct regcache *regcache, int regnum,
8475796c8dcSSimon Schubert const gdb_byte *buf)
8485796c8dcSSimon Schubert {
8495796c8dcSSimon Schubert struct cleanup *old_chain;
8505796c8dcSSimon Schubert
8515796c8dcSSimon Schubert gdb_assert (regcache != NULL && buf != NULL);
8525796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
8535796c8dcSSimon Schubert gdb_assert (!regcache->readonly_p);
8545796c8dcSSimon Schubert
8555796c8dcSSimon Schubert /* On the sparc, writing %g0 is a no-op, so we don't even want to
8565796c8dcSSimon Schubert change the registers array if something writes to this register. */
8575796c8dcSSimon Schubert if (gdbarch_cannot_store_register (get_regcache_arch (regcache), regnum))
8585796c8dcSSimon Schubert return;
8595796c8dcSSimon Schubert
8605796c8dcSSimon Schubert /* If we have a valid copy of the register, and new value == old
8615796c8dcSSimon Schubert value, then don't bother doing the actual store. */
862c50c785cSJohn Marino if (regcache_register_status (regcache, regnum) == REG_VALID
8635796c8dcSSimon Schubert && (memcmp (register_buffer (regcache, regnum), buf,
8645796c8dcSSimon Schubert regcache->descr->sizeof_register[regnum]) == 0))
8655796c8dcSSimon Schubert return;
8665796c8dcSSimon Schubert
8675796c8dcSSimon Schubert old_chain = save_inferior_ptid ();
8685796c8dcSSimon Schubert inferior_ptid = regcache->ptid;
8695796c8dcSSimon Schubert
8705796c8dcSSimon Schubert target_prepare_to_store (regcache);
8715796c8dcSSimon Schubert memcpy (register_buffer (regcache, regnum), buf,
8725796c8dcSSimon Schubert regcache->descr->sizeof_register[regnum]);
873c50c785cSJohn Marino regcache->register_status[regnum] = REG_VALID;
8745796c8dcSSimon Schubert target_store_registers (regcache, regnum);
8755796c8dcSSimon Schubert
8765796c8dcSSimon Schubert do_cleanups (old_chain);
8775796c8dcSSimon Schubert }
8785796c8dcSSimon Schubert
8795796c8dcSSimon Schubert void
regcache_cooked_write(struct regcache * regcache,int regnum,const gdb_byte * buf)8805796c8dcSSimon Schubert regcache_cooked_write (struct regcache *regcache, int regnum,
8815796c8dcSSimon Schubert const gdb_byte *buf)
8825796c8dcSSimon Schubert {
8835796c8dcSSimon Schubert gdb_assert (regnum >= 0);
8845796c8dcSSimon Schubert gdb_assert (regnum < regcache->descr->nr_cooked_registers);
8855796c8dcSSimon Schubert if (regnum < regcache->descr->nr_raw_registers)
8865796c8dcSSimon Schubert regcache_raw_write (regcache, regnum, buf);
8875796c8dcSSimon Schubert else
8885796c8dcSSimon Schubert gdbarch_pseudo_register_write (regcache->descr->gdbarch, regcache,
8895796c8dcSSimon Schubert regnum, buf);
8905796c8dcSSimon Schubert }
8915796c8dcSSimon Schubert
8925796c8dcSSimon Schubert /* Perform a partial register transfer using a read, modify, write
8935796c8dcSSimon Schubert operation. */
8945796c8dcSSimon Schubert
8955796c8dcSSimon Schubert typedef void (regcache_read_ftype) (struct regcache *regcache, int regnum,
8965796c8dcSSimon Schubert void *buf);
8975796c8dcSSimon Schubert typedef void (regcache_write_ftype) (struct regcache *regcache, int regnum,
8985796c8dcSSimon Schubert const void *buf);
8995796c8dcSSimon Schubert
900c50c785cSJohn Marino static enum register_status
regcache_xfer_part(struct regcache * regcache,int regnum,int offset,int len,void * in,const void * out,enum register_status (* read)(struct regcache * regcache,int regnum,gdb_byte * buf),void (* write)(struct regcache * regcache,int regnum,const gdb_byte * buf))9015796c8dcSSimon Schubert regcache_xfer_part (struct regcache *regcache, int regnum,
9025796c8dcSSimon Schubert int offset, int len, void *in, const void *out,
903c50c785cSJohn Marino enum register_status (*read) (struct regcache *regcache,
904c50c785cSJohn Marino int regnum,
9055796c8dcSSimon Schubert gdb_byte *buf),
9065796c8dcSSimon Schubert void (*write) (struct regcache *regcache, int regnum,
9075796c8dcSSimon Schubert const gdb_byte *buf))
9085796c8dcSSimon Schubert {
9095796c8dcSSimon Schubert struct regcache_descr *descr = regcache->descr;
9105796c8dcSSimon Schubert gdb_byte reg[MAX_REGISTER_SIZE];
911cf7f2e2dSJohn Marino
9125796c8dcSSimon Schubert gdb_assert (offset >= 0 && offset <= descr->sizeof_register[regnum]);
9135796c8dcSSimon Schubert gdb_assert (len >= 0 && offset + len <= descr->sizeof_register[regnum]);
9145796c8dcSSimon Schubert /* Something to do? */
9155796c8dcSSimon Schubert if (offset + len == 0)
916c50c785cSJohn Marino return REG_VALID;
9175796c8dcSSimon Schubert /* Read (when needed) ... */
9185796c8dcSSimon Schubert if (in != NULL
9195796c8dcSSimon Schubert || offset > 0
9205796c8dcSSimon Schubert || offset + len < descr->sizeof_register[regnum])
9215796c8dcSSimon Schubert {
922c50c785cSJohn Marino enum register_status status;
923c50c785cSJohn Marino
9245796c8dcSSimon Schubert gdb_assert (read != NULL);
925c50c785cSJohn Marino status = read (regcache, regnum, reg);
926c50c785cSJohn Marino if (status != REG_VALID)
927c50c785cSJohn Marino return status;
9285796c8dcSSimon Schubert }
9295796c8dcSSimon Schubert /* ... modify ... */
9305796c8dcSSimon Schubert if (in != NULL)
9315796c8dcSSimon Schubert memcpy (in, reg + offset, len);
9325796c8dcSSimon Schubert if (out != NULL)
9335796c8dcSSimon Schubert memcpy (reg + offset, out, len);
9345796c8dcSSimon Schubert /* ... write (when needed). */
9355796c8dcSSimon Schubert if (out != NULL)
9365796c8dcSSimon Schubert {
9375796c8dcSSimon Schubert gdb_assert (write != NULL);
9385796c8dcSSimon Schubert write (regcache, regnum, reg);
9395796c8dcSSimon Schubert }
940c50c785cSJohn Marino
941c50c785cSJohn Marino return REG_VALID;
9425796c8dcSSimon Schubert }
9435796c8dcSSimon Schubert
944c50c785cSJohn Marino enum register_status
regcache_raw_read_part(struct regcache * regcache,int regnum,int offset,int len,gdb_byte * buf)9455796c8dcSSimon Schubert regcache_raw_read_part (struct regcache *regcache, int regnum,
9465796c8dcSSimon Schubert int offset, int len, gdb_byte *buf)
9475796c8dcSSimon Schubert {
9485796c8dcSSimon Schubert struct regcache_descr *descr = regcache->descr;
949cf7f2e2dSJohn Marino
9505796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers);
951c50c785cSJohn Marino return regcache_xfer_part (regcache, regnum, offset, len, buf, NULL,
9525796c8dcSSimon Schubert regcache_raw_read, regcache_raw_write);
9535796c8dcSSimon Schubert }
9545796c8dcSSimon Schubert
9555796c8dcSSimon Schubert void
regcache_raw_write_part(struct regcache * regcache,int regnum,int offset,int len,const gdb_byte * buf)9565796c8dcSSimon Schubert regcache_raw_write_part (struct regcache *regcache, int regnum,
9575796c8dcSSimon Schubert int offset, int len, const gdb_byte *buf)
9585796c8dcSSimon Schubert {
9595796c8dcSSimon Schubert struct regcache_descr *descr = regcache->descr;
960cf7f2e2dSJohn Marino
9615796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < descr->nr_raw_registers);
9625796c8dcSSimon Schubert regcache_xfer_part (regcache, regnum, offset, len, NULL, buf,
9635796c8dcSSimon Schubert regcache_raw_read, regcache_raw_write);
9645796c8dcSSimon Schubert }
9655796c8dcSSimon Schubert
966c50c785cSJohn Marino enum register_status
regcache_cooked_read_part(struct regcache * regcache,int regnum,int offset,int len,gdb_byte * buf)9675796c8dcSSimon Schubert regcache_cooked_read_part (struct regcache *regcache, int regnum,
9685796c8dcSSimon Schubert int offset, int len, gdb_byte *buf)
9695796c8dcSSimon Schubert {
9705796c8dcSSimon Schubert struct regcache_descr *descr = regcache->descr;
971cf7f2e2dSJohn Marino
9725796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
973c50c785cSJohn Marino return regcache_xfer_part (regcache, regnum, offset, len, buf, NULL,
9745796c8dcSSimon Schubert regcache_cooked_read, regcache_cooked_write);
9755796c8dcSSimon Schubert }
9765796c8dcSSimon Schubert
9775796c8dcSSimon Schubert void
regcache_cooked_write_part(struct regcache * regcache,int regnum,int offset,int len,const gdb_byte * buf)9785796c8dcSSimon Schubert regcache_cooked_write_part (struct regcache *regcache, int regnum,
9795796c8dcSSimon Schubert int offset, int len, const gdb_byte *buf)
9805796c8dcSSimon Schubert {
9815796c8dcSSimon Schubert struct regcache_descr *descr = regcache->descr;
982cf7f2e2dSJohn Marino
9835796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
9845796c8dcSSimon Schubert regcache_xfer_part (regcache, regnum, offset, len, NULL, buf,
9855796c8dcSSimon Schubert regcache_cooked_read, regcache_cooked_write);
9865796c8dcSSimon Schubert }
9875796c8dcSSimon Schubert
9885796c8dcSSimon Schubert /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE. */
9895796c8dcSSimon Schubert
9905796c8dcSSimon Schubert void
regcache_raw_supply(struct regcache * regcache,int regnum,const void * buf)9915796c8dcSSimon Schubert regcache_raw_supply (struct regcache *regcache, int regnum, const void *buf)
9925796c8dcSSimon Schubert {
9935796c8dcSSimon Schubert void *regbuf;
9945796c8dcSSimon Schubert size_t size;
9955796c8dcSSimon Schubert
9965796c8dcSSimon Schubert gdb_assert (regcache != NULL);
9975796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
9985796c8dcSSimon Schubert gdb_assert (!regcache->readonly_p);
9995796c8dcSSimon Schubert
10005796c8dcSSimon Schubert regbuf = register_buffer (regcache, regnum);
10015796c8dcSSimon Schubert size = regcache->descr->sizeof_register[regnum];
10025796c8dcSSimon Schubert
10035796c8dcSSimon Schubert if (buf)
1004c50c785cSJohn Marino {
10055796c8dcSSimon Schubert memcpy (regbuf, buf, size);
1006c50c785cSJohn Marino regcache->register_status[regnum] = REG_VALID;
1007c50c785cSJohn Marino }
10085796c8dcSSimon Schubert else
1009c50c785cSJohn Marino {
1010c50c785cSJohn Marino /* This memset not strictly necessary, but better than garbage
1011c50c785cSJohn Marino in case the register value manages to escape somewhere (due
1012c50c785cSJohn Marino to a bug, no less). */
10135796c8dcSSimon Schubert memset (regbuf, 0, size);
1014c50c785cSJohn Marino regcache->register_status[regnum] = REG_UNAVAILABLE;
1015c50c785cSJohn Marino }
10165796c8dcSSimon Schubert }
10175796c8dcSSimon Schubert
10185796c8dcSSimon Schubert /* Collect register REGNUM from REGCACHE and store its contents in BUF. */
10195796c8dcSSimon Schubert
10205796c8dcSSimon Schubert void
regcache_raw_collect(const struct regcache * regcache,int regnum,void * buf)10215796c8dcSSimon Schubert regcache_raw_collect (const struct regcache *regcache, int regnum, void *buf)
10225796c8dcSSimon Schubert {
10235796c8dcSSimon Schubert const void *regbuf;
10245796c8dcSSimon Schubert size_t size;
10255796c8dcSSimon Schubert
10265796c8dcSSimon Schubert gdb_assert (regcache != NULL && buf != NULL);
10275796c8dcSSimon Schubert gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
10285796c8dcSSimon Schubert
10295796c8dcSSimon Schubert regbuf = register_buffer (regcache, regnum);
10305796c8dcSSimon Schubert size = regcache->descr->sizeof_register[regnum];
10315796c8dcSSimon Schubert memcpy (buf, regbuf, size);
10325796c8dcSSimon Schubert }
10335796c8dcSSimon Schubert
10345796c8dcSSimon Schubert
10355796c8dcSSimon Schubert /* Special handling for register PC. */
10365796c8dcSSimon Schubert
10375796c8dcSSimon Schubert CORE_ADDR
regcache_read_pc(struct regcache * regcache)10385796c8dcSSimon Schubert regcache_read_pc (struct regcache *regcache)
10395796c8dcSSimon Schubert {
10405796c8dcSSimon Schubert struct gdbarch *gdbarch = get_regcache_arch (regcache);
10415796c8dcSSimon Schubert
10425796c8dcSSimon Schubert CORE_ADDR pc_val;
10435796c8dcSSimon Schubert
10445796c8dcSSimon Schubert if (gdbarch_read_pc_p (gdbarch))
10455796c8dcSSimon Schubert pc_val = gdbarch_read_pc (gdbarch, regcache);
10465796c8dcSSimon Schubert /* Else use per-frame method on get_current_frame. */
10475796c8dcSSimon Schubert else if (gdbarch_pc_regnum (gdbarch) >= 0)
10485796c8dcSSimon Schubert {
10495796c8dcSSimon Schubert ULONGEST raw_val;
1050cf7f2e2dSJohn Marino
1051c50c785cSJohn Marino if (regcache_cooked_read_unsigned (regcache,
10525796c8dcSSimon Schubert gdbarch_pc_regnum (gdbarch),
1053c50c785cSJohn Marino &raw_val) == REG_UNAVAILABLE)
1054c50c785cSJohn Marino throw_error (NOT_AVAILABLE_ERROR, _("PC register is not available"));
1055c50c785cSJohn Marino
10565796c8dcSSimon Schubert pc_val = gdbarch_addr_bits_remove (gdbarch, raw_val);
10575796c8dcSSimon Schubert }
10585796c8dcSSimon Schubert else
10595796c8dcSSimon Schubert internal_error (__FILE__, __LINE__,
10605796c8dcSSimon Schubert _("regcache_read_pc: Unable to find PC"));
10615796c8dcSSimon Schubert return pc_val;
10625796c8dcSSimon Schubert }
10635796c8dcSSimon Schubert
10645796c8dcSSimon Schubert void
regcache_write_pc(struct regcache * regcache,CORE_ADDR pc)10655796c8dcSSimon Schubert regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
10665796c8dcSSimon Schubert {
10675796c8dcSSimon Schubert struct gdbarch *gdbarch = get_regcache_arch (regcache);
10685796c8dcSSimon Schubert
10695796c8dcSSimon Schubert if (gdbarch_write_pc_p (gdbarch))
10705796c8dcSSimon Schubert gdbarch_write_pc (gdbarch, regcache, pc);
10715796c8dcSSimon Schubert else if (gdbarch_pc_regnum (gdbarch) >= 0)
10725796c8dcSSimon Schubert regcache_cooked_write_unsigned (regcache,
10735796c8dcSSimon Schubert gdbarch_pc_regnum (gdbarch), pc);
10745796c8dcSSimon Schubert else
10755796c8dcSSimon Schubert internal_error (__FILE__, __LINE__,
10765796c8dcSSimon Schubert _("regcache_write_pc: Unable to update PC"));
10775796c8dcSSimon Schubert
10785796c8dcSSimon Schubert /* Writing the PC (for instance, from "load") invalidates the
10795796c8dcSSimon Schubert current frame. */
10805796c8dcSSimon Schubert reinit_frame_cache ();
10815796c8dcSSimon Schubert }
10825796c8dcSSimon Schubert
10835796c8dcSSimon Schubert
10845796c8dcSSimon Schubert static void
reg_flush_command(char * command,int from_tty)10855796c8dcSSimon Schubert reg_flush_command (char *command, int from_tty)
10865796c8dcSSimon Schubert {
10875796c8dcSSimon Schubert /* Force-flush the register cache. */
10885796c8dcSSimon Schubert registers_changed ();
10895796c8dcSSimon Schubert if (from_tty)
10905796c8dcSSimon Schubert printf_filtered (_("Register cache flushed.\n"));
10915796c8dcSSimon Schubert }
10925796c8dcSSimon Schubert
10935796c8dcSSimon Schubert static void
dump_endian_bytes(struct ui_file * file,enum bfd_endian endian,const gdb_byte * buf,long len)10945796c8dcSSimon Schubert dump_endian_bytes (struct ui_file *file, enum bfd_endian endian,
1095*ef5ccd6cSJohn Marino const gdb_byte *buf, long len)
10965796c8dcSSimon Schubert {
10975796c8dcSSimon Schubert int i;
1098cf7f2e2dSJohn Marino
10995796c8dcSSimon Schubert switch (endian)
11005796c8dcSSimon Schubert {
11015796c8dcSSimon Schubert case BFD_ENDIAN_BIG:
11025796c8dcSSimon Schubert for (i = 0; i < len; i++)
11035796c8dcSSimon Schubert fprintf_unfiltered (file, "%02x", buf[i]);
11045796c8dcSSimon Schubert break;
11055796c8dcSSimon Schubert case BFD_ENDIAN_LITTLE:
11065796c8dcSSimon Schubert for (i = len - 1; i >= 0; i--)
11075796c8dcSSimon Schubert fprintf_unfiltered (file, "%02x", buf[i]);
11085796c8dcSSimon Schubert break;
11095796c8dcSSimon Schubert default:
11105796c8dcSSimon Schubert internal_error (__FILE__, __LINE__, _("Bad switch"));
11115796c8dcSSimon Schubert }
11125796c8dcSSimon Schubert }
11135796c8dcSSimon Schubert
11145796c8dcSSimon Schubert enum regcache_dump_what
11155796c8dcSSimon Schubert {
1116c50c785cSJohn Marino regcache_dump_none, regcache_dump_raw,
1117a45ae5f8SJohn Marino regcache_dump_cooked, regcache_dump_groups,
1118a45ae5f8SJohn Marino regcache_dump_remote
11195796c8dcSSimon Schubert };
11205796c8dcSSimon Schubert
11215796c8dcSSimon Schubert static void
regcache_dump(struct regcache * regcache,struct ui_file * file,enum regcache_dump_what what_to_dump)11225796c8dcSSimon Schubert regcache_dump (struct regcache *regcache, struct ui_file *file,
11235796c8dcSSimon Schubert enum regcache_dump_what what_to_dump)
11245796c8dcSSimon Schubert {
11255796c8dcSSimon Schubert struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
11265796c8dcSSimon Schubert struct gdbarch *gdbarch = regcache->descr->gdbarch;
11275796c8dcSSimon Schubert int regnum;
11285796c8dcSSimon Schubert int footnote_nr = 0;
11295796c8dcSSimon Schubert int footnote_register_size = 0;
11305796c8dcSSimon Schubert int footnote_register_offset = 0;
11315796c8dcSSimon Schubert int footnote_register_type_name_null = 0;
11325796c8dcSSimon Schubert long register_offset = 0;
1133*ef5ccd6cSJohn Marino gdb_byte buf[MAX_REGISTER_SIZE];
11345796c8dcSSimon Schubert
11355796c8dcSSimon Schubert #if 0
11365796c8dcSSimon Schubert fprintf_unfiltered (file, "nr_raw_registers %d\n",
11375796c8dcSSimon Schubert regcache->descr->nr_raw_registers);
11385796c8dcSSimon Schubert fprintf_unfiltered (file, "nr_cooked_registers %d\n",
11395796c8dcSSimon Schubert regcache->descr->nr_cooked_registers);
11405796c8dcSSimon Schubert fprintf_unfiltered (file, "sizeof_raw_registers %ld\n",
11415796c8dcSSimon Schubert regcache->descr->sizeof_raw_registers);
1142c50c785cSJohn Marino fprintf_unfiltered (file, "sizeof_raw_register_status %ld\n",
1143c50c785cSJohn Marino regcache->descr->sizeof_raw_register_status);
11445796c8dcSSimon Schubert fprintf_unfiltered (file, "gdbarch_num_regs %d\n",
11455796c8dcSSimon Schubert gdbarch_num_regs (gdbarch));
11465796c8dcSSimon Schubert fprintf_unfiltered (file, "gdbarch_num_pseudo_regs %d\n",
11475796c8dcSSimon Schubert gdbarch_num_pseudo_regs (gdbarch));
11485796c8dcSSimon Schubert #endif
11495796c8dcSSimon Schubert
11505796c8dcSSimon Schubert gdb_assert (regcache->descr->nr_cooked_registers
11515796c8dcSSimon Schubert == (gdbarch_num_regs (gdbarch)
11525796c8dcSSimon Schubert + gdbarch_num_pseudo_regs (gdbarch)));
11535796c8dcSSimon Schubert
11545796c8dcSSimon Schubert for (regnum = -1; regnum < regcache->descr->nr_cooked_registers; regnum++)
11555796c8dcSSimon Schubert {
11565796c8dcSSimon Schubert /* Name. */
11575796c8dcSSimon Schubert if (regnum < 0)
11585796c8dcSSimon Schubert fprintf_unfiltered (file, " %-10s", "Name");
11595796c8dcSSimon Schubert else
11605796c8dcSSimon Schubert {
11615796c8dcSSimon Schubert const char *p = gdbarch_register_name (gdbarch, regnum);
1162cf7f2e2dSJohn Marino
11635796c8dcSSimon Schubert if (p == NULL)
11645796c8dcSSimon Schubert p = "";
11655796c8dcSSimon Schubert else if (p[0] == '\0')
11665796c8dcSSimon Schubert p = "''";
11675796c8dcSSimon Schubert fprintf_unfiltered (file, " %-10s", p);
11685796c8dcSSimon Schubert }
11695796c8dcSSimon Schubert
11705796c8dcSSimon Schubert /* Number. */
11715796c8dcSSimon Schubert if (regnum < 0)
11725796c8dcSSimon Schubert fprintf_unfiltered (file, " %4s", "Nr");
11735796c8dcSSimon Schubert else
11745796c8dcSSimon Schubert fprintf_unfiltered (file, " %4d", regnum);
11755796c8dcSSimon Schubert
11765796c8dcSSimon Schubert /* Relative number. */
11775796c8dcSSimon Schubert if (regnum < 0)
11785796c8dcSSimon Schubert fprintf_unfiltered (file, " %4s", "Rel");
11795796c8dcSSimon Schubert else if (regnum < gdbarch_num_regs (gdbarch))
11805796c8dcSSimon Schubert fprintf_unfiltered (file, " %4d", regnum);
11815796c8dcSSimon Schubert else
11825796c8dcSSimon Schubert fprintf_unfiltered (file, " %4d",
11835796c8dcSSimon Schubert (regnum - gdbarch_num_regs (gdbarch)));
11845796c8dcSSimon Schubert
11855796c8dcSSimon Schubert /* Offset. */
11865796c8dcSSimon Schubert if (regnum < 0)
11875796c8dcSSimon Schubert fprintf_unfiltered (file, " %6s ", "Offset");
11885796c8dcSSimon Schubert else
11895796c8dcSSimon Schubert {
11905796c8dcSSimon Schubert fprintf_unfiltered (file, " %6ld",
11915796c8dcSSimon Schubert regcache->descr->register_offset[regnum]);
11925796c8dcSSimon Schubert if (register_offset != regcache->descr->register_offset[regnum]
11935796c8dcSSimon Schubert || (regnum > 0
11945796c8dcSSimon Schubert && (regcache->descr->register_offset[regnum]
11955796c8dcSSimon Schubert != (regcache->descr->register_offset[regnum - 1]
11965796c8dcSSimon Schubert + regcache->descr->sizeof_register[regnum - 1])))
11975796c8dcSSimon Schubert )
11985796c8dcSSimon Schubert {
11995796c8dcSSimon Schubert if (!footnote_register_offset)
12005796c8dcSSimon Schubert footnote_register_offset = ++footnote_nr;
12015796c8dcSSimon Schubert fprintf_unfiltered (file, "*%d", footnote_register_offset);
12025796c8dcSSimon Schubert }
12035796c8dcSSimon Schubert else
12045796c8dcSSimon Schubert fprintf_unfiltered (file, " ");
12055796c8dcSSimon Schubert register_offset = (regcache->descr->register_offset[regnum]
12065796c8dcSSimon Schubert + regcache->descr->sizeof_register[regnum]);
12075796c8dcSSimon Schubert }
12085796c8dcSSimon Schubert
12095796c8dcSSimon Schubert /* Size. */
12105796c8dcSSimon Schubert if (regnum < 0)
12115796c8dcSSimon Schubert fprintf_unfiltered (file, " %5s ", "Size");
12125796c8dcSSimon Schubert else
12135796c8dcSSimon Schubert fprintf_unfiltered (file, " %5ld",
12145796c8dcSSimon Schubert regcache->descr->sizeof_register[regnum]);
12155796c8dcSSimon Schubert
12165796c8dcSSimon Schubert /* Type. */
12175796c8dcSSimon Schubert {
12185796c8dcSSimon Schubert const char *t;
1219cf7f2e2dSJohn Marino
12205796c8dcSSimon Schubert if (regnum < 0)
12215796c8dcSSimon Schubert t = "Type";
12225796c8dcSSimon Schubert else
12235796c8dcSSimon Schubert {
12245796c8dcSSimon Schubert static const char blt[] = "builtin_type";
1225cf7f2e2dSJohn Marino
12265796c8dcSSimon Schubert t = TYPE_NAME (register_type (regcache->descr->gdbarch, regnum));
12275796c8dcSSimon Schubert if (t == NULL)
12285796c8dcSSimon Schubert {
12295796c8dcSSimon Schubert char *n;
1230cf7f2e2dSJohn Marino
12315796c8dcSSimon Schubert if (!footnote_register_type_name_null)
12325796c8dcSSimon Schubert footnote_register_type_name_null = ++footnote_nr;
12335796c8dcSSimon Schubert n = xstrprintf ("*%d", footnote_register_type_name_null);
12345796c8dcSSimon Schubert make_cleanup (xfree, n);
12355796c8dcSSimon Schubert t = n;
12365796c8dcSSimon Schubert }
12375796c8dcSSimon Schubert /* Chop a leading builtin_type. */
12385796c8dcSSimon Schubert if (strncmp (t, blt, strlen (blt)) == 0)
12395796c8dcSSimon Schubert t += strlen (blt);
12405796c8dcSSimon Schubert }
12415796c8dcSSimon Schubert fprintf_unfiltered (file, " %-15s", t);
12425796c8dcSSimon Schubert }
12435796c8dcSSimon Schubert
12445796c8dcSSimon Schubert /* Leading space always present. */
12455796c8dcSSimon Schubert fprintf_unfiltered (file, " ");
12465796c8dcSSimon Schubert
12475796c8dcSSimon Schubert /* Value, raw. */
12485796c8dcSSimon Schubert if (what_to_dump == regcache_dump_raw)
12495796c8dcSSimon Schubert {
12505796c8dcSSimon Schubert if (regnum < 0)
12515796c8dcSSimon Schubert fprintf_unfiltered (file, "Raw value");
12525796c8dcSSimon Schubert else if (regnum >= regcache->descr->nr_raw_registers)
12535796c8dcSSimon Schubert fprintf_unfiltered (file, "<cooked>");
1254c50c785cSJohn Marino else if (regcache_register_status (regcache, regnum) == REG_UNKNOWN)
12555796c8dcSSimon Schubert fprintf_unfiltered (file, "<invalid>");
1256c50c785cSJohn Marino else if (regcache_register_status (regcache, regnum) == REG_UNAVAILABLE)
1257c50c785cSJohn Marino fprintf_unfiltered (file, "<unavailable>");
12585796c8dcSSimon Schubert else
12595796c8dcSSimon Schubert {
12605796c8dcSSimon Schubert regcache_raw_read (regcache, regnum, buf);
12615796c8dcSSimon Schubert fprintf_unfiltered (file, "0x");
12625796c8dcSSimon Schubert dump_endian_bytes (file,
12635796c8dcSSimon Schubert gdbarch_byte_order (gdbarch), buf,
12645796c8dcSSimon Schubert regcache->descr->sizeof_register[regnum]);
12655796c8dcSSimon Schubert }
12665796c8dcSSimon Schubert }
12675796c8dcSSimon Schubert
12685796c8dcSSimon Schubert /* Value, cooked. */
12695796c8dcSSimon Schubert if (what_to_dump == regcache_dump_cooked)
12705796c8dcSSimon Schubert {
12715796c8dcSSimon Schubert if (regnum < 0)
12725796c8dcSSimon Schubert fprintf_unfiltered (file, "Cooked value");
12735796c8dcSSimon Schubert else
12745796c8dcSSimon Schubert {
1275c50c785cSJohn Marino enum register_status status;
1276c50c785cSJohn Marino
1277c50c785cSJohn Marino status = regcache_cooked_read (regcache, regnum, buf);
1278c50c785cSJohn Marino if (status == REG_UNKNOWN)
1279c50c785cSJohn Marino fprintf_unfiltered (file, "<invalid>");
1280c50c785cSJohn Marino else if (status == REG_UNAVAILABLE)
1281c50c785cSJohn Marino fprintf_unfiltered (file, "<unavailable>");
1282c50c785cSJohn Marino else
1283c50c785cSJohn Marino {
12845796c8dcSSimon Schubert fprintf_unfiltered (file, "0x");
12855796c8dcSSimon Schubert dump_endian_bytes (file,
12865796c8dcSSimon Schubert gdbarch_byte_order (gdbarch), buf,
12875796c8dcSSimon Schubert regcache->descr->sizeof_register[regnum]);
12885796c8dcSSimon Schubert }
12895796c8dcSSimon Schubert }
1290c50c785cSJohn Marino }
12915796c8dcSSimon Schubert
12925796c8dcSSimon Schubert /* Group members. */
12935796c8dcSSimon Schubert if (what_to_dump == regcache_dump_groups)
12945796c8dcSSimon Schubert {
12955796c8dcSSimon Schubert if (regnum < 0)
12965796c8dcSSimon Schubert fprintf_unfiltered (file, "Groups");
12975796c8dcSSimon Schubert else
12985796c8dcSSimon Schubert {
12995796c8dcSSimon Schubert const char *sep = "";
13005796c8dcSSimon Schubert struct reggroup *group;
1301cf7f2e2dSJohn Marino
13025796c8dcSSimon Schubert for (group = reggroup_next (gdbarch, NULL);
13035796c8dcSSimon Schubert group != NULL;
13045796c8dcSSimon Schubert group = reggroup_next (gdbarch, group))
13055796c8dcSSimon Schubert {
13065796c8dcSSimon Schubert if (gdbarch_register_reggroup_p (gdbarch, regnum, group))
13075796c8dcSSimon Schubert {
1308c50c785cSJohn Marino fprintf_unfiltered (file,
1309c50c785cSJohn Marino "%s%s", sep, reggroup_name (group));
13105796c8dcSSimon Schubert sep = ",";
13115796c8dcSSimon Schubert }
13125796c8dcSSimon Schubert }
13135796c8dcSSimon Schubert }
13145796c8dcSSimon Schubert }
13155796c8dcSSimon Schubert
1316a45ae5f8SJohn Marino /* Remote packet configuration. */
1317a45ae5f8SJohn Marino if (what_to_dump == regcache_dump_remote)
1318a45ae5f8SJohn Marino {
1319a45ae5f8SJohn Marino if (regnum < 0)
1320a45ae5f8SJohn Marino {
1321a45ae5f8SJohn Marino fprintf_unfiltered (file, "Rmt Nr g/G Offset");
1322a45ae5f8SJohn Marino }
1323a45ae5f8SJohn Marino else if (regnum < regcache->descr->nr_raw_registers)
1324a45ae5f8SJohn Marino {
1325a45ae5f8SJohn Marino int pnum, poffset;
1326a45ae5f8SJohn Marino
1327a45ae5f8SJohn Marino if (remote_register_number_and_offset (get_regcache_arch (regcache), regnum,
1328a45ae5f8SJohn Marino &pnum, &poffset))
1329a45ae5f8SJohn Marino fprintf_unfiltered (file, "%7d %11d", pnum, poffset);
1330a45ae5f8SJohn Marino }
1331a45ae5f8SJohn Marino }
1332a45ae5f8SJohn Marino
13335796c8dcSSimon Schubert fprintf_unfiltered (file, "\n");
13345796c8dcSSimon Schubert }
13355796c8dcSSimon Schubert
13365796c8dcSSimon Schubert if (footnote_register_size)
13375796c8dcSSimon Schubert fprintf_unfiltered (file, "*%d: Inconsistent register sizes.\n",
13385796c8dcSSimon Schubert footnote_register_size);
13395796c8dcSSimon Schubert if (footnote_register_offset)
13405796c8dcSSimon Schubert fprintf_unfiltered (file, "*%d: Inconsistent register offsets.\n",
13415796c8dcSSimon Schubert footnote_register_offset);
13425796c8dcSSimon Schubert if (footnote_register_type_name_null)
13435796c8dcSSimon Schubert fprintf_unfiltered (file,
13445796c8dcSSimon Schubert "*%d: Register type's name NULL.\n",
13455796c8dcSSimon Schubert footnote_register_type_name_null);
13465796c8dcSSimon Schubert do_cleanups (cleanups);
13475796c8dcSSimon Schubert }
13485796c8dcSSimon Schubert
13495796c8dcSSimon Schubert static void
regcache_print(char * args,enum regcache_dump_what what_to_dump)13505796c8dcSSimon Schubert regcache_print (char *args, enum regcache_dump_what what_to_dump)
13515796c8dcSSimon Schubert {
13525796c8dcSSimon Schubert if (args == NULL)
13535796c8dcSSimon Schubert regcache_dump (get_current_regcache (), gdb_stdout, what_to_dump);
13545796c8dcSSimon Schubert else
13555796c8dcSSimon Schubert {
13565796c8dcSSimon Schubert struct cleanup *cleanups;
13575796c8dcSSimon Schubert struct ui_file *file = gdb_fopen (args, "w");
1358cf7f2e2dSJohn Marino
13595796c8dcSSimon Schubert if (file == NULL)
13605796c8dcSSimon Schubert perror_with_name (_("maintenance print architecture"));
13615796c8dcSSimon Schubert cleanups = make_cleanup_ui_file_delete (file);
13625796c8dcSSimon Schubert regcache_dump (get_current_regcache (), file, what_to_dump);
13635796c8dcSSimon Schubert do_cleanups (cleanups);
13645796c8dcSSimon Schubert }
13655796c8dcSSimon Schubert }
13665796c8dcSSimon Schubert
13675796c8dcSSimon Schubert static void
maintenance_print_registers(char * args,int from_tty)13685796c8dcSSimon Schubert maintenance_print_registers (char *args, int from_tty)
13695796c8dcSSimon Schubert {
13705796c8dcSSimon Schubert regcache_print (args, regcache_dump_none);
13715796c8dcSSimon Schubert }
13725796c8dcSSimon Schubert
13735796c8dcSSimon Schubert static void
maintenance_print_raw_registers(char * args,int from_tty)13745796c8dcSSimon Schubert maintenance_print_raw_registers (char *args, int from_tty)
13755796c8dcSSimon Schubert {
13765796c8dcSSimon Schubert regcache_print (args, regcache_dump_raw);
13775796c8dcSSimon Schubert }
13785796c8dcSSimon Schubert
13795796c8dcSSimon Schubert static void
maintenance_print_cooked_registers(char * args,int from_tty)13805796c8dcSSimon Schubert maintenance_print_cooked_registers (char *args, int from_tty)
13815796c8dcSSimon Schubert {
13825796c8dcSSimon Schubert regcache_print (args, regcache_dump_cooked);
13835796c8dcSSimon Schubert }
13845796c8dcSSimon Schubert
13855796c8dcSSimon Schubert static void
maintenance_print_register_groups(char * args,int from_tty)13865796c8dcSSimon Schubert maintenance_print_register_groups (char *args, int from_tty)
13875796c8dcSSimon Schubert {
13885796c8dcSSimon Schubert regcache_print (args, regcache_dump_groups);
13895796c8dcSSimon Schubert }
13905796c8dcSSimon Schubert
1391a45ae5f8SJohn Marino static void
maintenance_print_remote_registers(char * args,int from_tty)1392a45ae5f8SJohn Marino maintenance_print_remote_registers (char *args, int from_tty)
1393a45ae5f8SJohn Marino {
1394a45ae5f8SJohn Marino regcache_print (args, regcache_dump_remote);
1395a45ae5f8SJohn Marino }
1396a45ae5f8SJohn Marino
13975796c8dcSSimon Schubert extern initialize_file_ftype _initialize_regcache; /* -Wmissing-prototype */
13985796c8dcSSimon Schubert
13995796c8dcSSimon Schubert void
_initialize_regcache(void)14005796c8dcSSimon Schubert _initialize_regcache (void)
14015796c8dcSSimon Schubert {
1402c50c785cSJohn Marino regcache_descr_handle
1403c50c785cSJohn Marino = gdbarch_data_register_post_init (init_regcache_descr);
14045796c8dcSSimon Schubert
14055796c8dcSSimon Schubert observer_attach_target_changed (regcache_observer_target_changed);
14065796c8dcSSimon Schubert observer_attach_thread_ptid_changed (regcache_thread_ptid_changed);
14075796c8dcSSimon Schubert
14085796c8dcSSimon Schubert add_com ("flushregs", class_maintenance, reg_flush_command,
14095796c8dcSSimon Schubert _("Force gdb to flush its register cache (maintainer command)"));
14105796c8dcSSimon Schubert
1411c50c785cSJohn Marino add_cmd ("registers", class_maintenance, maintenance_print_registers,
1412c50c785cSJohn Marino _("Print the internal register configuration.\n"
1413c50c785cSJohn Marino "Takes an optional file parameter."), &maintenanceprintlist);
14145796c8dcSSimon Schubert add_cmd ("raw-registers", class_maintenance,
1415c50c785cSJohn Marino maintenance_print_raw_registers,
1416c50c785cSJohn Marino _("Print the internal register configuration "
1417c50c785cSJohn Marino "including raw values.\n"
1418c50c785cSJohn Marino "Takes an optional file parameter."), &maintenanceprintlist);
14195796c8dcSSimon Schubert add_cmd ("cooked-registers", class_maintenance,
1420c50c785cSJohn Marino maintenance_print_cooked_registers,
1421c50c785cSJohn Marino _("Print the internal register configuration "
1422c50c785cSJohn Marino "including cooked values.\n"
1423c50c785cSJohn Marino "Takes an optional file parameter."), &maintenanceprintlist);
14245796c8dcSSimon Schubert add_cmd ("register-groups", class_maintenance,
1425c50c785cSJohn Marino maintenance_print_register_groups,
1426c50c785cSJohn Marino _("Print the internal register configuration "
1427c50c785cSJohn Marino "including each register's group.\n"
1428c50c785cSJohn Marino "Takes an optional file parameter."),
14295796c8dcSSimon Schubert &maintenanceprintlist);
1430a45ae5f8SJohn Marino add_cmd ("remote-registers", class_maintenance,
1431a45ae5f8SJohn Marino maintenance_print_remote_registers, _("\
1432a45ae5f8SJohn Marino Print the internal register configuration including each register's\n\
1433a45ae5f8SJohn Marino remote register number and buffer offset in the g/G packets.\n\
1434a45ae5f8SJohn Marino Takes an optional file parameter."),
1435a45ae5f8SJohn Marino &maintenanceprintlist);
14365796c8dcSSimon Schubert
14375796c8dcSSimon Schubert }
1438