2002-08-25 Andrew Cagney * arch-utils.h (default_next_cooked_register_to_save): Declare. (default_next_cooked_register_to_restore): Declare. * arch-utils.c (default_next_cooked_register_to_save): New function. (default_next_cooked_register_to_restore): New function. * regcache.c (struct regcache): Replace passthrough_p with readonly_p. Replace raw_registers with registers. Replace raw_register_valid_p with register_valid_p. (struct regcache_descr): Replace sizeof_raw_registers with sizeof_registers. Replace sizeof_raw_register_valid_p with sizeof_register_valid_p. (init_legacy_regcache_descr): Update. (init_regcache_descr): Update. (regcache_xmalloc): Update. (regcache_xfree): Update. (regcache_cpy): Update. (regcache_cpy_no_passthrough): Update. (regcache_valid_p): Update. (deprecated_grub_regcache_for_registers): Update. (deprecated_grub_regcache_for_register_valid): Update. (register_buffer): Update. (regcache_raw_read): Update. (regcache_raw_write): Update. Assert that the register cache is not read-only. (build_regcache): Update. Clear the readonly_p flag. (regcache_cooked_read): Update. If a read-only cache, check for a cached cooked register value. (regcache_cooked_write): Assert that the cache isn't read-only. (next_cooked_register): New function. (regcache_restore): New function. (regcache_save): New function. (regcache_cpy): Rewrite. * gdbarch.sh (next_cooked_register_to_save): New method. (next_cooked_register_to_restore): New method. * gdbarch.h, gdbarch.c: Regenerate. Index: arch-utils.c =================================================================== RCS file: /cvs/src/src/gdb/arch-utils.c,v retrieving revision 1.67 diff -u -r1.67 arch-utils.c --- arch-utils.c 24 Aug 2002 00:21:34 -0000 1.67 +++ arch-utils.c 25 Aug 2002 19:06:10 -0000 @@ -493,6 +493,29 @@ REGISTER_CONVERT_TO_RAW (type, regnum, from, to); } +static int +next_cooked_register (struct gdbarch *gdbarch, int regnum) +{ + if (regnum < 0) + return 0; + regnum++; + if (regnum + >= (gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch))) + return -1; + return regnum; +} + +int +default_next_cooked_register_to_save (struct gdbarch *gdbarch, int regnum) +{ + return next_cooked_register (gdbarch, regnum); +} + +int +default_next_cooked_register_to_restore (struct gdbarch *gdbarch, int regnum) +{ + return next_cooked_register (gdbarch, regnum); +} /* Functions to manipulate the endianness of the target. */ Index: arch-utils.h =================================================================== RCS file: /cvs/src/src/gdb/arch-utils.h,v retrieving revision 1.41 diff -u -r1.41 arch-utils.h --- arch-utils.h 24 Aug 2002 00:21:34 -0000 1.41 +++ arch-utils.h 25 Aug 2002 19:06:11 -0000 @@ -171,6 +171,10 @@ extern void legacy_register_to_value (int regnum, struct type *type, char *from, char *to); extern void legacy_value_to_register (struct type *type, int regnum, char *from, char *to); +/* Iterators that provide the next/prev register to save/restore. */ +extern int default_next_cooked_register_to_save (struct gdbarch *gdbarch, int regnum); +extern int default_next_cooked_register_to_restore (struct gdbarch *gdbarch, int regnum); + /* For compatibility with older architectures, returns (LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid name. */ Index: gdbarch.c =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.c,v retrieving revision 1.146 diff -u -r1.146 gdbarch.c --- gdbarch.c 24 Aug 2002 00:21:34 -0000 1.146 +++ gdbarch.c 25 Aug 2002 19:06:25 -0000 @@ -113,7 +113,7 @@ Declare set/get functions and define the corresponding macro in gdbarch.h. - gdbarch_alloc(): If zero/NULL is not a suitable default, + gdba gdbarch_alloc(): If zero/NULL is not a suitable default, initialize the new field. verify_gdbarch(): Confirm that the target updated the field @@ -265,6 +265,8 @@ gdbarch_dwarf2_build_frame_info_ftype *dwarf2_build_frame_info; gdbarch_elf_make_msymbol_special_ftype *elf_make_msymbol_special; gdbarch_coff_make_msymbol_special_ftype *coff_make_msymbol_special; + gdbarch_next_cooked_register_to_save_ftype *next_cooked_register_to_save; + gdbarch_next_cooked_register_to_restore_ftype *next_cooked_register_to_restore; }; @@ -419,6 +421,8 @@ 0, 0, 0, + default_next_cooked_register_to_save, + default_next_cooked_register_to_restore, /* startup_gdbarch() */ }; @@ -549,6 +553,8 @@ current_gdbarch->construct_inferior_arguments = construct_inferior_arguments; current_gdbarch->elf_make_msymbol_special = default_elf_make_msymbol_special; current_gdbarch->coff_make_msymbol_special = default_coff_make_msymbol_special; + current_gdbarch->next_cooked_register_to_save = default_next_cooked_register_to_save; + current_gdbarch->next_cooked_register_to_restore = default_next_cooked_register_to_restore; /* gdbarch_alloc() */ return current_gdbarch; @@ -791,6 +797,12 @@ /* Skip verify of dwarf2_build_frame_info, has predicate */ /* Skip verify of elf_make_msymbol_special, invalid_p == 0 */ /* Skip verify of coff_make_msymbol_special, invalid_p == 0 */ + if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) + && (gdbarch->next_cooked_register_to_save == default_next_cooked_register_to_save)) + fprintf_unfiltered (log, "\n\tnext_cooked_register_to_save"); + if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) + && (gdbarch->next_cooked_register_to_restore == default_next_cooked_register_to_restore)) + fprintf_unfiltered (log, "\n\tnext_cooked_register_to_restore"); buf = ui_file_xstrdup (log, &dummy); make_cleanup (xfree, buf); if (strlen (buf) > 0) @@ -821,6 +833,14 @@ (long) current_gdbarch->in_function_epilogue_p); if (GDB_MULTI_ARCH) fprintf_unfiltered (file, + "gdbarch_dump: next_cooked_register_to_restore = 0x%08lx\n", + (long) current_gdbarch->next_cooked_register_to_restore); + if (GDB_MULTI_ARCH) + fprintf_unfiltered (file, + "gdbarch_dump: next_cooked_register_to_save = 0x%08lx\n", + (long) current_gdbarch->next_cooked_register_to_save); + if (GDB_MULTI_ARCH) + fprintf_unfiltered (file, "gdbarch_dump: pseudo_register_read = 0x%08lx\n", (long) current_gdbarch->pseudo_register_read); if (GDB_MULTI_ARCH) @@ -4880,6 +4900,44 @@ gdbarch_coff_make_msymbol_special_ftype coff_make_msymbol_special) { gdbarch->coff_make_msymbol_special = coff_make_msymbol_special; +} + +int +gdbarch_next_cooked_register_to_save (struct gdbarch *gdbarch, int last_regnum) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch->next_cooked_register_to_save == 0) + internal_error (__FILE__, __LINE__, + "gdbarch: gdbarch_next_cooked_register_to_save invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_next_cooked_register_to_save called\n"); + return gdbarch->next_cooked_register_to_save (gdbarch, last_regnum); +} + +void +set_gdbarch_next_cooked_register_to_save (struct gdbarch *gdbarch, + gdbarch_next_cooked_register_to_save_ftype next_cooked_register_to_save) +{ + gdbarch->next_cooked_register_to_save = next_cooked_register_to_save; +} + +int +gdbarch_next_cooked_register_to_restore (struct gdbarch *gdbarch, int last_regnum) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch->next_cooked_register_to_restore == 0) + internal_error (__FILE__, __LINE__, + "gdbarch: gdbarch_next_cooked_register_to_restore invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_next_cooked_register_to_restore called\n"); + return gdbarch->next_cooked_register_to_restore (gdbarch, last_regnum); +} + +void +set_gdbarch_next_cooked_register_to_restore (struct gdbarch *gdbarch, + gdbarch_next_cooked_register_to_restore_ftype next_cooked_register_to_restore) +{ + gdbarch->next_cooked_register_to_restore = next_cooked_register_to_restore; } Index: gdbarch.h =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.h,v retrieving revision 1.114 diff -u -r1.114 gdbarch.h --- gdbarch.h 24 Aug 2002 00:21:34 -0000 1.114 +++ gdbarch.h 25 Aug 2002 19:07:11 -0000 @@ -2483,6 +2483,16 @@ #endif #endif +/* Iterators for the registers to save or restore. */ + +typedef int (gdbarch_next_cooked_register_to_save_ftype) (struct gdbarch *gdbarch, int last_regnum); +extern int gdbarch_next_cooked_register_to_save (struct gdbarch *gdbarch, int last_regnum); +extern void set_gdbarch_next_cooked_register_to_save (struct gdbarch *gdbarch, gdbarch_next_cooked_register_to_save_ftype *next_cooked_register_to_save); + +typedef int (gdbarch_next_cooked_register_to_restore_ftype) (struct gdbarch *gdbarch, int last_regnum); +extern int gdbarch_next_cooked_register_to_restore (struct gdbarch *gdbarch, int last_regnum); +extern void set_gdbarch_next_cooked_register_to_restore (struct gdbarch *gdbarch, gdbarch_next_cooked_register_to_restore_ftype *next_cooked_register_to_restore); + extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); Index: gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.158 diff -u -r1.158 gdbarch.sh --- gdbarch.sh 24 Aug 2002 00:21:34 -0000 1.158 +++ gdbarch.sh 25 Aug 2002 19:07:12 -0000 @@ -658,6 +658,9 @@ F:2:DWARF2_BUILD_FRAME_INFO:void:dwarf2_build_frame_info:struct objfile *objfile:objfile:::0 f:2:ELF_MAKE_MSYMBOL_SPECIAL:void:elf_make_msymbol_special:asymbol *sym, struct minimal_symbol *msym:sym, msym:::default_elf_make_msymbol_special::0 f:2:COFF_MAKE_MSYMBOL_SPECIAL:void:coff_make_msymbol_special:int val, struct minimal_symbol *msym:val, msym:::default_coff_make_msymbol_special::0 +# Iterators for the cooked registers to save or restore. +m:::int:next_cooked_register_to_save:int last_regnum:last_regnum:::default_next_cooked_register_to_save +m:::int:next_cooked_register_to_restore:int last_regnum:last_regnum:::default_next_cooked_register_to_restore EOF } Index: regcache.c =================================================================== RCS file: /cvs/src/src/gdb/regcache.c,v retrieving revision 1.56 diff -u -r1.56 regcache.c --- regcache.c 25 Aug 2002 15:36:11 -0000 1.56 +++ regcache.c 25 Aug 2002 19:07:21 -0000 @@ -50,13 +50,11 @@ for raw and pseudo registers and allow access to both. */ int legacy_p; - /* The raw register cache. This should contain just [0 + /* The raw register space. This should contain just [0 .. NUM_RAW_REGISTERS). However, for older targets, it contains space for the full [0 .. NUM_RAW_REGISTERS + NUM_PSEUDO_REGISTERS). */ int nr_raw_registers; - long sizeof_raw_registers; - long sizeof_raw_register_valid_p; /* The cooked register space. Each cooked register in the range [0..NR_RAW_REGISTERS) is direct-mapped onto the corresponding raw @@ -66,6 +64,11 @@ gdbarch_register_read and gdbarch_register_write. */ int nr_cooked_registers; + /* The cache proper. A read-only cache can contain cooked values. + A read/write cache can not. */ + long sizeof_registers; + long sizeof_register_valid_p; + /* Offset and size (in 8 bit bytes), of reach register in the register cache. All registers (including those in the range [NR_RAW_REGISTERS .. NR_COOKED_REGISTERS) are given an offset. @@ -94,7 +97,6 @@ /* FIXME: cagney/2002-05-11: Shouldn't be including pseudo-registers in the register buffer. Unfortunatly some architectures do. */ descr->nr_raw_registers = descr->nr_cooked_registers; - descr->sizeof_raw_register_valid_p = descr->nr_cooked_registers; /* FIXME: cagney/2002-05-11: Instead of using REGISTER_BYTE() this code should compute the offets et.al. at runtime. This currently @@ -115,7 +117,7 @@ } /* Come up with the real size of the registers buffer. */ - descr->sizeof_raw_registers = REGISTER_BYTES; /* OK use. */ + descr->sizeof_registers = REGISTER_BYTES; /* OK use. */ for (i = 0; i < descr->nr_cooked_registers; i++) { long regend; @@ -130,8 +132,8 @@ Ulgh! New targets use gdbarch's register read/write and entirely avoid this uglyness. */ regend = descr->register_offset[i] + descr->sizeof_register[i]; - if (descr->sizeof_raw_registers < regend) - descr->sizeof_raw_registers = regend; + if (descr->sizeof_registers < regend) + descr->sizeof_registers = regend; } } @@ -151,6 +153,14 @@ either mapped onto raw-registers or memory. */ descr->nr_cooked_registers = NUM_REGS + NUM_PSEUDO_REGS; + /* NOTE: cagney/2002-08-25: Include space for both raw and cooked + registers in the register_valid_p table. A read-only regcache + can cache pre-computed cooked values (so needs the space). A + read/write shouldn't need the extra space, unfortunatly existing + code is able to access elements of the global register_valid_p[] + array in the range [NUM_REGS .. NUM_REGS + NUM_PSEUDO_REGS). */ + descr->sizeof_register_valid_p = NUM_REGS + NUM_PSEUDO_REGS; + /* Fill in a table of register types. */ descr->register_type = XCALLOC (descr->nr_cooked_registers, struct type *); @@ -173,12 +183,6 @@ into the register cache. */ descr->nr_raw_registers = NUM_REGS; - /* FIXME: cagney/2002-08-13: Overallocate the register_valid_p - array. This pretects GDB from erant code that accesses elements - of the global register_valid_p[] array in the range [NUM_REGS - .. NUM_REGS + NUM_PSEUDO_REGS). */ - descr->sizeof_raw_register_valid_p = NUM_REGS + NUM_PSEUDO_REGS; - /* Lay out the register cache. The pseud-registers are included in the layout even though their value isn't stored in the register cache. Some code, via read_register_bytes() access a register @@ -208,7 +212,7 @@ the register array directly using the global registers[]. Until that code has been purged, play safe and over allocating the register buffer. Ulgh! */ - descr->sizeof_raw_registers = offset; + descr->sizeof_registers = offset; /* = descr->register_offset[descr->nr_raw_registers]; */ } @@ -225,7 +229,7 @@ gdb_assert (descr->sizeof_register[i] == REGISTER_VIRTUAL_SIZE (i)); gdb_assert (descr->register_offset[i] == REGISTER_BYTE (i)); } - /* gdb_assert (descr->sizeof_raw_registers == REGISTER_BYTES (i)); */ + /* gdb_assert (descr->sizeof_cache == REGISTER_BYTES (i)); */ #endif return descr; @@ -276,11 +280,11 @@ struct regcache { struct regcache_descr *descr; - char *raw_registers; - char *raw_register_valid_p; - /* If a value isn't in the cache should the corresponding target be - queried for a value. */ - int passthrough_p; + char *registers; + char *register_valid_p; + /* A read-only regcache, can cache cooked values. It is + created/updated using the dup/cpy functions. */ + int readonly_p; }; struct regcache * @@ -292,11 +296,9 @@ descr = regcache_descr (gdbarch); regcache = XMALLOC (struct regcache); regcache->descr = descr; - regcache->raw_registers - = XCALLOC (descr->sizeof_raw_registers, char); - regcache->raw_register_valid_p - = XCALLOC (descr->sizeof_raw_register_valid_p, char); - regcache->passthrough_p = 0; + regcache->registers = XCALLOC (descr->sizeof_registers, char); + regcache->register_valid_p = XCALLOC (descr->sizeof_register_valid_p, char); + regcache->readonly_p = 1; return regcache; } @@ -305,8 +307,8 @@ { if (regcache == NULL) return; - xfree (regcache->raw_registers); - xfree (regcache->raw_register_valid_p); + xfree (regcache->registers); + xfree (regcache->register_valid_p); xfree (regcache); } @@ -322,6 +324,48 @@ return make_cleanup (do_regcache_xfree, regcache); } +static void +regcache_save (struct regcache *dst, struct regcache *src) +{ + struct gdbarch *gdbarch = dst->descr->gdbarch; + int regnum; + void *buf = alloca (dst->descr->max_register_size); + gdb_assert (src->descr->gdbarch == dst->descr->gdbarch); + gdb_assert (dst->readonly_p); + /* Clear the dest. */ + memset (dst->registers, 0, dst->descr->sizeof_registers); + memset (dst->register_valid_p, 0, dst->descr->sizeof_register_valid_p); + /* Copy over any relevant registers. */ + for (regnum = gdbarch_next_cooked_register_to_save (gdbarch, -1); + regnum >= 0; + regnum = gdbarch_next_cooked_register_to_save (gdbarch, regnum)) + { + regcache_cooked_read (src, regnum, buf); + memcpy (dst->registers + dst->descr->register_offset[regnum], + buf, dst->descr->sizeof_register[regnum]); + dst->register_valid_p[regnum] = 1; + } +} + +static void +regcache_restore (struct regcache *dst, struct regcache *src) +{ + struct gdbarch *gdbarch = dst->descr->gdbarch; + int regnum; + void *buf = alloca (dst->descr->max_register_size); + gdb_assert (src->descr->gdbarch == dst->descr->gdbarch); + gdb_assert (!dst->readonly_p); + /* Copy over any relevant registers. */ + for (regnum = gdbarch_next_cooked_register_to_restore (gdbarch, -1); + regnum >= 0; + regnum = gdbarch_next_cooked_register_to_restore (gdbarch, regnum)) + { + memcpy (buf, src->registers + src->descr->register_offset[regnum], + src->descr->sizeof_register[regnum]); + regcache_cooked_write (dst, regnum, buf); + } +} + void regcache_cpy (struct regcache *dst, struct regcache *src) { @@ -330,33 +374,13 @@ gdb_assert (src != NULL && dst != NULL); gdb_assert (src->descr->gdbarch == dst->descr->gdbarch); gdb_assert (src != dst); - /* FIXME: cagney/2002-05-17: To say this bit is bad is being polite. - It keeps the existing code working where things rely on going - through to the register cache. */ - if (src == current_regcache && src->descr->legacy_p) - { - /* ULGH!!!! Old way. Use REGISTER bytes and let code below - untangle fetch. */ - read_register_bytes (0, dst->raw_registers, REGISTER_BYTES); - return; - } - /* FIXME: cagney/2002-05-17: To say this bit is bad is being polite. - It keeps the existing code working where things rely on going - through to the register cache. */ - if (dst == current_regcache && dst->descr->legacy_p) - { - /* ULGH!!!! Old way. Use REGISTER bytes and let code below - untangle fetch. */ - write_register_bytes (0, src->raw_registers, REGISTER_BYTES); - return; - } - buf = alloca (src->descr->max_register_size); - for (i = 0; i < src->descr->nr_raw_registers; i++) - { - /* Should we worry about the valid bit here? */ - regcache_raw_read (src, i, buf); - regcache_raw_write (dst, i, buf); - } + gdb_assert (src->readonly_p || dst->readonly_p); + if (!src->readonly_p) + regcache_save (dst, src); + else if (!dst->readonly_p) + regcache_restore (dst, src); + else + regcache_cpy_no_passthrough (dst, src); } void @@ -369,10 +393,9 @@ move of data into the current_regcache(). Doing this would be silly - it would mean that valid_p would be completly invalid. */ gdb_assert (dst != current_regcache); - memcpy (dst->raw_registers, src->raw_registers, - dst->descr->sizeof_raw_registers); - memcpy (dst->raw_register_valid_p, src->raw_register_valid_p, - dst->descr->sizeof_raw_register_valid_p); + memcpy (dst->registers, src->registers, dst->descr->sizeof_registers); + memcpy (dst->register_valid_p, src->register_valid_p, + dst->descr->sizeof_register_valid_p); } struct regcache * @@ -400,19 +423,19 @@ { gdb_assert (regcache != NULL); gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); - return regcache->raw_register_valid_p[regnum]; + return regcache->register_valid_p[regnum]; } char * deprecated_grub_regcache_for_registers (struct regcache *regcache) { - return regcache->raw_registers; + return regcache->registers; } char * deprecated_grub_regcache_for_register_valid (struct regcache *regcache) { - return regcache->raw_register_valid_p; + return regcache->register_valid_p; } /* Global structure containing the current regcache. */ @@ -470,7 +493,7 @@ { gdb_assert (regnum >= 0); gdb_assert (regnum < current_regcache->descr->nr_raw_registers); - current_regcache->raw_register_valid_p[regnum] = state; + current_regcache->register_valid_p[regnum] = state; } /* REGISTER_CHANGED @@ -488,7 +511,7 @@ static char * register_buffer (struct regcache *regcache, int regnum) { - return regcache->raw_registers + regcache->descr->register_offset[regnum]; + return regcache->registers + regcache->descr->register_offset[regnum]; } /* Return whether register REGNUM is a real register. */ @@ -669,7 +692,7 @@ gdb_assert (regcache != NULL && buf != NULL); gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); if (regcache->descr->legacy_p - && regcache->passthrough_p) + && !regcache->readonly_p) { gdb_assert (regcache == current_regcache); /* For moment, just use underlying legacy code. Ulgh!!! This @@ -682,7 +705,7 @@ to the current thread. This switching shouldn't be necessary only there is still only one target side register cache. Sigh! On the bright side, at least there is a regcache object. */ - if (regcache->passthrough_p) + if (!regcache->readonly_p) { gdb_assert (regcache == current_regcache); if (! ptid_equal (registers_ptid, inferior_ptid)) @@ -694,7 +717,7 @@ target_fetch_registers (regnum); } /* Copy the value directly into the register cache. */ - memcpy (buf, (regcache->raw_registers + memcpy (buf, (regcache->registers + regcache->descr->register_offset[regnum]), regcache->descr->sizeof_register[regnum]); } @@ -744,6 +767,10 @@ gdb_assert (regnum < regcache->descr->nr_cooked_registers); if (regnum < regcache->descr->nr_raw_registers) regcache_raw_read (regcache, regnum, buf); + else if (regcache->readonly_p && regcache->register_valid_p[regnum]) + memcpy (buf, (regcache->registers + + regcache->descr->register_offset[regnum]), + regcache->descr->sizeof_register[regnum]); else gdbarch_pseudo_register_read (regcache->descr->gdbarch, regcache, regnum, buf); @@ -820,9 +847,9 @@ { gdb_assert (regcache != NULL && buf != NULL); gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); + gdb_assert (!regcache->readonly_p); - if (regcache->passthrough_p - && regcache->descr->legacy_p) + if (regcache->descr->legacy_p) { /* For moment, just use underlying legacy code. Ulgh!!! This silently and very indirectly updates the regcache's buffers @@ -837,17 +864,6 @@ if (CANNOT_STORE_REGISTER (regnum)) return; - /* Handle the simple case first -> not write through so just store - value in cache. */ - if (!regcache->passthrough_p) - { - memcpy ((regcache->raw_registers - + regcache->descr->register_offset[regnum]), buf, - regcache->descr->sizeof_register[regnum]); - regcache->raw_register_valid_p[regnum] = 1; - return; - } - /* Make certain that the correct cache is selected. */ gdb_assert (regcache == current_regcache); if (! ptid_equal (registers_ptid, inferior_ptid)) @@ -866,7 +882,7 @@ target_prepare_to_store (); memcpy (register_buffer (regcache, regnum), buf, regcache->descr->sizeof_register[regnum]); - regcache->raw_register_valid_p[regnum] = 1; + regcache->register_valid_p[regnum] = 1; target_store_registers (regnum); } @@ -888,6 +904,7 @@ { gdb_assert (regnum >= 0); gdb_assert (regnum < regcache->descr->nr_cooked_registers); + gdb_assert (!regcache->readonly_p); if (regnum < regcache->descr->nr_raw_registers) regcache_raw_write (regcache, regnum, buf); else @@ -1340,7 +1357,7 @@ build_regcache (void) { current_regcache = regcache_xmalloc (current_gdbarch); - current_regcache->passthrough_p = 1; + current_regcache->readonly_p = 0; registers = deprecated_grub_regcache_for_registers (current_regcache); register_valid = deprecated_grub_regcache_for_register_valid (current_regcache); }