From patchwork Fri Jul 31 15:16:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 7957 Received: (qmail 56671 invoked by alias); 31 Jul 2015 15:17:00 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 56567 invoked by uid 89); 31 Jul 2015 15:16:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f182.google.com Received: from mail-pd0-f182.google.com (HELO mail-pd0-f182.google.com) (209.85.192.182) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 31 Jul 2015 15:16:57 +0000 Received: by pdbbh15 with SMTP id bh15so44066283pdb.1 for ; Fri, 31 Jul 2015 08:16:55 -0700 (PDT) X-Received: by 10.70.123.37 with SMTP id lx5mr8096759pdb.158.1438355815445; Fri, 31 Jul 2015 08:16:55 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id pd10sm8253798pdb.66.2015.07.31.08.16.53 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 31 Jul 2015 08:16:54 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 2/7] New regs_info for aarch32 Date: Fri, 31 Jul 2015 16:16:36 +0100 Message-Id: <1438355801-25798-3-git-send-email-yao.qi@linaro.org> In-Reply-To: <1438355801-25798-1-git-send-email-yao.qi@linaro.org> References: <1438355801-25798-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes 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 * 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 . */ + +#include "server.h" +#include "arch/arm.h" +#include "linux-low.h" +#include "linux-aarch32-low.h" + +#include +/* 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 +#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 . */ + +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 /* 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); }