[binutils-gdb] bfd/ELF: Core file support for AArch64 FPMR

Ezra Sitorus ezrasitorus@sourceware.org
Mon Nov 17 12:46:57 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3c3f58814b17db4f875721481ecf264714d47a1d

commit 3c3f58814b17db4f875721481ecf264714d47a1d
Author: Ezra Sitorus <ezra.sitorus@arm.com>
Date:   Mon Nov 17 12:45:58 2025 +0000

    bfd/ELF: Core file support for AArch64 FPMR
    
    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.

Diff:
---
 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 c9aa3ff9ca9..418b4e91b8b 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -3037,6 +3037,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 1f4109ddf48..bf50fc21f95 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"
@@ -10731,6 +10732,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)
 {
@@ -11164,6 +11174,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);
@@ -12877,6 +12888,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,
@@ -12983,6 +13010,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 933dd34d4a8..633453ae2b2 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -21437,6 +21437,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 8a2ab7b055e..2db8a7d5a47 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".  */


More information about the Binutils-cvs mailing list