Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Vignesh Balasubramanian <vigbalas@amd.com>
To: <gdb-patches@sourceware.org>, <jinisusan.george@amd.com>,
	<christina.schimpe@intel.com>, <AlokKumar.Sharma@amd.com>,
	<jhb@FreeBSD.org>,  <simark@simark.ca>
Cc: Vignesh Balasubramanian <vigbalas@amd.com>
Subject: [PATCH 32 2/2] gcore: Create a new .note section for x86
Date: Mon, 8 Dec 2025 14:08:21 +0530	[thread overview]
Message-ID: <20251208083819.2560894-3-vigbalas@amd.com> (raw)
In-Reply-To: <20251208083819.2560894-1-vigbalas@amd.com>

This new .note section contains the offset and size information of the
xsave features present in the machine where the core file is dumped.
It helps to avoid reliance on predetermined and possibly incorrect
offsets of the xsave features.

Please refer the linux commit below for further details.
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>

V2 -> V3:
Removed malloc in "form_x86_xsave_cpuid_records" and used the vector instead.
Some NITs

---
 gdb/gcore-elf.c            | 18 ++++++++++++++++++
 gdb/gcore-elf.h            |  8 ++++++++
 gdb/linux-tdep.c           |  1 +
 gdb/nat/x86-xstate.c       | 31 +++++++++++++++++++++++++++++++
 gdb/nat/x86-xstate.h       |  6 ++++++
 gdb/target-debug.h         |  6 ++++++
 gdb/target-delegates-gen.c | 26 ++++++++++++++++++++++++++
 gdb/target.c               |  5 +++++
 gdb/target.h               | 10 ++++++++++
 gdb/x86-linux-nat.c        |  6 ++++++
 gdb/x86-linux-nat.h        |  1 +
 gdbsupport/x86-xstate.h    |  2 ++
 12 files changed, 120 insertions(+)

diff --git a/gdb/gcore-elf.c b/gdb/gcore-elf.c
index 1e4376dab5e..33ee306ca6a 100644
--- a/gdb/gcore-elf.c
+++ b/gdb/gcore-elf.c
@@ -162,3 +162,21 @@ gcore_elf_make_tdesc_note (struct gdbarch *gdbarch, bfd *obfd,
 						     tdesc_len));
     }
 }
+
+/* See gcore-elf.h.  */
+
+void
+gcore_elf_make_target_specific_note (struct gdbarch *gdbarch, bfd *obfd,
+				     gdb::unique_xmalloc_ptr<char> *note_data,
+				     int *note_size)
+{
+  std::vector<uint32_t> data = target_specific_core_note ();
+
+  if (!data.empty ())
+    note_data->reset (elfcore_write_register_note (obfd,
+						   note_data->release (),
+						   note_size,
+						   ".reg-xsave-layout",
+						   data.data(),
+						   data.size() * sizeof (data[0])));
+}
diff --git a/gdb/gcore-elf.h b/gdb/gcore-elf.h
index c43d0df741e..394e9195141 100644
--- a/gdb/gcore-elf.h
+++ b/gdb/gcore-elf.h
@@ -45,4 +45,12 @@ extern void gcore_elf_make_tdesc_note
   (struct gdbarch *gdbarch, bfd *obfd,
    gdb::unique_xmalloc_ptr<char> *note_data, int *note_size);
 
+/* Add content to *NOTE_DATA (and update *NOTE_SIZE) to include a note
+   containing the description of XSAVE Layout.  */
+
+extern void gcore_elf_make_target_specific_note
+  (struct gdbarch *gdbarch, bfd *obfd,
+   gdb::unique_xmalloc_ptr<char> *note_data,
+   int *note_size);
+
 #endif /* GDB_GCORE_ELF_H */
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 10843613c5d..cfebffc1206 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -2447,6 +2447,7 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
      per-thread tdesc, so just emit the tdesc for the signalled thread.  */
   gdbarch = target_thread_architecture (signalled_thr->ptid);
   gcore_elf_make_tdesc_note (gdbarch, obfd, &note_data, note_size);
+  gcore_elf_make_target_specific_note (gdbarch, obfd, &note_data, note_size);
 
   return note_data;
 }
diff --git a/gdb/nat/x86-xstate.c b/gdb/nat/x86-xstate.c
index 6f2dfde9448..e7a42952ee5 100644
--- a/gdb/nat/x86-xstate.c
+++ b/gdb/nat/x86-xstate.c
@@ -62,3 +62,34 @@ x86_fetch_xsave_layout (uint64_t xcr0, int len)
   layout.pkru_offset = xsave_feature_offset (xcr0, X86_XSTATE_PKRU_ID);
   return layout;
 }
+
+/* See x86-xstate.h.  */
+
+std::vector<uint32_t>
+form_x86_xsave_cpuid_records ()
+{
+  uint32_t ax = 0, bx = 0, cx = 0, dx = 0;
+  int features_present = 0;
+  std::vector<uint32_t> data;
+
+  if (x86_cpuid_count (0xd, 0, &ax, &bx, &cx, &dx))
+    features_present = ax;
+
+  for (int i = 2; i < MAX_XSAVE_CPUID_RECORDS; i++)
+    if (features_present & (1U << i))
+      {
+	if (x86_cpuid_count (0xd, i, &ax, &bx, &cx, &dx))
+	  {
+	    data.push_back (i);
+	    data.push_back (ax);
+	    data.push_back (bx);
+	    data.push_back (cx);
+	  }
+	ax = 0;
+	bx = 0;
+	cx = 0;
+	dx = 0;
+      }
+
+  return data;
+}
diff --git a/gdb/nat/x86-xstate.h b/gdb/nat/x86-xstate.h
index 0046ab8dc78..25dc686d472 100644
--- a/gdb/nat/x86-xstate.h
+++ b/gdb/nat/x86-xstate.h
@@ -32,4 +32,10 @@ int x86_xsave_length ();
 
 x86_xsave_layout x86_fetch_xsave_layout (uint64_t xcr0, int len);
 
+/* Form a array of records for each XSAVE feature present containing
+   its type, size, offset and flags via CPUID.  These will make a .note
+   section in core file.  */
+
+std::vector<uint32_t> form_x86_xsave_cpuid_records ();
+
 #endif /* GDB_NAT_X86_XSTATE_H */
diff --git a/gdb/target-debug.h b/gdb/target-debug.h
index 3e41e986b6c..a2e04a7b218 100644
--- a/gdb/target-debug.h
+++ b/gdb/target-debug.h
@@ -195,6 +195,12 @@ target_debug_print_std_vector_static_tracepoint_marker
   (const std::vector<static_tracepoint_marker> &vec)
 { return host_address_to_string (vec.data ()); }
 
+
+static std::string
+target_debug_print_std_vector_uint32_t
+  (const std::vector<uint32_t> &vec)
+{ return host_address_to_string (vec.data ()); }
+
 static std::string
 target_debug_print_const_target_desc_p (const target_desc *tdesc)
 { return host_address_to_string (tdesc); }
diff --git a/gdb/target-delegates-gen.c b/gdb/target-delegates-gen.c
index 33124864b6d..ddd3185612f 100644
--- a/gdb/target-delegates-gen.c
+++ b/gdb/target-delegates-gen.c
@@ -132,6 +132,7 @@ struct dummy_target : public target_ops
   bool supports_evaluation_of_breakpoint_conditions () override;
   bool supports_dumpcore () override;
   void dumpcore (const char *arg0) override;
+  std::vector<uint32_t> specific_core_note () override;
   bool can_run_breakpoint_commands () override;
   struct gdbarch *thread_architecture (ptid_t arg0) override;
   bool filesystem_is_local () override;
@@ -313,6 +314,7 @@ struct debug_target : public target_ops
   bool supports_evaluation_of_breakpoint_conditions () override;
   bool supports_dumpcore () override;
   void dumpcore (const char *arg0) override;
+  std::vector<uint32_t> specific_core_note () override;
   bool can_run_breakpoint_commands () override;
   struct gdbarch *thread_architecture (ptid_t arg0) override;
   bool filesystem_is_local () override;
@@ -2836,6 +2838,30 @@ debug_target::dumpcore (const char *arg0)
 	      target_debug_print_const_char_p (arg0).c_str ());
 }
 
+std::vector<uint32_t>
+target_ops::specific_core_note ()
+{
+  return this->beneath ()->specific_core_note ();
+}
+
+std::vector<uint32_t>
+dummy_target::specific_core_note ()
+{
+  return std::vector<uint32_t> ();
+}
+
+std::vector<uint32_t>
+debug_target::specific_core_note ()
+{
+  target_debug_printf_nofunc ("-> %s->specific_core_note (...)", this->beneath ()->shortname ());
+  std::vector<uint32_t> result
+    = this->beneath ()->specific_core_note ();
+  target_debug_printf_nofunc ("<- %s->specific_core_note () = %s",
+	      this->beneath ()->shortname (),
+	      target_debug_print_std_vector_uint32_t (result).c_str ());
+  return result;
+}
+
 bool
 target_ops::can_run_breakpoint_commands ()
 {
diff --git a/gdb/target.c b/gdb/target.c
index 05944319e26..86cb6280c11 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -261,6 +261,11 @@ target_dumpcore (const char *filename)
   return current_inferior ()->top_target ()->dumpcore (filename);
 }
 
+std::vector<uint32_t>
+target_specific_core_note ()
+{
+  return current_inferior ()->top_target ()->specific_core_note ();
+}
 /* See target.h.  */
 
 bool
diff --git a/gdb/target.h b/gdb/target.h
index bf35227b658..133bb94b4ec 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -961,6 +961,11 @@ struct target_ops
     virtual void dumpcore (const char *filename)
       TARGET_DEFAULT_IGNORE ();
 
+    /* Generate target specific .note section.
+       For X86, contains description of XSAVE layout.  */
+    virtual std::vector<uint32_t> specific_core_note ()
+      TARGET_DEFAULT_RETURN (std::vector<uint32_t> ());
+
     /* Does this target support evaluation of breakpoint commands on its
        end?  */
     virtual bool can_run_breakpoint_commands ()
@@ -1650,6 +1655,11 @@ extern bool target_supports_dumpcore ();
 
 extern void target_dumpcore (const char *filename);
 
+/* Generate target specific .note section.
+   For X86, contains description of XSAVE layout.  */
+
+extern std::vector<uint32_t> target_specific_core_note ();
+
 /* Returns true if this target can handle breakpoint commands
    on its end.  */
 
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index 0b84f4c0ada..626bd1192b2 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -44,6 +44,12 @@
 #include "x86-tdep.h"
 #include "nat/x86-linux-tdesc.h"
 
+
+std::vector<uint32_t>
+x86_linux_nat_target::specific_core_note ()
+{
+  return form_x86_xsave_cpuid_records();
+}
 /* linux_nat_target::low_new_fork implementation.  */
 
 void
diff --git a/gdb/x86-linux-nat.h b/gdb/x86-linux-nat.h
index 37e6da5d122..3c395035c9b 100644
--- a/gdb/x86-linux-nat.h
+++ b/gdb/x86-linux-nat.h
@@ -63,6 +63,7 @@ struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
   { return x86_stopped_data_address (addr_p); }
 
   void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
+  std::vector<uint32_t> specific_core_note () override;
 
   void low_forget_process (pid_t pid) override
   { x86_forget_process (pid); }
diff --git a/gdbsupport/x86-xstate.h b/gdbsupport/x86-xstate.h
index a9ab39152ad..130a7f24a88 100644
--- a/gdbsupport/x86-xstate.h
+++ b/gdbsupport/x86-xstate.h
@@ -49,6 +49,8 @@
 #define X86_XSTATE_PKRU		(1ULL << X86_XSTATE_PKRU_ID)
 #define X86_XSTATE_CET_U	(1ULL << X86_XSTATE_CET_U_ID)
 
+#define MAX_XSAVE_CPUID_RECORDS 32
+
 /* Total size of the XSAVE area extended region and offsets of
    register states within the region.  Offsets are set to 0 to
    indicate the absence of the associated registers.  */
-- 
2.34.1


  parent reply	other threads:[~2025-12-08  8:43 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-08  8:38 [PATCH 32 0/2] Handle the new .note section introduced in Linux Vignesh Balasubramanian
2025-12-08  8:38 ` [PATCH 32 1/2] core: Consume the new .note section that contains descriptions of xsave layout Vignesh Balasubramanian
2025-12-08  8:38 ` Vignesh Balasubramanian [this message]
2025-12-14 13:39 ` [PATCH 32 0/2] Handle the new .note section introduced in Linux Schimpe, Christina
2026-01-06  6:48   ` Balasubrmanian, Vignesh
2026-03-06  7:08     ` Schimpe, Christina
2026-03-06  7:42       ` Balasubrmanian, Vignesh
2026-03-06  8:13         ` Schimpe, Christina
2026-03-11  9:50           ` Schimpe, Christina
2026-03-13 14:08             ` Schimpe, Christina
2026-03-17 10:02               ` Schimpe, Christina
2026-02-08  4:18   ` Vignesh Balasubramanian
2026-03-16 12:59 ` [PATCH 32 0/2] Handle the new .note section introduced in Linux Schimpe, Christina

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=20251208083819.2560894-3-vigbalas@amd.com \
    --to=vigbalas@amd.com \
    --cc=AlokKumar.Sharma@amd.com \
    --cc=christina.schimpe@intel.com \
    --cc=gdb-patches@sourceware.org \
    --cc=jhb@FreeBSD.org \
    --cc=jinisusan.george@amd.com \
    --cc=simark@simark.ca \
    /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