diff options
author | Jiangshuai Li <jiangshuai_li@linux.alibaba.com> | 2022-08-08 11:15:30 +0800 |
---|---|---|
committer | Jiangshuai Li <jiangshuai_li@linux.alibaba.com> | 2022-08-08 11:15:30 +0800 |
commit | 0d3c36672045725236341529f087391470f65e87 (patch) | |
tree | ff56e5c0443bf013405857117ebff6ddb4f04b5c /gdb | |
parent | dd27fd47f174b537b9e6f203eb856b1b325dce85 (diff) | |
download | fsf-binutils-gdb-0d3c36672045725236341529f087391470f65e87.zip fsf-binutils-gdb-0d3c36672045725236341529f087391470f65e87.tar.gz fsf-binutils-gdb-0d3c36672045725236341529f087391470f65e87.tar.bz2 |
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.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/csky-linux-tdep.c | 149 | ||||
-rw-r--r-- | gdb/csky-tdep.h | 3 |
2 files changed, 140 insertions, 12 deletions
diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c index 440045e..106f629 100644 --- a/gdb/csky-linux-tdep.c +++ b/gdb/csky-linux-tdep.c @@ -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,14 +210,70 @@ 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) + { + for (regno = 0; regno < fregset_num; regno++) + { + 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) { - if ((regnum == csky_fregset_offset[regno] || regnum == -1) - && csky_fregset_offset[regno] != -1) + /* 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 ++) { - offset += register_size (gdbarch, csky_fregset_offset[regno]); - regcache->raw_collect (regno, fregs + offset); + 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); } } @@ -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. */ diff --git a/gdb/csky-tdep.h b/gdb/csky-tdep.h index 54000ab..3ee50fc 100644 --- a/gdb/csky-tdep.h +++ b/gdb/csky-tdep.h @@ -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 }; |