diff options
author | Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> | 2018-05-22 11:09:05 -0300 |
---|---|---|
committer | Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com> | 2018-05-22 11:52:03 -0300 |
commit | 2c3305f6b0432e37d26ce7761d0c4415ab5ca911 (patch) | |
tree | c3f2cfeb6eedcc5f382a063106ea284441cb7417 /gdb/ppc-linux-nat.c | |
parent | 1d75a65809b49d41e97518b99c551a4bb2517500 (diff) | |
download | binutils-gdb-2c3305f6b0432e37d26ce7761d0c4415ab5ca911.tar.gz |
[PowerPC] Fix VSX registers in linux core files
The functions used by the VSX regset to collect and supply registers
from core files where incorrect. This patch changes the regset to use
the standard regset collect/supply functions to fix this. The native
target is also changed to use the same regset.
gdb/ChangeLog:
2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
* ppc-linux-tdep.c (ppc_linux_vsxregset): New function.
(ppc32_linux_vsxregmap): New global.
(ppc32_linux_vsxregset): Initialize with ppc32_linux_vsxregmap,
regcache_supply_regset, and regcache_collect_regset.
* ppc-linux-tdep.h (ppc_linux_vsxregset): Declare.
* ppc-linux-nat.c (supply_vsxregset, fill_vsxregset): Remove.
(fetch_vsx_register, store_vsx_register): Remove.
(fetch_vsx_registers): Add regno parameter. Get regset using
ppc_linux_vsxregset. Use regset to supply registers.
(store_vsx_registers): Add regno parameter. Get regset using
ppc_linux_vsxregset. Use regset to collect registers.
(fetch_register): Call fetch_vsx_registers instead of
fetch_vsx_register.
(store_register): Call store_vsx_registers instead of
store_vsx_register.
(fetch_ppc_registers): Call fetch_vsx_registers with -1 for the
new regno parameter.
(store_ppc_registers): Call store_vsx_registers with -1 for the
new regno parameter.
* rs6000-tdep.c (ppc_vsx_support_p, ppc_supply_vsxreget)
(ppc_collect_vsxregset): Remove.
gdb/testsuite/ChangeLog:
2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
* gdb.arch/powerpc-vsx-gcore.exp: New file.
Diffstat (limited to 'gdb/ppc-linux-nat.c')
-rw-r--r-- | gdb/ppc-linux-nat.c | 106 |
1 files changed, 15 insertions, 91 deletions
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index e00831a2483..0f7dd4c8e26 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -409,13 +409,11 @@ ppc_register_u_addr (struct gdbarch *gdbarch, int regno) registers set mechanism, as opposed to the interface for all the other registers, that stores/fetches each register individually. */ static void -fetch_vsx_register (struct regcache *regcache, int tid, int regno) +fetch_vsx_registers (struct regcache *regcache, int tid, int regno) { int ret; gdb_vsxregset_t regs; - struct gdbarch *gdbarch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum); + const struct regset *vsxregset = ppc_linux_vsxregset (); ret = ptrace (PTRACE_GETVSXREGS, tid, 0, ®s); if (ret < 0) @@ -425,12 +423,11 @@ fetch_vsx_register (struct regcache *regcache, int tid, int regno) have_ptrace_getsetvsxregs = 0; return; } - perror_with_name (_("Unable to fetch VSX register")); + perror_with_name (_("Unable to fetch VSX registers")); } - regcache_raw_supply (regcache, regno, - regs + (regno - tdep->ppc_vsr0_upper_regnum) - * vsxregsize); + vsxregset->supply_regset (vsxregset, regcache, regno, ®s, + PPC_LINUX_SIZEOF_VSXREGSET); } /* The Linux kernel ptrace interface for AltiVec registers uses the @@ -563,7 +560,7 @@ fetch_register (struct regcache *regcache, int tid, int regno) { if (have_ptrace_getsetvsxregs) { - fetch_vsx_register (regcache, tid, regno); + fetch_vsx_registers (regcache, tid, regno); return; } } @@ -624,40 +621,6 @@ fetch_register (struct regcache *regcache, int tid, int regno) gdbarch_byte_order (gdbarch)); } -static void -supply_vsxregset (struct regcache *regcache, gdb_vsxregset_t *vsxregsetp) -{ - int i; - struct gdbarch *gdbarch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum); - - for (i = 0; i < ppc_num_vshrs; i++) - { - regcache_raw_supply (regcache, tdep->ppc_vsr0_upper_regnum + i, - *vsxregsetp + i * vsxregsize); - } -} - -static void -fetch_vsx_registers (struct regcache *regcache, int tid) -{ - int ret; - gdb_vsxregset_t regs; - - ret = ptrace (PTRACE_GETVSXREGS, tid, 0, ®s); - if (ret < 0) - { - if (errno == EIO) - { - have_ptrace_getsetvsxregs = 0; - return; - } - perror_with_name (_("Unable to fetch VSX registers")); - } - supply_vsxregset (regcache, ®s); -} - /* This function actually issues the request to ptrace, telling it to get all general-purpose registers and put them into the specified regset. @@ -799,7 +762,7 @@ fetch_ppc_registers (struct regcache *regcache, int tid) fetch_altivec_registers (regcache, tid, -1); if (have_ptrace_getsetvsxregs) if (tdep->ppc_vsr0_upper_regnum != -1) - fetch_vsx_registers (regcache, tid); + fetch_vsx_registers (regcache, tid, -1); if (tdep->ppc_ev0_upper_regnum >= 0) fetch_spe_register (regcache, tid, -1); } @@ -818,15 +781,12 @@ ppc_linux_nat_target::fetch_registers (struct regcache *regcache, int regno) fetch_register (regcache, tid, regno); } -/* Store one VSX register. */ static void -store_vsx_register (const struct regcache *regcache, int tid, int regno) +store_vsx_registers (const struct regcache *regcache, int tid, int regno) { int ret; gdb_vsxregset_t regs; - struct gdbarch *gdbarch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum); + const struct regset *vsxregset = ppc_linux_vsxregset (); ret = ptrace (PTRACE_GETVSXREGS, tid, 0, ®s); if (ret < 0) @@ -836,15 +796,15 @@ store_vsx_register (const struct regcache *regcache, int tid, int regno) have_ptrace_getsetvsxregs = 0; return; } - perror_with_name (_("Unable to fetch VSX register")); + perror_with_name (_("Unable to fetch VSX registers")); } - regcache_raw_collect (regcache, regno, regs + - (regno - tdep->ppc_vsr0_upper_regnum) * vsxregsize); + vsxregset->collect_regset (vsxregset, regcache, regno, ®s, + PPC_LINUX_SIZEOF_VSXREGSET); ret = ptrace (PTRACE_SETVSXREGS, tid, 0, ®s); if (ret < 0) - perror_with_name (_("Unable to store VSX register")); + perror_with_name (_("Unable to store VSX registers")); } static void @@ -980,7 +940,7 @@ store_register (const struct regcache *regcache, int tid, int regno) } if (vsx_register_p (gdbarch, regno)) { - store_vsx_register (regcache, tid, regno); + store_vsx_registers (regcache, tid, regno); return; } else if (spe_register_p (gdbarch, regno)) @@ -1038,42 +998,6 @@ store_register (const struct regcache *regcache, int tid, int regno) } } -static void -fill_vsxregset (const struct regcache *regcache, gdb_vsxregset_t *vsxregsetp) -{ - int i; - struct gdbarch *gdbarch = regcache->arch (); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum); - - for (i = 0; i < ppc_num_vshrs; i++) - regcache_raw_collect (regcache, tdep->ppc_vsr0_upper_regnum + i, - *vsxregsetp + i * vsxregsize); -} - -static void -store_vsx_registers (const struct regcache *regcache, int tid) -{ - int ret; - gdb_vsxregset_t regs; - - ret = ptrace (PTRACE_GETVSXREGS, tid, 0, ®s); - if (ret < 0) - { - if (errno == EIO) - { - have_ptrace_getsetvsxregs = 0; - return; - } - perror_with_name (_("Couldn't get VSX registers")); - } - - fill_vsxregset (regcache, ®s); - - if (ptrace (PTRACE_SETVSXREGS, tid, 0, ®s) < 0) - perror_with_name (_("Couldn't write VSX registers")); -} - /* This function actually issues the request to ptrace, telling it to store all general-purpose registers present in the specified regset. @@ -1235,7 +1159,7 @@ store_ppc_registers (const struct regcache *regcache, int tid) store_altivec_registers (regcache, tid, -1); if (have_ptrace_getsetvsxregs) if (tdep->ppc_vsr0_upper_regnum != -1) - store_vsx_registers (regcache, tid); + store_vsx_registers (regcache, tid, -1); if (tdep->ppc_ev0_upper_regnum >= 0) store_spe_register (regcache, tid, -1); } |