gdb/gdb-rhel-10464-xsave-update-7of21.patch

149 lines
5.1 KiB
Diff
Raw Normal View History

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