[RFC,11/13] x86-linux-nat: Support fetching TARGET_OBJECT_X86_CPUID objects

Message ID 20231009183617.24862-12-jhb@FreeBSD.org
State New
Headers
Series Proposal for a new NT_X86_CPUID core dump note |

Checks

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

Commit Message

John Baldwin Oct. 9, 2023, 6:36 p.m. UTC
  When probing for the cached XSAVE layout, fetch the CPUID note data
and cache it until needed for a future fetch via ::xfer_partial.
---
 gdb/configure.nat   |  7 ++++---
 gdb/x86-linux-nat.c | 37 +++++++++++++++++++++++++++++++++++++
 gdb/x86-linux-nat.h |  9 +++++++++
 3 files changed, 50 insertions(+), 3 deletions(-)
  

Patch

diff --git a/gdb/configure.nat b/gdb/configure.nat
index 4ed71d8619d..c540e070dbb 100644
--- a/gdb/configure.nat
+++ b/gdb/configure.nat
@@ -255,8 +255,8 @@  case ${gdb_host} in
 		;;
 	    i386)
 		# Host: Intel 386 running GNU/Linux.
-		NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \
-		nat/x86-xstate.o \
+		NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-cpuid.o \
+		nat/x86-dregs.o nat/x86-xstate.o \
 		i386-linux-nat.o x86-linux-nat.o nat/linux-btrace.o \
 		nat/x86-linux.o nat/x86-linux-dregs.o"
 		;;
@@ -321,7 +321,8 @@  case ${gdb_host} in
 	case ${gdb_host_cpu} in
 	    i386)
 		# Host: GNU/Linux x86-64
-		NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \
+		NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-cpuid.o \
+		nat/x86-dregs.o \
 		nat/x86-xstate.o amd64-nat.o amd64-linux-nat.o x86-linux-nat.o \
 		nat/linux-btrace.o \
 		nat/x86-linux.o nat/x86-linux-dregs.o \
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index cd8fd9c1dcd..517faccf934 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -36,6 +36,7 @@ 
 #include "amd64-linux-tdep.h"
 #endif
 #include "gdbsupport/x86-xstate.h"
+#include "nat/x86-cpuid.h"
 #include "nat/x86-xstate.h"
 #include "nat/linux-btrace.h"
 #include "nat/linux-nat.h"
@@ -182,6 +183,8 @@  x86_linux_nat_target::read_description ()
 			     / sizeof (uint64_t))];
 
 	  m_xsave_layout = x86_fetch_xsave_layout (xcr0, x86_xsave_length ());
+
+	  x86_cpuid_note (m_cpuid_note, m_cpuid_note_len);
 	}
     }
 
@@ -213,6 +216,40 @@  x86_linux_nat_target::read_description ()
 
   gdb_assert_not_reached ("failed to return tdesc");
 }
+
+enum target_xfer_status
+x86_linux_nat_target::xfer_partial (enum target_object object,
+				    const char *annex, gdb_byte *readbuf,
+				    const gdb_byte *writebuf,
+				    ULONGEST offset, ULONGEST len,
+				    ULONGEST *xfered_len)
+{
+  switch (object)
+    {
+    case TARGET_OBJECT_X86_CPUID:
+      if (readbuf)
+	{
+	  size_t size = m_cpuid_note_len;
+	  if (offset >= size)
+	    return TARGET_XFER_EOF;
+	  size -= offset;
+	  if (size > len)
+	    size = len;
+
+	  if (size == 0)
+	    return TARGET_XFER_EOF;
+
+	  memcpy (readbuf, m_cpuid_note.get () + offset, size);
+	  *xfered_len = size;
+	  return TARGET_XFER_OK;
+	}
+      return TARGET_XFER_E_IO;
+    default:
+      return linux_nat_target::xfer_partial (object, annex, readbuf,
+					     writebuf, offset, len,
+					     xfered_len);
+    }
+}
 
 
 /* Enable branch tracing.  */
diff --git a/gdb/x86-linux-nat.h b/gdb/x86-linux-nat.h
index a0f8ffc993e..c2a6452ce27 100644
--- a/gdb/x86-linux-nat.h
+++ b/gdb/x86-linux-nat.h
@@ -45,6 +45,13 @@  struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
   x86_xsave_layout fetch_x86_xsave_layout () override
   { return m_xsave_layout; }
 
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
   /* These two are rewired to low_ versions.  linux-nat.c queries
      stopped-by-watchpoint info as soon as an lwp stops (via the low_
      methods) and caches the result, to be returned via the normal
@@ -81,6 +88,8 @@  struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
 
 private:
   x86_xsave_layout m_xsave_layout;
+  gdb::unique_xmalloc_ptr<gdb_byte> m_cpuid_note;
+  size_t m_cpuid_note_len;
 };