[PATCH v2] bfd/aarch64: Core file support for FPMR

Ezra.Sitorus@arm.com Ezra.Sitorus@arm.com
Tue Oct 21 15:20:18 GMT 2025


From: Ezra Sitorus <ezra.sitorus@arm.com>

The Floating Point Mode Register is a new register which controls the
behaviour of FP8 instructions. This is handled by the Linux kernel
through a new NT_ARM_FPMR register set.

This patch adds required code to support core file dumps with
NT_ARM_FPMR in them.
---
Changes from v1->v2:
* Updated comment about ".reg-aarch-fpmr".

I'm unsure about changing 'AArch64 FPMR' to 'AArch64 FPMR register'. It
doesn't follow the others as mentioned in the comments, but I think for
this case it's cleaner if it doesn't have 'register'. 

The gdb patches can be found here:
https://inbox.sourceware.org/gdb-patches/20251021150300.59860-1-Ezra.Sitorus@arm.com/T/#t

Ezra

 bfd/elf-bfd.h        |  2 ++
 bfd/elf.c            | 28 ++++++++++++++++++++++++++++
 binutils/readelf.c   |  2 ++
 include/elf/common.h |  2 ++
 4 files changed, 34 insertions(+)

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index de7cc410a99..7fff172b84e 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -3003,6 +3003,8 @@ extern char *elfcore_write_aarch_za
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_aarch_zt
   (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_fpmr
+  (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_arc_v2
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_riscv_csr
diff --git a/bfd/elf.c b/bfd/elf.c
index 6ef60301091..7110d5ba819 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -61,6 +61,7 @@ SECTION
 #define NOTE_NAME_LINUX    "LINUX"
 
 /* Names of a pseudo-section which represent core notes.  */
+#define NOTE_PSEUDO_SECTION_AARCH_FPMR		".reg-aarch-fpmr"
 #define NOTE_PSEUDO_SECTION_AARCH_GCS		".reg-aarch-gcs"
 #define NOTE_PSEUDO_SECTION_AARCH_HW_BREAK	".reg-aarch-hw-break"
 #define NOTE_PSEUDO_SECTION_AARCH_HW_WATCH	".reg-aarch-hw-watch"
@@ -10732,6 +10733,15 @@ elfcore_grok_aarch_gcs (bfd *abfd, Elf_Internal_Note *note)
   return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_GCS, note);
 }
 
+/* Convert NOTE into the appropriate note pseudo-section for the AArch64 FPMR.
+ * Return TRUE if successful, otherwise return FALSE.  */
+
+static bool
+elfcore_grok_aarch_fpmr (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_FPMR, note);
+}
+
 static bool
 elfcore_grok_arc_v2 (bfd *abfd, Elf_Internal_Note *note)
 {
@@ -11165,6 +11175,7 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 	{
 	case NT_386_TLS:	return elfcore_grok_i386_tls (abfd, note);
 	case NT_ARC_V2:		return elfcore_grok_arc_v2 (abfd, note);
+	case NT_ARM_FPMR:	return elfcore_grok_aarch_fpmr (abfd, note);
 	case NT_ARM_GCS:	return elfcore_grok_aarch_gcs (abfd, note);
 	case NT_ARM_HW_BREAK:	return elfcore_grok_aarch_hw_break (abfd, note);
 	case NT_ARM_HW_WATCH:	return elfcore_grok_aarch_hw_watch (abfd, note);
@@ -12878,6 +12889,22 @@ elfcore_write_aarch_gcs (bfd *abfd, char *buf, int *bufsiz,
 			     aarch_gcs, size);
 }
 
+/* Write the buffer of FPMR value in AARCH_FPMR (length SIZE) into
+   the note buffer BUF and update *BUFSIZ.  ABFD is the bfd the note is being
+   written into.  Return a pointer to the new start of the note buffer, to
+   replace BUF which may no longer be valid.  */
+
+char *
+elfcore_write_aarch_fpmr (bfd *abfd,
+			char *buf,
+			int *bufsiz,
+			const void *aarch_fpmr,
+			int size)
+{
+  return elfcore_write_note (abfd, buf, bufsiz,
+			     NOTE_NAME_LINUX, NT_ARM_FPMR, aarch_fpmr, size);
+}
+
 char *
 elfcore_write_arc_v2 (bfd *abfd,
 		      char *buf,
@@ -12984,6 +13011,7 @@ elfcore_write_register_note (bfd *abfd,
     }
   note_writers [] =
     {
+      { NOTE_PSEUDO_SECTION_AARCH_FPMR,       elfcore_write_aarch_fpmr},
       { NOTE_PSEUDO_SECTION_AARCH_GCS,        elfcore_write_aarch_gcs},
       { NOTE_PSEUDO_SECTION_AARCH_HW_BREAK,   elfcore_write_aarch_hw_break},
       { NOTE_PSEUDO_SECTION_AARCH_HW_WATCH,   elfcore_write_aarch_hw_watch},
diff --git a/binutils/readelf.c b/binutils/readelf.c
index fd9722c8afc..00d2c987108 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -21433,6 +21433,8 @@ get_note_type (Filedata * filedata, unsigned e_type)
 	return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
       case NT_ARM_PAC_ENABLED_KEYS:
 	return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
+      case NT_ARM_FPMR:
+	return _("NT_ARM_FPMR (AArch64 Floating Point Mode Register)");
       case NT_ARC_V2:
 	return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
       case NT_RISCV_CSR:
diff --git a/include/elf/common.h b/include/elf/common.h
index 5d0f93ebf56..785d8ca7e28 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -755,6 +755,8 @@
 					/*   Note: name must be "LINUX".  */
 #define NT_ARM_ZT       0x40d           /* AArch64 SME2 ZT registers.  */
 					/*   Note: name must be "LINUX".  */
+#define NT_ARM_FPMR     0x40e           /* AArch64 FPMR.  */
+					/*   Note: name must be "LINUX".  */
 #define NT_ARM_GCS	0x410		/* AArch64 Guarded Control Stack
 					   registers.  */
 					/*   Note  name must be "LINUX".  */
-- 
2.45.2



More information about the Binutils mailing list