bfd: Add support to read note that describes xsave layout

Message ID 20250911071756.1210629-1-vigbalas@amd.com
State New
Headers
Series bfd: Add support to read note that describes xsave layout |

Commit Message

Vignesh Balasubramanian Sept. 11, 2025, 7:17 a.m. UTC
  This note section is already supported by Linux kernel.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/x86/kernel/fpu/xstate.c?id=ba386777a30b38dabcc7fb8a89ec2869a09915f7

Co-Authored-By: Jini Susan George <jinisusan.george@amd.com>
---
 bfd/elf-bfd.h        |  2 ++
 bfd/elf.c            | 24 +++++++++++++++++++++++-
 binutils/readelf.c   |  2 ++
 include/elf/common.h |  2 ++
 4 files changed, 29 insertions(+), 1 deletion(-)
  

Comments

Jan Beulich Sept. 11, 2025, 7:40 a.m. UTC | #1
On 11.09.2025 09:17, Vignesh Balasubramanian wrote:
> --- a/bfd/elf.c
> +++ b/bfd/elf.c
> @@ -114,6 +114,7 @@ SECTION
>  #define NOTE_PSEUDO_SECTION_X86_SEGBASES 	".reg-x86-segbases"
>  #define NOTE_PSEUDO_SECTION_XFP          	".reg-xfp"
>  #define NOTE_PSEUDO_SECTION_XSTATE       	".reg-xstate"
> +#define NOTE_PSEUDO_SECTION_XSAVE_LAYOUT	".reg.xsave.layout"

Why dots instead of dashes as separators here, and ...

> @@ -10492,6 +10493,14 @@ elfcore_grok_sspreg (bfd *abfd, Elf_Internal_Note *note)
>    return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_SSP, note);
>  }
>  
> +/* Linux dumps the XSAVE Layout description in a note named "LINUX"
> +   with a note type of NT_X86_XSAVE_LAYOUT. */
> +static bool
> +elfcore_grok_xsave_layout_desc (bfd *abfd, Elf_Internal_Note *note)
> +{
> +  return elfcore_make_note_pseudosection (abfd, ".reg-xsave-layout", note);

... why not using the #define here?

> @@ -12390,6 +12400,17 @@ elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
>  			     note_name, NT_X86_XSTATE, xfpregs, size);
>  }
>  
> +char *
> +elfcore_write_xsave_layout (bfd *abfd, char *buf, int *bufsiz,
> +			    const void *xsave_layout, int size)
> +{
> +  return elfcore_write_note (abfd, buf, bufsiz,
> +			     NOTE_NAME_LINUX,
> +			     NT_X86_XSAVE_LAYOUT,
> +			     xsave_layout,
> +			     size);
> +}
> +
>  static char *
>  elfcore_write_sspreg (bfd *abfd, char *buf, int *bufsiz,
>  		      const void *ssp, int size)
> @@ -13035,7 +13056,8 @@ elfcore_write_register_note (bfd *abfd,
>        { NOTE_PSEUDO_SECTION_TDESC,            elfcore_write_gdb_tdesc},
>        { NOTE_PSEUDO_SECTION_X86_SEGBASES,     elfcore_write_x86_segbases},
>        { NOTE_PSEUDO_SECTION_XFP,              elfcore_write_prxfpreg},
> -      { NOTE_PSEUDO_SECTION_XSTATE,           elfcore_write_xstatereg} /* NB/ No comma.  */
> +      { NOTE_PSEUDO_SECTION_XSTATE,           elfcore_write_xstatereg},
> +      { NOTE_PSEUDO_SECTION_XSAVE_LAYOUT,     elfcore_write_xsave_layout} /* NB/ No comma.  */
>      };

Considering the subject: There's more code here dealing with writing of
such a note ...

> --- a/binutils/readelf.c
> +++ b/binutils/readelf.c
> @@ -21375,6 +21375,8 @@ get_note_type (Filedata * filedata, unsigned e_type)
>  	return _("NT_386_IOPERM (x86 I/O permissions)");
>        case NT_X86_XSTATE:
>  	return _("NT_X86_XSTATE (x86 XSAVE extended state)");
> +      case NT_X86_XSAVE_LAYOUT:
> +	return _("NT_X86_XSAVE_LAYOUT (x86 XSAVE Layout description)");
>        case NT_X86_CET:
>  	return _("NT_X86_CET (x86 CET state)");
>        case NT_X86_SHSTK:

... than the "reading" of it (you only recognize it aiui, without actually
displaying its contents in a human-readable manner). IOW I'd suggest
s/read/handle/ along with adding "minimal" for the subject.

Jan
  

Patch

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index de7cc410a99..88c1dd8321c 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2925,6 +2925,8 @@  extern char *elfcore_write_prxfpreg
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_xstatereg
   (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_xsave_layout
+  (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_x86_segbases
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_i386_tls
diff --git a/bfd/elf.c b/bfd/elf.c
index 6ef60301091..23584c94261 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -114,6 +114,7 @@  SECTION
 #define NOTE_PSEUDO_SECTION_X86_SEGBASES 	".reg-x86-segbases"
 #define NOTE_PSEUDO_SECTION_XFP          	".reg-xfp"
 #define NOTE_PSEUDO_SECTION_XSTATE       	".reg-xstate"
+#define NOTE_PSEUDO_SECTION_XSAVE_LAYOUT	".reg.xsave.layout"
 
 static int elf_sort_sections (const void *, const void *);
 static bool assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
@@ -10492,6 +10493,14 @@  elfcore_grok_sspreg (bfd *abfd, Elf_Internal_Note *note)
   return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_SSP, note);
 }
 
+/* Linux dumps the XSAVE Layout description in a note named "LINUX"
+   with a note type of NT_X86_XSAVE_LAYOUT. */
+static bool
+elfcore_grok_xsave_layout_desc (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-xsave-layout", note);
+}
+
 static bool
 elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
 {
@@ -11211,6 +11220,7 @@  elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 	case NT_S390_VXRS_LOW:	return elfcore_grok_s390_vxrs_low (abfd, note);
 	case NT_X86_SHSTK:	return elfcore_grok_sspreg (abfd, note);
 	case NT_X86_XSTATE:	return elfcore_grok_xstatereg (abfd, note);
+	case NT_X86_XSAVE_LAYOUT: return elfcore_grok_xsave_layout_desc (abfd, note);
 	default: break;
 	}
     }
@@ -12390,6 +12400,17 @@  elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
 			     note_name, NT_X86_XSTATE, xfpregs, size);
 }
 
+char *
+elfcore_write_xsave_layout (bfd *abfd, char *buf, int *bufsiz,
+			    const void *xsave_layout, int size)
+{
+  return elfcore_write_note (abfd, buf, bufsiz,
+			     NOTE_NAME_LINUX,
+			     NT_X86_XSAVE_LAYOUT,
+			     xsave_layout,
+			     size);
+}
+
 static char *
 elfcore_write_sspreg (bfd *abfd, char *buf, int *bufsiz,
 		      const void *ssp, int size)
@@ -13035,7 +13056,8 @@  elfcore_write_register_note (bfd *abfd,
       { NOTE_PSEUDO_SECTION_TDESC,            elfcore_write_gdb_tdesc},
       { NOTE_PSEUDO_SECTION_X86_SEGBASES,     elfcore_write_x86_segbases},
       { NOTE_PSEUDO_SECTION_XFP,              elfcore_write_prxfpreg},
-      { NOTE_PSEUDO_SECTION_XSTATE,           elfcore_write_xstatereg} /* NB/ No comma.  */
+      { NOTE_PSEUDO_SECTION_XSTATE,           elfcore_write_xstatereg},
+      { NOTE_PSEUDO_SECTION_XSAVE_LAYOUT,     elfcore_write_xsave_layout} /* NB/ No comma.  */
     };
 
   int i;
diff --git a/binutils/readelf.c b/binutils/readelf.c
index fd9722c8afc..16f50318da9 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -21375,6 +21375,8 @@  get_note_type (Filedata * filedata, unsigned e_type)
 	return _("NT_386_IOPERM (x86 I/O permissions)");
       case NT_X86_XSTATE:
 	return _("NT_X86_XSTATE (x86 XSAVE extended state)");
+      case NT_X86_XSAVE_LAYOUT:
+	return _("NT_X86_XSAVE_LAYOUT (x86 XSAVE Layout description)");
       case NT_X86_CET:
 	return _("NT_X86_CET (x86 CET state)");
       case NT_X86_SHSTK:
diff --git a/include/elf/common.h b/include/elf/common.h
index 5d0f93ebf56..c0894870fc5 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -696,6 +696,8 @@ 
 #define NT_X86_SHSTK	0x204		/* x86 SHSTK state.  */
 					/* This replaces NT_X86_CET (0x203).  */
 					/*   note name must be "LINUX".  */
+#define NT_X86_XSAVE_LAYOUT	0x205	/* XSAVE layout description */
+					/*   note name must be "LINUX".  */
 #define NT_S390_HIGH_GPRS 0x300		/* S/390 upper halves of GPRs  */
 					/*   note name must be "LINUX".  */
 #define NT_S390_TIMER	0x301		/* S390 timer */