public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@sourceware.org>
To: gdb-cvs@sourceware.org
Subject: [binutils-gdb] Revert "gdb/gdbserver: share some code relating to target description creation"
Date: Tue, 26 Mar 2024 18:59:14 +0000 (GMT)	[thread overview]
Message-ID: <20240326185914.7C3583858C60@sourceware.org> (raw)

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

commit 49a7660fb50cc3c68e7830eb098905d068a3ccbf
Author: Andrew Burgess <aburgess@redhat.com>
Date:   Tue Mar 26 18:52:44 2024 +0000

    Revert "gdb/gdbserver: share some code relating to target description creation"
    
    This reverts commit cd9b374ffe372dcaf7e4c15548cf53a301d8dcdd.

Diff:
---
 gdb/Makefile.in              |   1 -
 gdb/amd64-linux-tdep.c       |   1 -
 gdb/amd64-linux-tdep.h       |   6 ++
 gdb/configure.nat            |   4 +-
 gdb/i386-linux-tdep.c        |   1 -
 gdb/i386-linux-tdep.h        |   3 +
 gdb/nat/x86-linux-tdesc.c    | 124 ------------------------------------
 gdb/nat/x86-linux-tdesc.h    |  75 ----------------------
 gdb/x86-linux-nat.c          |  91 ++++++++++++++++++++++----
 gdbserver/configure.srv      |   2 -
 gdbserver/linux-amd64-ipa.cc |   1 -
 gdbserver/linux-i386-ipa.cc  |   1 -
 gdbserver/linux-x86-low.cc   | 148 ++++++++++++++++++++++++++++++-------------
 gdbserver/linux-x86-tdesc.cc |   1 -
 gdbserver/linux-x86-tdesc.h  |   7 ++
 15 files changed, 199 insertions(+), 267 deletions(-)

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 38f4d5fde98..331620375ae 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1585,7 +1585,6 @@ HFILES_NO_SRCDIR = \
 	nat/x86-gcc-cpuid.h \
 	nat/x86-linux.h \
 	nat/x86-linux-dregs.h \
-	nat/x86-linux-tdesc.h \
 	python/py-event.h \
 	python/py-events.h \
 	python/py-stopevent.h \
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 7e0900dc6f9..a512ec5dd02 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -43,7 +43,6 @@
 #include "target-descriptions.h"
 #include "expop.h"
 #include "nat/x86-linux.h"
-#include "nat/x86-linux-tdesc.h"
 
 /* The syscall's XML filename for i386.  */
 #define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml"
diff --git a/gdb/amd64-linux-tdep.h b/gdb/amd64-linux-tdep.h
index 0ec49e7fe03..2003dcda78f 100644
--- a/gdb/amd64-linux-tdep.h
+++ b/gdb/amd64-linux-tdep.h
@@ -43,6 +43,12 @@ extern struct target_desc *tdesc_x32_linux;
 extern struct target_desc *tdesc_x32_avx_linux;
 extern struct target_desc *tdesc_x32_avx_avx512_linux;
 
+/* Return the right amd64-linux target descriptions according to
+   XCR0_FEATURES_BIT and IS_X32.  */
+
+const target_desc *amd64_linux_read_description (uint64_t xcr0_features_bit,
+						 bool is_x32);
+
 /* Enum that defines the syscall identifiers for amd64 linux.
    Used for process record/replay, these will be translated into
    a gdb-canonical set of syscall ids in linux-record.c.  */
diff --git a/gdb/configure.nat b/gdb/configure.nat
index 4bcc0696027..8b98511cef7 100644
--- a/gdb/configure.nat
+++ b/gdb/configure.nat
@@ -256,7 +256,7 @@ case ${gdb_host} in
 		NATDEPFILES="${NATDEPFILES} x86-nat.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 nat/x86-linux-tdesc.o"
+		nat/x86-linux.o nat/x86-linux-dregs.o"
 		;;
 	    ia64)
 		# Host: Intel IA-64 running GNU/Linux
@@ -322,7 +322,7 @@ case ${gdb_host} in
 		NATDEPFILES="${NATDEPFILES} x86-nat.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 nat/x86-linux-tdesc.o \
+		nat/x86-linux.o nat/x86-linux-dregs.o \
 		nat/amd64-linux-siginfo.o"
 		;;
 	    sparc)
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index f5f7a36bf36..8dd7203b6c3 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -41,7 +41,6 @@
 #include "i387-tdep.h"
 #include "gdbsupport/x86-xstate.h"
 #include "nat/x86-linux.h"
-#include "nat/x86-linux-tdesc.h"
 
 /* The syscall's XML filename for i386.  */
 #define XML_SYSCALL_FILENAME_I386 "syscalls/i386-linux.xml"
diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h
index e8691cd778e..07593c6a8ec 100644
--- a/gdb/i386-linux-tdep.h
+++ b/gdb/i386-linux-tdep.h
@@ -55,6 +55,9 @@ extern void i386_linux_report_signal_info (struct gdbarch *gdbarch,
 					   struct ui_out *uiout,
 					   enum gdb_signal siggnal);
 
+/* Return the target description according to XCR0.  */
+extern const struct target_desc *i386_linux_read_description (uint64_t xcr0);
+
 extern int i386_linux_gregset_reg_offset[];
 
 /* Return x86 siginfo type.  */
diff --git a/gdb/nat/x86-linux-tdesc.c b/gdb/nat/x86-linux-tdesc.c
deleted file mode 100644
index be7014d2b5f..00000000000
--- a/gdb/nat/x86-linux-tdesc.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Target description related code for GNU/Linux x86 (i386 and x86-64).
-
-   Copyright (C) 2024 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include "gdbsupport/common-defs.h"
-#include "nat/x86-linux-tdesc.h"
-#ifdef __x86_64__
-#include "arch/amd64.h"
-#endif
-#include "arch/i386.h"
-
-#include "gdbsupport/common-defs.h"
-#include "nat/x86-linux.h"
-#include "nat/x86-linux-dregs.h"
-#include "nat/gdb_ptrace.h"
-#include "nat/x86-xstate.h"
-#include "nat/x86-linux-tdesc.h"
-
-#include <cstdint>
-#include <cstdlib>
-#include <linux/uio.h>
-#include <elf.h>
-#include <sys/user.h>
-#include <sys/user.h>
-
-/* See nat/x86-linux-tdesc.h.  */
-
-const target_desc *
-x86_linux_tdesc_for_tid (int tid, enum tribool *have_ptrace_getregset,
-			 gdb::function_view<void (uint64_t)> xcr0_init_cb,
-			 const char *error_msg, uint64_t *xcr0_storage)
-{
-#ifdef __x86_64__
-
-  x86_linux_arch_size arch_size = x86_linux_ptrace_get_arch_size (tid);
-  bool is_64bit = arch_size.is_64bit ();
-  bool is_x32 = arch_size.is_x32 ();
-
-  if (sizeof (void *) == 4 && is_64bit && !is_x32)
-    error ("%s", error_msg);
-
-#elif HAVE_PTRACE_GETFPXREGS
-  if (have_ptrace_getfpxregs == -1)
-    {
-      elf_fpxregset_t fpxregs;
-
-      if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0)
-	{
-	  have_ptrace_getfpxregs = 0;
-	  *have_ptrace_getregset = TRIBOOL_FALSE;
-	  return i386_linux_read_description (X86_XSTATE_X87_MASK);
-	}
-    }
-#endif
-
-  if (*have_ptrace_getregset == TRIBOOL_UNKNOWN)
-    {
-      uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))];
-      struct iovec iov;
-
-      iov.iov_base = xstateregs;
-      iov.iov_len = sizeof (xstateregs);
-
-      /* Check if PTRACE_GETREGSET works.  */
-      if (ptrace (PTRACE_GETREGSET, tid,
-		  (unsigned int) NT_X86_XSTATE, &iov) < 0)
-	{
-	  *have_ptrace_getregset = TRIBOOL_FALSE;
-	  *xcr0_storage = 0;
-	}
-      else
-	{
-	  *have_ptrace_getregset = TRIBOOL_TRUE;
-
-	  /* Get XCR0 from XSAVE extended state.  */
-	  *xcr0_storage = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
-				      / sizeof (uint64_t))];
-
-#ifdef __x86_64__
-	  /* No MPX on x32.  */
-	  if (is_64bit && is_x32)
-	    *xcr0_storage &= ~X86_XSTATE_MPX;
-#endif /* __x86_64__ */
-
-	  xcr0_init_cb (*xcr0_storage);
-	}
-    }
-
-  /* Check the native XCR0 only if PTRACE_GETREGSET is available.  If
-     PTRACE_GETREGSET is not available then set xcr0_features_bits to
-     zero so that the "no-features" descriptions are returned by the
-     switches below.  */
-  uint64_t xcr0_features_bits;
-  if (*have_ptrace_getregset == TRIBOOL_TRUE)
-    xcr0_features_bits = *xcr0_storage & X86_XSTATE_ALL_MASK;
-  else
-    xcr0_features_bits = 0;
-
-#ifdef __x86_64__
-  if (is_64bit)
-    {
-      return amd64_linux_read_description (xcr0_features_bits, is_x32);
-    }
-  else
-#endif
-    return i386_linux_read_description (xcr0_features_bits);
-
-  gdb_assert_not_reached ("failed to return tdesc");
-}
diff --git a/gdb/nat/x86-linux-tdesc.h b/gdb/nat/x86-linux-tdesc.h
deleted file mode 100644
index 3727a8bf95e..00000000000
--- a/gdb/nat/x86-linux-tdesc.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Target description related code for GNU/Linux x86 (i386 and x86-64).
-
-   Copyright (C) 2024 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef NAT_X86_LINUX_TDESC_H
-#define NAT_X86_LINUX_TDESC_H
-
-#include "gdbsupport/function-view.h"
-
-struct target_desc;
-
-/* Return the target description for Linux thread TID.
-
-   When *HAVE_PTRACE_GETREGSET is TRIBOOL_UNKNOWN then the current value of
-   xcr0 is read using ptrace calls and stored into *XCR0_STORAGE.  Then
-   XCR0_INIT_CB is called with the value of *XCR0_STORAGE and
-   *HAVE_PTRACE_GETREGSET is set to TRIBOOL_TRUE.
-
-   If the attempt to read xcr0 using ptrace fails then *XCR0_STORAGE is set
-   to zero and *HAVE_PTRACE_GETREGSET is set to TRIBOOL_FALSE.
-
-   The storage pointed to by XCR0_STORAGE must exist until the program
-   terminates, this storage is used to cache the xcr0 value.  As such
-   XCR0_INIT_CB will only be called once if xcr0 is successfully read using
-   ptrace, or not at all if the ptrace call fails.
-
-   This function returns a target description based on the extracted xcr0
-   value along with other characteristics of the thread identified by TID.
-
-   This function can return nullptr if we encounter a machine configuration
-   for which a target_desc cannot be created.  Ideally this would not be
-   the case, we should be able to create a target description for every
-   possible machine configuration.  See amd64_linux_read_description and
-   i386_linux_read_description for cases when nullptr might be
-   returned.
-
-   ERROR_MSG is using in an error() call if we try to create a target
-   description for a 64-bit process but this is a 32-bit build of GDB.  */
-
-extern const target_desc *
-x86_linux_tdesc_for_tid (int tid, enum tribool *have_ptrace_getregset,
-			 gdb::function_view<void (uint64_t)> xcr0_init_cb,
-			 const char *error_msg, uint64_t *xcr0_storage);
-
-#ifdef __x86_64__
-
-/* Return the right amd64-linux target descriptions according to
-   XCR0_FEATURES_BIT and IS_X32.  This is implemented separately in both
-   GDB and gdbserver.  */
-
-extern const target_desc *amd64_linux_read_description
-	(uint64_t xcr0_features_bit, bool is_x32);
-
-#endif
-
-/* Return the target description according to XCR0.  This is implemented
-   separately in both GDB and gdbserver.  */
-extern const struct target_desc *i386_linux_read_description (uint64_t xcr0);
-
-#endif /* NAT_X86_LINUX_TDESC_H */
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index 872e27e739f..b39d05c401f 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -42,7 +42,6 @@
 #include "nat/x86-linux.h"
 #include "nat/x86-linux-dregs.h"
 #include "nat/linux-ptrace.h"
-#include "nat/x86-linux-tdesc.h"
 
 /* linux_nat_target::low_new_fork implementation.  */
 
@@ -97,26 +96,90 @@ x86_linux_nat_target::post_startup_inferior (ptid_t ptid)
 const struct target_desc *
 x86_linux_nat_target::read_description ()
 {
-  static uint64_t xcr0_storage;
+  int tid;
+  int is_64bit = 0;
+#ifdef __x86_64__
+  int is_x32;
+#endif
+  static uint64_t xcr0;
+  uint64_t xcr0_features_bits;
 
   if (inferior_ptid == null_ptid)
     return this->beneath ()->read_description ();
 
-  int tid = inferior_ptid.pid ();
+  tid = inferior_ptid.pid ();
+
+#ifdef __x86_64__
+
+  x86_linux_arch_size arch_size = x86_linux_ptrace_get_arch_size (tid);
+  is_64bit = arch_size.is_64bit ();
+  is_x32 = arch_size.is_x32 ();
+
+#elif HAVE_PTRACE_GETFPXREGS
+  if (have_ptrace_getfpxregs == -1)
+    {
+      elf_fpxregset_t fpxregs;
+
+      if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0)
+	{
+	  have_ptrace_getfpxregs = 0;
+	  have_ptrace_getregset = TRIBOOL_FALSE;
+	  return i386_linux_read_description (X86_XSTATE_X87_MASK);
+	}
+    }
+#endif
+
+  if (have_ptrace_getregset == TRIBOOL_UNKNOWN)
+    {
+      uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))];
+      struct iovec iov;
+
+      iov.iov_base = xstateregs;
+      iov.iov_len = sizeof (xstateregs);
+
+      /* Check if PTRACE_GETREGSET works.  */
+      if (ptrace (PTRACE_GETREGSET, tid,
+		  (unsigned int) NT_X86_XSTATE, &iov) < 0)
+	have_ptrace_getregset = TRIBOOL_FALSE;
+      else
+	{
+	  have_ptrace_getregset = TRIBOOL_TRUE;
+
+	  /* Get XCR0 from XSAVE extended state.  */
+	  xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
+			     / sizeof (uint64_t))];
+
+	  m_xsave_layout = x86_fetch_xsave_layout (xcr0, x86_xsave_length ());
+	}
+    }
+
+  /* Check the native XCR0 only if PTRACE_GETREGSET is available.  If
+     PTRACE_GETREGSET is not available then set xcr0_features_bits to
+     zero so that the "no-features" descriptions are returned by the
+     switches below.  */
+  if (have_ptrace_getregset == TRIBOOL_TRUE)
+    xcr0_features_bits = xcr0 & X86_XSTATE_ALL_MASK;
+  else
+    xcr0_features_bits = 0;
+
+  if (is_64bit)
+    {
+#ifdef __x86_64__
+      return amd64_linux_read_description (xcr0_features_bits, is_x32);
+#endif
+    }
+  else
+    {
+      const struct target_desc * tdesc
+	= i386_linux_read_description (xcr0_features_bits);
 
-  const char *error_msg
-    = _("Can't debug 64-bit process with 32-bit GDB");
+      if (tdesc == NULL)
+	tdesc = i386_linux_read_description (X86_XSTATE_SSE_MASK);
 
-  /* Callback that is triggered the first time x86_linux_tdesc_for_tid
-     reads the xcr0 register.  Setup other bits of state */
-  auto cb = [&] (uint64_t xcr0)
-  {
-    this->m_xsave_layout
-      = x86_fetch_xsave_layout (xcr0, x86_xsave_length ());
-  };
+      return tdesc;
+    }
 
-  return x86_linux_tdesc_for_tid (tid, &have_ptrace_getregset, cb,
-				  error_msg, &xcr0_storage);
+  gdb_assert_not_reached ("failed to return tdesc");
 }
 \f
 
diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv
index 7a2702d78bf..9e861a75088 100644
--- a/gdbserver/configure.srv
+++ b/gdbserver/configure.srv
@@ -109,7 +109,6 @@ case "${gdbserver_host}" in
 			srv_tgtobj="${srv_tgtobj} nat/linux-btrace.o"
 			srv_tgtobj="${srv_tgtobj} nat/x86-linux.o"
 			srv_tgtobj="${srv_tgtobj} nat/x86-linux-dregs.o"
-			srv_tgtobj="${srv_tgtobj} nat/x86-linux-tdesc.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
@@ -372,7 +371,6 @@ case "${gdbserver_host}" in
 			srv_tgtobj="${srv_tgtobj} nat/linux-btrace.o"
 			srv_tgtobj="${srv_tgtobj} nat/x86-linux.o"
 			srv_tgtobj="${srv_tgtobj} nat/x86-linux-dregs.o"
-			srv_tgtobj="${srv_tgtobj} nat/x86-linux-tdesc.o"
 			srv_tgtobj="${srv_tgtobj} nat/amd64-linux-siginfo.o"
 			srv_linux_usrregs=yes # This is for i386 progs.
 			srv_linux_regsets=yes
diff --git a/gdbserver/linux-amd64-ipa.cc b/gdbserver/linux-amd64-ipa.cc
index f97b0d6a1d9..54e4c9812bb 100644
--- a/gdbserver/linux-amd64-ipa.cc
+++ b/gdbserver/linux-amd64-ipa.cc
@@ -23,7 +23,6 @@
 #include "tracepoint.h"
 #include "linux-x86-tdesc.h"
 #include "gdbsupport/x86-xstate.h"
-#include "nat/x86-linux-tdesc.h"
 
 /* Defined in auto-generated file amd64-linux.c.  */
 void init_registers_amd64_linux (void);
diff --git a/gdbserver/linux-i386-ipa.cc b/gdbserver/linux-i386-ipa.cc
index 459b8055b5c..2e4646f8c03 100644
--- a/gdbserver/linux-i386-ipa.cc
+++ b/gdbserver/linux-i386-ipa.cc
@@ -23,7 +23,6 @@
 #include "tracepoint.h"
 #include "linux-x86-tdesc.h"
 #include "gdbsupport/x86-xstate.h"
-#include "nat/x86-linux-tdesc.h"
 
 /* GDB register numbers.  */
 
diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc
index 9bf369f8a34..30d876efc5d 100644
--- a/gdbserver/linux-x86-low.cc
+++ b/gdbserver/linux-x86-low.cc
@@ -48,7 +48,6 @@
 #include "nat/x86-linux.h"
 #include "nat/x86-linux-dregs.h"
 #include "linux-x86-tdesc.h"
-#include "nat/x86-linux-tdesc.h"
 
 #ifdef __x86_64__
 static target_desc_up tdesc_amd64_linux_no_xml;
@@ -845,20 +844,32 @@ int have_ptrace_getfpxregs =
 #endif
 ;
 
-/* Cached xcr0 value.  This is initialised the first time
-   x86_linux_read_description is called.  */
-
-static uint64_t xcr0_storage;
-
 /* Get Linux/x86 target description from running target.  */
 
 static const struct target_desc *
 x86_linux_read_description (void)
 {
-  int tid = lwpid_of (current_thread);
+  unsigned int machine;
+  int is_elf64;
+  int xcr0_features;
+  int tid;
+  static uint64_t xcr0;
+  static int xsave_len;
+  struct regset_info *regset;
+
+  tid = lwpid_of (current_thread);
+
+  is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
 
-  const char *error_msg
-    = _("Can't debug 64-bit process with 32-bit GDBserver");
+  if (sizeof (void *) == 4)
+    {
+      if (is_elf64 > 0)
+       error (_("Can't debug 64-bit process with 32-bit GDBserver"));
+#ifndef __x86_64__
+      else if (machine == EM_X86_64)
+       error (_("Can't debug x86-64 process with 32-bit GDBserver"));
+#endif
+    }
 
   /* If we are not allowed to send an XML target description then we need
      to use the hard-wired target descriptions.  This corresponds to GDB's
@@ -868,54 +879,103 @@ x86_linux_read_description (void)
      generate some alternative target descriptions.  */
   if (!use_xml)
     {
-      x86_linux_arch_size arch_size = x86_linux_ptrace_get_arch_size (tid);
-      bool is_64bit = arch_size.is_64bit ();
-      bool is_x32 = arch_size.is_x32 ();
-
-      if (sizeof (void *) == 4 && is_64bit && !is_x32)
-	error ("%s", error_msg);
-
 #ifdef __x86_64__
-      if (is_64bit && !is_x32)
+      if (machine == EM_X86_64)
 	return tdesc_amd64_linux_no_xml.get ();
       else
 #endif
 	return tdesc_i386_linux_no_xml.get ();
     }
 
-  /* Callback that is triggered the first time x86_linux_tdesc_for_tid
-     reads the xcr0 register.  Setup other bits of state */
-  auto cb = [] (uint64_t xcr0)
-  {
-    i387_set_xsave_mask (xcr0, x86_xsave_length ());
-  };
+#if !defined __x86_64__ && defined HAVE_PTRACE_GETFPXREGS
+  if (machine == EM_386 && have_ptrace_getfpxregs == -1)
+    {
+      elf_fpxregset_t fpxregs;
 
-  /* If have_ptrace_getregset is changed to true by calling
-     x86_linux_tdesc_for_tid then we will perform some additional
-     initialisation.  */
-  bool have_ptrace_getregset_is_unknown
-    = have_ptrace_getregset == TRIBOOL_UNKNOWN;
+      if (ptrace (PTRACE_GETFPXREGS, tid, 0, (long) &fpxregs) < 0)
+	{
+	  have_ptrace_getfpxregs = 0;
+	  have_ptrace_getregset = TRIBOOL_FALSE;
+	  return i386_linux_read_description (X86_XSTATE_X87);
+	}
+      else
+	have_ptrace_getfpxregs = 1;
+    }
+#endif
 
-  const target_desc *tdesc
-    = x86_linux_tdesc_for_tid (tid, &have_ptrace_getregset, cb, error_msg,
-			       &xcr0_storage);
+  if (have_ptrace_getregset == TRIBOOL_UNKNOWN)
+    {
+      uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))];
+      struct iovec iov;
 
-  if (have_ptrace_getregset_is_unknown
-      && have_ptrace_getregset == TRIBOOL_TRUE)
+      iov.iov_base = xstateregs;
+      iov.iov_len = sizeof (xstateregs);
+
+      /* Check if PTRACE_GETREGSET works.  */
+      if (ptrace (PTRACE_GETREGSET, tid,
+		  (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
+	have_ptrace_getregset = TRIBOOL_FALSE;
+      else
+	{
+	  have_ptrace_getregset = TRIBOOL_TRUE;
+
+	  /* Get XCR0 from XSAVE extended state.  */
+	  xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
+			     / sizeof (uint64_t))];
+
+	  /* No MPX on x32.  */
+	  if (machine == EM_X86_64 && !is_elf64)
+	    xcr0 &= ~X86_XSTATE_MPX;
+
+	  xsave_len = x86_xsave_length ();
+
+	  /* Use PTRACE_GETREGSET if it is available.  */
+	  for (regset = x86_regsets;
+	       regset->fill_function != NULL; regset++)
+	    if (regset->get_request == PTRACE_GETREGSET)
+	      regset->size = xsave_len;
+	    else if (regset->type != GENERAL_REGS)
+	      regset->size = 0;
+	}
+    }
+
+  /* Check the native XCR0 only if PTRACE_GETREGSET is available.  */
+  xcr0_features = (have_ptrace_getregset == TRIBOOL_TRUE
+		   && (xcr0 & X86_XSTATE_ALL_MASK));
+
+  if (xcr0_features)
+    i387_set_xsave_mask (xcr0, xsave_len);
+
+  if (machine == EM_X86_64)
+    {
+#ifdef __x86_64__
+      const target_desc *tdesc = NULL;
+
+      if (xcr0_features)
+	{
+	  tdesc = amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK,
+						!is_elf64);
+	}
+
+      if (tdesc == NULL)
+	tdesc = amd64_linux_read_description (X86_XSTATE_SSE_MASK, !is_elf64);
+      return tdesc;
+#endif
+    }
+  else
     {
-      int xsave_len = x86_xsave_length ();
-
-      /* Use PTRACE_GETREGSET if it is available.  */
-      for (regset_info *regset = x86_regsets;
-	   regset->fill_function != nullptr;
-	   regset++)
-	if (regset->get_request == PTRACE_GETREGSET)
-	  regset->size = xsave_len;
-	else if (regset->type != GENERAL_REGS)
-	  regset->size = 0;
+      const target_desc *tdesc = NULL;
+
+      if (xcr0_features)
+	  tdesc = i386_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK);
+
+      if (tdesc == NULL)
+	tdesc = i386_linux_read_description (X86_XSTATE_SSE);
+
+      return tdesc;
     }
 
-  return tdesc;
+  gdb_assert_not_reached ("failed to return tdesc");
 }
 
 /* Update all the target description of all processes; a new GDB
diff --git a/gdbserver/linux-x86-tdesc.cc b/gdbserver/linux-x86-tdesc.cc
index 9fd64d8574b..626207fc477 100644
--- a/gdbserver/linux-x86-tdesc.cc
+++ b/gdbserver/linux-x86-tdesc.cc
@@ -26,7 +26,6 @@
 #include "arch/amd64.h"
 #endif
 #include "x86-tdesc.h"
-#include "nat/x86-linux-tdesc.h"
 
 /* Return the right x86_linux_tdesc index for a given XCR0.  Return
    X86_TDESC_LAST if can't find a match.  */
diff --git a/gdbserver/linux-x86-tdesc.h b/gdbserver/linux-x86-tdesc.h
index 576aaf5e165..f9561b129ae 100644
--- a/gdbserver/linux-x86-tdesc.h
+++ b/gdbserver/linux-x86-tdesc.h
@@ -46,4 +46,11 @@ int amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc);
 
 const struct target_desc *i386_get_ipa_tdesc (int idx);
 
+#ifdef __x86_64__
+const struct target_desc *amd64_linux_read_description (uint64_t xcr0,
+							bool is_x32);
+#endif
+
+const struct target_desc *i386_linux_read_description (uint64_t xcr0);
+
 #endif /* GDBSERVER_LINUX_X86_TDESC_H */

                 reply	other threads:[~2024-03-26 18:59 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20240326185914.7C3583858C60@sourceware.org \
    --to=aburgess@sourceware.org \
    --cc=gdb-cvs@sourceware.org \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).