public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] gdb/csky support .reg2 for kernel 4.x and later
@ 2022-07-22  5:54 Jiangshuai Li
  2022-07-23 21:42 ` Kevin Buettner
  0 siblings, 1 reply; 2+ messages in thread
From: Jiangshuai Li @ 2022-07-22  5:54 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 | 203 +++++++++++++++++++++++++++++++++---------
 1 file changed, 161 insertions(+), 42 deletions(-)

diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c
index 440045e7713..86a40a4d0e9 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.  */
@@ -65,8 +67,8 @@ static const int csky_fregset_offset[] =
 
 static void
 csky_supply_gregset (const struct regset *regset,
-		     struct regcache *regcache, int regnum,
-		     const void *regs, size_t len)
+                     struct regcache *regcache, int regnum,
+                     const void *regs, size_t len)
 {
   int i, gregset_num;
   const gdb_byte *gregs = (const gdb_byte *) regs ;
@@ -77,8 +79,8 @@ csky_supply_gregset (const struct regset *regset,
   for (i = 0; i < gregset_num; i++)
     {
       if ((regnum == csky_gregset_offset[i] || regnum == -1)
-	  && csky_gregset_offset[i] != -1)
-	regcache->raw_supply (csky_gregset_offset[i], gregs + 4 * i);
+          && csky_gregset_offset[i] != -1)
+        regcache->raw_supply (csky_gregset_offset[i], gregs + 4 * i);
     }
 }
 
@@ -86,8 +88,8 @@ csky_supply_gregset (const struct regset *regset,
 
 static void
 csky_collect_gregset (const struct regset *regset,
-		      const struct regcache *regcache,
-		      int regnum, void *gregs_buf, size_t len)
+                      const struct regcache *regcache,
+                      int regnum, void *gregs_buf, size_t len)
 {
   int regno, gregset_num;
   gdb_byte *gregs = (gdb_byte *) gregs_buf ;
@@ -98,9 +100,9 @@ csky_collect_gregset (const struct regset *regset,
   for (regno = 0; regno < gregset_num; regno++)
     {
       if ((regnum == csky_gregset_offset[regno] || regnum == -1)
-	  && csky_gregset_offset[regno] != -1)
-	regcache->raw_collect (regno,
-			       gregs + 4 + csky_gregset_offset[regno]);
+          && csky_gregset_offset[regno] != -1)
+        regcache->raw_collect (regno,
+                               gregs + 4 + csky_gregset_offset[regno]);
     }
 }
 
@@ -108,8 +110,8 @@ csky_collect_gregset (const struct regset *regset,
 
 static void
 csky_supply_fregset (const struct regset *regset,
-		     struct regcache *regcache, int regnum,
-		     const void *regs, size_t len)
+                     struct regcache *regcache, int regnum,
+                     const void *regs, size_t len)
 {
   int i;
   int offset = 0;
@@ -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);
     }
 }
 
@@ -134,8 +197,8 @@ csky_supply_fregset (const struct regset *regset,
 
 static void
 csky_collect_fregset (const struct regset *regset,
-		      const struct regcache *regcache,
-		      int regnum, void *fregs_buf, size_t len)
+                      const struct regcache *regcache,
+                      int regnum, void *fregs_buf, size_t len)
 {
   int regno;
   struct gdbarch *gdbarch = regcache->arch ();
@@ -144,14 +207,67 @@ 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,16 +282,19 @@ 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.  */
 
 static void
 csky_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
-					 iterate_over_regset_sections_cb *cb,
-					 void *cb_data,
-					 const struct regcache *regcache)
+                                         iterate_over_regset_sections_cb *cb,
+                                         void *cb_data,
+                                         const struct regcache *regcache)
 {
   cb (".reg", sizeof (csky_gregset_offset), sizeof (csky_gregset_offset),
       &csky_regset_general, NULL, cb_data);
@@ -185,17 +304,17 @@ csky_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
 
 static void
 csky_linux_rt_sigreturn_init (const struct tramp_frame *self,
-			      struct frame_info *this_frame,
-			      struct trad_frame_cache *this_cache,
-			      CORE_ADDR func)
+                              struct frame_info *this_frame,
+                              struct trad_frame_cache *this_cache,
+                              CORE_ADDR func)
 {
   int i;
   CORE_ADDR sp = get_frame_register_unsigned (this_frame, 14);
 
   CORE_ADDR base = sp + CSKY_SIGINFO_OFFSET + CSKY_SIGINFO_SIZE
-		   + CSKY_UCONTEXT_SIGCONTEXT
-		   + CSKY_SIGCONTEXT_SC_USP
-		   + CSKY_SIGCONTEXT_SC_A0;
+                   + CSKY_UCONTEXT_SIGCONTEXT
+                   + CSKY_SIGCONTEXT_SC_USP
+                   + CSKY_SIGCONTEXT_SC_A0;
 
   /* Set addrs of R0 ~ R13.  */
   for (i = 0; i < 14; i++)
@@ -239,11 +358,11 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
   set_solib_svr4_fetch_link_map_offsets (gdbarch,
-					 linux_ilp32_fetch_link_map_offsets);
+                                         linux_ilp32_fetch_link_map_offsets);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
-					     svr4_fetch_objfile_link_map);
+                                             svr4_fetch_objfile_link_map);
 
   /* Core file support.  */
   set_gdbarch_iterate_over_regset_sections (
@@ -252,7 +371,7 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Append tramp frame unwinder for SIGNAL.  */
 
   tramp_frame_prepend_unwinder (gdbarch,
-				&csky_linux_rt_sigreturn_tramp_frame);
+                                &csky_linux_rt_sigreturn_tramp_frame);
 }
 
 void _initialize_csky_linux_tdep ();
@@ -260,5 +379,5 @@ void
 _initialize_csky_linux_tdep ()
 {
   gdbarch_register_osabi (bfd_arch_csky, 0, GDB_OSABI_LINUX,
-			  csky_linux_init_abi);
+                          csky_linux_init_abi);
 }
-- 
2.25.1


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

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

On Fri, 22 Jul 2022 13:54:46 +0800
Jiangshuai Li via Gdb-patches <gdb-patches@sourceware.org> wrote:
 
>  static void
>  csky_supply_gregset (const struct regset *regset,
> -		     struct regcache *regcache, int regnum,
> -		     const void *regs, size_t len)
> +                     struct regcache *regcache, int regnum,
> +                     const void *regs, size_t len)
>  {
>    int i, gregset_num;
>    const gdb_byte *gregs = (const gdb_byte *) regs ;
> @@ -77,8 +79,8 @@ csky_supply_gregset (const struct regset *regset,
>    for (i = 0; i < gregset_num; i++)
>      {
>        if ((regnum == csky_gregset_offset[i] || regnum == -1)
> -	  && csky_gregset_offset[i] != -1)
> -	regcache->raw_supply (csky_gregset_offset[i], gregs + 4 * i);
> +          && csky_gregset_offset[i] != -1)
> +        regcache->raw_supply (csky_gregset_offset[i], gregs + 4 * i);
>      }
>  }
>  

So... in the above two hunks of this patch, plus in many other places
in the patch, it seems that the only change was to convert tabs to
spaces.

Could you please resend your patch without these whitespace changes? 

Not only will it be easier to review, but I think we still prefer the
use of tabs in place of leading spaces in GDB's source code.  Even if
such a change were desirable, we'd prefer to see a separate patch for
whitespace changes.

Thanks,

Kevin


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

end of thread, other threads:[~2022-07-23 21:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-22  5:54 [PATCH] gdb/csky support .reg2 for kernel 4.x and later Jiangshuai Li
2022-07-23 21:42 ` Kevin Buettner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).