public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Jiangshuai Li <jiangshuai_li@linux.alibaba.com>
To: gdb-patches@sourceware.org
Cc: Jiangshuai Li <jiangshuai_li@linux.alibaba.com>
Subject: [PATCH] gdb/csky support .reg2 for kernel 4.x and later
Date: Fri, 22 Jul 2022 13:54:46 +0800	[thread overview]
Message-ID: <20220722055446.2836-1-jiangshuai_li@linux.alibaba.com> (raw)

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


             reply	other threads:[~2022-07-22  5:54 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-22  5:54 Jiangshuai Li [this message]
2022-07-23 21:42 ` Kevin Buettner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220722055446.2836-1-jiangshuai_li@linux.alibaba.com \
    --to=jiangshuai_li@linux.alibaba.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).