diff mbox

[2/7] Fixes for aarch64-linux gdb core file support

Message ID 1401898871-2270-3-git-send-email-omair.javaid@linaro.org
State New
Headers show

Commit Message

Omair Javaid June 4, 2014, 4:21 p.m. UTC
This patch fixes aarch64 linux core file support by adding/updating
aarch64-linux supply/collect methods for aarch64 register set.

gdb:

2014-06-04  Omair Javaid  <omair.javaid@linaro.org>

	* aarch64-linux-tdep.c (aarch64_linux_supply_gregset): Updated.
	(aarch64_linux_supply_fpregset): Updated.
	(supply_gregset_from_core): Removed.
	(aarch64_linux_collect_gregset): New function.
	(supply_fpregset_from_core): Removed.
	(aarch64_linux_collect_fpregset): New function.
	(struct regset aarch64_linux_gregset): Updated.
	(struct core_regset_section aarch64_linux_regset_sections[]): Declared.
	* aarch64-linux-tdep.h (aarch64_linux_supply_gregset): Updated extern.
	(aarch64_linux_supply_fpregset): New extern declaration.
	(aarch64_linux_collect_gregset): New extern declaration.
	(aarch64_linux_collect_fpregset): New extern declaration.
	* aarch64-linux-nat.c (aarch64_linux_supply_gregset): Updated.
	(aarch64_linux_supply_fpregset): Updated.

---
 gdb/aarch64-linux-nat.c  |  4 +--
 gdb/aarch64-linux-tdep.c | 91 +++++++++++++++++++++++++++++++++---------------
 gdb/aarch64-linux-tdep.h | 22 +++++++++---
 3 files changed, 83 insertions(+), 34 deletions(-)

Comments

Andreas Arnez June 4, 2014, 5:11 p.m. UTC | #1
On Wed, Jun 04 2014, Omair Javaid wrote:

> This patch fixes aarch64 linux core file support by adding/updating
> aarch64-linux supply/collect methods for aarch64 register set.

Have you looked at that patch?

  https://sourceware.org/ml/gdb-patches/2014-05/msg00637.html

Apart from 'core_regset_sections', I believe it provides the same
functionality as this patch, right?
Will Newton June 5, 2014, 9:07 a.m. UTC | #2
On 4 June 2014 17:21, Omair Javaid <omair.javaid@linaro.org> wrote:
> This patch fixes aarch64 linux core file support by adding/updating
> aarch64-linux supply/collect methods for aarch64 register set.
>
> gdb:
>
> 2014-06-04  Omair Javaid  <omair.javaid@linaro.org>
>
>         * aarch64-linux-tdep.c (aarch64_linux_supply_gregset): Updated.
>         (aarch64_linux_supply_fpregset): Updated.
>         (supply_gregset_from_core): Removed.
>         (aarch64_linux_collect_gregset): New function.
>         (supply_fpregset_from_core): Removed.
>         (aarch64_linux_collect_fpregset): New function.
>         (struct regset aarch64_linux_gregset): Updated.
>         (struct core_regset_section aarch64_linux_regset_sections[]): Declared.
>         * aarch64-linux-tdep.h (aarch64_linux_supply_gregset): Updated extern.
>         (aarch64_linux_supply_fpregset): New extern declaration.
>         (aarch64_linux_collect_gregset): New extern declaration.
>         (aarch64_linux_collect_fpregset): New extern declaration.
>         * aarch64-linux-nat.c (aarch64_linux_supply_gregset): Updated.
>         (aarch64_linux_supply_fpregset): Updated.
>
> ---
>  gdb/aarch64-linux-nat.c  |  4 +--
>  gdb/aarch64-linux-tdep.c | 91 +++++++++++++++++++++++++++++++++---------------
>  gdb/aarch64-linux-tdep.h | 22 +++++++++---
>  3 files changed, 83 insertions(+), 34 deletions(-)
>
> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> index 877e702..f631d9e 100644
> --- a/gdb/aarch64-linux-nat.c
> +++ b/gdb/aarch64-linux-nat.c
> @@ -632,7 +632,7 @@ fill_gregset (const struct regcache *regcache,
>  void
>  supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
>  {
> -  aarch64_linux_supply_gregset (regcache, (const gdb_byte *) gregsetp);
> +  aarch64_linux_supply_gregset (NULL, regcache, -1, gregsetp, 0);
>  }
>
>  /* Fill register REGNO (if it is a floating-point register) in
> @@ -667,7 +667,7 @@ fill_fpregset (const struct regcache *regcache,
>  void
>  supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
>  {
> -  aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) fpregsetp);
> +  aarch64_linux_supply_fpregset (NULL, regcache, -1, fpregsetp, 0);
>  }
>
>  /* Called when resuming a thread.
> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> index 30ed73f..b285818 100644
> --- a/gdb/aarch64-linux-tdep.c
> +++ b/gdb/aarch64-linux-tdep.c
> @@ -191,70 +191,93 @@ static const struct tramp_frame aarch64_linux_rt_sigframe =
>  };
>
>  /* Fill GDB's register array with the general-purpose register values
> -   in the buffer pointed by GREGS_BUF.  */
> +   in the buffer pointed by gregs_buf.  */

I believe upper casing parameter names in comments is actually correct
per the GNU coding style.
>
>  void
> -aarch64_linux_supply_gregset (struct regcache *regcache,
> -                             const gdb_byte *gregs_buf)
> +aarch64_linux_supply_gregset (const struct regset *regset,
> +                              struct regcache *regcache, int regnum,
> +                              const void *gregs_buf, size_t len)
>  {
> +  gdb_byte *gregs_bufp = (gdb_byte *) gregs_buf;
>    int regno;
>
>    for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
>      regcache_raw_supply (regcache, regno,
> -                        gregs_buf + X_REGISTER_SIZE
> +            gregs_bufp + X_REGISTER_SIZE
>                          * (regno - AARCH64_X0_REGNUM));
>  }
>
> -/* The "supply_regset" function for the general-purpose register set.  */
> +/* Fill registers in *gregs_buf with the values in GDB's register cache.  */
>
> -static void
> -supply_gregset_from_core (const struct regset *regset,
> -                         struct regcache *regcache,
> -                         int regnum, const void *regbuf, size_t len)
> +void
> +aarch64_linux_collect_gregset (const struct regset *regset,
> +                              const struct regcache *regcache, int regnum,
> +                              void *gregs_buf, size_t len)
>  {
> -  aarch64_linux_supply_gregset (regcache, (const gdb_byte *) regbuf);
> +  gdb_byte *gregs_bufp = (gdb_byte *) gregs_buf;
> +  int regno;
> +
> +  for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
> +    if (regnum == -1 || regnum == regno)
> +      regcache_raw_collect (regcache, regno, gregs_bufp + X_REGISTER_SIZE *
> +                            (regno - AARCH64_X0_REGNUM));
>  }
>
>  /* Fill GDB's register array with the floating-point register values
> -   in the buffer pointed by FPREGS_BUF.  */
> +   in the buffer pointed by fpregs_buf.  */
>
>  void
> -aarch64_linux_supply_fpregset (struct regcache *regcache,
> -                              const gdb_byte *fpregs_buf)
> +aarch64_linux_supply_fpregset (const struct regset *regset,
> +                               struct regcache *regcache, int regnum,
> +                               const void *fpregs_buf, size_t len)
>  {
> +  gdb_byte *fpregs_bufp = (gdb_byte *) fpregs_buf;
>    int regno;
>
>    for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
> -    regcache_raw_supply (regcache, regno,
> -                        fpregs_buf + V_REGISTER_SIZE
> -                        * (regno - AARCH64_V0_REGNUM));
> +    regcache_raw_supply (regcache, regno, fpregs_bufp + V_REGISTER_SIZE *
> +                         (regno - AARCH64_V0_REGNUM));
>
> -  regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM,
> -                      fpregs_buf + V_REGISTER_SIZE * 32);
> -  regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM,
> -                      fpregs_buf + V_REGISTER_SIZE * 32 + 4);
> +  regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM, fpregs_bufp +
> +                       V_REGISTER_SIZE * 32);
> +  regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM, fpregs_bufp +
> +                       V_REGISTER_SIZE * 32 + 4);
>  }
>
> -/* The "supply_regset" function for the floating-point register set.  */
> +/* Fill registers in *fpregs_buf with the values in GDB's register cache.  */
>
> -static void
> -supply_fpregset_from_core (const struct regset *regset,
> -                          struct regcache *regcache,
> -                          int regnum, const void *regbuf, size_t len)
> +void
> +aarch64_linux_collect_fpregset (const struct regset *regset,
> +                                const struct regcache *regcache, int regnum,
> +                                void *fpregs_buf, size_t len)
>  {
> -  aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) regbuf);
> +  gdb_byte *fpregs_bufp = (gdb_byte *) fpregs_buf;
> +  int regno;
> +
> +  for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
> +    if (regnum == -1 || regnum == regno)
> +      regcache_raw_collect (regcache, regno, fpregs_bufp + V_REGISTER_SIZE *
> +                            (regno - AARCH64_V0_REGNUM));
> +
> +  if (regnum == -1 || regnum == AARCH64_FPSR_REGNUM)
> +    regcache_raw_collect (regcache, AARCH64_FPSR_REGNUM, fpregs_bufp +
> +                          V_REGISTER_SIZE * 32);
> +
> +  if (regnum == -1 || regnum == AARCH64_FPCR_REGNUM)
> +    regcache_raw_collect (regcache, AARCH64_FPCR_REGNUM, fpregs_bufp +
> +                          V_REGISTER_SIZE * 32 + 4);
>  }
>
>  /* Register set definitions. */
>
>  static const struct regset aarch64_linux_gregset =
>    {
> -    NULL, supply_gregset_from_core, NULL
> +    NULL, aarch64_linux_supply_gregset, aarch64_linux_collect_gregset
>    };
>
>  static const struct regset aarch64_linux_fpregset =
>    {
> -    NULL, supply_fpregset_from_core, NULL
> +    NULL, aarch64_linux_supply_fpregset, aarch64_linux_collect_fpregset
>    };
>
>  /* Implement the "regset_from_core_section" gdbarch method.  */
> @@ -275,6 +298,15 @@ aarch64_linux_regset_from_core_section (struct gdbarch *gdbarch,
>    return NULL;
>  }
>
> +/* Core file register set sections.  */
> +
> +static struct core_regset_section aarch64_linux_regset_sections[] =
> +{
> +  { ".reg", AARCH64_LINUX_SIZEOF_GREGSET, "general-purpose" },
> +  { ".reg2", AARCH64_LINUX_SIZEOF_FPREGSET, "floating-point" },
> +  { NULL, 0}
> +};
> +
>  /* Implementation of `gdbarch_stap_is_single_operand', as defined in
>     gdbarch.h.  */
>
> @@ -420,6 +452,9 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>    /* Enable longjmp.  */
>    tdep->jb_pc = 11;
>
> +  /* Install supported register note sections.  */
> +  set_gdbarch_core_regset_sections (gdbarch, aarch64_linux_regset_sections);
> +
>    set_gdbarch_regset_from_core_section (gdbarch,
>                                         aarch64_linux_regset_from_core_section);
>
> diff --git a/gdb/aarch64-linux-tdep.h b/gdb/aarch64-linux-tdep.h
> index 48c7092..e3d7ed7 100644
> --- a/gdb/aarch64-linux-tdep.h
> +++ b/gdb/aarch64-linux-tdep.h
> @@ -20,7 +20,21 @@
>
>  struct regcache;
>
> -extern void aarch64_linux_supply_gregset (struct regcache *regcache,
> -                                         const gdb_byte *gregs_buf);
> -extern void aarch64_linux_supply_fpregset (struct regcache *regcache,
> -                                          const gdb_byte *fpregs_buf);
> +/* Function prototypes for function transferring the general-purpose
> +   registers between GDB, inferiors and core files.  */
> +
> +/* Fill GDB's register array with the general-purpose register values
> +   in *gregs_buf.  */
> +
> +extern void aarch64_linux_supply_gregset (const struct regset *regset,
> +                                  struct regcache *regcache, int regnum,
> +                                  const void *gregs_buf, size_t len);
> +extern void aarch64_linux_collect_gregset (const struct regset *regset,
> +                                   const struct regcache *regcache,
> +                                   int regnum, void *gregs_buf, size_t len);
> +extern void aarch64_linux_supply_fpregset (const struct regset *regset,
> +                                   struct regcache *regcache, int regnum,
> +                                   const void *fpregs_buf, size_t len);
> +extern void aarch64_linux_collect_fpregset (const struct regset *regset,
> +                                    const struct regcache *regcache,
> +                                    int regnum, void *fpregs_buf, size_t len);
> --
> 1.9.1
>
Omair Javaid June 5, 2014, 5:08 p.m. UTC | #3
On 4 June 2014 22:11, Andreas Arnez <arnez@linux.vnet.ibm.com> wrote:
> On Wed, Jun 04 2014, Omair Javaid wrote:
>
>> This patch fixes aarch64 linux core file support by adding/updating
>> aarch64-linux supply/collect methods for aarch64 register set.
>
> Have you looked at that patch?
>
>   https://sourceware.org/ml/gdb-patches/2014-05/msg00637.html
>
> Apart from 'core_regset_sections', I believe it provides the same
> functionality as this patch, right?
>
Agreed!. I wrote this patch when I started work on aarch64 record
replay in april and corefile support wasnt working. I guess once
regset rework patches gets pushed then we may have to rework this
patch to extract corefile related changes only.

Thanks Andreas for bringing this up.
diff mbox

Patch

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 877e702..f631d9e 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -632,7 +632,7 @@  fill_gregset (const struct regcache *regcache,
 void
 supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
 {
-  aarch64_linux_supply_gregset (regcache, (const gdb_byte *) gregsetp);
+  aarch64_linux_supply_gregset (NULL, regcache, -1, gregsetp, 0);
 }
 
 /* Fill register REGNO (if it is a floating-point register) in
@@ -667,7 +667,7 @@  fill_fpregset (const struct regcache *regcache,
 void
 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
 {
-  aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) fpregsetp);
+  aarch64_linux_supply_fpregset (NULL, regcache, -1, fpregsetp, 0);
 }
 
 /* Called when resuming a thread.
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 30ed73f..b285818 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -191,70 +191,93 @@  static const struct tramp_frame aarch64_linux_rt_sigframe =
 };
 
 /* Fill GDB's register array with the general-purpose register values
-   in the buffer pointed by GREGS_BUF.  */
+   in the buffer pointed by gregs_buf.  */
 
 void
-aarch64_linux_supply_gregset (struct regcache *regcache,
-			      const gdb_byte *gregs_buf)
+aarch64_linux_supply_gregset (const struct regset *regset,
+                              struct regcache *regcache, int regnum,
+                              const void *gregs_buf, size_t len)
 {
+  gdb_byte *gregs_bufp = (gdb_byte *) gregs_buf;
   int regno;
 
   for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
     regcache_raw_supply (regcache, regno,
-			 gregs_buf + X_REGISTER_SIZE
+            gregs_bufp + X_REGISTER_SIZE
 			 * (regno - AARCH64_X0_REGNUM));
 }
 
-/* The "supply_regset" function for the general-purpose register set.  */
+/* Fill registers in *gregs_buf with the values in GDB's register cache.  */
 
-static void
-supply_gregset_from_core (const struct regset *regset,
-			  struct regcache *regcache,
-			  int regnum, const void *regbuf, size_t len)
+void
+aarch64_linux_collect_gregset (const struct regset *regset,
+                              const struct regcache *regcache, int regnum,
+                              void *gregs_buf, size_t len)
 {
-  aarch64_linux_supply_gregset (regcache, (const gdb_byte *) regbuf);
+  gdb_byte *gregs_bufp = (gdb_byte *) gregs_buf;
+  int regno;
+
+  for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
+    if (regnum == -1 || regnum == regno)
+      regcache_raw_collect (regcache, regno, gregs_bufp + X_REGISTER_SIZE *
+                            (regno - AARCH64_X0_REGNUM));
 }
 
 /* Fill GDB's register array with the floating-point register values
-   in the buffer pointed by FPREGS_BUF.  */
+   in the buffer pointed by fpregs_buf.  */
 
 void
-aarch64_linux_supply_fpregset (struct regcache *regcache,
-			       const gdb_byte *fpregs_buf)
+aarch64_linux_supply_fpregset (const struct regset *regset,
+                               struct regcache *regcache, int regnum,
+                               const void *fpregs_buf, size_t len)
 {
+  gdb_byte *fpregs_bufp = (gdb_byte *) fpregs_buf;
   int regno;
 
   for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
-    regcache_raw_supply (regcache, regno,
-			 fpregs_buf + V_REGISTER_SIZE
-			 * (regno - AARCH64_V0_REGNUM));
+    regcache_raw_supply (regcache, regno, fpregs_bufp + V_REGISTER_SIZE *
+                         (regno - AARCH64_V0_REGNUM));
 
-  regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM,
-		       fpregs_buf + V_REGISTER_SIZE * 32);
-  regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM,
-		       fpregs_buf + V_REGISTER_SIZE * 32 + 4);
+  regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM, fpregs_bufp +
+                       V_REGISTER_SIZE * 32);
+  regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM, fpregs_bufp +
+                       V_REGISTER_SIZE * 32 + 4);
 }
 
-/* The "supply_regset" function for the floating-point register set.  */
+/* Fill registers in *fpregs_buf with the values in GDB's register cache.  */
 
-static void
-supply_fpregset_from_core (const struct regset *regset,
-			   struct regcache *regcache,
-			   int regnum, const void *regbuf, size_t len)
+void
+aarch64_linux_collect_fpregset (const struct regset *regset,
+                                const struct regcache *regcache, int regnum,
+                                void *fpregs_buf, size_t len)
 {
-  aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) regbuf);
+  gdb_byte *fpregs_bufp = (gdb_byte *) fpregs_buf;
+  int regno;
+
+  for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
+    if (regnum == -1 || regnum == regno)
+      regcache_raw_collect (regcache, regno, fpregs_bufp + V_REGISTER_SIZE *
+                            (regno - AARCH64_V0_REGNUM));
+
+  if (regnum == -1 || regnum == AARCH64_FPSR_REGNUM)
+    regcache_raw_collect (regcache, AARCH64_FPSR_REGNUM, fpregs_bufp +
+                          V_REGISTER_SIZE * 32);
+
+  if (regnum == -1 || regnum == AARCH64_FPCR_REGNUM)
+    regcache_raw_collect (regcache, AARCH64_FPCR_REGNUM, fpregs_bufp +
+                          V_REGISTER_SIZE * 32 + 4);
 }
 
 /* Register set definitions. */
 
 static const struct regset aarch64_linux_gregset =
   {
-    NULL, supply_gregset_from_core, NULL
+    NULL, aarch64_linux_supply_gregset, aarch64_linux_collect_gregset
   };
 
 static const struct regset aarch64_linux_fpregset =
   {
-    NULL, supply_fpregset_from_core, NULL
+    NULL, aarch64_linux_supply_fpregset, aarch64_linux_collect_fpregset
   };
 
 /* Implement the "regset_from_core_section" gdbarch method.  */
@@ -275,6 +298,15 @@  aarch64_linux_regset_from_core_section (struct gdbarch *gdbarch,
   return NULL;
 }
 
+/* Core file register set sections.  */
+
+static struct core_regset_section aarch64_linux_regset_sections[] =
+{
+  { ".reg", AARCH64_LINUX_SIZEOF_GREGSET, "general-purpose" },
+  { ".reg2", AARCH64_LINUX_SIZEOF_FPREGSET, "floating-point" },
+  { NULL, 0}
+};
+
 /* Implementation of `gdbarch_stap_is_single_operand', as defined in
    gdbarch.h.  */
 
@@ -420,6 +452,9 @@  aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Enable longjmp.  */
   tdep->jb_pc = 11;
 
+  /* Install supported register note sections.  */
+  set_gdbarch_core_regset_sections (gdbarch, aarch64_linux_regset_sections);
+
   set_gdbarch_regset_from_core_section (gdbarch,
 					aarch64_linux_regset_from_core_section);
 
diff --git a/gdb/aarch64-linux-tdep.h b/gdb/aarch64-linux-tdep.h
index 48c7092..e3d7ed7 100644
--- a/gdb/aarch64-linux-tdep.h
+++ b/gdb/aarch64-linux-tdep.h
@@ -20,7 +20,21 @@ 
 
 struct regcache;
 
-extern void aarch64_linux_supply_gregset (struct regcache *regcache,
-					  const gdb_byte *gregs_buf);
-extern void aarch64_linux_supply_fpregset (struct regcache *regcache,
-					   const gdb_byte *fpregs_buf);
+/* Function prototypes for function transferring the general-purpose
+   registers between GDB, inferiors and core files.  */
+
+/* Fill GDB's register array with the general-purpose register values
+   in *gregs_buf.  */
+
+extern void aarch64_linux_supply_gregset (const struct regset *regset,
+                                  struct regcache *regcache, int regnum,
+                                  const void *gregs_buf, size_t len);
+extern void aarch64_linux_collect_gregset (const struct regset *regset,
+                                   const struct regcache *regcache,
+                                   int regnum, void *gregs_buf, size_t len);
+extern void aarch64_linux_supply_fpregset (const struct regset *regset,
+                                   struct regcache *regcache, int regnum,
+                                   const void *fpregs_buf, size_t len);
+extern void aarch64_linux_collect_fpregset (const struct regset *regset,
+                                    const struct regcache *regcache,
+                                    int regnum, void *fpregs_buf, size_t len);