From: Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 6/8] [PowerPC] Fix VSX registers in linux core files
Date: Thu, 10 May 2018 20:33:00 -0000 [thread overview]
Message-ID: <20180510195840.17734-7-pedromfc@linux.vnet.ibm.com> (raw)
In-Reply-To: <20180510195840.17734-1-pedromfc@linux.vnet.ibm.com>
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:
yyyy-mm-dd 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:
yyyy-mm-dd Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
* gdb.arch/powerpc-vsx-gcore.exp: New file.
---
gdb/ppc-linux-nat.c | 106 ++++-----------------------
gdb/ppc-linux-tdep.c | 18 ++++-
gdb/ppc-linux-tdep.h | 1 +
gdb/rs6000-tdep.c | 75 -------------------
gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp | 90 +++++++++++++++++++++++
5 files changed, 121 insertions(+), 169 deletions(-)
create mode 100644 gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 85cd08cd8e..59c5f0c4b9 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);
}
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 3c8ba26f8e..54de34d0b7 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -560,10 +560,16 @@ static const struct regset ppc32_be_linux_vrregset = {
ppc_linux_collect_vrregset
};
+static const struct regcache_map_entry ppc32_linux_vsxregmap[] =
+ {
+ { 32, PPC_VSR0_UPPER_REGNUM, 8 },
+ { 0 }
+ };
+
static const struct regset ppc32_linux_vsxregset = {
- &ppc32_linux_reg_offsets,
- ppc_supply_vsxregset,
- ppc_collect_vsxregset
+ ppc32_linux_vsxregmap,
+ regcache_supply_regset,
+ regcache_collect_regset
};
const struct regset *
@@ -587,6 +593,12 @@ ppc_linux_vrregset (struct gdbarch *gdbarch)
return &ppc32_le_linux_vrregset;
}
+const struct regset *
+ppc_linux_vsxregset (void)
+{
+ return &ppc32_linux_vsxregset;
+}
+
/* Iterate over supported core file register note sections. */
static void
diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h
index a8715bd418..51f4b506a1 100644
--- a/gdb/ppc-linux-tdep.h
+++ b/gdb/ppc-linux-tdep.h
@@ -30,6 +30,7 @@ const struct regset *ppc_linux_fpregset (void);
/* Get the vector regset that matches the target byte order. */
const struct regset *ppc_linux_vrregset (struct gdbarch *gdbarch);
+const struct regset *ppc_linux_vsxregset (void);
/* Extra register number constants. The Linux kernel stores a
"trap" code and the original value of r3 into special "registers";
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index c5b49c5f46..3f0b7f77a1 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -224,16 +224,6 @@ ppc_floating_point_unit_p (struct gdbarch *gdbarch)
}
/* Return non-zero if the architecture described by GDBARCH has
- VSX registers (vsr0 --- vsr63). */
-static int
-ppc_vsx_support_p (struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- return tdep->ppc_vsr0_regnum >= 0;
-}
-
-/* Return non-zero if the architecture described by GDBARCH has
Altivec registers (vr0 --- vr31, vrsave and vscr). */
int
ppc_altivec_support_p (struct gdbarch *gdbarch)
@@ -591,37 +581,6 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
-/* Supply register REGNUM in the VSX register set REGSET
- from the buffer specified by VSXREGS and LEN to register cache
- REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
-
-void
-ppc_supply_vsxregset (const struct regset *regset, struct regcache *regcache,
- int regnum, const void *vsxregs, size_t len)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- struct gdbarch_tdep *tdep;
-
- if (!ppc_vsx_support_p (gdbarch))
- return;
-
- tdep = gdbarch_tdep (gdbarch);
-
- if (regnum == -1)
- {
- int i;
-
- for (i = tdep->ppc_vsr0_upper_regnum;
- i < tdep->ppc_vsr0_upper_regnum + 32;
- i++)
- ppc_supply_reg (regcache, i, (const gdb_byte *) vsxregs, 0, 8);
-
- return;
- }
- else
- ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 8);
-}
-
/* Supply register REGNUM in the Altivec register set REGSET
from the buffer specified by VRREGS and LEN to register cache
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
@@ -757,40 +716,6 @@ ppc_collect_fpregset (const struct regset *regset,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
-/* Collect register REGNUM in the VSX register set
- REGSET from register cache REGCACHE into the buffer specified by
- VSXREGS and LEN. If REGNUM is -1, do this for all registers in
- REGSET. */
-
-void
-ppc_collect_vsxregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *vsxregs, size_t len)
-{
- struct gdbarch *gdbarch = regcache->arch ();
- struct gdbarch_tdep *tdep;
-
- if (!ppc_vsx_support_p (gdbarch))
- return;
-
- tdep = gdbarch_tdep (gdbarch);
-
- if (regnum == -1)
- {
- int i;
-
- for (i = tdep->ppc_vsr0_upper_regnum;
- i < tdep->ppc_vsr0_upper_regnum + 32;
- i++)
- ppc_collect_reg (regcache, i, (gdb_byte *) vsxregs, 0, 8);
-
- return;
- }
- else
- ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 8);
-}
-
-
/* Collect register REGNUM in the Altivec register set
REGSET from register cache REGCACHE into the buffer specified by
VRREGS and LEN. If REGNUM is -1, do this for all registers in
diff --git a/gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp b/gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp
new file mode 100644
index 0000000000..e9bdfcdd44
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/powerpc-vsx-gcore.exp
@@ -0,0 +1,90 @@
+# Copyright (C) 2018 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+# This test checks that generating and loading a core file preserves
+# the correct VSX register state.
+
+if {![istarget "powerpc*-*-linux*"] || [skip_vsx_tests]} then {
+ verbose "Skipping PowerPC test for corefiles with VSX registers."
+ return
+}
+
+standard_testfile .c
+
+set gen_src [standard_output_file $srcfile]
+
+gdb_produce_source $gen_src {
+ int main() {
+ return 0;
+ }
+}
+
+if {[build_executable "compile" $binfile $gen_src] == -1} {
+ return -1
+}
+
+clean_restart $binfile
+
+if ![runto_main] then {
+ fail "could not run to main"
+ return -1
+}
+
+# Check if VSX register access through gdb is supported
+proc check_vsx_access {} {
+ global gdb_prompt
+
+ set test "vsx register access"
+ gdb_test_multiple "info reg vs0" "$test" {
+ -re "Invalid register.*\r\n$gdb_prompt $" {
+ unsupported "$test"
+ return 0
+ }
+ -re "\r\nvs0.*\r\n$gdb_prompt $" {
+ pass "$test"
+ return 1
+ }
+ }
+ return 0
+}
+
+if { ![check_vsx_access] } {
+ return -1
+}
+
+for {set i 0} {$i < 64} {incr i 1} {
+ gdb_test_no_output "set \$vs$i.uint128 = $i"
+}
+
+set core_filename [standard_output_file "$testfile.core"]
+set core_generated [gdb_gcore_cmd "$core_filename" "generate core file"]
+
+if { !$core_generated } {
+ return -1
+}
+
+clean_restart
+
+set core_loaded [gdb_core_cmd "$core_filename" "load core file"]
+
+if { $core_loaded != 1 } {
+ return -1
+}
+
+for {set i 0} {$i < 64} {incr i 1} {
+ gdb_test "print \$vs$i.uint128" ".* = $i" "print vs$i"
+}
--
2.13.6
next prev parent reply other threads:[~2018-05-10 20:00 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-10 19:59 [PATCH 0/8] [PowerPC] Miscellaneous fixes for register access Pedro Franco de Carvalho
2018-05-10 19:59 ` [PATCH 1/8] [PowerPC] Consolidate linux target description selection Pedro Franco de Carvalho
2018-05-16 14:05 ` Ulrich Weigand
2018-05-16 22:50 ` Pedro Franco de Carvalho
2018-05-17 8:28 ` Ulrich Weigand
2018-05-10 19:59 ` [PATCH 3/8] [PowerPC] Disable regsets using zero sizes in gdbserver Pedro Franco de Carvalho
2018-05-16 16:17 ` Ulrich Weigand
2018-05-10 19:59 ` [PATCH 4/8] [PowerPC] Consolidate linux vector regset sizes Pedro Franco de Carvalho
2018-05-16 16:35 ` Ulrich Weigand
2018-05-10 20:00 ` [PATCH 8/8] [PowerPC] Recognize isa205 in linux core files Pedro Franco de Carvalho
2018-05-16 15:53 ` Ulrich Weigand
2018-05-16 23:32 ` Pedro Franco de Carvalho
2018-05-17 10:22 ` Ulrich Weigand
2018-05-21 20:46 ` Pedro Franco de Carvalho
2018-05-22 12:48 ` Ulrich Weigand
2018-05-22 14:33 ` Pedro Franco de Carvalho
2018-05-10 20:33 ` [PATCH 2/8] [PowerPC] Consolidate wordsize getter between native and gdbserver Pedro Franco de Carvalho
2018-05-16 15:54 ` Ulrich Weigand
2018-05-10 20:33 ` Pedro Franco de Carvalho [this message]
2018-05-16 14:18 ` [PATCH 6/8] [PowerPC] Fix VSX registers in linux core files Ulrich Weigand
2018-05-10 21:46 ` [PATCH 5/8] [PowerPC] Fix access to VSCR in linux targets Pedro Franco de Carvalho
2018-05-16 14:06 ` Ulrich Weigand
2018-05-17 21:25 ` Pedro Franco de Carvalho
2018-05-18 15:37 ` Ulrich Weigand
2018-05-21 20:46 ` Pedro Franco de Carvalho
2018-05-22 12:56 ` Ulrich Weigand
2018-05-10 22:25 ` [PATCH 7/8] [PowerPC] Fix inclusion of dfp pseudoregs in tdep Pedro Franco de Carvalho
2018-05-16 14:18 ` Ulrich Weigand
2018-05-21 20:46 ` [PATCH v2 1/8] [PowerPC] Consolidate linux target description selection Pedro Franco de Carvalho
2018-05-21 20:46 ` [PATCH v2 3/8] [PowerPC] Disable regsets using zero sizes in gdbserver Pedro Franco de Carvalho
2018-05-22 12:48 ` Ulrich Weigand
2018-05-21 20:46 ` [PATCH v2 4/8] [PowerPC] Consolidate linux vector regset sizes Pedro Franco de Carvalho
2018-05-22 12:48 ` Ulrich Weigand
2018-05-21 20:46 ` [PATCH v2 2/8] [PowerPC] Consolidate wordsize getter between native and gdbserver Pedro Franco de Carvalho
2018-05-22 12:56 ` Ulrich Weigand
2018-05-21 23:45 ` [PATCH v2 5/8] [PowerPC] Fix access to VSCR in linux targets Pedro Franco de Carvalho
2018-05-22 12:56 ` Ulrich Weigand
2018-05-21 23:55 ` [PATCH v2 8/8] [PowerPC] Recognize isa205 in linux core files Pedro Franco de Carvalho
2018-05-22 13:34 ` Ulrich Weigand
2018-05-21 23:56 ` [PATCH v2 7/8] [PowerPC] Fix inclusion of dfp pseudoregs in tdep Pedro Franco de Carvalho
2018-05-22 12:56 ` Ulrich Weigand
2018-05-22 0:54 ` [PATCH v2 6/8] [PowerPC] Fix VSX registers in linux core files Pedro Franco de Carvalho
2018-05-22 13:46 ` Ulrich Weigand
2018-05-22 12:48 ` [PATCH v2 1/8] [PowerPC] Consolidate linux target description selection Ulrich Weigand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180510195840.17734-7-pedromfc@linux.vnet.ibm.com \
--to=pedromfc@linux.vnet.ibm.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).