diff options
author | Yao Qi <yao.qi@linaro.org> | 2015-08-04 14:34:14 +0100 |
---|---|---|
committer | Yao Qi <yao.qi@linaro.org> | 2015-08-04 14:34:14 +0100 |
commit | bd9e6534b7be7a228ce339bced963d2d15856390 (patch) | |
tree | 235c3cbcddc0c69bf7be0d341360c860479607b1 /gdb/gdbserver | |
parent | ded48a5ef34314f7af698b7ec7916b084c94b18d (diff) | |
download | gdb-bd9e6534b7be7a228ce339bced963d2d15856390.zip gdb-bd9e6534b7be7a228ce339bced963d2d15856390.tar.gz 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')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 18 | ||||
-rw-r--r-- | gdb/gdbserver/configure.srv | 1 | ||||
-rw-r--r-- | gdb/gdbserver/linux-aarch32-low.c | 140 | ||||
-rw-r--r-- | gdb/gdbserver/linux-aarch32-low.h | 29 | ||||
-rw-r--r-- | gdb/gdbserver/linux-arm-low.c | 78 |
5 files changed, 219 insertions, 47 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index f653d77..0ed70a2 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,23 @@ 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): Call 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. + +2015-08-04 Yao Qi <yao.qi@linaro.org> + * linux-x86-low.c (have_ptrace_getregset): Move it to ... * linux-low.c: ... here. * linux-low.h (have_ptrace_getregset): Declare it. 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..7f3b985 --- /dev/null +++ b/gdb/gdbserver/linux-aarch32-low.c @@ -0,0 +1,140 @@ +/* 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 NUM number of VFP registers from REGCACHE to buffer BUF. */ + +void +arm_fill_vfpregset_num (struct regcache *regcache, void *buf, int num) +{ + int i, base; + + gdb_assert (num == 16 || num == 32); + + 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 NUM number of VFP registers contents, stored in BUF, to + REGCACHE. */ + +void +arm_store_vfpregset_num (struct regcache *regcache, const void *buf, int num) +{ + int i, base; + + gdb_assert (num == 16 || num == 32); + + 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); +} + +static void +arm_fill_vfpregset (struct regcache *regcache, void *buf) +{ + arm_fill_vfpregset_num (regcache, buf, 32); +} + +static void +arm_store_vfpregset (struct regcache *regcache, const void *buf) +{ + arm_store_vfpregset_num (regcache, buf, 32); +} + +/* 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_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..6682f0a --- /dev/null +++ b/gdb/gdbserver/linux-aarch32-low.h @@ -0,0 +1,29 @@ +/* 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_num (struct regcache *regcache, void *buf, int num); +void arm_store_vfpregset_num (struct regcache *regcache, const void *buf, + int num); + +void initialize_low_arch_aarch32 (void); + +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..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, ®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; @@ -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 ®s_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 ®s_info_aarch32; + else + return ®s_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); } |