aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/linux-arm-low.c
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2015-08-04 14:34:14 +0100
committerYao Qi <yao.qi@linaro.org>2015-08-04 14:34:14 +0100
commitbd9e6534b7be7a228ce339bced963d2d15856390 (patch)
tree235c3cbcddc0c69bf7be0d341360c860479607b1 /gdb/gdbserver/linux-arm-low.c
parentded48a5ef34314f7af698b7ec7916b084c94b18d (diff)
downloadfsf-binutils-gdb-bd9e6534b7be7a228ce339bced963d2d15856390.zip
fsf-binutils-gdb-bd9e6534b7be7a228ce339bced963d2d15856390.tar.gz
fsf-binutils-gdb-bd9e6534b7be7a228ce339bced963d2d15856390.tar.bz2
New regs_info for aarch32
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-08-04 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): Likewise. (arm_fill_vfpregset): Call arm_fill_vfpregset_num (arm_store_vfpregset): Caa arm_store_vfpregset_num. (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 is arm_with_neon or arm_with_vfpv3. (initialize_low_arch): Don't call init_registers_arm_with_neon. Call initialize_low_arch_aarch32 instead.
Diffstat (limited to 'gdb/gdbserver/linux-arm-low.c')
-rw-r--r--gdb/gdbserver/linux-arm-low.c78
1 files changed, 31 insertions, 47 deletions
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index 3c5956b..6a27e6e 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
@@ -41,9 +43,6 @@ 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 +149,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, &regs[i]);
-
- collect_register (regcache, ARM_PS_REGNUM, &regs[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, &regs[i]);
-
- for (; i < ARM_PS_REGNUM; i++)
- supply_register (regcache, i, zerobuf);
-
- supply_register (regcache, ARM_PS_REGNUM, &regs[16]);
-}
-
-static void
arm_fill_wmmxregset (struct regcache *regcache, void *buf)
{
int i;
@@ -215,7 +185,7 @@ arm_store_wmmxregset (struct regcache *regcache, const void *buf)
static void
arm_fill_vfpregset (struct regcache *regcache, void *buf)
{
- int i, num, base;
+ int num;
if (regcache->tdesc == tdesc_arm_with_neon
|| regcache->tdesc == tdesc_arm_with_vfpv3)
@@ -225,17 +195,13 @@ arm_fill_vfpregset (struct regcache *regcache, void *buf)
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);
+ arm_fill_vfpregset_num (regcache, buf, num);
}
static void
arm_store_vfpregset (struct regcache *regcache, const void *buf)
{
- int i, num, base;
+ int num;
if (regcache->tdesc == tdesc_arm_with_neon
|| regcache->tdesc == tdesc_arm_with_vfpv3)
@@ -245,11 +211,7 @@ arm_store_vfpregset (struct regcache *regcache, const void *buf)
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);
+ arm_store_vfpregset_num (regcache, buf, num);
}
extern int debug_threads;
@@ -888,9 +850,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 +894,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 +904,13 @@ static struct regs_info regs_info =
static const struct regs_info *
arm_regs_info (void)
{
- return &regs_info;
+ const struct target_desc *tdesc = current_process ()->tdesc;
+
+ if (have_ptrace_getregset == 1
+ && (tdesc == tdesc_arm_with_neon || tdesc == tdesc_arm_with_vfpv3))
+ return &regs_info_aarch32;
+ else
+ return &regs_info_arm;
}
struct linux_target_ops the_low_target = {
@@ -975,7 +958,8 @@ initialize_low_arch (void)
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);
}