From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1489 invoked by alias); 25 Aug 2002 19:17:16 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 1463 invoked from network); 25 Aug 2002 19:17:06 -0000 Received: from unknown (HELO localhost.redhat.com) (24.112.240.27) by sources.redhat.com with SMTP; 25 Aug 2002 19:17:06 -0000 Received: from ges.redhat.com (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 318063E10 for ; Sun, 25 Aug 2002 15:16:55 -0400 (EDT) Message-ID: <3D692D27.4010003@ges.redhat.com> Date: Sun, 25 Aug 2002 12:23:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-US; rv:1.0.0) Gecko/20020824 X-Accept-Language: en-us, en MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: [patch/wip] Save/restore cooked registers Content-Type: multipart/mixed; boundary="------------020100090403040904090201" X-SW-Source: 2002-08/txt/msg00832.txt.bz2 This is a multi-part message in MIME format. --------------020100090403040904090201 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 247 Hello, The attached is work-in-progress to get gdb saving just a subset of cooked registers when doing things like an inferior function call. It appears to work, however, I'll put it on hold until after the 5.3 branch gets cut. enjoy, Andrew --------------020100090403040904090201 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 24659 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); } --------------020100090403040904090201--