This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PING^2][RFC][PATCH v2][PR remote/16896] Invalidate a register in cache when a remote target failed to write it.
- From: Pierre Langlois <pierre dot langlois at embecosm dot com>
- To: gdb-patches at sourceware dot org, palves at redhat dot com
- Date: Wed, 11 Jun 2014 17:58:24 +0100
- Subject: [PING^2][RFC][PATCH v2][PR remote/16896] Invalidate a register in cache when a remote target failed to write it.
- Authentication-results: sourceware.org; auth=none
- References: <537E086A dot 9030803 at embecosm dot com> <538C400B dot 609 at embecosm dot com>
Ping.
On 02/06/14 10:12, Pierre Langlois wrote:
> 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);
>>
>