[2/7] Fixes for aarch64-linux gdb core file support
Commit Message
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
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?
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
>
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.
@@ -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.
@@ -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);
@@ -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);