From 49a7660fb50cc3c68e7830eb098905d068a3ccbf Mon Sep 17 00:00:00 2001 From: Andrew Burgess Date: Tue, 26 Mar 2024 18:52:44 +0000 Subject: Revert "gdb/gdbserver: share some code relating to target description creation" This reverts commit cd9b374ffe372dcaf7e4c15548cf53a301d8dcdd. --- 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 ++ 6 files changed, 111 insertions(+), 49 deletions(-) (limited to 'gdbserver') diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 7a2702d..9e861a7 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 f97b0d6..54e4c98 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 459b805..2e4646f 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 9bf369f..30d876e 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 9fd64d8..626207f 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 576aaf5..f9561b1 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 */ -- cgit v1.1