aboutsummaryrefslogtreecommitdiff
path: root/gdbserver
diff options
context:
space:
mode:
Diffstat (limited to 'gdbserver')
-rw-r--r--gdbserver/configure.srv2
-rw-r--r--gdbserver/linux-amd64-ipa.cc1
-rw-r--r--gdbserver/linux-i386-ipa.cc1
-rw-r--r--gdbserver/linux-x86-low.cc148
-rw-r--r--gdbserver/linux-x86-tdesc.cc1
-rw-r--r--gdbserver/linux-x86-tdesc.h7
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 */