diff --git a/gdb/ChangeLog b/gdb/ChangeLog index dc0a926fda9..9e70cea3837 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +2021-03-04 Simon Marchi + + PR gdb/27147 + * sparc-nat.h (sparc_fetch_inferior_registers): Add + process_stratum_target parameter, + sparc_store_inferior_registers): update callers. + * sparc-nat.c (sparc_fetch_inferior_registers, + sparc_store_inferior_registers): Add process_stratum_target + parameter. Switch current thread before calling + sparc_supply_gregset / sparc_collect_rwindow. + (sparc_store_inferior_registers): Likewise. + * sparc-obsd-tdep.c (sparc32obsd_supply_uthread): Add assertion. + (sparc32obsd_collect_uthread): Likewise. + * sparc-tdep.c (sparc_supply_rwindow, sparc_collect_rwindow): + Add assertion. + * sparc64-obsd-tdep.c (sparc64obsd_collect_uthread, + sparc64obsd_supply_uthread): Add assertion. + 2021-02-25 Simon Marchi PR gdb/26861 diff --git a/gdb/sparc-nat.c b/gdb/sparc-nat.c index bc3afce2027..fa3b32cee18 100644 --- a/gdb/sparc-nat.c +++ b/gdb/sparc-nat.c @@ -147,7 +147,8 @@ sparc32_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum) for all registers (including the floating-point registers). */ void -sparc_fetch_inferior_registers (struct regcache *regcache, int regnum) +sparc_fetch_inferior_registers (process_stratum_target *proc_target, + regcache *regcache, int regnum) { struct gdbarch *gdbarch = regcache->arch (); ptid_t ptid = regcache->ptid (); @@ -167,6 +168,12 @@ sparc_fetch_inferior_registers (struct regcache *regcache, int regnum) if (gdb_ptrace (PTRACE_GETREGS, ptid, (PTRACE_TYPE_ARG3) ®s) == -1) perror_with_name (_("Couldn't get registers")); + /* Deep down, sparc_supply_rwindow reads memory, so needs the global + thread context to be set. */ + thread_info *thread = find_thread_ptid (proc_target, ptid); + scoped_restore_current_thread restore_thread; + switch_to_thread (thread); + sparc_supply_gregset (sparc_gregmap, regcache, -1, ®s); if (regnum != -1) return; @@ -184,7 +191,8 @@ sparc_fetch_inferior_registers (struct regcache *regcache, int regnum) } void -sparc_store_inferior_registers (struct regcache *regcache, int regnum) +sparc_store_inferior_registers (process_stratum_target *proc_target, + regcache *regcache, int regnum) { struct gdbarch *gdbarch = regcache->arch (); ptid_t ptid = regcache->ptid (); @@ -208,6 +216,13 @@ sparc_store_inferior_registers (struct regcache *regcache, int regnum) ULONGEST sp; regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); + + /* Deep down, sparc_collect_rwindow writes memory, so needs the global + thread context to be set. */ + thread_info *thread = find_thread_ptid (proc_target, ptid); + scoped_restore_current_thread restore_thread; + switch_to_thread (thread); + sparc_collect_rwindow (regcache, sp, regnum); } diff --git a/gdb/sparc-nat.h b/gdb/sparc-nat.h index 196bf1f2307..9d0c24f731f 100644 --- a/gdb/sparc-nat.h +++ b/gdb/sparc-nat.h @@ -41,8 +41,10 @@ extern int (*sparc_fpregset_supplies_p) (struct gdbarch *gdbarch, int); extern int sparc32_gregset_supplies_p (struct gdbarch *gdbarch, int regnum); extern int sparc32_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum); -extern void sparc_fetch_inferior_registers (struct regcache *, int); -extern void sparc_store_inferior_registers (struct regcache *, int); +extern void sparc_fetch_inferior_registers (process_stratum_target *proc_target, + regcache *, int); +extern void sparc_store_inferior_registers (process_stratum_target *proc_target, + regcache *, int); extern target_xfer_status sparc_xfer_wcookie (enum target_object object, const char *annex, @@ -59,10 +61,10 @@ template struct sparc_target : public BaseTarget { void fetch_registers (struct regcache *regcache, int regnum) override - { sparc_fetch_inferior_registers (regcache, regnum); } + { sparc_fetch_inferior_registers (this, regcache, regnum); } void store_registers (struct regcache *regcache, int regnum) override - { sparc_store_inferior_registers (regcache, regnum); } + { sparc_store_inferior_registers (this, regcache, regnum); } enum target_xfer_status xfer_partial (enum target_object object, const char *annex, diff --git a/gdb/sparc-obsd-tdep.c b/gdb/sparc-obsd-tdep.c index 01656d79861..53ba5d27e31 100644 --- a/gdb/sparc-obsd-tdep.c +++ b/gdb/sparc-obsd-tdep.c @@ -25,6 +25,7 @@ #include "regcache.h" #include "symtab.h" #include "trad-frame.h" +#include "inferior.h" #include "obsd-tdep.h" #include "sparc-tdep.h" @@ -158,6 +159,9 @@ sparc32obsd_supply_uthread (struct regcache *regcache, CORE_ADDR fp, fp_addr = addr + SPARC32OBSD_UTHREAD_FP_OFFSET; gdb_byte buf[4]; + /* This function calls functions that depend on the global current thread. */ + gdb_assert (regcache->ptid () == inferior_ptid); + gdb_assert (regnum >= -1); fp = read_memory_unsigned_integer (fp_addr, 4, byte_order); @@ -203,6 +207,9 @@ sparc32obsd_collect_uthread(const struct regcache *regcache, CORE_ADDR sp; gdb_byte buf[4]; + /* This function calls functions that depend on the global current thread. */ + gdb_assert (regcache->ptid () == inferior_ptid); + gdb_assert (regnum >= -1); if (regnum == SPARC_SP_REGNUM || regnum == -1) diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index bbceb74951f..b2a6842f8a3 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1944,6 +1944,9 @@ sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum) gdb_byte buf[8]; int i; + /* This function calls functions that depend on the global current thread. */ + gdb_assert (regcache->ptid () == inferior_ptid); + if (sp & 1) { /* Registers are 64-bit. */ @@ -2018,6 +2021,9 @@ sparc_collect_rwindow (const struct regcache *regcache, gdb_byte buf[8]; int i; + /* This function calls functions that depend on the global current thread. */ + gdb_assert (regcache->ptid () == inferior_ptid); + if (sp & 1) { /* Registers are 64-bit. */ diff --git a/gdb/sparc64-linux-nat.c b/gdb/sparc64-linux-nat.c index ad2cc35bd70..b741d0216c3 100644 --- a/gdb/sparc64-linux-nat.c +++ b/gdb/sparc64-linux-nat.c @@ -35,10 +35,10 @@ class sparc64_linux_nat_target final : public linux_nat_target public: /* Add our register access methods. */ void fetch_registers (struct regcache *regcache, int regnum) override - { sparc_fetch_inferior_registers (regcache, regnum); } + { sparc_fetch_inferior_registers (this, regcache, regnum); } void store_registers (struct regcache *regcache, int regnum) override - { sparc_store_inferior_registers (regcache, regnum); } + { sparc_store_inferior_registers (this, regcache, regnum); } /* Override linux_nat_target low methods. */ diff --git a/gdb/sparc64-obsd-tdep.c b/gdb/sparc64-obsd-tdep.c index a000bcac668..f90e4944589 100644 --- a/gdb/sparc64-obsd-tdep.c +++ b/gdb/sparc64-obsd-tdep.c @@ -27,6 +27,7 @@ #include "symtab.h" #include "objfiles.h" #include "trad-frame.h" +#include "inferior.h" #include "obsd-tdep.h" #include "sparc64-tdep.h" @@ -328,6 +329,9 @@ sparc64obsd_supply_uthread (struct regcache *regcache, CORE_ADDR fp, fp_addr = addr + SPARC64OBSD_UTHREAD_FP_OFFSET; gdb_byte buf[8]; + /* This function calls functions that depend on the global current thread. */ + gdb_assert (regcache->ptid () == inferior_ptid); + gdb_assert (regnum >= -1); fp = read_memory_unsigned_integer (fp_addr, 8, byte_order); @@ -373,6 +377,9 @@ sparc64obsd_collect_uthread(const struct regcache *regcache, CORE_ADDR sp; gdb_byte buf[8]; + /* This function calls functions that depend on the global current thread. */ + gdb_assert (regcache->ptid () == inferior_ptid); + gdb_assert (regnum >= -1); if (regnum == SPARC_SP_REGNUM || regnum == -1)