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:
parent
ded48a5ef3
commit
bd9e6534b7
5 changed files with 219 additions and 47 deletions
|
@ -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 ...
|
||||
|
|
|
@ -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"
|
||||
|
|
140
gdb/gdbserver/linux-aarch32-low.c
Normal file
140
gdb/gdbserver/linux-aarch32-low.c
Normal 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, ®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 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);
|
||||
}
|
29
gdb/gdbserver/linux-aarch32-low.h
Normal file
29
gdb/gdbserver/linux-aarch32-low.h
Normal 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;
|
|
@ -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, ®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)
|
||||
{
|
||||
|
@ -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 ®s_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 ®s_info_aarch32;
|
||||
else
|
||||
return ®s_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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue