From: Andreas Arnez Date: Fri, 12 Dec 2014 13:14:20 +0000 (+0100) Subject: gdbserver: Prevent stale/random values in register cache X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=098dbe61246fd65ea5e3825d77afb31d52c43153;p=binutils-gdb.git gdbserver: Prevent stale/random values in register cache When fetch_inferior_registers does not update all registers, this patch assures that no stale register values remain in the register cache. On Linux platforms using the regsets interface, when one of the ptrace calls used for fetching the register values returns an error, this patch also avoids copying the random data returned from ptrace into the register cache. All unfetched registers are marked "unavailable" instead. gdb/gdbserver/ChangeLog: * linux-low.c (regsets_fetch_inferior_registers): Do not invoke the regset's store function when ptrace returned an error. * regcache.c (get_thread_regcache): Invalidate register cache before fetching inferior's registers. --- diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 7471dae583d..54caa55ef12 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,10 @@ +2014-12-12 Andreas Arnez + + * linux-low.c (regsets_fetch_inferior_registers): Do not invoke + the regset's store function when ptrace returned an error. + * regcache.c (get_thread_regcache): Invalidate register cache + before fetching inferior's registers. + 2014-12-12 Andreas Arnez * linux-low.c (regsets_fetch_inferior_registers): Rephrase diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 164b0f66240..c1b53ff42d1 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -4255,8 +4255,6 @@ regsets_fetch_inferior_registers (struct regsets_info *regsets_info, /* If we get EIO on a regset, do not try it again for this process mode. */ disable_regset (regsets_info, regset); - free (buf); - continue; } else { @@ -4266,9 +4264,12 @@ regsets_fetch_inferior_registers (struct regsets_info *regsets_info, perror (s); } } - else if (regset->type == GENERAL_REGS) - saw_general_regs = 1; - regset->store_function (regcache, buf); + else + { + if (regset->type == GENERAL_REGS) + saw_general_regs = 1; + regset->store_function (regcache, buf); + } free (buf); } if (saw_general_regs) diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c index 718ae8c3c9b..8c874f0c2a4 100644 --- a/gdb/gdbserver/regcache.c +++ b/gdb/gdbserver/regcache.c @@ -52,6 +52,9 @@ get_thread_regcache (struct thread_info *thread, int fetch) struct thread_info *saved_thread = current_thread; current_thread = thread; + /* Invalidate all registers, to prevent stale left-overs. */ + memset (regcache->register_status, REG_UNAVAILABLE, + regcache->tdesc->num_registers); fetch_inferior_registers (regcache, -1); current_thread = saved_thread; regcache->registers_valid = 1;