diff options
Diffstat (limited to 'gdbserver')
-rw-r--r-- | gdbserver/configure.srv | 2 | ||||
-rw-r--r-- | gdbserver/linux-amd64-ipa.cc | 1 | ||||
-rw-r--r-- | gdbserver/linux-i386-ipa.cc | 1 | ||||
-rw-r--r-- | gdbserver/linux-x86-low.cc | 148 | ||||
-rw-r--r-- | gdbserver/linux-x86-tdesc.cc | 1 | ||||
-rw-r--r-- | gdbserver/linux-x86-tdesc.h | 7 |
6 files changed, 49 insertions, 111 deletions
diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 9e861a7..7a2702d 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -109,6 +109,7 @@ 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 @@ -371,6 +372,7 @@ 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 54e4c98..f97b0d6 100644 --- a/gdbserver/linux-amd64-ipa.cc +++ b/gdbserver/linux-amd64-ipa.cc @@ -23,6 +23,7 @@ #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 2e4646f..459b805 100644 --- a/gdbserver/linux-i386-ipa.cc +++ b/gdbserver/linux-i386-ipa.cc @@ -23,6 +23,7 @@ #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 30d876e..9bf369f 100644 --- a/gdbserver/linux-x86-low.cc +++ b/gdbserver/linux-x86-low.cc @@ -48,6 +48,7 @@ #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; @@ -844,32 +845,20 @@ 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) { - 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); + int tid = lwpid_of (current_thread); - 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 - } + const char *error_msg + = _("Can't debug 64-bit process with 32-bit GDBserver"); /* 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 @@ -879,103 +868,54 @@ 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 (machine == EM_X86_64) + if (is_64bit && !is_x32) return tdesc_amd64_linux_no_xml.get (); else #endif return tdesc_i386_linux_no_xml.get (); } -#if !defined __x86_64__ && defined HAVE_PTRACE_GETFPXREGS - if (machine == EM_386 && have_ptrace_getfpxregs == -1) - { - elf_fpxregset_t fpxregs; - - 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 - - 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, (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); + /* 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 (machine == EM_X86_64) - { -#ifdef __x86_64__ - const target_desc *tdesc = NULL; + /* 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 (xcr0_features) - { - tdesc = amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK, - !is_elf64); - } + const target_desc *tdesc + = x86_linux_tdesc_for_tid (tid, &have_ptrace_getregset, cb, error_msg, + &xcr0_storage); - if (tdesc == NULL) - tdesc = amd64_linux_read_description (X86_XSTATE_SSE_MASK, !is_elf64); - return tdesc; -#endif - } - else + if (have_ptrace_getregset_is_unknown + && have_ptrace_getregset == TRIBOOL_TRUE) { - 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; + 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; } - gdb_assert_not_reached ("failed to return tdesc"); + 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 626207f..9fd64d8 100644 --- a/gdbserver/linux-x86-tdesc.cc +++ b/gdbserver/linux-x86-tdesc.cc @@ -26,6 +26,7 @@ #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 f9561b1..576aaf5 100644 --- a/gdbserver/linux-x86-tdesc.h +++ b/gdbserver/linux-x86-tdesc.h @@ -46,11 +46,4 @@ 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 */ |