From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1726) id 7C3583858C60; Tue, 26 Mar 2024 18:59:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7C3583858C60 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1711479554; bh=x27XP1zG+8LYB4KWXx+pwFFDpfkerx8+AuF+Da/Dzvc=; h=From:To:Subject:Date:From; b=YIpFtqiVmLPV9PIlXFmkRDT25tQzxJoA80K4wGEfSCvYKDeTomxwkOfzBOzBG+Dh/ X4RVyGmGIyUPo8T6UHizKwSl3EqAT98YzpShocPoWn6gplodpVHmRa7jpUxLmVaNX2 S2AQDX17+Fo5oa7T4mbuFsz4yADPIm/5lJt06yYA= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Andrew Burgess To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Revert "gdb/gdbserver: share some code relating to target description creation" X-Act-Checkin: binutils-gdb X-Git-Author: Andrew Burgess X-Git-Refname: refs/heads/master X-Git-Oldrev: 0991b56074af7e6b106015c67925fdcfe039f077 X-Git-Newrev: 49a7660fb50cc3c68e7830eb098905d068a3ccbf Message-Id: <20240326185914.7C3583858C60@sourceware.org> Date: Tue, 26 Mar 2024 18:59:14 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D49a7660fb50c= c3c68e7830eb098905d068a3ccbf commit 49a7660fb50cc3c68e7830eb098905d068a3ccbf Author: Andrew Burgess Date: Tue Mar 26 18:52:44 2024 +0000 Revert "gdb/gdbserver: share some code relating to target description c= reation" =20 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 =3D \ 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" =20 /* 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; =20 +/* 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_bi= t, + 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=3D"${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=3D"${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" =20 /* 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); =20 +/* Return the target description according to XCR0. */ +extern const struct target_desc *i386_linux_read_description (uint64_t xcr= 0); + extern int i386_linux_gregset_reg_offset[]; =20 /* 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 . = */ - -#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 -#include -#include -#include -#include -#include - -/* See nat/x86-linux-tdesc.h. */ - -const target_desc * -x86_linux_tdesc_for_tid (int tid, enum tribool *have_ptrace_getregset, - gdb::function_view xcr0_init_cb, - const char *error_msg, uint64_t *xcr0_storage) -{ -#ifdef __x86_64__ - - x86_linux_arch_size arch_size =3D x86_linux_ptrace_get_arch_size (tid); - bool is_64bit =3D arch_size.is_64bit (); - bool is_x32 =3D arch_size.is_x32 (); - - if (sizeof (void *) =3D=3D 4 && is_64bit && !is_x32) - error ("%s", error_msg); - -#elif HAVE_PTRACE_GETFPXREGS - if (have_ptrace_getfpxregs =3D=3D -1) - { - elf_fpxregset_t fpxregs; - - if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) - { - have_ptrace_getfpxregs =3D 0; - *have_ptrace_getregset =3D TRIBOOL_FALSE; - return i386_linux_read_description (X86_XSTATE_X87_MASK); - } - } -#endif - - if (*have_ptrace_getregset =3D=3D TRIBOOL_UNKNOWN) - { - uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))]; - struct iovec iov; - - iov.iov_base =3D xstateregs; - iov.iov_len =3D sizeof (xstateregs); - - /* Check if PTRACE_GETREGSET works. */ - if (ptrace (PTRACE_GETREGSET, tid, - (unsigned int) NT_X86_XSTATE, &iov) < 0) - { - *have_ptrace_getregset =3D TRIBOOL_FALSE; - *xcr0_storage =3D 0; - } - else - { - *have_ptrace_getregset =3D TRIBOOL_TRUE; - - /* Get XCR0 from XSAVE extended state. */ - *xcr0_storage =3D xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET - / sizeof (uint64_t))]; - -#ifdef __x86_64__ - /* No MPX on x32. */ - if (is_64bit && is_x32) - *xcr0_storage &=3D ~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 =3D=3D TRIBOOL_TRUE) - xcr0_features_bits =3D *xcr0_storage & X86_XSTATE_ALL_MASK; - else - xcr0_features_bits =3D 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 . = */ - -#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 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 xcr= 0); - -#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" =20 /* linux_nat_target::low_new_fork implementation. */ =20 @@ -97,26 +96,90 @@ x86_linux_nat_target::post_startup_inferior (ptid_t pti= d) const struct target_desc * x86_linux_nat_target::read_description () { - static uint64_t xcr0_storage; + int tid; + int is_64bit =3D 0; +#ifdef __x86_64__ + int is_x32; +#endif + static uint64_t xcr0; + uint64_t xcr0_features_bits; =20 if (inferior_ptid =3D=3D null_ptid) return this->beneath ()->read_description (); =20 - int tid =3D inferior_ptid.pid (); + tid =3D inferior_ptid.pid (); + +#ifdef __x86_64__ + + x86_linux_arch_size arch_size =3D x86_linux_ptrace_get_arch_size (tid); + is_64bit =3D arch_size.is_64bit (); + is_x32 =3D arch_size.is_x32 (); + +#elif HAVE_PTRACE_GETFPXREGS + if (have_ptrace_getfpxregs =3D=3D -1) + { + elf_fpxregset_t fpxregs; + + if (ptrace (PTRACE_GETFPXREGS, tid, 0, (int) &fpxregs) < 0) + { + have_ptrace_getfpxregs =3D 0; + have_ptrace_getregset =3D TRIBOOL_FALSE; + return i386_linux_read_description (X86_XSTATE_X87_MASK); + } + } +#endif + + if (have_ptrace_getregset =3D=3D TRIBOOL_UNKNOWN) + { + uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))]; + struct iovec iov; + + iov.iov_base =3D xstateregs; + iov.iov_len =3D sizeof (xstateregs); + + /* Check if PTRACE_GETREGSET works. */ + if (ptrace (PTRACE_GETREGSET, tid, + (unsigned int) NT_X86_XSTATE, &iov) < 0) + have_ptrace_getregset =3D TRIBOOL_FALSE; + else + { + have_ptrace_getregset =3D TRIBOOL_TRUE; + + /* Get XCR0 from XSAVE extended state. */ + xcr0 =3D xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET + / sizeof (uint64_t))]; + + m_xsave_layout =3D 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 =3D=3D TRIBOOL_TRUE) + xcr0_features_bits =3D xcr0 & X86_XSTATE_ALL_MASK; + else + xcr0_features_bits =3D 0; + + if (is_64bit) + { +#ifdef __x86_64__ + return amd64_linux_read_description (xcr0_features_bits, is_x32); +#endif + } + else + { + const struct target_desc * tdesc + =3D i386_linux_read_description (xcr0_features_bits); =20 - const char *error_msg - =3D _("Can't debug 64-bit process with 32-bit GDB"); + if (tdesc =3D=3D NULL) + tdesc =3D i386_linux_read_description (X86_XSTATE_SSE_MASK); =20 - /* Callback that is triggered the first time x86_linux_tdesc_for_tid - reads the xcr0 register. Setup other bits of state */ - auto cb =3D [&] (uint64_t xcr0) - { - this->m_xsave_layout - =3D x86_fetch_xsave_layout (xcr0, x86_xsave_length ()); - }; + return tdesc; + } =20 - return x86_linux_tdesc_for_tid (tid, &have_ptrace_getregset, cb, - error_msg, &xcr0_storage); + gdb_assert_not_reached ("failed to return tdesc"); } =0C =20 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=3D"${srv_tgtobj} nat/linux-btrace.o" srv_tgtobj=3D"${srv_tgtobj} nat/x86-linux.o" srv_tgtobj=3D"${srv_tgtobj} nat/x86-linux-dregs.o" - srv_tgtobj=3D"${srv_tgtobj} nat/x86-linux-tdesc.o" srv_linux_usrregs=3Dyes srv_linux_regsets=3Dyes srv_linux_thread_db=3Dyes @@ -372,7 +371,6 @@ case "${gdbserver_host}" in srv_tgtobj=3D"${srv_tgtobj} nat/linux-btrace.o" srv_tgtobj=3D"${srv_tgtobj} nat/x86-linux.o" srv_tgtobj=3D"${srv_tgtobj} nat/x86-linux-dregs.o" - srv_tgtobj=3D"${srv_tgtobj} nat/x86-linux-tdesc.o" srv_tgtobj=3D"${srv_tgtobj} nat/amd64-linux-siginfo.o" srv_linux_usrregs=3Dyes # This is for i386 progs. srv_linux_regsets=3Dyes 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" =20 /* 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" =20 /* GDB register numbers. */ =20 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" =20 #ifdef __x86_64__ static target_desc_up tdesc_amd64_linux_no_xml; @@ -845,20 +844,32 @@ int have_ptrace_getfpxregs =3D #endif ; =20 -/* 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. */ =20 static const struct target_desc * x86_linux_read_description (void) { - int tid =3D 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 =3D lwpid_of (current_thread); + + is_elf64 =3D linux_pid_exe_is_elf_64_file (tid, &machine); =20 - const char *error_msg - =3D _("Can't debug 64-bit process with 32-bit GDBserver"); + if (sizeof (void *) =3D=3D 4) + { + if (is_elf64 > 0) + error (_("Can't debug 64-bit process with 32-bit GDBserver")); +#ifndef __x86_64__ + else if (machine =3D=3D EM_X86_64) + error (_("Can't debug x86-64 process with 32-bit GDBserver")); +#endif + } =20 /* 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 =3D x86_linux_ptrace_get_arch_size (ti= d); - bool is_64bit =3D arch_size.is_64bit (); - bool is_x32 =3D arch_size.is_x32 (); - - if (sizeof (void *) =3D=3D 4 && is_64bit && !is_x32) - error ("%s", error_msg); - #ifdef __x86_64__ - if (is_64bit && !is_x32) + if (machine =3D=3D EM_X86_64) return tdesc_amd64_linux_no_xml.get (); else #endif return tdesc_i386_linux_no_xml.get (); } =20 - /* Callback that is triggered the first time x86_linux_tdesc_for_tid - reads the xcr0 register. Setup other bits of state */ - auto cb =3D [] (uint64_t xcr0) - { - i387_set_xsave_mask (xcr0, x86_xsave_length ()); - }; +#if !defined __x86_64__ && defined HAVE_PTRACE_GETFPXREGS + if (machine =3D=3D EM_386 && have_ptrace_getfpxregs =3D=3D -1) + { + elf_fpxregset_t fpxregs; =20 - /* 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 - =3D have_ptrace_getregset =3D=3D TRIBOOL_UNKNOWN; + if (ptrace (PTRACE_GETFPXREGS, tid, 0, (long) &fpxregs) < 0) + { + have_ptrace_getfpxregs =3D 0; + have_ptrace_getregset =3D TRIBOOL_FALSE; + return i386_linux_read_description (X86_XSTATE_X87); + } + else + have_ptrace_getfpxregs =3D 1; + } +#endif =20 - const target_desc *tdesc - =3D x86_linux_tdesc_for_tid (tid, &have_ptrace_getregset, cb, error_ms= g, - &xcr0_storage); + if (have_ptrace_getregset =3D=3D TRIBOOL_UNKNOWN) + { + uint64_t xstateregs[(X86_XSTATE_SSE_SIZE / sizeof (uint64_t))]; + struct iovec iov; =20 - if (have_ptrace_getregset_is_unknown - && have_ptrace_getregset =3D=3D TRIBOOL_TRUE) + iov.iov_base =3D xstateregs; + iov.iov_len =3D sizeof (xstateregs); + + /* Check if PTRACE_GETREGSET works. */ + if (ptrace (PTRACE_GETREGSET, tid, + (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) + have_ptrace_getregset =3D TRIBOOL_FALSE; + else + { + have_ptrace_getregset =3D TRIBOOL_TRUE; + + /* Get XCR0 from XSAVE extended state. */ + xcr0 =3D xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET + / sizeof (uint64_t))]; + + /* No MPX on x32. */ + if (machine =3D=3D EM_X86_64 && !is_elf64) + xcr0 &=3D ~X86_XSTATE_MPX; + + xsave_len =3D x86_xsave_length (); + + /* Use PTRACE_GETREGSET if it is available. */ + for (regset =3D x86_regsets; + regset->fill_function !=3D NULL; regset++) + if (regset->get_request =3D=3D PTRACE_GETREGSET) + regset->size =3D xsave_len; + else if (regset->type !=3D GENERAL_REGS) + regset->size =3D 0; + } + } + + /* Check the native XCR0 only if PTRACE_GETREGSET is available. */ + xcr0_features =3D (have_ptrace_getregset =3D=3D TRIBOOL_TRUE + && (xcr0 & X86_XSTATE_ALL_MASK)); + + if (xcr0_features) + i387_set_xsave_mask (xcr0, xsave_len); + + if (machine =3D=3D EM_X86_64) + { +#ifdef __x86_64__ + const target_desc *tdesc =3D NULL; + + if (xcr0_features) + { + tdesc =3D amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK, + !is_elf64); + } + + if (tdesc =3D=3D NULL) + tdesc =3D amd64_linux_read_description (X86_XSTATE_SSE_MASK, !is_elf64); + return tdesc; +#endif + } + else { - int xsave_len =3D x86_xsave_length (); - - /* Use PTRACE_GETREGSET if it is available. */ - for (regset_info *regset =3D x86_regsets; - regset->fill_function !=3D nullptr; - regset++) - if (regset->get_request =3D=3D PTRACE_GETREGSET) - regset->size =3D xsave_len; - else if (regset->type !=3D GENERAL_REGS) - regset->size =3D 0; + const target_desc *tdesc =3D NULL; + + if (xcr0_features) + tdesc =3D i386_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK); + + if (tdesc =3D=3D NULL) + tdesc =3D i386_linux_read_description (X86_XSTATE_SSE); + + return tdesc; } =20 - return tdesc; + gdb_assert_not_reached ("failed to return tdesc"); } =20 /* 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" =20 /* 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 *t= desc); =20 const struct target_desc *i386_get_ipa_tdesc (int idx); =20 +#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 */