mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-19 01:19:41 +08:00
Revert "gdb/gdbserver: share some code relating to target description creation"
This reverts commit cd9b374ffe.
This commit is contained 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 \
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 ();
|
||||
|
||||
const char *error_msg
|
||||
= _("Can't debug 64-bit process with 32-bit GDB");
|
||||
#ifdef __x86_64__
|
||||
|
||||
/* 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 ());
|
||||
};
|
||||
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 ();
|
||||
|
||||
return x86_linux_tdesc_for_tid (tid, &have_ptrace_getregset, cb,
|
||||
error_msg, &xcr0_storage);
|
||||
#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);
|
||||
|
||||
if (tdesc == NULL)
|
||||
tdesc = i386_linux_read_description (X86_XSTATE_SSE_MASK);
|
||||
|
||||
return tdesc;
|
||||
}
|
||||
|
||||
gdb_assert_not_reached ("failed to return tdesc");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
const char *error_msg
|
||||
= _("Can't debug 64-bit process with 32-bit GDBserver");
|
||||
tid = lwpid_of (current_thread);
|
||||
|
||||
is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
|
||||
|
||||
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 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;
|
||||
|
||||
const target_desc *tdesc
|
||||
= x86_linux_tdesc_for_tid (tid, &have_ptrace_getregset, cb, error_msg,
|
||||
&xcr0_storage);
|
||||
|
||||
if (have_ptrace_getregset_is_unknown
|
||||
&& have_ptrace_getregset == TRIBOOL_TRUE)
|
||||
#if !defined __x86_64__ && defined HAVE_PTRACE_GETFPXREGS
|
||||
if (machine == EM_386 && have_ptrace_getfpxregs == -1)
|
||||
{
|
||||
int xsave_len = x86_xsave_length ();
|
||||
elf_fpxregset_t fpxregs;
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return tdesc;
|
||||
/* 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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
gdb_assert_not_reached ("failed to return tdesc");
|
||||
}
|
||||
|
||||
/* Update all the target description of all processes; a new GDB
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user