From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7882) id CA1C338582B3; Mon, 8 Aug 2022 03:16:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CA1C338582B3 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Jiangshuai Li To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb/csky support .reg2 for kernel 4.x and later X-Act-Checkin: binutils-gdb X-Git-Author: Jiangshuai Li X-Git-Refname: refs/heads/master X-Git-Oldrev: dd27fd47f174b537b9e6f203eb856b1b325dce85 X-Git-Newrev: 0d3c36672045725236341529f087391470f65e87 Message-Id: <20220808031640.CA1C338582B3@sourceware.org> Date: Mon, 8 Aug 2022 03:16:40 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Aug 2022 03:16:40 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D0d3c36672045= 725236341529f087391470f65e87 commit 0d3c36672045725236341529f087391470f65e87 Author: Jiangshuai Li Date: Mon Aug 8 11:15:30 2022 +0800 gdb/csky support .reg2 for kernel 4.x and later =20 When kernel's version >=3D 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; }; =20 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). =20 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. Diff: --- gdb/csky-linux-tdep.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++= ---- 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 440045e7713..106f629b8b0 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 =20 /* 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 =3D ARRAY_SIZE (csky_fregset_offset); =20 gdb_assert (len >=3D SIZEOF_CSKY_FREGSET); - for (i =3D 0; i < fregset_num; i++) + if (len =3D=3D SIZEOF_CSKY_FREGSET) { - if ((regnum =3D=3D csky_fregset_offset[i] || regnum =3D=3D -1) - && csky_fregset_offset[i] !=3D -1) + for (i =3D 0; i < fregset_num; i++) { - int num =3D csky_fregset_offset[i]; - offset +=3D register_size (gdbarch, num); - regcache->raw_supply (csky_fregset_offset[i], fregs + offset); + if ((regnum =3D=3D csky_fregset_offset[i] || regnum =3D=3D -1) + && csky_fregset_offset[i] !=3D -1) + { + int num =3D csky_fregset_offset[i]; + offset +=3D register_size (gdbarch, num); + regcache->raw_supply (csky_fregset_offset[i], fregs + offset); + } } } + else if (len =3D=3D SIZEOF_CSKY_FREGSET_K4X) + { + /* When kernel version >=3D 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[] =3D {122, 123, 121}; /* fcr, fesr, fid. */ + + /* Supply vr0~vr15. */ + for (i =3D 0; i < 16; i ++) + { + if (gdbarch_register_name (gdbarch, (CSKY_VR0_REGNUM + i))) + { + offset =3D 16 * i; + regcache->raw_supply (CSKY_VR0_REGNUM + i, fregs + offset); + } + } + /* Supply fr0~fr15. */ + for (i =3D 0; i < 16; i ++) + { + if (gdbarch_register_name (gdbarch, (CSKY_FR0_REGNUM + i))) + { + offset =3D 16 * i; + regcache->raw_supply (CSKY_FR0_REGNUM + i, fregs + offset); + } + } + /* Supply fr16~fr31. */ + for (i =3D 0; i < 16; i ++) + { + if (gdbarch_register_name (gdbarch, (CSKY_FR16_REGNUM + i))) + { + offset =3D (16 * 16) + (8 * i); + regcache->raw_supply (CSKY_FR16_REGNUM + i, fregs + offset); + } + } + /* Supply fcr, fesr, fid. */ + for (i =3D 0; i < 3; i ++) + { + if (gdbarch_register_name (gdbarch, fcr_regno[i])) + { + offset =3D (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); + } } =20 /* Implement the collect_regset hook for FP registers in core files. */ @@ -144,14 +210,70 @@ csky_collect_fregset (const struct regset *regset, int offset =3D 0; =20 gdb_assert (len >=3D SIZEOF_CSKY_FREGSET); - for (regno =3D 0; regno < fregset_num; regno++) + if (len =3D=3D SIZEOF_CSKY_FREGSET) + { + for (regno =3D 0; regno < fregset_num; regno++) + { + if ((regnum =3D=3D csky_fregset_offset[regno] || regnum =3D=3D -1) + && csky_fregset_offset[regno] !=3D -1) + { + offset +=3D register_size (gdbarch, csky_fregset_offset[regno]); + regcache->raw_collect (regno, fregs + offset); + } + } + } + else if (len =3D=3D SIZEOF_CSKY_FREGSET_K4X) { - if ((regnum =3D=3D csky_fregset_offset[regno] || regnum =3D=3D -1) - && csky_fregset_offset[regno] !=3D -1) + /* When kernel version >=3D 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 =3D 0; + int fcr_regno[] =3D {122, 123, 121}; /* fcr, fesr, fid. */ + + /* Supply vr0~vr15. */ + for (i =3D 0; i < 16; i ++) { - offset +=3D register_size (gdbarch, csky_fregset_offset[regno]); - regcache->raw_collect (regno, fregs + offset); + if (gdbarch_register_name (gdbarch, (CSKY_VR0_REGNUM + i))) + { + offset =3D 16 * i; + regcache ->raw_collect (CSKY_VR0_REGNUM + i, fregs + offset); + } } + /* Supply fr16~fr31. */ + for (i =3D 0; i < 16; i ++) + { + if (gdbarch_register_name (gdbarch, (CSKY_FR16_REGNUM + i))) + { + offset =3D (16 * 16) + (8 * i); + regcache ->raw_collect (CSKY_FR16_REGNUM + i, fregs + offset); + } + } + /* Supply fcr, fesr, fid. */ + for (i =3D 0; i < 3; i ++) + { + if (gdbarch_register_name (gdbarch, fcr_regno[i])) + { + offset =3D (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); } } =20 @@ -166,7 +288,10 @@ static const struct regset csky_regset_float =3D { 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 }; =20 /* Iterate over core file register note sections. */ diff --git a/gdb/csky-tdep.h b/gdb/csky-tdep.h index 54000ab8287..3ee50fc5931 100644 --- a/gdb/csky-tdep.h +++ b/gdb/csky-tdep.h @@ -93,6 +93,9 @@ enum csky_regnum CSKY_PSR_REGNUM =3D CSKY_CR0_REGNUM, =20 CSKY_MAX_REGISTER_SIZE =3D 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 =3D 253 };