[3/7] Use arm target description and regs_info for 32-bit file on aarch64 GDBserver
Commit Message
This patch teaches aarch64-linux GDBserver use 32-bit arm target
description and regs_info if the elf file is 32-bit.
gdb/gdbserver:
2015-07-31 Yao Qi <yao.qi@linaro.org>
* configure.srv (case aarch64*-*-linux*): Append arm-with-neon.o
to srv_regobj and append arm-core.xml arm-vfpv3.xml and
arm-with-neon.xml to srv_xmlfiles.
* linux-aarch32-low.c (arm_fill_vfpregset) [__aarch64__]: Add
assert and set num to 32.
(arm_store_vfpregset) [__aarch64__]: Likewise.
(initialize_low_arch_aarch32) [!__aarch64__] Call
init_registers_arm_with_vfpv2 and
init_registers_arm_with_vfpv3.
* linux-aarch32-low.h [!__aarch64__]: Declare
init_registers_arm_with_vfpv2, tdesc_arm_with_vfpv2,
init_registers_arm_with_vfpv3 and tdesc_arm_with_vfpv3.
* linux-aarch64-low.c: Include linux-aarch32-low.h.
(is_64bit_tdesc): New function.
(tdesc_arm_with_neon): Declare
(aarch64_linux_read_description): New function.
(aarch64_arch_setup): Call aarch64_linux_read_description.
(regs_info): Rename to regs_info_aarch64.
(aarch64_regs_info): Return right regs_info.
(initialize_low_arch): Call initialize_low_arch_aarch32.
---
gdb/gdbserver/configure.srv | 4 ++++
gdb/gdbserver/linux-aarch32-low.c | 13 +++++++++++-
gdb/gdbserver/linux-aarch32-low.h | 4 ++++
gdb/gdbserver/linux-aarch64-low.c | 42 ++++++++++++++++++++++++++++++++++++---
4 files changed, 59 insertions(+), 4 deletions(-)
@@ -49,11 +49,15 @@ srv_linux_obj="linux-low.o linux-osdata.o linux-procfs.o linux-ptrace.o linux-wa
case "${target}" in
aarch64*-*-linux*)
srv_regobj="aarch64.o"
+ srv_regobj="${srv_regobj} arm-with-neon.o"
srv_tgtobj="linux-aarch64-low.o aarch64-linux-hw-point.o"
+ srv_tgtobj="$srv_tgtobj linux-aarch32-low.o"
srv_tgtobj="${srv_tgtobj} $srv_linux_obj"
srv_xmlfiles="aarch64.xml"
srv_xmlfiles="${srv_xmlfiles} aarch64-core.xml"
srv_xmlfiles="${srv_xmlfiles} aarch64-fpu.xml"
+ srv_xmlfiles="${srv_xmlfiles} arm-core.xml arm-vfpv3.xml"
+ srv_xmlfiles="${srv_xmlfiles} arm-with-neon.xml"
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
@@ -67,6 +67,10 @@ arm_fill_vfpregset (struct regcache *regcache, void *buf)
{
int i, num, base;
+#ifdef __aarch64__
+ gdb_assert (regcache->tdesc == tdesc_arm_with_neon);
+ num = 32;
+#else
if (regcache->tdesc == tdesc_arm_with_neon
|| regcache->tdesc == tdesc_arm_with_vfpv3)
num = 32;
@@ -74,6 +78,7 @@ arm_fill_vfpregset (struct regcache *regcache, void *buf)
num = 16;
else
return;
+#endif
base = find_regno (regcache->tdesc, "d0");
for (i = 0; i < num; i++)
@@ -88,7 +93,10 @@ void
arm_store_vfpregset (struct regcache *regcache, const void *buf)
{
int i, num, base;
-
+#ifdef __aarch64__
+ gdb_assert (regcache->tdesc == tdesc_arm_with_neon);
+ num = 32;
+#else
if (regcache->tdesc == tdesc_arm_with_neon
|| regcache->tdesc == tdesc_arm_with_vfpv3)
num = 32;
@@ -96,6 +104,7 @@ arm_store_vfpregset (struct regcache *regcache, const void *buf)
num = 16;
else
return;
+#endif
base = find_regno (regcache->tdesc, "d0");
for (i = 0; i < num; i++)
@@ -133,8 +142,10 @@ struct regs_info regs_info_aarch32 =
void
initialize_low_arch_aarch32 (void)
{
+#ifndef __aarch64__
init_registers_arm_with_vfpv2 ();
init_registers_arm_with_vfpv3 ();
+#endif
init_registers_arm_with_neon ();
initialize_regsets_info (&aarch32_regsets_info);
@@ -24,9 +24,13 @@ void arm_store_vfpregset (struct regcache *regcache, const void *buf);
void initialize_low_arch_aarch32 (void);
+#ifndef __aarch64__
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;
+#endif
+
void init_registers_arm_with_neon (void);
extern const struct target_desc *tdesc_arm_with_neon;
@@ -22,6 +22,7 @@
#include "server.h"
#include "linux-low.h"
#include "nat/aarch64-linux-hw-point.h"
+#include "linux-aarch32-low.h"
#include "elf/common.h"
#include <signal.h>
@@ -69,6 +70,16 @@ struct arch_process_info
struct aarch64_debug_reg_state debug_reg_state;
};
+/* Return true if the size of register 0 is 8 byte. */
+
+static int
+is_64bit_tdesc (void)
+{
+ struct regcache *regcache = get_thread_regcache (current_thread, 0);
+
+ return register_size (regcache->tdesc, 0) == 8;
+}
+
/* Implementation of linux_target_ops method "cannot_store_register". */
static int
@@ -582,12 +593,32 @@ aarch64_linux_prepare_to_resume (struct lwp_info *lwp)
}
}
+/* Return the right target description according to the ELF file of
+ current thread. */
+
+static const struct target_desc *
+aarch64_linux_read_description (void)
+{
+ unsigned int machine;
+ int is_elf64;
+ int tid;
+
+ tid = lwpid_of (current_thread);
+
+ is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
+
+ if (is_elf64)
+ return tdesc_aarch64;
+ else
+ return tdesc_arm_with_neon;
+}
+
/* Implementation of linux_target_ops method "arch_setup". */
static void
aarch64_arch_setup (void)
{
- current_process ()->tdesc = tdesc_aarch64;
+ current_process ()->tdesc = aarch64_linux_read_description ();
aarch64_linux_get_debug_reg_capacity (lwpid_of (current_thread));
}
@@ -611,7 +642,7 @@ static struct regsets_info aarch64_regsets_info =
NULL, /* disabled_regsets */
};
-static struct regs_info regs_info =
+static struct regs_info regs_info_aarch64 =
{
NULL, /* regset_bitmap */
NULL, /* usrregs */
@@ -623,7 +654,10 @@ static struct regs_info regs_info =
static const struct regs_info *
aarch64_regs_info (void)
{
- return ®s_info;
+ if (is_64bit_tdesc ())
+ return ®s_info_aarch64;
+ else
+ return ®s_info_aarch32;
}
/* Implementation of linux_target_ops method "supports_tracepoints". */
@@ -682,5 +716,7 @@ initialize_low_arch (void)
{
init_registers_aarch64 ();
+ initialize_low_arch_aarch32 ();
+
initialize_regsets_info (&aarch64_regsets_info);
}