This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PING][RFC][PATCH v2][PR remote/16896] Invalidate a register in cache when a remote target failed to write it.


Ping.

On 22/05/14 15:23, Pierre Langlois wrote:
> Hello all,
> 
> This patch addresses the issue in patch [1] generically as pointed out by
> a comment [2].
> 
> As opposed to invalidating a register in cache in the remote target before
> throwing an error, we can do this using a cleanup in regcache_raw_write.  This
> patch adds routines to add a regcache_invalidate cleanup to the current chain.
> We can use this before target_store_registers and discard it after if an error
> was not thrown.
> 
> [1] https://sourceware.org/ml/gdb-patches/2014-05/msg00083.html
> [2] https://sourceware.org/ml/gdb-patches/2014-05/msg00357.html
> 
> 2014-05-20  Pierre Langlois  <pierre.langlois@embecosm.com>
> 
>     PR remote/16896
>     * regcache.c (register_to_invalidate): New structure. Combines a pointer
>         to a struct regcache and a register number.
>     (do_register_invalidate): New function. Call regcache_invalidate.
>     (make_cleanup_regcache_invalidate): New function. Construct a cleanup
>         for invalidating a register.
>     (regcache_raw_write): Call make_cleanup_regcache_invalidate
>     * regcache.h (make_cleanup_regcache_invalidate): New prototype.
> 
> ---
>  gdb/regcache.c | 41 ++++++++++++++++++++++++++++++++++++++---
>  gdb/regcache.h |  2 ++
>  2 files changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/gdb/regcache.c b/gdb/regcache.c
> index 8b588c6..87a6b02 100644
> --- a/gdb/regcache.c
> +++ b/gdb/regcache.c
> @@ -267,6 +267,30 @@ make_cleanup_regcache_xfree (struct regcache *regcache)
>    return make_cleanup (do_regcache_xfree, regcache);
>  }
>  
> +/* Cleanup routines for invalidating a register.  */
> +
> +struct register_to_invalidate
> +{
> +  struct regcache *regcache;
> +  int regnum;
> +};
> +
> +static void
> +do_regcache_invalidate (void *data)
> +{
> +  struct register_to_invalidate *reg = data;
> +  regcache_invalidate (reg->regcache, reg->regnum);
> +}
> +
> +struct cleanup *
> +make_cleanup_regcache_invalidate (struct regcache *regcache, int regnum)
> +{
> +  struct register_to_invalidate* reg = XNEW (struct register_to_invalidate);
> +  reg->regcache = regcache;
> +  reg->regnum = regnum;
> +  return make_cleanup_dtor (do_regcache_invalidate, (void *) reg, xfree);
> +}
> +
>  /* Return REGCACHE's architecture.  */
>  
>  struct gdbarch *
> @@ -846,7 +870,8 @@ void
>  regcache_raw_write (struct regcache *regcache, int regnum,
>              const gdb_byte *buf)
>  {
> -  struct cleanup *old_chain;
> +  struct cleanup *chain_before_save_inferior;
> +  struct cleanup *chain_before_invalidate_register;
>  
>    gdb_assert (regcache != NULL && buf != NULL);
>    gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
> @@ -864,16 +889,26 @@ regcache_raw_write (struct regcache *regcache, int regnum,
>            regcache->descr->sizeof_register[regnum]) == 0))
>      return;
>  
> -  old_chain = save_inferior_ptid ();
> +  chain_before_save_inferior = save_inferior_ptid ();
>    inferior_ptid = regcache->ptid;
>  
>    target_prepare_to_store (regcache);
>    memcpy (register_buffer (regcache, regnum), buf,
>        regcache->descr->sizeof_register[regnum]);
>    regcache->register_status[regnum] = REG_VALID;
> +
> +  /* Register a cleanup function for invalidating the register after it is
> +     written, in case of a failure.  */
> +  chain_before_invalidate_register =
> +    make_cleanup_regcache_invalidate (regcache, regnum);
> +
>    target_store_registers (regcache, regnum);
>  
> -  do_cleanups (old_chain);
> +  /* The target did not throw an error so we can discard invalidating the
> +     register and restore the cleanup chain to what it was.  */
> +  discard_cleanups (chain_before_invalidate_register);
> +
> +  do_cleanups (chain_before_save_inferior);
>  }
>  
>  void
> diff --git a/gdb/regcache.h b/gdb/regcache.h
> index 8423f57..bb40b65 100644
> --- a/gdb/regcache.h
> +++ b/gdb/regcache.h
> @@ -33,6 +33,8 @@ extern struct regcache *get_thread_arch_aspace_regcache (ptid_t,
>  
>  void regcache_xfree (struct regcache *regcache);
>  struct cleanup *make_cleanup_regcache_xfree (struct regcache *regcache);
> +struct cleanup *make_cleanup_regcache_invalidate (struct regcache *regcache,
> +                          int regnum);
>  struct regcache *regcache_xmalloc (struct gdbarch *gdbarch,
>                     struct address_space *aspace);
>  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]