From: Yao Qi Date: Wed, 21 Feb 2018 11:20:03 +0000 (+0000) Subject: Class readonly_detached_regcache X-Git-Tag: users/gbenson/thread_db-test/2018-05-23~830 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=daf6667d1f94c7e74df4076daf021cd28a2797b6;p=thirdparty%2Fbinutils-gdb.git Class readonly_detached_regcache This patch adds a new class (type) for readonly regcache, which is created via regcache::save. readonly_detached_regcache inherits readable_regcache. gdb: 2018-02-21 Yao Qi * dummy-frame.c (dummy_frame_cache) : Use readonly_detached_regcache. (dummy_frame_prev_register): Use regcache->cooked_read. * frame.c (frame_save_as_regcache): Change return type. (frame_pop): Update. * frame.h (frame_save_as_regcache): Update declaration. * inferior.h (get_infcall_suspend_state_regcache): Update declaration. * infrun.c (infcall_suspend_state) : use readonly_detached_regcache. (save_infcall_suspend_state): Don't use regcache_dup. (get_infcall_suspend_state_regcache): Change return type. * linux-fork.c (struct fork_info) : Change to readonly_detached_regcache. : New field. (fork_save_infrun_state): Don't use regcache_dup. (info_checkpoints_command): Adjust. * mi/mi-main.c (register_changed_p): Update declaration. (mi_cmd_data_list_changed_registers): Use readonly_detached_regcache. (register_changed_p): Change parameter type to readonly_detached_regcache. * ppc-linux-tdep.c (ppu2spu_cache) : Use readonly_detached_regcache. (ppu2spu_sniffer): Construct a new readonly_detached_regcache. * regcache.c (readonly_detached_regcache::readonly_detached_regcache): New. (regcache::save): Move it to reg_buffer. (regcache::restore): Change parameter type. (regcache_dup): Remove. * regcache.h (reg_buffer) : New method. (readonly_detached_regcache): New class. * spu-tdep.c (spu2ppu_cache) : Use readonly_detached_regcache. (spu2ppu_sniffer): Construct a new readonly_detached_regcache. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a7da794070b..bb59b311b2b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,41 @@ +2018-02-21 Yao Qi + + * dummy-frame.c (dummy_frame_cache) : Use + readonly_detached_regcache. + (dummy_frame_prev_register): Use regcache->cooked_read. + * frame.c (frame_save_as_regcache): Change return type. + (frame_pop): Update. + * frame.h (frame_save_as_regcache): Update declaration. + * inferior.h (get_infcall_suspend_state_regcache): Update + declaration. + * infrun.c (infcall_suspend_state) : use + readonly_detached_regcache. + (save_infcall_suspend_state): Don't use regcache_dup. + (get_infcall_suspend_state_regcache): Change return type. + * linux-fork.c (struct fork_info) : Change to + readonly_detached_regcache. + : New field. + (fork_save_infrun_state): Don't use regcache_dup. + (info_checkpoints_command): Adjust. + * mi/mi-main.c (register_changed_p): Update declaration. + (mi_cmd_data_list_changed_registers): Use + readonly_detached_regcache. + (register_changed_p): Change parameter type to + readonly_detached_regcache. + * ppc-linux-tdep.c (ppu2spu_cache) : Use + readonly_detached_regcache. + (ppu2spu_sniffer): Construct a new readonly_detached_regcache. + * regcache.c (readonly_detached_regcache::readonly_detached_regcache): + New. + (regcache::save): Move it to reg_buffer. + (regcache::restore): Change parameter type. + (regcache_dup): Remove. + * regcache.h (reg_buffer) : New method. + (readonly_detached_regcache): New class. + * spu-tdep.c (spu2ppu_cache) : Use + readonly_detached_regcache. + (spu2ppu_sniffer): Construct a new readonly_detached_regcache. + 2018-02-21 Yao Qi * frame.c (frame_save_as_regcache): Use regcache method save. diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index db8ba1b8e0b..a67033e6f2c 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -282,7 +282,7 @@ cleanup_dummy_frames (struct target_ops *target, int from_tty) struct dummy_frame_cache { struct frame_id this_id; - struct regcache *prev_regcache; + readonly_detached_regcache *prev_regcache; }; static int @@ -352,8 +352,8 @@ dummy_frame_prev_register (struct frame_info *this_frame, /* Use the regcache_cooked_read() method so that it, on the fly, constructs either a raw or pseudo register from the raw register cache. */ - regcache_cooked_read (cache->prev_regcache, regnum, - value_contents_writeable (reg_val)); + cache->prev_regcache->cooked_read (regnum, + value_contents_writeable (reg_val)); return reg_val; } diff --git a/gdb/frame.c b/gdb/frame.c index 773fd0449d3..0b04a4ebacb 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1017,13 +1017,13 @@ do_frame_register_read (void *src, int regnum, gdb_byte *buf) return REG_VALID; } -std::unique_ptr +std::unique_ptr frame_save_as_regcache (struct frame_info *this_frame) { - std::unique_ptr regcache - (new struct regcache (get_frame_arch (this_frame))); + std::unique_ptr regcache + (new readonly_detached_regcache (get_frame_arch (this_frame), + do_frame_register_read, this_frame)); - regcache->save (do_frame_register_read, this_frame); return regcache; } @@ -1057,7 +1057,7 @@ frame_pop (struct frame_info *this_frame) Save them in a scratch buffer so that there isn't a race between trying to extract the old values from the current regcache while at the same time writing new values into that same cache. */ - std::unique_ptr scratch + std::unique_ptr scratch = frame_save_as_regcache (prev_frame); /* FIXME: cagney/2003-03-16: It should be possible to tell the diff --git a/gdb/frame.h b/gdb/frame.h index 8293a49ec23..d5800b78c25 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -680,8 +680,9 @@ extern void *frame_obstack_zalloc (unsigned long size); #define FRAME_OBSTACK_CALLOC(NUMBER,TYPE) \ ((TYPE *) frame_obstack_zalloc ((NUMBER) * sizeof (TYPE))) +class readonly_detached_regcache; /* Create a regcache, and copy the frame's registers into it. */ -std::unique_ptr frame_save_as_regcache +std::unique_ptr frame_save_as_regcache (struct frame_info *this_frame); extern const struct block *get_frame_block (struct frame_info *, diff --git a/gdb/inferior.h b/gdb/inferior.h index 22008a005b9..391a5fdaa5c 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -70,7 +70,7 @@ extern struct cleanup *make_cleanup_restore_infcall_control_state extern void discard_infcall_suspend_state (struct infcall_suspend_state *); extern void discard_infcall_control_state (struct infcall_control_state *); -extern struct regcache * +extern readonly_detached_regcache * get_infcall_suspend_state_regcache (struct infcall_suspend_state *); extern void set_sigint_trap (void); diff --git a/gdb/infrun.c b/gdb/infrun.c index b4e6c6b6916..c6639085681 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -8805,7 +8805,7 @@ struct infcall_suspend_state /* Other fields: */ CORE_ADDR stop_pc; - struct regcache *registers; + readonly_detached_regcache *registers; /* Format of SIGINFO_DATA or NULL if it is not present. */ struct gdbarch *siginfo_gdbarch; @@ -8861,7 +8861,7 @@ save_infcall_suspend_state (void) inf_state->stop_pc = stop_pc; - inf_state->registers = regcache_dup (regcache); + inf_state->registers = new readonly_detached_regcache (*regcache); return inf_state; } @@ -8918,7 +8918,7 @@ discard_infcall_suspend_state (struct infcall_suspend_state *inf_state) xfree (inf_state); } -struct regcache * +readonly_detached_regcache * get_infcall_suspend_state_regcache (struct infcall_suspend_state *inf_state) { return inf_state->registers; diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index df7ea4e1710..9ffab1ff6c2 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -45,8 +45,9 @@ struct fork_info ptid_t ptid; ptid_t parent_ptid; int num; /* Convenient handle (GDB fork id). */ - struct regcache *savedregs; /* Convenient for info fork, saves + readonly_detached_regcache *savedregs; /* Convenient for info fork, saves having to actually switch contexts. */ + CORE_ADDR pc; int clobber_regs; /* True if we should restore saved regs. */ off_t *filepos; /* Set of open file descriptors' offsets. */ int maxfd; @@ -294,7 +295,8 @@ fork_save_infrun_state (struct fork_info *fp, int clobber_regs) if (fp->savedregs) delete fp->savedregs; - fp->savedregs = regcache_dup (get_current_regcache ()); + fp->savedregs = new readonly_detached_regcache (*get_current_regcache ()); + fp->pc = regcache_read_pc (get_current_regcache ()); fp->clobber_regs = clobber_regs; if (clobber_regs) @@ -590,15 +592,11 @@ info_checkpoints_command (const char *arg, int from_tty) printed = fp; if (ptid_equal (fp->ptid, inferior_ptid)) - { - printf_filtered ("* "); - pc = regcache_read_pc (get_current_regcache ()); - } + printf_filtered ("* "); else - { - printf_filtered (" "); - pc = regcache_read_pc (fp->savedregs); - } + printf_filtered (" "); + + pc = fp->pc; printf_filtered ("%d %s", fp->num, target_pid_to_str (fp->ptid)); if (fp->num == 0) printf_filtered (_(" (main process)")); diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 51d33c9e9ff..1716a7fe443 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -96,8 +96,8 @@ static void mi_execute_cli_command (const char *cmd, int args_p, const char *args); static void mi_execute_async_cli_command (const char *cli_command, char **argv, int argc); -static bool register_changed_p (int regnum, regcache *, - regcache *); +static bool register_changed_p (int regnum, readonly_detached_regcache *, + readonly_detached_regcache *); static void output_register (struct frame_info *, int regnum, int format, int skip_unavailable); @@ -931,9 +931,9 @@ mi_cmd_data_list_register_names (const char *command, char **argv, int argc) void mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) { - static std::unique_ptr this_regs; + static std::unique_ptr this_regs; struct ui_out *uiout = current_uiout; - std::unique_ptr prev_regs; + std::unique_ptr prev_regs; struct gdbarch *gdbarch; int regnum, numregs; int i; @@ -995,8 +995,8 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc) } static bool -register_changed_p (int regnum, struct regcache *prev_regs, - struct regcache *this_regs) +register_changed_p (int regnum, readonly_detached_regcache *prev_regs, + readonly_detached_regcache *this_regs) { struct gdbarch *gdbarch = this_regs->arch (); struct value *prev_value, *this_value; diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 13a50d67563..d6a98fc0dbf 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -1262,7 +1262,7 @@ ppc_linux_spe_context (int wordsize, enum bfd_endian byte_order, struct ppu2spu_cache { struct frame_id frame_id; - struct regcache *regcache; + readonly_detached_regcache *regcache; }; static struct gdbarch * @@ -1369,10 +1369,10 @@ ppu2spu_sniffer (const struct frame_unwind *self, { struct ppu2spu_cache *cache = FRAME_OBSTACK_CALLOC (1, struct ppu2spu_cache); - std::unique_ptr regcache - (new struct regcache (data.gdbarch)); - - regcache->save (ppu2spu_unwind_register, &data); + std::unique_ptr regcache + (new readonly_detached_regcache (data.gdbarch, + ppu2spu_unwind_register, + &data)); cache->frame_id = frame_id_build (base, func); cache->regcache = regcache.release (); diff --git a/gdb/regcache.c b/gdb/regcache.c index 0df6a88ada6..ebe3c7bac07 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -226,6 +226,11 @@ regcache::regcache (readonly_t, const regcache &src) save (do_cooked_read, (void *) &src); } +readonly_detached_regcache::readonly_detached_regcache (const regcache &src) + : readonly_detached_regcache (src.arch (), do_cooked_read, (void *) &src) +{ +} + gdbarch * reg_buffer::arch () const { @@ -282,16 +287,14 @@ reg_buffer::register_buffer (int regnum) const } void -regcache::save (regcache_cooked_read_ftype *cooked_read, - void *src) +reg_buffer::save (regcache_cooked_read_ftype *cooked_read, + void *src) { struct gdbarch *gdbarch = m_descr->gdbarch; int regnum; - /* The DST should be `read-only', if it wasn't then the save would - end up trying to write the register values back out to the - target. */ - gdb_assert (m_readonly_p); + /* It should have pseudo registers. */ + gdb_assert (m_has_pseudo); /* Clear the dest. */ memset (m_registers, 0, m_descr->sizeof_cooked_registers); memset (m_register_status, 0, m_descr->nr_cooked_registers); @@ -317,16 +320,14 @@ regcache::save (regcache_cooked_read_ftype *cooked_read, } void -regcache::restore (struct regcache *src) +regcache::restore (readonly_detached_regcache *src) { struct gdbarch *gdbarch = m_descr->gdbarch; int regnum; gdb_assert (src != NULL); - /* The dst had better not be read-only. If it is, the `restore' - doesn't make much sense. */ gdb_assert (!m_readonly_p); - gdb_assert (src->m_readonly_p); + gdb_assert (src->m_has_pseudo); gdb_assert (gdbarch == src->arch ()); @@ -344,12 +345,6 @@ regcache::restore (struct regcache *src) } } -struct regcache * -regcache_dup (struct regcache *src) -{ - return new regcache (regcache::readonly, *src); -} - enum register_status regcache_register_status (const struct regcache *regcache, int regnum) { diff --git a/gdb/regcache.h b/gdb/regcache.h index a4ca2ecf7a3..4ad0060fdd1 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -243,6 +243,11 @@ protected: gdb_byte *register_buffer (int regnum) const; + /* Save a register cache. The set of registers saved into the + regcache determined by the save_reggroup. COOKED_READ returns + zero iff the register's value can't be returned. */ + void save (regcache_cooked_read_ftype *cooked_read, void *src); + struct regcache_descr *m_descr; bool m_has_pseudo; @@ -250,6 +255,8 @@ protected: gdb_byte *m_registers; /* Register cache status. */ signed char *m_register_status; + + friend class regcache; }; /* An abstract class which only has methods doing read. */ @@ -284,6 +291,8 @@ protected: bool is_raw); }; +class readonly_detached_regcache; + /* The register cache for storing raw register values. */ class regcache : public readable_regcache @@ -307,15 +316,11 @@ public: return m_aspace; } -/* Save/restore 'this' regcache. The set of registers saved / - restored into the regcache determined by the save_reggroup / - restore_reggroup respectively. COOKED_READ returns zero iff the - register's value can't be returned. */ - void save (regcache_cooked_read_ftype *cooked_read, void *src); - - /* Writes to regcache will go through to the target. SRC is a + /* Restore 'this' regcache. The set of registers restored into + the regcache determined by the restore_reggroup. + Writes to regcache will go through to the target. SRC is a read-only register cache. */ - void restore (struct regcache *src); + void restore (readonly_detached_regcache *src); void cooked_write (int regnum, const gdb_byte *buf); @@ -413,9 +418,26 @@ private: registers_changed_ptid (ptid_t ptid); }; -/* Duplicate the contents of a register cache to a read-only register - cache. The operation is pass-through. */ -extern struct regcache *regcache_dup (struct regcache *regcache); +class readonly_detached_regcache : public readable_regcache +{ +public: + readonly_detached_regcache (const regcache &src); + + /* Create a readonly regcache by getting contents from COOKED_READ. */ + + readonly_detached_regcache (gdbarch *gdbarch, + regcache_cooked_read_ftype *cooked_read, + void *src) + : readable_regcache (gdbarch, true) + { + save (cooked_read, src); + } + + DISABLE_COPY_AND_ASSIGN (readonly_detached_regcache); + + void raw_update (int regnum) override + {} +}; extern void registers_changed (void); extern void registers_changed_ptid (ptid_t); diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index da7b93764d2..a632c0656e9 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -1202,7 +1202,7 @@ spu_write_pc (struct regcache *regcache, CORE_ADDR pc) struct spu2ppu_cache { struct frame_id frame_id; - struct regcache *regcache; + readonly_detached_regcache *regcache; }; static struct gdbarch * @@ -1229,7 +1229,7 @@ spu2ppu_prev_register (struct frame_info *this_frame, gdb_byte *buf; buf = (gdb_byte *) alloca (register_size (gdbarch, regnum)); - regcache_cooked_read (cache->regcache, regnum, buf); + cache->regcache->cooked_read (regnum, buf); return frame_unwind_got_bytes (this_frame, regnum, buf); } @@ -1274,7 +1274,7 @@ spu2ppu_sniffer (const struct frame_unwind *self, { struct regcache *regcache; regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ()); - cache->regcache = regcache_dup (regcache); + cache->regcache = new readonly_detached_regcache (*regcache); *this_prologue_cache = cache; return 1; }