AARCH64 Linux: Fill 'collect_regset' in regset structures.

In order to provide 'collect_regset' support, the generic function
regcache_collect_regset is exploited.  Since this requires writing
appropriate register maps, these can be used for supply_regset as
well.
This commit is contained in:
Andreas Arnez 2014-04-01 09:42:46 +00:00 committed by Ulrich Weigand
parent 99b7da5d7a
commit d4d793bfeb
4 changed files with 76 additions and 101 deletions

View File

@ -1,3 +1,28 @@
2014-08-07 Andreas Arnez <arnez@linux.vnet.ibm.com>
* aarch64-linux-nat.c (fill_gregset, fill_fpregset): Replace logic
by call to regcache_collect_regset.
(supply_gregset, supply_fpregset): Call regcache_supply_regset
instead of aarch64_linux_supply_gregset/_fpregset.
* aarch64-linux-tdep.c (AARCH64_LINUX_SIZEOF_GREGSET)
(AARCH64_LINUX_SIZEOF_FPREGSET): Delete macros here, move to
header file instead.
(aarch64_linux_supply_gregset, supply_gregset_from_core)
(aarch64_linux_suply_fpregset, supply_fpregset_from_core): Delete
functions. Move logic to ...
(aarch64_linux_gregmap, aarch64_linux_fpregmap): ... these new
register maps.
(aarch64_linux_gregset, aarch64_linux_fpregset): Make global,
refer to new register maps, replace *_regset_from_core by
regcache_supply_regset, and also use regcache_collect_regset.
* aarch64-linux-tdep.h: Include "regset.h".
(aarch64_linux_supply_gregset, aarch64_linux_supply_fpregset):
Delete prototypes.
(AARCH64_LINUX_SIZEOF_GREGSET, AARCH64_LINUX_SIZEOF_FPREGSET): New
macros, moved from C source file.
(aarch64_linux_gregset, aarch64_linux_fpregset): New global
variable declarations.
2014-08-07 Andreas Arnez <arnez@linux.vnet.ibm.com>
* s390-linux-nat.c: Include "regset.h".

View File

@ -616,14 +616,9 @@ void
fill_gregset (const struct regcache *regcache,
gdb_gregset_t *gregsetp, int regno)
{
gdb_byte *gregs_buf = (gdb_byte *) gregsetp;
int i;
for (i = AARCH64_X0_REGNUM; i <= AARCH64_CPSR_REGNUM; i++)
if (regno == -1 || regno == i)
regcache_raw_collect (regcache, i,
gregs_buf + X_REGISTER_SIZE
* (i - AARCH64_X0_REGNUM));
regcache_collect_regset (&aarch64_linux_gregset, regcache,
regno, (gdb_byte *) gregsetp,
AARCH64_LINUX_SIZEOF_GREGSET);
}
/* Fill GDB's register array with the general-purpose register values
@ -632,7 +627,9 @@ fill_gregset (const struct regcache *regcache,
void
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
{
aarch64_linux_supply_gregset (regcache, (const gdb_byte *) gregsetp);
regcache_supply_regset (&aarch64_linux_gregset, regcache, -1,
(const gdb_byte *) gregsetp,
AARCH64_LINUX_SIZEOF_GREGSET);
}
/* Fill register REGNO (if it is a floating-point register) in
@ -643,22 +640,9 @@ void
fill_fpregset (const struct regcache *regcache,
gdb_fpregset_t *fpregsetp, int regno)
{
gdb_byte *fpregs_buf = (gdb_byte *) fpregsetp;
int i;
for (i = AARCH64_V0_REGNUM; i <= AARCH64_V31_REGNUM; i++)
if (regno == -1 || regno == i)
regcache_raw_collect (regcache, i,
fpregs_buf + V_REGISTER_SIZE
* (i - AARCH64_V0_REGNUM));
if (regno == -1 || regno == AARCH64_FPSR_REGNUM)
regcache_raw_collect (regcache, AARCH64_FPSR_REGNUM,
fpregs_buf + V_REGISTER_SIZE * 32);
if (regno == -1 || regno == AARCH64_FPCR_REGNUM)
regcache_raw_collect (regcache, AARCH64_FPCR_REGNUM,
fpregs_buf + V_REGISTER_SIZE * 32 + 4);
regcache_collect_regset (&aarch64_linux_fpregset, regcache,
regno, (gdb_byte *) fpregsetp,
AARCH64_LINUX_SIZEOF_FPREGSET);
}
/* Fill GDB's register array with the floating-point register values
@ -667,7 +651,9 @@ fill_fpregset (const struct regcache *regcache,
void
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
{
aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) fpregsetp);
regcache_supply_regset (&aarch64_linux_fpregset, regcache, -1,
(const gdb_byte *) fpregsetp,
AARCH64_LINUX_SIZEOF_FPREGSET);
}
/* Called when resuming a thread.

View File

@ -41,16 +41,6 @@
#include "user-regs.h"
#include <ctype.h>
/* The general-purpose regset consists of 31 X registers, plus SP, PC,
and PSTATE registers, as defined in the AArch64 port of the Linux
kernel. */
#define AARCH64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE)
/* The fp regset consists of 32 V registers, plus FPCR and FPSR which
are 4 bytes wide each, and the whole structure is padded to 128 bit
alignment. */
#define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
/* Signal frame handling.
+------------+ ^
@ -190,71 +180,37 @@ static const struct tramp_frame aarch64_linux_rt_sigframe =
aarch64_linux_sigframe_init
};
/* Fill GDB's register array with the general-purpose register values
in the buffer pointed by GREGS_BUF. */
/* Register maps. */
void
aarch64_linux_supply_gregset (struct regcache *regcache,
const gdb_byte *gregs_buf)
{
int regno;
for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
regcache_raw_supply (regcache, regno,
gregs_buf + X_REGISTER_SIZE
* (regno - AARCH64_X0_REGNUM));
}
/* The "supply_regset" function for the general-purpose register set. */
static void
supply_gregset_from_core (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *regbuf, size_t len)
{
aarch64_linux_supply_gregset (regcache, (const gdb_byte *) regbuf);
}
/* Fill GDB's register array with the floating-point register values
in the buffer pointed by FPREGS_BUF. */
void
aarch64_linux_supply_fpregset (struct regcache *regcache,
const gdb_byte *fpregs_buf)
{
int regno;
for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
regcache_raw_supply (regcache, regno,
fpregs_buf + V_REGISTER_SIZE
* (regno - AARCH64_V0_REGNUM));
regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM,
fpregs_buf + V_REGISTER_SIZE * 32);
regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM,
fpregs_buf + V_REGISTER_SIZE * 32 + 4);
}
/* The "supply_regset" function for the floating-point register set. */
static void
supply_fpregset_from_core (const struct regset *regset,
struct regcache *regcache,
int regnum, const void *regbuf, size_t len)
{
aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) regbuf);
}
/* Register set definitions. */
static const struct regset aarch64_linux_gregset =
static const struct regcache_map_entry aarch64_linux_gregmap[] =
{
NULL, supply_gregset_from_core, NULL
{ 31, AARCH64_X0_REGNUM, 8 }, /* x0 ... x30 */
{ 1, AARCH64_SP_REGNUM, 8 },
{ 1, AARCH64_PC_REGNUM, 8 },
{ 1, AARCH64_CPSR_REGNUM, 8 },
{ 0 }
};
static const struct regset aarch64_linux_fpregset =
static const struct regcache_map_entry aarch64_linux_fpregmap[] =
{
NULL, supply_fpregset_from_core, NULL
{ 32, AARCH64_V0_REGNUM, 16 }, /* v0 ... v31 */
{ 1, AARCH64_FPSR_REGNUM, 4 },
{ 1, AARCH64_FPCR_REGNUM, 4 },
{ 0 }
};
/* Register set definitions. */
const struct regset aarch64_linux_gregset =
{
aarch64_linux_gregmap,
regcache_supply_regset, regcache_collect_regset
};
const struct regset aarch64_linux_fpregset =
{
aarch64_linux_fpregmap,
regcache_supply_regset, regcache_collect_regset
};
/* Implement the "regset_from_core_section" gdbarch method. */

View File

@ -18,9 +18,17 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
struct regcache;
#include "regset.h"
extern void aarch64_linux_supply_gregset (struct regcache *regcache,
const gdb_byte *gregs_buf);
extern void aarch64_linux_supply_fpregset (struct regcache *regcache,
const gdb_byte *fpregs_buf);
/* The general-purpose regset consists of 31 X registers, plus SP, PC,
and PSTATE registers, as defined in the AArch64 port of the Linux
kernel. */
#define AARCH64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE)
/* The fp regset consists of 32 V registers, plus FPCR and FPSR which
are 4 bytes wide each, and the whole structure is padded to 128 bit
alignment. */
#define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
extern const struct regset aarch64_linux_gregset;
extern const struct regset aarch64_linux_fpregset;