[6/7] Arm: Use read_description funcs in gdbserver
Commit Message
Switch gdbserver over to using feature target descriptions.
Add a function for determining the type of a given target description,
and use where required.
2019-07-05 Alan Hayward <alan.hayward@arm.com>
* 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/configure.srv | 14 +++---
gdb/gdbserver/linux-aarch32-low.c | 2 -
gdb/gdbserver/linux-aarch32-low.h | 2 -
gdb/gdbserver/linux-aarch32-tdesc.c | 46 +++++++++++++++++
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 +++++++++++
9 files changed, 211 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
Comments
> diff --git a/gdb/gdbserver/linux-aarch32-tdesc.c b/gdb/gdbserver/linux-aarch32-tdesc.c
> new file mode 100644
> index 0000000000..6f0e8c9aa9
> --- /dev/null
> +++ b/gdb/gdbserver/linux-aarch32-tdesc.c
> @@ -0,0 +1,46 @@
> +/* 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 <http://www.gnu.org/licenses/>. */
> +
> +#include "server.h"
> +#include "tdesc.h"
> +#include "arch/aarch32.h"
> +#include <inttypes.h>
> +
> +struct target_desc *tdesc_aarch32;
static
> diff --git a/gdb/gdbserver/linux-arm-tdesc.c b/gdb/gdbserver/linux-arm-tdesc.c
> new file mode 100644
> index 0000000000..fa54e48592
> --- /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 <http://www.gnu.org/licenses/>. */
> +
> +#include "server.h"
> +#include "tdesc.h"
> +#include "arch/arm.h"
> +#include <inttypes.h>
> +
> +/* All possible Arm target descriptors. */
> +struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID];
static
> +
> +/* 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)
Return type on its own line.
> +{
> + if (tdesc == nullptr)
> + return ARM_FP_TYPE_INVALID;
Can this (tdesc == nullptr) actually happen? If you expect it's not possible,
don't hesitate to use a gdb_assert instead. It helps catch bugs and acts as
some kind of self-documentation of the allowed values.
> +
> + /* 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_VFPV2; i < ARM_FP_TYPE_INVALID; i++)
Is it intended here that you skip ARM_FP_TYPE_NONE? Why?
Simon
> On 10 Jul 2019, at 05:04, Simon Marchi <simark@simark.ca> wrote:
>
>> diff --git a/gdb/gdbserver/linux-aarch32-tdesc.c b/gdb/gdbserver/linux-aarch32-tdesc.c
>> new file mode 100644
>> index 0000000000..6f0e8c9aa9
>> --- /dev/null
>> +++ b/gdb/gdbserver/linux-aarch32-tdesc.c
>> @@ -0,0 +1,46 @@
>> +/* 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 <http://www.gnu.org/licenses/>. */
>> +
>> +#include "server.h"
>> +#include "tdesc.h"
>> +#include "arch/aarch32.h"
>> +#include <inttypes.h>
>> +
>> +struct target_desc *tdesc_aarch32;
>
> static
Done.
>
>> diff --git a/gdb/gdbserver/linux-arm-tdesc.c b/gdb/gdbserver/linux-arm-tdesc.c
>> new file mode 100644
>> index 0000000000..fa54e48592
>> --- /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 <http://www.gnu.org/licenses/>. */
>> +
>> +#include "server.h"
>> +#include "tdesc.h"
>> +#include "arch/arm.h"
>> +#include <inttypes.h>
>> +
>> +/* All possible Arm target descriptors. */
>> +struct target_desc *tdesc_arm_list[ARM_FP_TYPE_INVALID];
>
> static
Done.
>
>> +
>> +/* 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)
>
> Return type on its own line.
Done.
>
>> +{
>> + if (tdesc == nullptr)
>> + return ARM_FP_TYPE_INVALID;
>
> Can this (tdesc == nullptr) actually happen? If you expect it's not possible,
> don't hesitate to use a gdb_assert instead. It helps catch bugs and acts as
> some kind of self-documentation of the allowed values.
It would mean that regcache->tdesc was null, which as far as I can tell is not
possible. There are no fails when testing either.
I’ll switch to gdb_assert.
>
>> +
>> + /* 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_VFPV2; i < ARM_FP_TYPE_INVALID; i++)
>
> Is it intended here that you skip ARM_FP_TYPE_NONE? Why?
My mistake. An earlier version didn’t have ARM_FP_TYPE_NONE, and I missed this.
Fixed to start with ARM_FP_TYPE_NONE.
>
> Simon
>
@@ -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"
@@ -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);
}
@@ -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 */
new file mode 100644
@@ -0,0 +1,46 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#include "server.h"
+#include "tdesc.h"
+#include "arch/aarch32.h"
+#include <inttypes.h>
+
+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)
+{
+ return tdesc != nullptr && tdesc == tdesc_aarch32;
+}
new file mode 100644
@@ -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 <http://www.gnu.org/licenses/>. */
+
+#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. */
@@ -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));
}
@@ -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 <sys/uio.h>
/* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h.
@@ -33,19 +35,6 @@
#include <signal.h>
#include <sys/syscall.h>
-/* 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);
}
new file mode 100644
@@ -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 <http://www.gnu.org/licenses/>. */
+
+#include "server.h"
+#include "tdesc.h"
+#include "arch/arm.h"
+#include <inttypes.h>
+
+/* All possible Arm target descriptors. */
+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)
+{
+ if (tdesc == nullptr)
+ return ARM_FP_TYPE_INVALID;
+
+ /* 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_VFPV2; i < ARM_FP_TYPE_INVALID; i++)
+ {
+ if (tdesc == tdesc_arm_list[i])
+ return (arm_fp_type) i;
+ }
+
+ return ARM_FP_TYPE_INVALID;
+}
new file mode 100644
@@ -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 <http://www.gnu.org/licenses/>. */
+
+#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. */