149 lines
5.1 KiB
Diff
149 lines
5.1 KiB
Diff
|
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
|||
|
From: John Baldwin <jhb@FreeBSD.org>
|
|||
|
Date: Thu, 11 Apr 2024 14:05:43 -0700
|
|||
|
Subject: gdb-rhel-10464-xsave-update-7of21.patch
|
|||
|
|
|||
|
;; Backport "gdb: Support XSAVE layouts for the current host in the Linux
|
|||
|
;; x86 targets."
|
|||
|
;; (John Baldwin, RHEL-10464)
|
|||
|
|
|||
|
Note that this uses the CPUID instruction to determine the total size
|
|||
|
of the XSAVE register set. If there is a way to fetch the register set
|
|||
|
size using ptrace that would probably be better.
|
|||
|
|
|||
|
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|||
|
|
|||
|
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
|
|||
|
--- a/gdb/amd64-linux-nat.c
|
|||
|
+++ b/gdb/amd64-linux-nat.c
|
|||
|
@@ -210,6 +210,7 @@ void
|
|||
|
amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
|
|||
|
{
|
|||
|
struct gdbarch *gdbarch = regcache->arch ();
|
|||
|
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
|||
|
int tid;
|
|||
|
|
|||
|
/* GNU/Linux LWP ID's are process ID's. */
|
|||
|
@@ -235,7 +236,7 @@ amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
|
|||
|
|
|||
|
if (have_ptrace_getregset == TRIBOOL_TRUE)
|
|||
|
{
|
|||
|
- char xstateregs[X86_XSTATE_MAX_SIZE];
|
|||
|
+ char xstateregs[tdep->xsave_layout.sizeof_xsave];
|
|||
|
struct iovec iov;
|
|||
|
|
|||
|
/* Pre-4.14 kernels have a bug (fixed by commit 0852b374173b
|
|||
|
@@ -270,6 +271,7 @@ void
|
|||
|
amd64_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
|
|||
|
{
|
|||
|
struct gdbarch *gdbarch = regcache->arch ();
|
|||
|
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
|||
|
int tid;
|
|||
|
|
|||
|
/* GNU/Linux LWP ID's are process ID's. */
|
|||
|
@@ -299,7 +301,7 @@ amd64_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
|
|||
|
|
|||
|
if (have_ptrace_getregset == TRIBOOL_TRUE)
|
|||
|
{
|
|||
|
- char xstateregs[X86_XSTATE_MAX_SIZE];
|
|||
|
+ char xstateregs[tdep->xsave_layout.sizeof_xsave];
|
|||
|
struct iovec iov;
|
|||
|
|
|||
|
iov.iov_base = xstateregs;
|
|||
|
diff --git a/gdb/configure.nat b/gdb/configure.nat
|
|||
|
--- a/gdb/configure.nat
|
|||
|
+++ b/gdb/configure.nat
|
|||
|
@@ -246,6 +246,7 @@ case ${gdb_host} in
|
|||
|
i386)
|
|||
|
# Host: Intel 386 running GNU/Linux.
|
|||
|
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"
|
|||
|
;;
|
|||
|
@@ -303,7 +304,7 @@ case ${gdb_host} in
|
|||
|
i386)
|
|||
|
# Host: GNU/Linux x86-64
|
|||
|
NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \
|
|||
|
- amd64-nat.o amd64-linux-nat.o x86-linux-nat.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/amd64-linux-siginfo.o"
|
|||
|
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
|
|||
|
--- a/gdb/i386-linux-nat.c
|
|||
|
+++ b/gdb/i386-linux-nat.c
|
|||
|
@@ -330,7 +330,9 @@ store_fpregs (const struct regcache *regcache, int tid, int regno)
|
|||
|
static int
|
|||
|
fetch_xstateregs (struct regcache *regcache, int tid)
|
|||
|
{
|
|||
|
- char xstateregs[X86_XSTATE_MAX_SIZE];
|
|||
|
+ struct gdbarch *gdbarch = regcache->arch ();
|
|||
|
+ const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
|
|||
|
+ char xstateregs[tdep->xsave_layout.sizeof_xsave];
|
|||
|
struct iovec iov;
|
|||
|
|
|||
|
if (have_ptrace_getregset != TRIBOOL_TRUE)
|
|||
|
@@ -353,7 +355,9 @@ fetch_xstateregs (struct regcache *regcache, int tid)
|
|||
|
static int
|
|||
|
store_xstateregs (const struct regcache *regcache, int tid, int regno)
|
|||
|
{
|
|||
|
- char xstateregs[X86_XSTATE_MAX_SIZE];
|
|||
|
+ struct gdbarch *gdbarch = regcache->arch ();
|
|||
|
+ const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
|
|||
|
+ char xstateregs[tdep->xsave_layout.sizeof_xsave];
|
|||
|
struct iovec iov;
|
|||
|
|
|||
|
if (have_ptrace_getregset != TRIBOOL_TRUE)
|
|||
|
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
|
|||
|
--- a/gdb/x86-linux-nat.c
|
|||
|
+++ b/gdb/x86-linux-nat.c
|
|||
|
@@ -36,6 +36,7 @@
|
|||
|
#include "amd64-linux-tdep.h"
|
|||
|
#endif
|
|||
|
#include "gdbsupport/x86-xstate.h"
|
|||
|
+#include "nat/x86-xstate.h"
|
|||
|
#include "nat/linux-btrace.h"
|
|||
|
#include "nat/linux-nat.h"
|
|||
|
#include "nat/x86-linux.h"
|
|||
|
@@ -177,6 +178,8 @@ x86_linux_nat_target::read_description ()
|
|||
|
/* 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 ());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
diff --git a/gdb/x86-linux-nat.h b/gdb/x86-linux-nat.h
|
|||
|
--- a/gdb/x86-linux-nat.h
|
|||
|
+++ b/gdb/x86-linux-nat.h
|
|||
|
@@ -22,6 +22,7 @@
|
|||
|
|
|||
|
#include "gdb_proc_service.h" /* For ps_err_e. */
|
|||
|
#include "linux-nat.h"
|
|||
|
+#include "gdbsupport/x86-xstate.h"
|
|||
|
#include "x86-nat.h"
|
|||
|
#include "nat/x86-linux.h"
|
|||
|
|
|||
|
@@ -44,6 +45,9 @@ struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
|
|||
|
enum btrace_read_type type) override;
|
|||
|
const struct btrace_config *btrace_conf (const struct btrace_target_info *) override;
|
|||
|
|
|||
|
+ x86_xsave_layout fetch_x86_xsave_layout () override
|
|||
|
+ { return m_xsave_layout; }
|
|||
|
+
|
|||
|
/* These two are rewired to low_ versions. linux-nat.c queries
|
|||
|
stopped-by-watchpoint info as soon as an lwp stops (via the low_
|
|||
|
methods) and caches the result, to be returned via the normal
|
|||
|
@@ -73,6 +77,9 @@ struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
|
|||
|
|
|||
|
void low_delete_thread (struct arch_lwp_info *lwp) override
|
|||
|
{ x86_linux_delete_thread (lwp); }
|
|||
|
+
|
|||
|
+private:
|
|||
|
+ x86_xsave_layout m_xsave_layout;
|
|||
|
};
|
|||
|
|
|||
|
|