mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
gdb/csky support .reg2 for kernel 4.x and later
When kernel's version >= 4.x, the size of .reg2 section will be 400. Contents of .reg2 are { unsigned long vr[96]; unsigned long fcr; unsigned long fesr; unsigned long fid; unsigned long reserved; }; VR[96] means: (vr0~vr15) + (fr16~fr31), each Vector register is 128-bits, each Float register is 64 bits, the total size is (4*96). In addition, for fr0~fr15, each FRx is the lower 64 bits of the corresponding VRx. So fr0~fr15 and vr0~vr15 regisetrs use the same offset.
This commit is contained in:
parent
dd27fd47f1
commit
0d3c366720
@ -36,6 +36,8 @@
|
||||
#define SIZEOF_CSKY_GREGSET 34*4
|
||||
/* Float regset fesr fsr fr0-fr31 for CK810. */
|
||||
#define SIZEOF_CSKY_FREGSET 34*4
|
||||
/* Float regset vr0~vr15 fr15~fr31, reserved for CK810 when kernel 4.x. */
|
||||
#define SIZEOF_CSKY_FREGSET_K4X 400
|
||||
|
||||
/* Offset mapping table from core_section to regcache of general
|
||||
registers for ck810. */
|
||||
@ -118,16 +120,80 @@ csky_supply_fregset (const struct regset *regset,
|
||||
int fregset_num = ARRAY_SIZE (csky_fregset_offset);
|
||||
|
||||
gdb_assert (len >= SIZEOF_CSKY_FREGSET);
|
||||
for (i = 0; i < fregset_num; i++)
|
||||
if (len == SIZEOF_CSKY_FREGSET)
|
||||
{
|
||||
if ((regnum == csky_fregset_offset[i] || regnum == -1)
|
||||
&& csky_fregset_offset[i] != -1)
|
||||
for (i = 0; i < fregset_num; i++)
|
||||
{
|
||||
int num = csky_fregset_offset[i];
|
||||
offset += register_size (gdbarch, num);
|
||||
regcache->raw_supply (csky_fregset_offset[i], fregs + offset);
|
||||
if ((regnum == csky_fregset_offset[i] || regnum == -1)
|
||||
&& csky_fregset_offset[i] != -1)
|
||||
{
|
||||
int num = csky_fregset_offset[i];
|
||||
offset += register_size (gdbarch, num);
|
||||
regcache->raw_supply (csky_fregset_offset[i], fregs + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (len == SIZEOF_CSKY_FREGSET_K4X)
|
||||
{
|
||||
/* When kernel version >= 4.x, .reg2 size will be 400.
|
||||
Contents is {
|
||||
unsigned long vr[96];
|
||||
unsigned long fcr;
|
||||
unsigned long fesr;
|
||||
unsigned long fid;
|
||||
unsigned long reserved;
|
||||
}
|
||||
VR[96] means: (vr0~vr15) + (fr16~fr31), each Vector register is
|
||||
128-bits, each Float register is 64 bits, the total size is
|
||||
(4*96).
|
||||
|
||||
In addition, for fr0~fr15, each FRx is the lower 64 bits of the
|
||||
corresponding VRx. So fr0~fr15 and vr0~vr15 regisetrs use the same
|
||||
offset. */
|
||||
int fcr_regno[] = {122, 123, 121}; /* fcr, fesr, fid. */
|
||||
|
||||
/* Supply vr0~vr15. */
|
||||
for (i = 0; i < 16; i ++)
|
||||
{
|
||||
if (gdbarch_register_name (gdbarch, (CSKY_VR0_REGNUM + i)))
|
||||
{
|
||||
offset = 16 * i;
|
||||
regcache->raw_supply (CSKY_VR0_REGNUM + i, fregs + offset);
|
||||
}
|
||||
}
|
||||
/* Supply fr0~fr15. */
|
||||
for (i = 0; i < 16; i ++)
|
||||
{
|
||||
if (gdbarch_register_name (gdbarch, (CSKY_FR0_REGNUM + i)))
|
||||
{
|
||||
offset = 16 * i;
|
||||
regcache->raw_supply (CSKY_FR0_REGNUM + i, fregs + offset);
|
||||
}
|
||||
}
|
||||
/* Supply fr16~fr31. */
|
||||
for (i = 0; i < 16; i ++)
|
||||
{
|
||||
if (gdbarch_register_name (gdbarch, (CSKY_FR16_REGNUM + i)))
|
||||
{
|
||||
offset = (16 * 16) + (8 * i);
|
||||
regcache->raw_supply (CSKY_FR16_REGNUM + i, fregs + offset);
|
||||
}
|
||||
}
|
||||
/* Supply fcr, fesr, fid. */
|
||||
for (i = 0; i < 3; i ++)
|
||||
{
|
||||
if (gdbarch_register_name (gdbarch, fcr_regno[i]))
|
||||
{
|
||||
offset = (16 * 16) + (16 * 8) + (4 * i);
|
||||
regcache->raw_supply (fcr_regno[i], fregs + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
warning (_("Unknow size %ld of section .reg2, can not get value"
|
||||
" of float registers."), len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Implement the collect_regset hook for FP registers in core files. */
|
||||
@ -144,15 +210,71 @@ csky_collect_fregset (const struct regset *regset,
|
||||
int offset = 0;
|
||||
|
||||
gdb_assert (len >= SIZEOF_CSKY_FREGSET);
|
||||
for (regno = 0; regno < fregset_num; regno++)
|
||||
if (len == SIZEOF_CSKY_FREGSET)
|
||||
{
|
||||
if ((regnum == csky_fregset_offset[regno] || regnum == -1)
|
||||
&& csky_fregset_offset[regno] != -1)
|
||||
for (regno = 0; regno < fregset_num; regno++)
|
||||
{
|
||||
offset += register_size (gdbarch, csky_fregset_offset[regno]);
|
||||
regcache->raw_collect (regno, fregs + offset);
|
||||
if ((regnum == csky_fregset_offset[regno] || regnum == -1)
|
||||
&& csky_fregset_offset[regno] != -1)
|
||||
{
|
||||
offset += register_size (gdbarch, csky_fregset_offset[regno]);
|
||||
regcache->raw_collect (regno, fregs + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (len == SIZEOF_CSKY_FREGSET_K4X)
|
||||
{
|
||||
/* When kernel version >= 4.x, .reg2 size will be 400.
|
||||
Contents is {
|
||||
unsigned long vr[96];
|
||||
unsigned long fcr;
|
||||
unsigned long fesr;
|
||||
unsigned long fid;
|
||||
unsigned long reserved;
|
||||
}
|
||||
VR[96] means: (vr0~vr15) + (fr16~fr31), each Vector register is$
|
||||
128-bits, each Float register is 64 bits, the total size is$
|
||||
(4*96).$
|
||||
|
||||
In addition, for fr0~fr15, each FRx is the lower 64 bits of the$
|
||||
corresponding VRx. So fr0~fr15 and vr0~vr15 regisetrs use the same$
|
||||
offset. */
|
||||
int i = 0;
|
||||
int fcr_regno[] = {122, 123, 121}; /* fcr, fesr, fid. */
|
||||
|
||||
/* Supply vr0~vr15. */
|
||||
for (i = 0; i < 16; i ++)
|
||||
{
|
||||
if (gdbarch_register_name (gdbarch, (CSKY_VR0_REGNUM + i)))
|
||||
{
|
||||
offset = 16 * i;
|
||||
regcache ->raw_collect (CSKY_VR0_REGNUM + i, fregs + offset);
|
||||
}
|
||||
}
|
||||
/* Supply fr16~fr31. */
|
||||
for (i = 0; i < 16; i ++)
|
||||
{
|
||||
if (gdbarch_register_name (gdbarch, (CSKY_FR16_REGNUM + i)))
|
||||
{
|
||||
offset = (16 * 16) + (8 * i);
|
||||
regcache ->raw_collect (CSKY_FR16_REGNUM + i, fregs + offset);
|
||||
}
|
||||
}
|
||||
/* Supply fcr, fesr, fid. */
|
||||
for (i = 0; i < 3; i ++)
|
||||
{
|
||||
if (gdbarch_register_name (gdbarch, fcr_regno[i]))
|
||||
{
|
||||
offset = (16 * 16) + (16 * 8) + (4 * i);
|
||||
regcache ->raw_collect (fcr_regno[i], fregs + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
warning (_("Unknow size %ld of section .reg2, will not set value"
|
||||
" of float registers."), len);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regset csky_regset_general =
|
||||
@ -166,7 +288,10 @@ static const struct regset csky_regset_float =
|
||||
{
|
||||
NULL,
|
||||
csky_supply_fregset,
|
||||
csky_collect_fregset
|
||||
csky_collect_fregset,
|
||||
/* Allow .reg2 to have a different size, and the size of .reg2 should
|
||||
always be bigger than SIZEOF_CSKY_FREGSET. */
|
||||
1
|
||||
};
|
||||
|
||||
/* Iterate over core file register note sections. */
|
||||
|
@ -93,6 +93,9 @@ enum csky_regnum
|
||||
CSKY_PSR_REGNUM = CSKY_CR0_REGNUM,
|
||||
|
||||
CSKY_MAX_REGISTER_SIZE = 16,
|
||||
|
||||
/* Actually, the max regs number should be 1187. But if the
|
||||
gdb stub does not send a tdesc-xml file to gdb, 253 works. */
|
||||
CSKY_MAX_REGS = 253
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user