From: "Sérgio Durigan Júnior" <sergiodj@linux.vnet.ibm.com>
To: luisgpm@linux.vnet.ibm.com
Cc: gdb-patches@sourceware.org, Mark Kettenis <mark.kettenis@xs4all.nl>
Subject: Re: [PATCH] Improve the fetch/store of general-purpose and floating-point PowerPC registers
Date: Wed, 21 Jan 2009 17:28:00 -0000 [thread overview]
Message-ID: <1232558849.6328.23.camel@miki> (raw)
In-Reply-To: <1231503988.12849.6.camel@gargoyle>
[-- Attachment #1: Type: text/plain, Size: 880 bytes --]
Hi Luis,
This version of the patch fixes what you suggested. Also, I removed some
unecessary checks regarding PPC32/64.
Regards,
--
Sérgio Durigan Júnior
Linux on Power Toolchain - Software Engineer
Linux Technology Center - LTC
IBM Brazil
2009-01-21 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com>
* ppc-linux-nat.c (have_ptrace_getsetregs): New variable.
(have_ptrace_getsetfpregs): Likewise.
fetch_all_gp_regs): New function.
(fetch_gp_regs): New function.
(fetch_all_fp_regs): Likewise.
(fetch_fp_regs): New function.
(fetch_ppc_registers): Using the new methods to fetch general-
purpose and floating-pointer registers.
(store_all_gp_regs): New function.
(store_gp_regs): Likewise.
(store_all_fp_regs): New function.
(store_fp_regs): Likewise.
(store_ppc_registers): Using the new methods to store general-
purpose and floating-pointer registers.
[-- Attachment #2: read-regs.patch --]
[-- Type: text/x-patch, Size: 7991 bytes --]
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index b946093..bc1b767 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -108,6 +108,21 @@
#define PTRACE_GETSIGINFO 0x4202
#endif
+/* Similarly for the general-purpose (gp0 -- gp31)
+ and floating-point registers (fp0 -- fp31). */
+#ifndef PTRACE_GETREGS
+#define PTRACE_GETREGS 12
+#endif
+#ifndef PTRACE_SETREGS
+#define PTRACE_SETREGS 13
+#endif
+#ifndef PTRACE_GETFPREGS
+#define PTRACE_GETFPREGS 14
+#endif
+#ifndef PTRACE_SETFPREGS
+#define PTRACE_SETFPREGS 15
+#endif
+
/* This oddity is because the Linux kernel defines elf_vrregset_t as
an array of 33 16 bytes long elements. I.e. it leaves out vrsave.
However the PTRACE_GETVRREGS and PTRACE_SETVRREGS requests return
@@ -218,6 +233,18 @@ int have_ptrace_getvrregs = 1;
error. */
int have_ptrace_getsetevrregs = 1;
+/* Non-zero if our kernel may support the PTRACE_GETREGS and
+ PTRACE_SETREGS requests, for reading and writing the
+ general-purpose registers. Zero if we've tried one of
+ them and gotten an error. */
+int have_ptrace_getsetregs = 1;
+
+/* Non-zero if our kernel may support the PTRACE_GETFPREGS and
+ PTRACE_SETFPREGS requests, for reading and writing the
+ floating-pointers registers. Zero if we've tried one of
+ them and gotten an error. */
+int have_ptrace_getsetfpregs = 1;
+
/* *INDENT-OFF* */
/* registers layout, as presented by the ptrace interface:
PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
@@ -601,6 +628,84 @@ fetch_altivec_registers (struct regcache *regcache, int tid)
supply_vrregset (regcache, ®s);
}
+static int
+fetch_all_gp_regs (struct regcache *regcache, int tid)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ gdb_gregset_t gregset;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getsetregs = 0;
+ return 0;
+ }
+ perror_with_name (_("Couldn't get general-purpose registers."));
+ }
+
+ supply_gregset (regcache, (const gdb_gregset_t *) &gregset);
+
+ return 1;
+}
+
+static void
+fetch_gp_regs (struct regcache *regcache, int tid)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int i;
+
+ if (have_ptrace_getsetregs)
+ if (fetch_all_gp_regs (regcache, tid))
+ return;
+
+ /* If we've hit this point, it doesn't really matter which
+ architecture we are using. We just need to read the
+ registers in the "old-fashioned way". */
+ for (i = 0; i < ppc_num_gprs; i++)
+ fetch_register (regcache, tid, tdep->ppc_gp0_regnum + i);
+}
+
+static int
+fetch_all_fp_regs (struct regcache *regcache, int tid)
+{
+ gdb_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (void *) &fpregs) < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getsetfpregs = 0;
+ return 0;
+ }
+ perror_with_name (_("Couldn't get floating-point registers."));
+ }
+
+ supply_fpregset (regcache, (const gdb_fpregset_t *) &fpregs);
+
+ return 1;
+}
+
+static void
+fetch_fp_regs (struct regcache *regcache, int tid)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int i;
+
+ if (have_ptrace_getsetfpregs)
+ if (fetch_all_fp_regs (regcache, tid))
+ return;
+
+ /* If we've hit this point, it doesn't really matter which
+ architecture we are using. We just need to read the
+ registers in the "old-fashioned way". */
+ for (i = 0; i < ppc_num_fprs; i++)
+ fetch_register (regcache, tid, tdep->ppc_fp0_regnum + i);
+}
+
static void
fetch_ppc_registers (struct regcache *regcache, int tid)
{
@@ -608,11 +713,9 @@ fetch_ppc_registers (struct regcache *regcache, int tid)
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- for (i = 0; i < ppc_num_gprs; i++)
- fetch_register (regcache, tid, tdep->ppc_gp0_regnum + i);
+ fetch_gp_regs (regcache, tid);
if (tdep->ppc_fp0_regnum >= 0)
- for (i = 0; i < ppc_num_fprs; i++)
- fetch_register (regcache, tid, tdep->ppc_fp0_regnum + i);
+ fetch_fp_regs (regcache, tid);
fetch_register (regcache, tid, gdbarch_pc_regnum (gdbarch));
if (tdep->ppc_ps_regnum != -1)
fetch_register (regcache, tid, tdep->ppc_ps_regnum);
@@ -969,18 +1072,114 @@ store_altivec_registers (const struct regcache *regcache, int tid)
perror_with_name (_("Couldn't write AltiVec registers"));
}
+static int
+store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ gdb_gregset_t gregset;
+
+ if (ptrace (PTRACE_GETREGS, tid, 0, (void *) &gregset) < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getsetregs = 0;
+ return 0;
+ }
+ perror_with_name (_("Couldn't get general-purpose registers."));
+ }
+
+ fill_gregset (regcache, &gregset, regno);
+
+ if (ptrace (PTRACE_SETREGS, tid, 0, (void *) &gregset) < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getsetregs = 0;
+ return 0;
+ }
+ perror_with_name (_("Couldn't set general-purpose registers."));
+ }
+
+ return 1;
+}
+
static void
-store_ppc_registers (const struct regcache *regcache, int tid)
+store_gp_regs (const struct regcache *regcache, int tid, int regno)
{
- int i;
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
+ int i;
+
+ if (have_ptrace_getsetregs)
+ if (store_all_gp_regs (regcache, tid, regno))
+ return;
+
+ /* If we hit this point, it doesn't really matter which
+ architecture we are using. We just need to store the
+ registers in the "old-fashioned way". */
for (i = 0; i < ppc_num_gprs; i++)
store_register (regcache, tid, tdep->ppc_gp0_regnum + i);
+}
+
+static int
+store_all_fp_regs (const struct regcache *regcache, int tid, int regno)
+{
+ gdb_fpregset_t fpregs;
+
+ if (ptrace (PTRACE_GETFPREGS, tid, 0, (void *) &fpregs) < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getsetfpregs = 0;
+ return 0;
+ }
+ perror_with_name (_("Couldn't get floating-point registers."));
+ }
+
+ fill_fpregset (regcache, &fpregs, regno);
+
+ if (ptrace (PTRACE_SETFPREGS, tid, 0, (void *) &fpregs) < 0)
+ {
+ if (errno == EIO)
+ {
+ have_ptrace_getsetfpregs = 0;
+ return 0;
+ }
+ perror_with_name (_("Couldn't set floating-point registers."));
+ }
+
+ return 1;
+}
+
+static void
+store_fp_regs (const struct regcache *regcache, int tid, int regno)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int i;
+
+ if (have_ptrace_getsetfpregs)
+ if (store_all_fp_regs (regcache, tid, regno))
+ return;
+
+ /* If we hit this point, it doesn't really matter which
+ architecture we are using. We just need to store the
+ registers in the "old-fashioned way". */
+ for (i = 0; i < ppc_num_fprs; i++)
+ store_register (regcache, tid, tdep->ppc_fp0_regnum + i);
+}
+
+static void
+store_ppc_registers (const struct regcache *regcache, int tid)
+{
+ int i;
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ store_gp_regs (regcache, tid, -1);
if (tdep->ppc_fp0_regnum >= 0)
- for (i = 0; i < ppc_num_fprs; i++)
- store_register (regcache, tid, tdep->ppc_fp0_regnum + i);
+ store_fp_regs (regcache, tid, -1);
store_register (regcache, tid, gdbarch_pc_regnum (gdbarch));
if (tdep->ppc_ps_regnum != -1)
store_register (regcache, tid, tdep->ppc_ps_regnum);
next prev parent reply other threads:[~2009-01-21 17:28 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-07 18:32 Sérgio Durigan Júnior
2008-10-16 20:07 ` Sérgio Durigan Júnior
2009-01-07 0:44 ` Sérgio Durigan Júnior
2009-01-07 9:56 ` Mark Kettenis
2009-01-07 16:09 ` Sérgio Durigan Júnior
2009-01-08 17:46 ` Sérgio Durigan Júnior
2009-01-09 12:26 ` Luis Machado
2009-01-21 17:28 ` Sérgio Durigan Júnior [this message]
2009-04-28 20:07 ` Joel Brobecker
2009-04-29 2:16 ` Sérgio Durigan Júnior
2009-04-29 4:05 ` Joel Brobecker
2009-05-05 18:34 ` Sérgio Durigan Júnior
2009-05-06 16:58 ` Joel Brobecker
2009-05-09 3:20 ` [PATCH] Improve the fetch/store of general-purpose andfloating-point " Sérgio Durigan Júnior
2008-11-17 23:22 ` [PATCH] Improve the fetch/store of general-purpose and floating-point " Sérgio Durigan Júnior
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=1232558849.6328.23.camel@miki \
--to=sergiodj@linux.vnet.ibm.com \
--cc=gdb-patches@sourceware.org \
--cc=luisgpm@linux.vnet.ibm.com \
--cc=mark.kettenis@xs4all.nl \
/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