[v3,4/5,4/5] gdb/aarch64: Add core file support for FEAT_S1POE

Message ID 20260714201530.78374-5-srinath.parvathaneni@arm.com
State New
Headers
Series gdb/aarch64: Add POR_EL0 register support for FEAT_S1POE |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed

Commit Message

Srinath Parvathaneni July 14, 2026, 8:15 p.m. UTC
  From: Srinath Parvathaneni <srinath.parvathaneni@arm.com>

Add support for POR_EL0 dumps/reads for core files and also the
support for reading the POE values in the signal frame.
---
 gdb/aarch64-linux-tdep.c | 50 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
  

Comments

Luis Machado July 21, 2026, 8:14 p.m. UTC | #1
On 14/07/2026 21:15, srinath.parvathaneni@arm.com wrote:
> From: Srinath Parvathaneni <srinath.parvathaneni@arm.com>
> 
> Add support for POR_EL0 dumps/reads for core files and also the
> support for reading the POE values in the signal frame.

You might want to split this patch in two for corefile and signal frame 
support, or update the patch subject to clarify what this is doing.

> ---
>   gdb/aarch64-linux-tdep.c | 50 ++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 50 insertions(+)
> 
> diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
> index b8a02ab9972..94ed3234009 100644
> --- a/gdb/aarch64-linux-tdep.c
> +++ b/gdb/aarch64-linux-tdep.c
> @@ -171,6 +171,7 @@
>   #define AARCH64_ZT_MAGIC			0x5a544e01
>   #define AARCH64_GCS_MAGIC			0x47435300
>   #define AARCH64_FPMR_MAGIC			0x46504d52
> +#define AARCH64_POE_MAGIC			0x504f4530
>   
>   /* Defines for the extra_context that follows an AARCH64_EXTRA_MAGIC.  */
>   #define AARCH64_EXTRA_DATAP_OFFSET		8
> @@ -220,6 +221,9 @@
>   /* FPMR constants.  */
>   #define AARCH64_FPMR_OFFSET			8
>   
> +/* POE constants.  */
> +#define AARCH64_POE_OFFSET			8
> +
>   /* Holds information about the signal frame.  */
>   struct aarch64_linux_sigframe
>   {
> @@ -273,6 +277,10 @@ struct aarch64_linux_sigframe
>     /* FPMR value.  */
>     CORE_ADDR fpmr = 0;
>   
> +  /* True if we have an POE entry in the signal context, false otherwise.  */

Nit: s/an POE/a POE

> +  bool poe_available = false;
> +  /* FPMR value.  */

Spurious change above?

> +  CORE_ADDR poe = 0;
>   };
>   
>   /* Read an aarch64_ctx, returning the magic value, and setting *SIZE to the
> @@ -605,6 +613,22 @@ aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame,
>   	    section += size;
>   	    break;
>   	  }
> +	case AARCH64_POE_MAGIC:
> +	  {
> +	    gdb_byte buf[8];
> +	    if (target_read_memory (section + AARCH64_POE_OFFSET,
> +				    buf, 8) != 0)
> +	      {
> +		warning (_("Failed to read the POE section address from the"
> +			   " signal frame context."));
> +		section += size;
> +		break;
> +	      }
> +	    signal_frame.poe = extract_unsigned_integer (buf, 8, byte_order);
> +	    signal_frame.poe_available = true;
> +	    section += size;
> +	    break;
> +	  }
>   	case AARCH64_EXTRA_MAGIC:
>   	  {
>   	    /* Extra is always the last valid section in reserved and points to
> @@ -775,6 +799,13 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self,
>   			      signal_frame.fpmr);
>     }
>   
> +  /* Handle POE register.  */
> +  if (tdep->has_poe () && signal_frame.poe_available)
> +  {
> +    trad_frame_set_reg_value (this_cache, tdep->poe_regnum,
> +			      signal_frame.poe);

Is the identation off above?

> +  }
> +
>     /* Restore the tpidr2 register, if the target supports it and if there is
>        an entry for it.  */
>     if (signal_frame.tpidr2_section != 0 && tdep->has_tls ()
> @@ -828,6 +859,7 @@ aarch64_linux_sigframe_prev_arch (const frame_info_ptr &this_frame,
>     features.vq = sve_vq_from_vl (signal_frame.vl);
>     features.svq = (uint8_t) sve_vq_from_vl (signal_frame.svl);
>     features.fpmr = signal_frame.fpmr_available;
> +  features.poe = signal_frame.poe_available;
>   
>     struct gdbarch_info info;
>     info.bfd_arch_info = bfd_lookup_arch (bfd_arch_aarch64, bfd_mach_aarch64);
> @@ -1655,6 +1687,23 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
>   	  &aarch64_linux_fpmr_regset, "FPMR", cb_data);
>       }
>   
> +  if (tdep->has_poe ())
> +    {
> +      const struct regcache_map_entry poe_regmap[] =
> +	{
> +	  { 1, tdep->poe_regnum, sizeof (uint64_t) },
> +	  { 0 }
> +	};
> +
> +      const struct regset aarch64_linux_poe_regset =
> +	{
> +	  poe_regmap, regcache_supply_regset, regcache_collect_regset
> +	};
> +
> +      cb (".reg-aarch-poe", sizeof (uint64_t), sizeof (uint64_t),
> +	  &aarch64_linux_poe_regset, "POE register", cb_data);
> +    }
> +
>     if (tdep->has_pauth ())
>       {
>         /* Create this on the fly in order to handle the variable location.  */
> @@ -1768,6 +1817,7 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
>     features.gcs = features.gcs_linux = hwcap & AARCH64_HWCAP_GCS;
>     features.mte = hwcap2 & AARCH64_HWCAP2_MTE;
>     features.fpmr = hwcap2 & AARCH64_HWCAP2_FPMR;
> +  features.poe = hwcap2 & AARCH64_HWCAP2_POE;
>   
>     /* Handle the TLS section.  */
>     asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");
  

Patch

diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index b8a02ab9972..94ed3234009 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -171,6 +171,7 @@ 
 #define AARCH64_ZT_MAGIC			0x5a544e01
 #define AARCH64_GCS_MAGIC			0x47435300
 #define AARCH64_FPMR_MAGIC			0x46504d52
+#define AARCH64_POE_MAGIC			0x504f4530
 
 /* Defines for the extra_context that follows an AARCH64_EXTRA_MAGIC.  */
 #define AARCH64_EXTRA_DATAP_OFFSET		8
@@ -220,6 +221,9 @@ 
 /* FPMR constants.  */
 #define AARCH64_FPMR_OFFSET			8
 
+/* POE constants.  */
+#define AARCH64_POE_OFFSET			8
+
 /* Holds information about the signal frame.  */
 struct aarch64_linux_sigframe
 {
@@ -273,6 +277,10 @@  struct aarch64_linux_sigframe
   /* FPMR value.  */
   CORE_ADDR fpmr = 0;
 
+  /* True if we have an POE entry in the signal context, false otherwise.  */
+  bool poe_available = false;
+  /* FPMR value.  */
+  CORE_ADDR poe = 0;
 };
 
 /* Read an aarch64_ctx, returning the magic value, and setting *SIZE to the
@@ -605,6 +613,22 @@  aarch64_linux_read_signal_frame_info (const frame_info_ptr &this_frame,
 	    section += size;
 	    break;
 	  }
+	case AARCH64_POE_MAGIC:
+	  {
+	    gdb_byte buf[8];
+	    if (target_read_memory (section + AARCH64_POE_OFFSET,
+				    buf, 8) != 0)
+	      {
+		warning (_("Failed to read the POE section address from the"
+			   " signal frame context."));
+		section += size;
+		break;
+	      }
+	    signal_frame.poe = extract_unsigned_integer (buf, 8, byte_order);
+	    signal_frame.poe_available = true;
+	    section += size;
+	    break;
+	  }
 	case AARCH64_EXTRA_MAGIC:
 	  {
 	    /* Extra is always the last valid section in reserved and points to
@@ -775,6 +799,13 @@  aarch64_linux_sigframe_init (const struct tramp_frame *self,
 			      signal_frame.fpmr);
   }
 
+  /* Handle POE register.  */
+  if (tdep->has_poe () && signal_frame.poe_available)
+  {
+    trad_frame_set_reg_value (this_cache, tdep->poe_regnum,
+			      signal_frame.poe);
+  }
+
   /* Restore the tpidr2 register, if the target supports it and if there is
      an entry for it.  */
   if (signal_frame.tpidr2_section != 0 && tdep->has_tls ()
@@ -828,6 +859,7 @@  aarch64_linux_sigframe_prev_arch (const frame_info_ptr &this_frame,
   features.vq = sve_vq_from_vl (signal_frame.vl);
   features.svq = (uint8_t) sve_vq_from_vl (signal_frame.svl);
   features.fpmr = signal_frame.fpmr_available;
+  features.poe = signal_frame.poe_available;
 
   struct gdbarch_info info;
   info.bfd_arch_info = bfd_lookup_arch (bfd_arch_aarch64, bfd_mach_aarch64);
@@ -1655,6 +1687,23 @@  aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
 	  &aarch64_linux_fpmr_regset, "FPMR", cb_data);
     }
 
+  if (tdep->has_poe ())
+    {
+      const struct regcache_map_entry poe_regmap[] =
+	{
+	  { 1, tdep->poe_regnum, sizeof (uint64_t) },
+	  { 0 }
+	};
+
+      const struct regset aarch64_linux_poe_regset =
+	{
+	  poe_regmap, regcache_supply_regset, regcache_collect_regset
+	};
+
+      cb (".reg-aarch-poe", sizeof (uint64_t), sizeof (uint64_t),
+	  &aarch64_linux_poe_regset, "POE register", cb_data);
+    }
+
   if (tdep->has_pauth ())
     {
       /* Create this on the fly in order to handle the variable location.  */
@@ -1768,6 +1817,7 @@  aarch64_linux_core_read_description (struct gdbarch *gdbarch,
   features.gcs = features.gcs_linux = hwcap & AARCH64_HWCAP_GCS;
   features.mte = hwcap2 & AARCH64_HWCAP2_MTE;
   features.fpmr = hwcap2 & AARCH64_HWCAP2_FPMR;
+  features.poe = hwcap2 & AARCH64_HWCAP2_POE;
 
   /* Handle the TLS section.  */
   asection *tls = bfd_get_section_by_name (abfd, ".reg-aarch-tls");