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 <yao.qi@linaro.org> * dummy-frame.c (dummy_frame_cache) <prev_regcache>: 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) <registers>: 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) <savedregs>: Change to readonly_detached_regcache. <pc>: 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) <regcache>: 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) <save>: New method. (readonly_detached_regcache): New class. * spu-tdep.c (spu2ppu_cache) <regcache>: Use readonly_detached_regcache. (spu2ppu_sniffer): Construct a new readonly_detached_regcache.
This commit is contained in:
parent
fc5b873615
commit
daf6667d1f
12 changed files with 118 additions and 64 deletions
|
@ -1,3 +1,41 @@
|
|||
2018-02-21 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* dummy-frame.c (dummy_frame_cache) <prev_regcache>: 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) <registers>: 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) <savedregs>: Change to
|
||||
readonly_detached_regcache.
|
||||
<pc>: 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) <regcache>: 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) <save>: New method.
|
||||
(readonly_detached_regcache): New class.
|
||||
* spu-tdep.c (spu2ppu_cache) <regcache>: Use
|
||||
readonly_detached_regcache.
|
||||
(spu2ppu_sniffer): Construct a new readonly_detached_regcache.
|
||||
|
||||
2018-02-21 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* frame.c (frame_save_as_regcache): Use regcache method save.
|
||||
|
|
|
@ -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,7 +352,7 @@ 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,
|
||||
cache->prev_regcache->cooked_read (regnum,
|
||||
value_contents_writeable (reg_val));
|
||||
return reg_val;
|
||||
}
|
||||
|
|
10
gdb/frame.c
10
gdb/frame.c
|
@ -1017,13 +1017,13 @@ do_frame_register_read (void *src, int regnum, gdb_byte *buf)
|
|||
return REG_VALID;
|
||||
}
|
||||
|
||||
std::unique_ptr<struct regcache>
|
||||
std::unique_ptr<readonly_detached_regcache>
|
||||
frame_save_as_regcache (struct frame_info *this_frame)
|
||||
{
|
||||
std::unique_ptr<struct regcache> regcache
|
||||
(new struct regcache (get_frame_arch (this_frame)));
|
||||
std::unique_ptr<readonly_detached_regcache> 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<struct regcache> scratch
|
||||
std::unique_ptr<readonly_detached_regcache> scratch
|
||||
= frame_save_as_regcache (prev_frame);
|
||||
|
||||
/* FIXME: cagney/2003-03-16: It should be possible to tell the
|
||||
|
|
|
@ -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<struct regcache> frame_save_as_regcache
|
||||
std::unique_ptr<readonly_detached_regcache> frame_save_as_regcache
|
||||
(struct frame_info *this_frame);
|
||||
|
||||
extern const struct block *get_frame_block (struct frame_info *,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ());
|
||||
}
|
||||
else
|
||||
{
|
||||
printf_filtered (" ");
|
||||
pc = regcache_read_pc (fp->savedregs);
|
||||
}
|
||||
|
||||
pc = fp->pc;
|
||||
printf_filtered ("%d %s", fp->num, target_pid_to_str (fp->ptid));
|
||||
if (fp->num == 0)
|
||||
printf_filtered (_(" (main process)"));
|
||||
|
|
|
@ -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<struct regcache> this_regs;
|
||||
static std::unique_ptr<readonly_detached_regcache> this_regs;
|
||||
struct ui_out *uiout = current_uiout;
|
||||
std::unique_ptr<struct regcache> prev_regs;
|
||||
std::unique_ptr<readonly_detached_regcache> 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;
|
||||
|
|
|
@ -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<struct regcache> regcache
|
||||
(new struct regcache (data.gdbarch));
|
||||
|
||||
regcache->save (ppu2spu_unwind_register, &data);
|
||||
std::unique_ptr<readonly_detached_regcache> regcache
|
||||
(new readonly_detached_regcache (data.gdbarch,
|
||||
ppu2spu_unwind_register,
|
||||
&data));
|
||||
|
||||
cache->frame_id = frame_id_build (base, func);
|
||||
cache->regcache = regcache.release ();
|
||||
|
|
|
@ -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,
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue