Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH v2] gdb/csky support .reg2 for kernel 4.x and later
@ 2022-07-27  7:29 jiangshuai_li via Gdb-patches
  2022-07-28 17:55 ` Kevin Buettner via Gdb-patches
  0 siblings, 1 reply; 4+ messages in thread
From: jiangshuai_li via Gdb-patches @ 2022-07-27  7:29 UTC (permalink / raw)
  To: gdb-patches, Kevin Buettner


>> When kernel's version >= 4.x, the size of .reg2 section will be 400.
>> Contents of .reg2 are {
>>     unsigned long vr[96]; // vr0~vr15 & fr16~fr31
>>     unsigned long fcr;
>>     unsigned long fesr;
>>     unsigned long fid;
>>     unsigned long reserved;
>> };
>>
>> ---
>>  gdb/csky-linux-tdep.c | 150 +++++++++++++++++++++++++++++++++++++-----
>>  1 file changed, 134 insertions(+), 16 deletions(-)
>> 
>> diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c
>> index 440045e7713..aa85a299922 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.  */
>
>You might want to expand the comment above indicating that the struct
>layout can be found in a comment within csky_supply_fregset.
>
>> +#define SIZEOF_CSKY_FREGSET_K4X  400
>>  
>>  /* Offset mapping table from core_section to regcache of general
>>     registers for ck810.  */
>> @@ -118,15 +120,76 @@ 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)
>> - {
>> -   int num = csky_fregset_offset[i];
>> -   offset += register_size (gdbarch, num);
>> -   regcache->raw_supply (csky_fregset_offset[i], fregs +
>> offset);
>> - }
>> +      for (i = 0; i < fregset_num; i++)
>> +        {
>> +          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]; // vr0~vr15 + fr16~fr31
>> +           unsigned long fcr;
>> +           unsigned long fesr;
>> +           unsigned long fid;
>> +           unsigned long reserved;
>> +         }  */
>> +      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;
>
>Are these offsets correct?  I.e. do the fr0~fr15 registers use
>the same offsets as vr0~vr15?

Yes. The bit width of floating-point register is 64bits, and the bit width of vector
register is 128bit. In fr0~fr15 and vr0~vr15, each FRx is the lower 64 bits of
the corresponding VRx.

>
>Also, not related to this patch, but while trying to figure this out,
>I found this line in csky-tdep.h - it looks fishy to me since it's
>way bigger than CSKY_MAX_REGS:
>
>  CSKY_FR16_REGNUM = 1172,

Actually, the max regs number should be 1187, but if the gdb stub does not send a
tdesc-xml file to gdb, 253 works.

>
>It definitely matters since you refer to CSKY_FR16_REGNUM below.
>
>> +              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);
>>      }
>>  }
>>  
>> @@ -144,14 +207,66 @@ 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)
>> +    {
>> +      /* When kernel version >= 4.x, .reg2 size will be 400.
>> +         Contents is {
>> +           unsigned long vr[96]; // vr0~vr15 + fr16~fr31
>> +           unsigned long fcr;
>> +           unsigned long fesr;
>> +           unsigned long fid;
>> +           unsigned long reserved;
>> +         }  */
>> +      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
>>      {
>> -      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);
>> - }
>> +      warning (_("Unknow size %ld of section .reg2, will not set
>> value"
>> +                 " of float registers."), len);
>>      }
>>  }
>>  
>> @@ -166,7 +281,10 @@ static const struct regset csky_regset_float =
>>  {
>>    NULL,
>>    csky_supply_fregset,
>> -  csky_collect_fregset
>> +  csky_collect_fregset,
>> +  /* Allow .reg2 has different size, buf size of .reg2 should
>> +     always is or bigger than SIZEOF_CSKY_FREGSET.  */
>
>I recommend a slightly different wording for the above comment:
>
>     /* Allow .reg2 to have a different size, but the size of .reg2 should
>       always be bigger than SIZEOF_CSKY_FREGSET.  */

Get.

>
>> +  1
>>  };
>>  
>>  /* Iterate over core file register note sections.  */
>> -- 
>> 2.25.1
>> 

Thanks Kevin Buettner.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] gdb/csky support .reg2 for kernel 4.x and later
  2022-07-27  7:29 [PATCH v2] gdb/csky support .reg2 for kernel 4.x and later jiangshuai_li via Gdb-patches
@ 2022-07-28 17:55 ` Kevin Buettner via Gdb-patches
  0 siblings, 0 replies; 4+ messages in thread
From: Kevin Buettner via Gdb-patches @ 2022-07-28 17:55 UTC (permalink / raw)
  To: jiangshuai_li; +Cc: gdb-patches

On Wed, 27 Jul 2022 15:29:17 +0800
"jiangshuai_li" <jiangshuai_li@linux.alibaba.com> wrote:

> >> +      /* 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;  
> >
> >Are these offsets correct?  I.e. do the fr0~fr15 registers use
> >the same offsets as vr0~vr15?  
> 
> Yes. The bit width of floating-point register is 64bits, and the bit width of vector
> register is 128bit. In fr0~fr15 and vr0~vr15, each FRx is the lower 64 bits of
> the corresponding VRx.

Thanks for the explanation.  You might consider adding a comment
about this if one doesn't already exist.

> >Also, not related to this patch, but while trying to figure this out,
> >I found this line in csky-tdep.h - it looks fishy to me since it's
> >way bigger than CSKY_MAX_REGS:
> >
> >  CSKY_FR16_REGNUM = 1172,  
> 
> Actually, the max regs number should be 1187, but if the gdb stub does not send a
> tdesc-xml file to gdb, 253 works.

Again, a comment regarding this fact would be nice...

Kevin


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] gdb/csky support .reg2 for kernel 4.x and later
  2022-07-25  2:44 Jiangshuai Li via Gdb-patches
@ 2022-07-27  0:49 ` Kevin Buettner via Gdb-patches
  0 siblings, 0 replies; 4+ messages in thread
From: Kevin Buettner via Gdb-patches @ 2022-07-27  0:49 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiangshuai Li

On Mon, 25 Jul 2022 10:44:59 +0800
Jiangshuai Li via Gdb-patches <gdb-patches@sourceware.org> wrote:

> When kernel's version >= 4.x, the size of .reg2 section will be 400.
> Contents of .reg2 are {
>     unsigned long vr[96]; // vr0~vr15 & fr16~fr31
>     unsigned long fcr;
>     unsigned long fesr;
>     unsigned long fid;
>     unsigned long reserved;
> };
>
> ---
>  gdb/csky-linux-tdep.c | 150 +++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 134 insertions(+), 16 deletions(-)
> 
> diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c
> index 440045e7713..aa85a299922 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.  */

You might want to expand the comment above indicating that the struct
layout can be found in a comment within csky_supply_fregset.

> +#define SIZEOF_CSKY_FREGSET_K4X  400
>  
>  /* Offset mapping table from core_section to regcache of general
>     registers for ck810.  */
> @@ -118,15 +120,76 @@ 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)
> -	{
> -	  int num = csky_fregset_offset[i];
> -	  offset += register_size (gdbarch, num);
> -	  regcache->raw_supply (csky_fregset_offset[i], fregs +
> offset);
> -	}
> +      for (i = 0; i < fregset_num; i++)
> +        {
> +          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]; // vr0~vr15 + fr16~fr31
> +           unsigned long fcr;
> +           unsigned long fesr;
> +           unsigned long fid;
> +           unsigned long reserved;
> +         }  */
> +      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;

Are these offsets correct?  I.e. do the fr0~fr15 registers use
the same offsets as vr0~vr15?

Also, not related to this patch, but while trying to figure this out,
I found this line in csky-tdep.h - it looks fishy to me since it's
way bigger than CSKY_MAX_REGS:

  CSKY_FR16_REGNUM = 1172,

It definitely matters since you refer to CSKY_FR16_REGNUM below.

> +              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);
>      }
>  }
>  
> @@ -144,14 +207,66 @@ 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)
> +    {
> +      /* When kernel version >= 4.x, .reg2 size will be 400.
> +         Contents is {
> +           unsigned long vr[96]; // vr0~vr15 + fr16~fr31
> +           unsigned long fcr;
> +           unsigned long fesr;
> +           unsigned long fid;
> +           unsigned long reserved;
> +         }  */
> +      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
>      {
> -      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);
> -	}
> +      warning (_("Unknow size %ld of section .reg2, will not set
> value"
> +                 " of float registers."), len);
>      }
>  }
>  
> @@ -166,7 +281,10 @@ static const struct regset csky_regset_float =
>  {
>    NULL,
>    csky_supply_fregset,
> -  csky_collect_fregset
> +  csky_collect_fregset,
> +  /* Allow .reg2 has different size, buf size of .reg2 should
> +     always is or bigger than SIZEOF_CSKY_FREGSET.  */

I recommend a slightly different wording for the above comment:

     /* Allow .reg2 to have a different size, but the size of .reg2 should
        always be bigger than SIZEOF_CSKY_FREGSET.  */

> +  1
>  };
>  
>  /* Iterate over core file register note sections.  */
> -- 
> 2.25.1
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2] gdb/csky support .reg2 for kernel 4.x and later
@ 2022-07-25  2:44 Jiangshuai Li via Gdb-patches
  2022-07-27  0:49 ` Kevin Buettner via Gdb-patches
  0 siblings, 1 reply; 4+ messages in thread
From: Jiangshuai Li via Gdb-patches @ 2022-07-25  2:44 UTC (permalink / raw)
  To: gdb-patches; +Cc: Jiangshuai Li

When kernel's version >= 4.x, the size of .reg2 section will be 400.
Contents of .reg2 are {
    unsigned long vr[96]; // vr0~vr15 & fr16~fr31
    unsigned long fcr;
    unsigned long fesr;
    unsigned long fid;
    unsigned long reserved;
};
---
 gdb/csky-linux-tdep.c | 150 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 134 insertions(+), 16 deletions(-)

diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c
index 440045e7713..aa85a299922 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,15 +120,76 @@ 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)
-	{
-	  int num = csky_fregset_offset[i];
-	  offset += register_size (gdbarch, num);
-	  regcache->raw_supply (csky_fregset_offset[i], fregs + offset);
-	}
+      for (i = 0; i < fregset_num; i++)
+        {
+          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]; // vr0~vr15 + fr16~fr31
+           unsigned long fcr;
+           unsigned long fesr;
+           unsigned long fid;
+           unsigned long reserved;
+         }  */
+      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);
     }
 }
 
@@ -144,14 +207,66 @@ 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)
+    {
+      /* When kernel version >= 4.x, .reg2 size will be 400.
+         Contents is {
+           unsigned long vr[96]; // vr0~vr15 + fr16~fr31
+           unsigned long fcr;
+           unsigned long fesr;
+           unsigned long fid;
+           unsigned long reserved;
+         }  */
+      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
     {
-      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);
-	}
+      warning (_("Unknow size %ld of section .reg2, will not set value"
+                 " of float registers."), len);
     }
 }
 
@@ -166,7 +281,10 @@ static const struct regset csky_regset_float =
 {
   NULL,
   csky_supply_fregset,
-  csky_collect_fregset
+  csky_collect_fregset,
+  /* Allow .reg2 has different size, buf size of .reg2 should
+     always is or bigger than SIZEOF_CSKY_FREGSET.  */
+  1
 };
 
 /* Iterate over core file register note sections.  */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-07-28 17:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-27  7:29 [PATCH v2] gdb/csky support .reg2 for kernel 4.x and later jiangshuai_li via Gdb-patches
2022-07-28 17:55 ` Kevin Buettner via Gdb-patches
  -- strict thread matches above, loose matches on Subject: below --
2022-07-25  2:44 Jiangshuai Li via Gdb-patches
2022-07-27  0:49 ` Kevin Buettner via Gdb-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox