From 7cc17433020a62935e4d91053251fe900d83c7f0 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Fri, 19 Jul 2019 15:04:48 +0100 Subject: [PATCH] Arm: Use read_description funcs in gdbserver Switch gdbserver over to using feature target descriptions. Add a function for determining the type of a given target description, and use where required. gdb/gdbserver/ChangeLog: * configure.srv: Add new files. Remove xml generated files. * linux-aarch32-low.c (initialize_low_arch_aarch32): Don't init registers. * linux-aarch32-low.h (tdesc_arm_with_neon): Remove. * linux-aarch32-tdesc.c: New file. * linux-aarch32-tdesc.h: New file. * linux-aarch64-low.c (aarch64_arch_setup): Call aarch32_linux_read_description. * linux-arm-low.c (init_registers_arm, tdesc_arm) (init_registers_arm_with_iwmmxt, tdesc_arm_with_iwmmxt) (init_registers_arm_with_vfpv2, tdesc_arm_with_vfpv2) (init_registers_arm_with_vfpv3, tdesc_arm_with_vfpv3): Remove. (arm_fill_wmmxregset, arm_store_wmmxregset, arm_fill_vfpregset) (arm_store_vfpregset): Call arm_linux_get_tdesc_fp_type. (arm_read_description): Call arm_linux_read_description. (initialize_low_arch): Don't init registers. * linux-arm-tdesc.c: New file. * linux-arm-tdesc.h: New file. --- gdb/gdbserver/ChangeLog | 20 ++++++++ gdb/gdbserver/configure.srv | 14 +++--- gdb/gdbserver/linux-aarch32-low.c | 2 - gdb/gdbserver/linux-aarch32-low.h | 2 - gdb/gdbserver/linux-aarch32-tdesc.c | 47 ++++++++++++++++++ gdb/gdbserver/linux-aarch32-tdesc.h | 29 +++++++++++ gdb/gdbserver/linux-aarch64-low.c | 3 +- gdb/gdbserver/linux-arm-low.c | 77 ++++++++++++++--------------- gdb/gdbserver/linux-arm-tdesc.c | 62 +++++++++++++++++++++++ gdb/gdbserver/linux-arm-tdesc.h | 29 +++++++++++ 10 files changed, 232 insertions(+), 53 deletions(-) create mode 100644 gdb/gdbserver/linux-aarch32-tdesc.c create mode 100644 gdb/gdbserver/linux-aarch32-tdesc.h create mode 100644 gdb/gdbserver/linux-arm-tdesc.c create mode 100644 gdb/gdbserver/linux-arm-tdesc.h diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 51aaa77ce1..3fb691c6a1 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,23 @@ +2019-07-19 Alan Hayward + + * configure.srv: Add new files. Remove xml generated files. + * linux-aarch32-low.c (initialize_low_arch_aarch32): Don't init + registers. + * linux-aarch32-low.h (tdesc_arm_with_neon): Remove. + * linux-aarch32-tdesc.c: New file. + * linux-aarch32-tdesc.h: New file. + * linux-aarch64-low.c (aarch64_arch_setup): Call aarch32_linux_read_description. + * linux-arm-low.c (init_registers_arm, tdesc_arm) + (init_registers_arm_with_iwmmxt, tdesc_arm_with_iwmmxt) + (init_registers_arm_with_vfpv2, tdesc_arm_with_vfpv2) + (init_registers_arm_with_vfpv3, tdesc_arm_with_vfpv3): Remove. + (arm_fill_wmmxregset, arm_store_wmmxregset, arm_fill_vfpregset) + (arm_store_vfpregset): Call arm_linux_get_tdesc_fp_type. + (arm_read_description): Call arm_linux_read_description. + (initialize_low_arch): Don't init registers. + * linux-arm-tdesc.c: New file. + * linux-arm-tdesc.h: New file. + 2019-07-10 Alan Hayward * linux-arm-low.c (arm_fill_wmmxregset, arm_store_wmmxregset): diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index c20177ef18..097dc4e9db 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -33,9 +33,10 @@ srv_linux_obj="linux-low.o linux-osdata.o linux-procfs.o linux-ptrace.o linux-wa # Input is taken from the "${target}" variable. case "${target}" in - aarch64*-*-linux*) srv_regobj="arm-with-neon.o" - srv_tgtobj="linux-aarch64-low.o aarch64-linux-hw-point.o" + aarch64*-*-linux*) srv_tgtobj="linux-aarch64-low.o aarch64-linux-hw-point.o" srv_tgtobj="$srv_tgtobj linux-aarch32-low.o" + srv_tgtobj="$srv_tgtobj linux-aarch32-tdesc.o" + srv_tgtobj="${srv_tgtobj} arch/aarch32.o" srv_tgtobj="${srv_tgtobj} arch/arm.o" srv_tgtobj="$srv_tgtobj aarch64-linux.o" srv_tgtobj="$srv_tgtobj arch/aarch64-insn.o" @@ -49,12 +50,11 @@ case "${target}" in ipa_obj="${ipa_obj} linux-aarch64-tdesc-ipa.o" ipa_obj="${ipa_obj} arch/aarch64-ipa.o" ;; - arm*-*-linux*) srv_regobj="reg-arm.o arm-with-iwmmxt.o" - srv_regobj="${srv_regobj} arm-with-vfpv2.o" - 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" + arm*-*-linux*) srv_tgtobj="$srv_linux_obj linux-arm-low.o" + srv_tgtobj="$srv_tgtobj linux-arm-tdesc.o" srv_tgtobj="$srv_tgtobj linux-aarch32-low.o" + srv_tgtobj="$srv_tgtobj linux-aarch32-tdesc.o" + srv_tgtobj="${srv_tgtobj} arch/aarch32.o" srv_tgtobj="${srv_tgtobj} arch/arm.o" srv_tgtobj="${srv_tgtobj} arch/arm-linux.o" srv_tgtobj="${srv_tgtobj} arch/arm-get-next-pcs.o" diff --git a/gdb/gdbserver/linux-aarch32-low.c b/gdb/gdbserver/linux-aarch32-low.c index a932373518..f1f2ae02a4 100644 --- a/gdb/gdbserver/linux-aarch32-low.c +++ b/gdb/gdbserver/linux-aarch32-low.c @@ -299,7 +299,5 @@ arm_breakpoint_kind_from_current_state (CORE_ADDR *pcptr) 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 index 44e626c719..3078fca35e 100644 --- a/gdb/gdbserver/linux-aarch32-low.h +++ b/gdb/gdbserver/linux-aarch32-low.h @@ -36,6 +36,4 @@ void initialize_low_arch_aarch32 (void); void init_registers_arm_with_neon (void); int arm_is_thumb_mode (void); -extern const struct target_desc *tdesc_arm_with_neon; - #endif /* GDBSERVER_LINUX_AARCH32_LOW_H */ diff --git a/gdb/gdbserver/linux-aarch32-tdesc.c b/gdb/gdbserver/linux-aarch32-tdesc.c new file mode 100644 index 0000000000..c1d8949bd4 --- /dev/null +++ b/gdb/gdbserver/linux-aarch32-tdesc.c @@ -0,0 +1,47 @@ +/* Copyright (C) 2019 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 "tdesc.h" +#include "arch/aarch32.h" +#include + +static struct target_desc *tdesc_aarch32; + +/* See linux-aarch32-tdesc.h. */ + +const target_desc * +aarch32_linux_read_description () +{ + if (tdesc_aarch32 == nullptr) + { + tdesc_aarch32 = aarch32_create_target_description (); + + static const char *expedite_regs[] = { "r11", "sp", "pc", 0 }; + init_target_desc (tdesc_aarch32, expedite_regs); + } + return tdesc_aarch32; +} + +/* See linux-aarch32-tdesc.h. */ + +bool +is_aarch32_linux_description (const target_desc *tdesc) +{ + gdb_assert (tdesc != nullptr); + return tdesc == tdesc_aarch32; +} diff --git a/gdb/gdbserver/linux-aarch32-tdesc.h b/gdb/gdbserver/linux-aarch32-tdesc.h new file mode 100644 index 0000000000..8887cbfdf4 --- /dev/null +++ b/gdb/gdbserver/linux-aarch32-tdesc.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2019 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 . */ + +#ifndef GDBSERVER_LINUX_AARCH32_TDESC_H +#define GDBSERVER_LINUX_AARCH32_TDESC_H + +/* Return the AArch32 target description. */ + +const target_desc * aarch32_linux_read_description (); + +/* Return true if TDESC is the AArch32 target description. */ + +bool is_aarch32_linux_description (const target_desc *tdesc); + +#endif /* linux-aarch32-tdesc.h. */ diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c index 5aea5de372..ab2f40ea98 100644 --- a/gdb/gdbserver/linux-aarch64-low.c +++ b/gdb/gdbserver/linux-aarch64-low.c @@ -39,6 +39,7 @@ #include "gdb_proc_service.h" #include "arch/aarch64.h" +#include "linux-aarch32-tdesc.h" #include "linux-aarch64-tdesc.h" #include "nat/aarch64-sve-linux-ptrace.h" #include "tdesc.h" @@ -527,7 +528,7 @@ aarch64_arch_setup (void) current_process ()->tdesc = aarch64_linux_read_description (vq, pauth_p); } else - current_process ()->tdesc = tdesc_arm_with_neon; + current_process ()->tdesc = aarch32_linux_read_description (); aarch64_linux_get_debug_reg_capacity (lwpid_of (current_thread)); } diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c index 7d6c9d9dd9..0e30af3562 100644 --- a/gdb/gdbserver/linux-arm-low.c +++ b/gdb/gdbserver/linux-arm-low.c @@ -22,6 +22,8 @@ #include "arch/arm-linux.h" #include "arch/arm-get-next-pcs.h" #include "linux-aarch32-low.h" +#include "linux-aarch32-tdesc.h" +#include "linux-arm-tdesc.h" #include /* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h. @@ -33,19 +35,6 @@ #include #include -/* Defined in auto-generated files. */ -void init_registers_arm (void); -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; - #ifndef PTRACE_GET_THREAD_AREA #define PTRACE_GET_THREAD_AREA 22 #endif @@ -175,7 +164,7 @@ arm_cannot_fetch_register (int regno) static void arm_fill_wmmxregset (struct regcache *regcache, void *buf) { - if (regcache->tdesc != tdesc_arm_with_iwmmxt) + if (arm_linux_get_tdesc_fp_type (regcache->tdesc) != ARM_FP_TYPE_IWMMXT) return; for (int i = 0; i < 16; i++) @@ -190,7 +179,7 @@ arm_fill_wmmxregset (struct regcache *regcache, void *buf) static void arm_store_wmmxregset (struct regcache *regcache, const void *buf) { - if (regcache->tdesc != tdesc_arm_with_iwmmxt) + if (arm_linux_get_tdesc_fp_type (regcache->tdesc) != ARM_FP_TYPE_IWMMXT) return; for (int i = 0; i < 16; i++) @@ -207,13 +196,19 @@ arm_fill_vfpregset (struct regcache *regcache, void *buf) { int num; - if (regcache->tdesc == tdesc_arm_with_neon - || regcache->tdesc == tdesc_arm_with_vfpv3) + if (is_aarch32_linux_description (regcache->tdesc)) num = 32; - else if (regcache->tdesc == tdesc_arm_with_vfpv2) - num = 16; else - return; + { + arm_fp_type fp_type = arm_linux_get_tdesc_fp_type (regcache->tdesc); + + if (fp_type == ARM_FP_TYPE_VFPV3) + num = 32; + else if (fp_type == ARM_FP_TYPE_VFPV2) + num = 16; + else + return; + } arm_fill_vfpregset_num (regcache, buf, num); } @@ -230,13 +225,19 @@ arm_store_vfpregset (struct regcache *regcache, const void *buf) { int num; - if (regcache->tdesc == tdesc_arm_with_neon - || regcache->tdesc == tdesc_arm_with_vfpv3) + if (is_aarch32_linux_description (regcache->tdesc)) num = 32; - else if (regcache->tdesc == tdesc_arm_with_vfpv2) - num = 16; else - return; + { + arm_fp_type fp_type = arm_linux_get_tdesc_fp_type (regcache->tdesc); + + if (fp_type == ARM_FP_TYPE_VFPV3) + num = 32; + else if (fp_type == ARM_FP_TYPE_VFPV2) + num = 16; + else + return; + } arm_store_vfpregset_num (regcache, buf, num); } @@ -849,7 +850,7 @@ arm_read_description (void) unsigned long arm_hwcap = linux_get_hwcap (4); if (arm_hwcap & HWCAP_IWMMXT) - return tdesc_arm_with_iwmmxt; + return arm_linux_read_description (ARM_FP_TYPE_IWMMXT); if (arm_hwcap & HWCAP_VFP) { @@ -859,21 +860,21 @@ arm_read_description (void) errno = 0; char *buf = (char *) alloca (ARM_VFP3_REGS_SIZE); if (ptrace (PTRACE_GETVFPREGS, pid, 0, buf) < 0 && errno == EIO) - return tdesc_arm; + return arm_linux_read_description (ARM_FP_TYPE_NONE); /* NEON implies either no VFP, or VFPv3-D32. We only support it with VFP. */ if (arm_hwcap & HWCAP_NEON) - return tdesc_arm_with_neon; + return aarch32_linux_read_description (); else if ((arm_hwcap & (HWCAP_VFPv3 | HWCAP_VFPv3D16)) == HWCAP_VFPv3) - return tdesc_arm_with_vfpv3; + return arm_linux_read_description (ARM_FP_TYPE_VFPV3); else - return tdesc_arm_with_vfpv2; + return arm_linux_read_description (ARM_FP_TYPE_VFPV2); } /* The default configuration uses legacy FPA registers, probably simulated. */ - return tdesc_arm; + return arm_linux_read_description (ARM_FP_TYPE_NONE); } static void @@ -997,10 +998,11 @@ arm_regs_info (void) const struct target_desc *tdesc = current_process ()->tdesc; if (have_ptrace_getregset == 1 - && (tdesc == tdesc_arm_with_neon || tdesc == tdesc_arm_with_vfpv3)) + && (is_aarch32_linux_description (tdesc) + || arm_linux_get_tdesc_fp_type (tdesc) == ARM_FP_TYPE_VFPV3)) return ®s_info_aarch32; - else - return ®s_info_arm; + + return ®s_info_arm; } struct linux_target_ops the_low_target = { @@ -1045,13 +1047,6 @@ struct linux_target_ops the_low_target = { void 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 (); - initialize_low_arch_aarch32 (); - initialize_regsets_info (&arm_regsets_info); } diff --git a/gdb/gdbserver/linux-arm-tdesc.c b/gdb/gdbserver/linux-arm-tdesc.c new file mode 100644 index 0000000000..cdc4dab87a --- /dev/null +++ b/gdb/gdbserver/linux-arm-tdesc.c @@ -0,0 +1,62 @@ +/* Copyright (C) 2019 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 "tdesc.h" +#include "arch/arm.h" +#include + +/* All possible Arm target descriptors. */ +static struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID]; + +/* See linux-arm-tdesc.h. */ + +const target_desc * +arm_linux_read_description (arm_fp_type fp_type) +{ + struct target_desc *tdesc = tdesc_arm_list[fp_type]; + + if (tdesc == nullptr) + { + tdesc = arm_create_target_description (fp_type); + + static const char *expedite_regs[] = { "r11", "sp", "pc", 0 }; + init_target_desc (tdesc, expedite_regs); + + tdesc_arm_list[fp_type] = tdesc; + } + + return tdesc; +} + +/* See linux-arm-tdesc.h. */ + +arm_fp_type +arm_linux_get_tdesc_fp_type (const target_desc *tdesc) +{ + gdb_assert (tdesc != nullptr); + + /* Many of the tdesc_arm_list entries may not have been initialised yet. This + is ok, because tdesc must be one of the initialised ones. */ + for (int i = ARM_FP_TYPE_NONE; i < ARM_FP_TYPE_INVALID; i++) + { + if (tdesc == tdesc_arm_list[i]) + return (arm_fp_type) i; + } + + return ARM_FP_TYPE_INVALID; +} diff --git a/gdb/gdbserver/linux-arm-tdesc.h b/gdb/gdbserver/linux-arm-tdesc.h new file mode 100644 index 0000000000..51efb9fb48 --- /dev/null +++ b/gdb/gdbserver/linux-arm-tdesc.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2019 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 . */ + +#ifndef GDBSERVER_LINUX_ARM_TDESC_H +#define GDBSERVER_LINUX_ARM_TDESC_H + +/* Return the Arm target description with fp registers FP_TYPE. */ + +const target_desc * arm_linux_read_description (arm_fp_type fp_type); + +/* For a target description TDESC, return its fp type. */ + +arm_fp_type arm_linux_get_tdesc_fp_type (const target_desc *tdesc); + +#endif /* linux-arm-tdesc.h. */ -- 2.34.1