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.
This commit is contained in:
Yao Qi 2015-08-04 14:34:14 +01:00
parent ded48a5ef3
commit bd9e6534b7
5 changed files with 219 additions and 47 deletions

View file

@ -1,3 +1,21 @@
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 ...

View file

@ -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"

View file

@ -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, &regs[i]);
collect_register (regcache, ARM_PS_REGNUM, &regs[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, &regs[i]);
for (; i < ARM_PS_REGNUM; i++)
supply_register (regcache, i, zerobuf);
supply_register (regcache, ARM_PS_REGNUM, &regs[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);
}

View file

@ -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;

View file

@ -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
@ -149,35 +148,6 @@ arm_cannot_fetch_register (int regno)
return (regno >= arm_num_regs);
}
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, &regs[i]);
collect_register (regcache, ARM_PS_REGNUM, &regs[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, &regs[i]);
for (; i < ARM_PS_REGNUM; i++)
supply_register (regcache, i, zerobuf);
supply_register (regcache, ARM_PS_REGNUM, &regs[16]);
}
static void
arm_fill_wmmxregset (struct regcache *regcache, void *buf)
{
@ -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 &regs_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 &regs_info_aarch32;
else
return &regs_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);
}