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;
|
||
};
|
||
|
||
|