This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PING][RFC] Core file support for Aaarch64 SVE
- From: Alan Hayward <Alan dot Hayward at arm dot com>
- To: "gdb-patches at sourceware dot org" <gdb-patches at sourceware dot org>
- Cc: nd <nd at arm dot com>
- Date: Mon, 2 Jul 2018 15:35:38 +0000
- Subject: [PING][RFC] Core file support for Aaarch64 SVE
- References: <20180625151002.35415-1-alan.hayward@arm.com>
Ping.
Hoping patch should mostly be fine, just need some advice on where
to move functions to get the all-targets build working.
Alan.
> On 25 Jun 2018, at 16:10, Alan Hayward <Alan.Hayward@arm.com> wrote:
>
> The following patch fails to compile for an all targets build.
> This is due to aarch64-linux-tdep.c requiring functions from
> nat/aarch64-sve-linux-ptrace.c. This is used because the SVE
> section of a aarch64 core file starts with a header structure
> (the same as in a ptrace read), which is defined in the kernel.
>
> I considered putting the nat/ file into an all targets build, but
> this seemed wrong (in addition it would require additional .deps
> dir adding for nat/).
>
> What is the correct solution here? Should I move the required nat/
> functions into elsewhere? The arch/ still doesn't feel right.
>
> Other than the above issue, the patch is ready and working. I thought
> it best to ask here rather than guess the correct solution.
>
> Thanks,
> Alan
>
> Support both the reading and writing of core files on aarch64 SVE.
>
> SVE core files are doumented here:
> https://github.com/torvalds/linux/blob/master/Documentation/arm64/sve.txt
> * A NT_ARM_SVE note will be added to each coredump for each thread of the
> dumped process. The contents will be equivalent to the data that would have
> been read if a PTRACE_GETREGSET of NT_ARM_SVE were executed for each thread
> when the coredump was generated.
>
> When creating a core files target description, read the SVE section to find
> the vector length.
>
> When reading/writing core files, use the existing nat/ functions to parse
> the structure. Given that the function is only called through the one call
> chain, there is no need to support copying a single register or invalidating
> the set.
>
> Dependant on binutils patch "[PATCH] Add BFD core support for Aarch64 SVE"
> https://sourceware.org/ml/binutils/2018-06/msg00314.html
>
> Checked with make check on x86 and aarch64.
> Generated core files on SVE emulator both from gdb "generate-core-file"
> command and a segfault. Loaded these back into gdb.
>
> 2018-06-25 Alan Hayward <alan.hayward@arm.com>
>
> gdb/
> * aarch64-linux-tdep.c (aarch64_linux_core_read_vq): New function.
> (aarch64_linux_supply_sve_regset): Likewise.
> (aarch64_linux_collect_sve_regset): Likewise.
> (aarch64_linux_iterate_over_regset_sections): Check for SVE.
> (aarch64_linux_core_read_description): Likewise.
> * nat/aarch64-sve-linux-sigcontext.h (struct _aarch64_ctx): Add for
> build compatibility.
> (struct user_fpsimd_state): Likewise.
> ---
> gdb/aarch64-linux-tdep.c | 114 ++++++++++++++++++++++++++++++++-
> gdb/nat/aarch64-sve-linux-sigcontext.h | 14 ++++
> 2 files changed, 125 insertions(+), 3 deletions(-)
>
> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> index 93b6d416a3..919873b816 100644
> --- a/gdb/aarch64-linux-tdep.c
> +++ b/gdb/aarch64-linux-tdep.c
> @@ -47,6 +47,7 @@
> #include "linux-record.h"
> #include "auxv.h"
> #include "elf/common.h"
> +#include "nat/aarch64-sve-linux-ptrace.h"
>
> /* Signal frame handling.
>
> @@ -169,6 +170,100 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self,
> trad_frame_set_id (this_cache, frame_id_build (sp, func));
> }
>
> +
> +/* Get VG value from SVE section in the core dump. */
> +
> +static uint64_t
> +aarch64_linux_core_read_vq (bfd *abfd)
> +{
> + struct user_sve_header header;
> + asection *sve_section = bfd_get_section_by_name (abfd, ".reg-aarch-sve");
> +
> + if (!sve_section)
> + {
> + /* No SVE state. */
> + return 0;
> + }
> +
> + size_t size = bfd_section_size (abfd, sve_section);
> +
> + /* Check extended state size. */
> + if (size < sizeof (struct user_sve_header))
> + {
> + warning (_("'.reg-aarch-sve' section in core file too small."));
> + return 0;
> + }
> +
> + if (! bfd_get_section_contents (abfd, sve_section, &header, 0,
> + sizeof (struct user_sve_header)))
> + {
> + warning (_("Couldn't read sve header from "
> + "'.reg-aarch-sve' section in core file."));
> + return 0;
> + }
> +
> + if (!sve_vl_valid (header.vl))
> + {
> + warning (_("sve header invalid in"
> + "'.reg-aarch-sve' section in core file."));
> + return 0;
> + }
> +
> + return sve_vq_from_vl (header.vl);
> +}
> +
> +
> +/* Supply register REGNUM from BUF to REGCACHE, ignoring the register map
> + in REGSET. */
> +
> +static void
> +aarch64_linux_supply_sve_regset (const struct regset *regset,
> + struct regcache *regcache,
> + int regnum, const void *buf, size_t size)
> +{
> + /* Only called via aarch64_linux_iterate_over_regset_sections loop, so no
> + need to support anything other than a full regset, and no need to support
> + null buffers. */
> + gdb_assert (buf != NULL);
> + gdb_assert (regnum == -1);
> +
> + aarch64_sve_regs_copy_to_reg_buf (regcache, buf);
> +}
> +
> +/* Collect register REGNUM from REGCACHE to BUF, ignoring the register
> + map in REGSET. If REGNUM is -1, do this for all registers in
> + REGSET. */
> +
> +static void
> +aarch64_linux_collect_sve_regset (const struct regset *regset,
> + const struct regcache *regcache,
> + int regnum, void *buf, size_t size)
> +{
> + /* Only called via aarch64_linux_iterate_over_regset_sections loop, so no
> + need to support anything other than a full regset, and no need to support
> + null buffers. */
> + gdb_assert (buf != NULL);
> + gdb_assert (regnum == -1);
> +
> + /* Read vector size from regcache. */
> + uint64_t vg;
> + regcache->raw_collect_integer (AARCH64_SVE_VG_REGNUM, (gdb_byte *)&vg,
> + sizeof (uint64_t), false);
> + uint64_t vq = sve_vq_from_vg (vg);
> +
> + /* Initialize a valid SVE header. */
> + struct user_sve_header *header = (struct user_sve_header *)buf;
> + header->flags = SVE_PT_REGS_SVE;
> + header->size = SVE_PT_SIZE (vq, header->flags);
> + header->max_size = size;
> + header->vl = sve_vl_from_vg (vg);
> + header->max_vl = SVE_VL_MAX;
> +
> + gdb_assert (size >= header->size);
> +
> + aarch64_sve_regs_copy_from_reg_buf (regcache, buf);
> +}
> +
> static const struct tramp_frame aarch64_linux_rt_sigframe =
> {
> SIGTRAMP_FRAME,
> @@ -219,6 +314,12 @@ const struct regset aarch64_linux_fpregset =
> regcache_supply_regset, regcache_collect_regset
> };
>
> +const struct regset aarch64_linux_sve_regset =
> + {
> + NULL, aarch64_linux_supply_sve_regset, aarch64_linux_collect_sve_regset,
> + REGSET_VARIABLE_SIZE
> + };
> +
> /* Implement the "regset_from_core_section" gdbarch method. */
>
> static void
> @@ -227,10 +328,17 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
> void *cb_data,
> const struct regcache *regcache)
> {
> + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +
> cb (".reg", AARCH64_LINUX_SIZEOF_GREGSET, &aarch64_linux_gregset,
> NULL, cb_data);
> - cb (".reg2", AARCH64_LINUX_SIZEOF_FPREGSET, &aarch64_linux_fpregset,
> - NULL, cb_data);
> +
> + if (tdep->has_sve ())
> + cb (".reg-aarch-sve", SVE_PT_SIZE (tdep->vq, 0),
> + &aarch64_linux_sve_regset, "SVE registers", cb_data);
> + else
> + cb (".reg2", AARCH64_LINUX_SIZEOF_FPREGSET, &aarch64_linux_fpregset, NULL,
> + cb_data);
> }
>
> /* Implement the "core_read_description" gdbarch method. SVE not yet
> @@ -245,7 +353,7 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
> if (target_auxv_search (target, AT_HWCAP, &aarch64_hwcap) != 1)
> return NULL;
>
> - return aarch64_read_description (0);
> + return aarch64_read_description (aarch64_linux_core_read_vq (abfd));
> }
>
> /* Implementation of `gdbarch_stap_is_single_operand', as defined in
> diff --git a/gdb/nat/aarch64-sve-linux-sigcontext.h b/gdb/nat/aarch64-sve-linux-sigcontext.h
> index bdece8e17d..ad6e111e71 100644
> --- a/gdb/nat/aarch64-sve-linux-sigcontext.h
> +++ b/gdb/nat/aarch64-sve-linux-sigcontext.h
> @@ -19,6 +19,20 @@
> #ifndef AARCH64_SVE_LINUX_SIGCONTEXT_H
> #define AARCH64_SVE_LINUX_SIGCONTEXT_H
>
> +#ifndef _aarch64_ctx
> +struct _aarch64_ctx {
> + __u32 magic;
> + __u32 size;
> +};
> +
> +struct user_fpsimd_state {
> + __uint128_t vregs[32];
> + __u32 fpsr;
> + __u32 fpcr;
> + __u32 __reserved[2];
> +};
> +#endif
> +
> #define SVE_MAGIC 0x53564501
>
> struct sve_context {
> --
> 2.15.2 (Apple Git-101.1)
>