Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
To: <Ezra.Sitorus@arm.com>
Cc: <gdb-patches@sourceware.org>,  <luis.machado.foss@gmail.com>
Subject: Re: [RFC PATCH 1/5] gdb/aarch64: Enable FPMR for AArch64 in gdb on Linux
Date: Wed, 10 Sep 2025 20:45:16 -0300	[thread overview]
Message-ID: <87zfb150tv.fsf@linaro.org> (raw)
In-Reply-To: <20250905131707.77027-2-Ezra.Sitorus@arm.com> (Ezra Sitorus's message of "Fri, 5 Sep 2025 14:17:03 +0100")

<Ezra.Sitorus@arm.com> writes:

> From: Ezra Sitorus <ezra.sitorus@arm.com>
>
> The Floating Point Mode Register controls the behaviours of FP8
> instructions. This patch add FPMR to GDB if it is enabled on the
> target.
>
> Manually validated with Shrinkwrap (Arm FVP).
>
> For this patch:
> * Are the FPMR fields useful? What to do if the format is not valid
>   (0x2)? What about the OSC/OSM fields with Inf/Nan, are these helpful
>   too?

I think they are useful. It's always good to get a "decoded" value from
this kind of register.

For invalid values, I think (though not sure) that GDB will just display
the "raw" value of the field since no enum value will match...

> ---
>  gdb/aarch64-linux-nat.c       | 58 ++++++++++++++++++++++++++++++++++-
>  gdb/aarch64-linux-tdep.c      |  2 +-
>  gdb/aarch64-tdep.c            | 18 +++++++++--
>  gdb/aarch64-tdep.h            |  7 +++++
>  gdb/arch/aarch64.c            |  4 +++
>  gdb/arch/aarch64.h            |  4 ++-
>  gdb/features/Makefile         |  1 +
>  gdb/features/aarch64-fpmr.c   | 44 ++++++++++++++++++++++++++
>  gdb/features/aarch64-fpmr.xml | 55 +++++++++++++++++++++++++++++++++
>  9 files changed, 188 insertions(+), 5 deletions(-)
>  create mode 100644 gdb/features/aarch64-fpmr.c
>  create mode 100644 gdb/features/aarch64-fpmr.xml
>
> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> index 89ecedda57d..b524aa352be 100644
> --- a/gdb/aarch64-linux-nat.c
> +++ b/gdb/aarch64-linux-nat.c
> @@ -604,6 +604,48 @@ store_gcsregs_to_thread (regcache *regcache)
>      perror_with_name (_("Unable to store GCS registers"));
>  }
>  
> +/* Fill GDB's REGCACHE with the FPMR register content from the
> +   thread associated with REGCACHE.  If there is no active FPMR register state,
> +   make the FPMR register contents zero.  */
> +
> +static void
> +fetch_fpmr_from_thread (struct regcache *regcache)
> +{
> +  aarch64_gdbarch_tdep *tdep
> +    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
> +
> +    int tid = regcache->ptid ().lwp ();
> +
> +    struct iovec iov;
> +    uint64_t val;
> +    iov.iov_base = &val;
> +    iov.iov_len = sizeof(val);

Missing space between function name and parenthesis.

> +
> +    if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_FPMR, &iov) < 0)
> +      perror_with_name (_("Unable to fetch FPMR"));
> +    regcache->raw_supply (tdep->fpmr_regnum, &val);
> +}
> +
> +/* Store the NT_ARM_FPMR register set contents from GDB's REGCACHE to the
> +    thread associated with REGCACHE.  */
> +static void
> +store_fpmr_to_thread (struct regcache *regcache)
> +{
> +  aarch64_gdbarch_tdep *tdep
> +    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
> +
> +  int tid = regcache->ptid ().lwp ();
> +
> +  struct iovec iov;
> +  uint64_t val;
> +  iov.iov_base = &val;
> +  iov.iov_len = sizeof(val);

Missing space between function name and parenthesis.

> +
> +  regcache->raw_collect (tdep->fpmr_regnum, (char *) &val);
> +  if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_FPMR, &iov) < 0)
> +    perror_with_name (_("Unable to store FPMR"));
> +}
> +
>  /* The AArch64 version of the "fetch_registers" target_ops method.  Fetch
>     REGNO from the target and place the result into REGCACHE.  */
>  
> @@ -642,6 +684,9 @@ aarch64_fetch_registers (struct regcache *regcache, int regno)
>  
>        if (tdep->has_gcs_linux ())
>  	fetch_gcsregs_from_thread (regcache);
> +
> +      if (tdep->has_fpmr ())
> +	fetch_fpmr_from_thread (regcache);
>      }
>    /* General purpose register?  */
>    else if (regno < AARCH64_V0_REGNUM)
> @@ -679,6 +724,9 @@ aarch64_fetch_registers (struct regcache *regcache, int regno)
>  	   && (regno == tdep->gcs_reg_base || regno == tdep->gcs_linux_reg_base
>  	       || regno == tdep->gcs_linux_reg_base + 1))
>      fetch_gcsregs_from_thread (regcache);
> +  /* FP8/FPMR? */
> +  else if (tdep->has_fpmr () && (regno == tdep->fpmr_regnum))
> +    fetch_fpmr_from_thread (regcache);
>  }
>  
>  /* A version of the "fetch_registers" target_ops method used when running
> @@ -753,6 +801,9 @@ aarch64_store_registers (struct regcache *regcache, int regno)
>  
>        if (tdep->has_gcs_linux ())
>  	store_gcsregs_to_thread (regcache);
> +
> +      if (tdep->has_fpmr ())
> +	store_fpmr_to_thread (regcache);
>      }
>    /* General purpose register?  */
>    else if (regno < AARCH64_V0_REGNUM)
> @@ -784,7 +835,9 @@ aarch64_store_registers (struct regcache *regcache, int regno)
>  	   && (regno == tdep->gcs_reg_base || regno == tdep->gcs_linux_reg_base
>  	       || regno == tdep->gcs_linux_reg_base + 1))
>      store_gcsregs_to_thread (regcache);
> -
> +  /* FPMR?  */
> +  else if (tdep->has_fpmr() && regno == tdep->fpmr_regnum)
> +    store_fpmr_to_thread (regcache);
>    /* PAuth registers are read-only.  */
>  }
>  
> @@ -969,6 +1022,9 @@ aarch64_linux_nat_target::read_description ()
>    if ((hwcap2 & HWCAP2_SME2) || (hwcap2 & HWCAP2_SME2P1))
>      features.sme2 = supports_zt_registers (tid);
>  
> +  /* Check for FP8/FPMR. */

Two spaces after the period.

> +  features.fpmr = hwcap2 & (1UL << 48);
> +

Both Linux and glibc define HWCAP2_FPMR so it's better to use it here
and in the two other places were you use this value (one of them is in
another patch).

You can provide a definition in a header file for the case where the
system headers aren't new enough to have it, as is done for HWCAP_GCS
and HWCAP_MTE. With the difference that in both of those cases there's a
separate header specific for that hardware feature. For FPMR, I'd put
the definition in gdb/arch/aarch64.h.

>    return aarch64_read_description (features);
>  }
>  
> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> index 76bde85188b..acb650db514 100644
> --- a/gdb/aarch64-linux-tdep.c
> +++ b/gdb/aarch64-linux-tdep.c
> @@ -1713,7 +1713,7 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
>    features.pauth = hwcap & AARCH64_HWCAP_PACA;
>    features.gcs = features.gcs_linux = hwcap & HWCAP_GCS;
>    features.mte = hwcap2 & HWCAP2_MTE;
> -

It's subjective, but I think the code looks better with this blank line
separating this setup of the features struct and the "Handle the TLS
section" part below.

> +  features.fpmr = hwcap2 & (1UL << 48);

Here too, you can use HWCAP2_FPMR.

>    /* Handle the TLS section.  */
>    asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
>    if (tls != nullptr)
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index 500ac77d75a..33bef91c44e 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -4141,6 +4141,10 @@ aarch64_features_from_target_desc (const struct target_desc *tdesc)
>  			!= nullptr);
>  
>    return features;
> +
> +  /* Check for FPMR feature.  */
> +  features.fpmr = (tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpmr")
> +		   != nullptr);

This needs to be above the return.

>  }
>  
>  /* Implement the "cannot_store_register" gdbarch method.  */
> @@ -4448,11 +4452,12 @@ static struct gdbarch *
>  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
>    const struct tdesc_feature *feature_core, *feature_fpu, *feature_sve;
> -  const struct tdesc_feature *feature_pauth;
> +  const struct tdesc_feature *feature_pauth, *feature_fpmr;
>    bool valid_p = true;
>    int i, num_regs = 0, num_pseudo_regs = 0;
>    int first_pauth_regnum = -1, ra_sign_state_offset = -1;
>    int first_mte_regnum = -1, first_tls_regnum = -1;
> +  int fpmr_regnum = -1;
>    uint64_t vq = aarch64_get_tdesc_vq (info.target_desc);
>    uint64_t svq = aarch64_get_tdesc_svq (info.target_desc);
>  
> @@ -4550,6 +4555,14 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>        num_pseudo_regs += 32;	/* add the Bn scalar register pseudos */
>      }
>  
> +  feature_fpmr = tdesc_find_feature (tdesc, "org.gnu.gdb.aarch64.fpmr");
> +  if (feature_fpmr != nullptr)
> +  {
> +    fpmr_regnum = num_regs++;
> +    valid_p &= tdesc_numbered_register (feature_fpmr, tdesc_data.get (),
> +					fpmr_regnum, "fpmr");
> +  }
> +

The curly braces need to be indented 2 spaces forward.

>    int first_sme_regnum = -1;
>    int first_sme2_regnum = -1;
>    int first_sme_pseudo_regnum = -1;
> @@ -4760,7 +4773,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    /* Set the SME2 register set details.  */
>    tdep->sme2_zt0_regnum = first_sme2_regnum;
> -
> +  /* Set the FPMR regnum.  */
> +  tdep->fpmr_regnum = fpmr_regnum;
>    set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call);
>    set_gdbarch_frame_align (gdbarch, aarch64_frame_align);
>  
> diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h
> index 99e7d26ce4a..403743516df 100644
> --- a/gdb/aarch64-tdep.h
> +++ b/gdb/aarch64-tdep.h
> @@ -207,6 +207,13 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep_base
>    {
>      return gcs_linux_reg_base != -1;
>    }

Missing blank line here.

> +  /* Index of FPMR. This is -1 if FPMR/FP8 is not supported. */

Missing two spaces after the two periods.

> +  int fpmr_regnum = -1;
> +
> +  bool has_fpmr () const

bool needs to be on its own line.

> +  {
> +    return fpmr_regnum != -1;
> +  }
>  };

-- 
Thiago

  parent reply	other threads:[~2025-09-10 23:45 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-05 13:17 [RFC PATCH 0/5] gdb/aarch64: Support for FPMR Ezra.Sitorus
2025-09-05 13:17 ` [RFC PATCH 1/5] gdb/aarch64: Enable FPMR for AArch64 in gdb on Linux Ezra.Sitorus
2025-09-07 22:55   ` Luis
2025-09-10 23:56     ` Thiago Jung Bauermann
2025-09-10 23:45   ` Thiago Jung Bauermann [this message]
2025-09-05 13:17 ` [RFC PATCH 2/5] gdbserver/aarch64: Enable FPMR for AArch64 in gdbserver " Ezra.Sitorus
2025-09-07 22:55   ` Luis
2025-09-10 23:46   ` Thiago Jung Bauermann
2025-09-05 13:17 ` [RFC PATCH 3/5] gdb/aarch64: signal frame support for fpmr Ezra.Sitorus
2025-09-07 22:56   ` Luis
2025-09-11  0:03     ` Thiago Jung Bauermann
2025-09-10 23:47   ` Thiago Jung Bauermann
2025-09-05 13:17 ` [RFC PATCH 4/5] gdb/aarch64: core file support for FPMR Ezra.Sitorus
2025-09-07 22:56   ` Luis
2025-09-10 23:48   ` Thiago Jung Bauermann
2025-09-05 13:17 ` [RFC PATCH 5/5] gdb/aarch64: Tests for fpmr Ezra.Sitorus
2025-09-07 22:56   ` Luis
2025-09-16 11:09     ` Ezra Sitorus
2025-09-16 23:50       ` Luis
2025-09-10 23:53   ` Thiago Jung Bauermann
2025-09-10 23:39 ` [RFC PATCH 0/5] gdb/aarch64: Support for FPMR Thiago Jung Bauermann
2025-09-11 15:52   ` Ezra Sitorus
2025-09-12  3:17     ` Thiago Jung Bauermann

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=87zfb150tv.fsf@linaro.org \
    --to=thiago.bauermann@linaro.org \
    --cc=Ezra.Sitorus@arm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=luis.machado.foss@gmail.com \
    /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