This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 2/7] New regs_info for aarch32
- From: Yao Qi <qiyaoltc at gmail dot com>
- To: gdb-patches at sourceware dot org
- Date: Fri, 31 Jul 2015 16:16:36 +0100
- Subject: [PATCH 2/7] New regs_info for aarch32
- Authentication-results: sourceware.org; auth=none
- References: <1438355801-25798-1-git-send-email-yao dot qi at linaro dot org>
This patch adds a new regs_info regs_info_aarch32 for aarch32, which
can be used by both aarch64 and arm backend.
gdb/gdbserver:
2015-07-28 Yao Qi <yao.qi@linaro.org>
* configure.srv (srv_tgtobj): Add linux-aarch32-low.o.
* linux-aarch32-low.c: New file.
* linux-aarch32-low.h: New file.
* linux-arm-low.c (arm_fill_gregset): Move it to
linux-aarch32-low.c.
(arm_store_gregset), arm_fill_vfpregset): Likewise.
(arm_store_vfpregset): Likewise.
(arm_arch_setup): Check if PTRACE_GETREGSET works.
(regs_info): Rename to regs_info_arm.
(arm_regs_info): Return regs_info_aarch32 if
have_ptrace_getregset is 1 and target description isn't
iwmmxt.
(initialize_low_arch): Don't call
init_registers_arm_with_vfpv2, init_registers_arm_with_vfpv3,
and init_registers_arm_with_neon. Call
initialize_low_arch_aarch32 instead.
---
gdb/gdbserver/configure.srv | 1 +
gdb/gdbserver/linux-aarch32-low.c | 141 ++++++++++++++++++++++++++++++++++++++
gdb/gdbserver/linux-aarch32-low.h | 32 +++++++++
gdb/gdbserver/linux-arm-low.c | 108 +++++++----------------------
4 files changed, 199 insertions(+), 83 deletions(-)
create mode 100644 gdb/gdbserver/linux-aarch32-low.c
create mode 100644 gdb/gdbserver/linux-aarch32-low.h
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 9a04aac..1a8361a 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -62,6 +62,7 @@ case "${target}" in
srv_regobj="${srv_regobj} arm-with-vfpv3.o"
srv_regobj="${srv_regobj} arm-with-neon.o"
srv_tgtobj="$srv_linux_obj linux-arm-low.o"
+ srv_tgtobj="$srv_tgtobj linux-aarch32-low.o"
srv_xmlfiles="arm-with-iwmmxt.xml"
srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv2.xml"
srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv3.xml"
diff --git a/gdb/gdbserver/linux-aarch32-low.c b/gdb/gdbserver/linux-aarch32-low.c
new file mode 100644
index 0000000..0ca40c3
--- /dev/null
+++ b/gdb/gdbserver/linux-aarch32-low.c
@@ -0,0 +1,141 @@
+/* Copyright (C) 1995-2015 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+#include "server.h"
+#include "arch/arm.h"
+#include "linux-low.h"
+#include "linux-aarch32-low.h"
+
+#include <sys/ptrace.h>
+/* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
+ On Bionic elf.h and linux/elf.h have conflicting definitions. */
+#ifndef ELFMAG0
+#include <elf.h>
+#endif
+
+/* Collect GP registers from REGCACHE to buffer BUF. */
+
+void
+arm_fill_gregset (struct regcache *regcache, void *buf)
+{
+ int i;
+ uint32_t *regs = buf;
+
+ for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
+ collect_register (regcache, i, ®s[i]);
+
+ collect_register (regcache, ARM_PS_REGNUM, ®s[16]);
+}
+
+/* Supply GP registers contents, stored in BUF, to REGCACHE. */
+
+void
+arm_store_gregset (struct regcache *regcache, const void *buf)
+{
+ int i;
+ char zerobuf[8];
+ const uint32_t *regs = buf;
+
+ memset (zerobuf, 0, 8);
+ for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
+ supply_register (regcache, i, ®s[i]);
+
+ for (; i < ARM_PS_REGNUM; i++)
+ supply_register (regcache, i, zerobuf);
+
+ supply_register (regcache, ARM_PS_REGNUM, ®s[16]);
+}
+
+/* Collect VFP registers from REGCACHE to buffer BUF. */
+
+void
+arm_fill_vfpregset (struct regcache *regcache, void *buf)
+{
+ int i, num, base;
+
+ if (regcache->tdesc == tdesc_arm_with_neon
+ || regcache->tdesc == tdesc_arm_with_vfpv3)
+ num = 32;
+ else if (regcache->tdesc == tdesc_arm_with_vfpv2)
+ num = 16;
+ else
+ return;
+
+ base = find_regno (regcache->tdesc, "d0");
+ for (i = 0; i < num; i++)
+ collect_register (regcache, base + i, (char *) buf + i * 8);
+
+ collect_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
+}
+
+/* Supply VFP registers contents, stored in BUF, to REGCACHE. */
+
+void
+arm_store_vfpregset (struct regcache *regcache, const void *buf)
+{
+ int i, num, base;
+
+ if (regcache->tdesc == tdesc_arm_with_neon
+ || regcache->tdesc == tdesc_arm_with_vfpv3)
+ num = 32;
+ else if (regcache->tdesc == tdesc_arm_with_vfpv2)
+ num = 16;
+ else
+ return;
+
+ base = find_regno (regcache->tdesc, "d0");
+ for (i = 0; i < num; i++)
+ supply_register (regcache, base + i, (char *) buf + i * 8);
+
+ supply_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
+}
+
+/* Register sets with using PTRACE_GETREGSET. */
+
+static struct regset_info aarch32_regsets[] = {
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS, 18 * 4,
+ GENERAL_REGS,
+ arm_fill_gregset, arm_store_gregset },
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_VFP, 32 * 8 + 4,
+ EXTENDED_REGS,
+ arm_fill_vfpregset, arm_store_vfpregset },
+ { 0, 0, 0, -1, -1, NULL, NULL }
+};
+
+static struct regsets_info aarch32_regsets_info =
+ {
+ aarch32_regsets, /* regsets */
+ 0, /* num_regsets */
+ NULL, /* disabled_regsets */
+ };
+
+struct regs_info regs_info_aarch32 =
+ {
+ NULL, /* regset_bitmap */
+ NULL, /* usrregs */
+ &aarch32_regsets_info
+ };
+
+void
+initialize_low_arch_aarch32 (void)
+{
+ init_registers_arm_with_vfpv2 ();
+ init_registers_arm_with_vfpv3 ();
+ init_registers_arm_with_neon ();
+
+ initialize_regsets_info (&aarch32_regsets_info);
+}
diff --git a/gdb/gdbserver/linux-aarch32-low.h b/gdb/gdbserver/linux-aarch32-low.h
new file mode 100644
index 0000000..49bd5c3
--- /dev/null
+++ b/gdb/gdbserver/linux-aarch32-low.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 1995-2015 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+extern struct regs_info regs_info_aarch32;
+
+void arm_fill_gregset (struct regcache *regcache, void *buf);
+void arm_store_gregset (struct regcache *regcache, const void *buf);
+void arm_fill_vfpregset (struct regcache *regcache, void *buf);
+void arm_store_vfpregset (struct regcache *regcache, const void *buf);
+
+void initialize_low_arch_aarch32 (void);
+
+void init_registers_arm_with_vfpv2 (void);
+extern const struct target_desc *tdesc_arm_with_vfpv2;
+void init_registers_arm_with_vfpv3 (void);
+extern const struct target_desc *tdesc_arm_with_vfpv3;
+void init_registers_arm_with_neon (void);
+extern const struct target_desc *tdesc_arm_with_neon;
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index 3c5956b..6aebd29 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -19,7 +19,9 @@
#include "server.h"
#include "linux-low.h"
#include "arch/arm.h"
+#include "linux-aarch32-low.h"
+#include <sys/uio.h>
/* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
On Bionic elf.h and linux/elf.h have conflicting definitions. */
#ifndef ELFMAG0
@@ -35,15 +37,6 @@ extern const struct target_desc *tdesc_arm;
void init_registers_arm_with_iwmmxt (void);
extern const struct target_desc *tdesc_arm_with_iwmmxt;
-void init_registers_arm_with_vfpv2 (void);
-extern const struct target_desc *tdesc_arm_with_vfpv2;
-
-void init_registers_arm_with_vfpv3 (void);
-extern const struct target_desc *tdesc_arm_with_vfpv3;
-
-void init_registers_arm_with_neon (void);
-extern const struct target_desc *tdesc_arm_with_neon;
-
#ifndef PTRACE_GET_THREAD_AREA
#define PTRACE_GET_THREAD_AREA 22
#endif
@@ -150,35 +143,6 @@ arm_cannot_fetch_register (int regno)
}
static void
-arm_fill_gregset (struct regcache *regcache, void *buf)
-{
- int i;
- uint32_t *regs = buf;
-
- for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
- collect_register (regcache, i, ®s[i]);
-
- collect_register (regcache, ARM_PS_REGNUM, ®s[16]);
-}
-
-static void
-arm_store_gregset (struct regcache *regcache, const void *buf)
-{
- int i;
- char zerobuf[8];
- const uint32_t *regs = buf;
-
- memset (zerobuf, 0, 8);
- for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
- supply_register (regcache, i, ®s[i]);
-
- for (; i < ARM_PS_REGNUM; i++)
- supply_register (regcache, i, zerobuf);
-
- supply_register (regcache, ARM_PS_REGNUM, ®s[16]);
-}
-
-static void
arm_fill_wmmxregset (struct regcache *regcache, void *buf)
{
int i;
@@ -212,46 +176,6 @@ arm_store_wmmxregset (struct regcache *regcache, const void *buf)
(char *) buf + 16 * 8 + i * 4);
}
-static void
-arm_fill_vfpregset (struct regcache *regcache, void *buf)
-{
- int i, num, base;
-
- if (regcache->tdesc == tdesc_arm_with_neon
- || regcache->tdesc == tdesc_arm_with_vfpv3)
- num = 32;
- else if (regcache->tdesc == tdesc_arm_with_vfpv2)
- num = 16;
- else
- return;
-
- base = find_regno (regcache->tdesc, "d0");
- for (i = 0; i < num; i++)
- collect_register (regcache, base + i, (char *) buf + i * 8);
-
- collect_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
-}
-
-static void
-arm_store_vfpregset (struct regcache *regcache, const void *buf)
-{
- int i, num, base;
-
- if (regcache->tdesc == tdesc_arm_with_neon
- || regcache->tdesc == tdesc_arm_with_vfpv3)
- num = 32;
- else if (regcache->tdesc == tdesc_arm_with_vfpv2)
- num = 16;
- else
- return;
-
- base = find_regno (regcache->tdesc, "d0");
- for (i = 0; i < num; i++)
- supply_register (regcache, base + i, (char *) buf + i * 8);
-
- supply_register_by_name (regcache, "fpscr", (char *) buf + 32 * 8);
-}
-
extern int debug_threads;
static CORE_ADDR
@@ -888,9 +812,24 @@ arm_read_description (void)
static void
arm_arch_setup (void)
{
+ int tid = lwpid_of (current_thread);
+ int gpregs[18];
+ struct iovec iov;
+
current_process ()->tdesc = arm_read_description ();
+
+ iov.iov_base = gpregs;
+ iov.iov_len = sizeof (gpregs);
+
+ /* Check if PTRACE_GETREGSET works. */
+ if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov) == 0)
+ have_ptrace_getregset = 1;
+ else
+ have_ptrace_getregset = 0;
}
+/* Register sets without using PTRACE_GETREGSET. */
+
static struct regset_info arm_regsets[] = {
{ PTRACE_GETREGS, PTRACE_SETREGS, 0, 18 * 4,
GENERAL_REGS,
@@ -917,7 +856,7 @@ static struct usrregs_info arm_usrregs_info =
arm_regmap,
};
-static struct regs_info regs_info =
+static struct regs_info regs_info_arm =
{
NULL, /* regset_bitmap */
&arm_usrregs_info,
@@ -927,7 +866,11 @@ static struct regs_info regs_info =
static const struct regs_info *
arm_regs_info (void)
{
- return ®s_info;
+ if (have_ptrace_getregset == 1
+ && current_process ()->tdesc != tdesc_arm_with_iwmmxt)
+ return ®s_info_aarch32;
+ else
+ return ®s_info_arm;
}
struct linux_target_ops the_low_target = {
@@ -973,9 +916,8 @@ initialize_low_arch (void)
/* Initialize the Linux target descriptions. */
init_registers_arm ();
init_registers_arm_with_iwmmxt ();
- init_registers_arm_with_vfpv2 ();
- init_registers_arm_with_vfpv3 ();
- init_registers_arm_with_neon ();
+
+ initialize_low_arch_aarch32 ();
initialize_regsets_info (&arm_regsets_info);
}
--
1.9.1