From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 From: Keith Seitz Date: Thu, 11 Apr 2024 14:05:42 -0700 Subject: gdb-rhel-10464-xsave-update-2of21.patch ;; Backport "gdb: Store an x86_xsave_layout in i386_gdbarch_tdep." ;; (John Baldwin, RHEL-10464) This structure is fetched from the current target in i386_gdbarch_init via a new "fetch_x86_xsave_layout" target method. Approved-By: Simon Marchi diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -8456,10 +8456,20 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int bnd0_regnum; int num_bnd_cooked; + x86_xsave_layout xsave_layout = target_fetch_x86_xsave_layout (); + /* If there is already a candidate, use it. */ - arches = gdbarch_list_lookup_by_info (arches, &info); - if (arches != NULL) - return arches->gdbarch; + for (arches = gdbarch_list_lookup_by_info (arches, &info); + arches != NULL; + arches = gdbarch_list_lookup_by_info (arches->next, &info)) + { + /* Check that the XSAVE layout of ARCHES matches the layout for + the current target. */ + struct gdbarch_tdep *other_tdep = gdbarch_tdep (arches->gdbarch); + + if (other_tdep->xsave_layout == xsave_layout) + return arches->gdbarch; + } /* Allocate space for the new architecture. Assume i386 for now. */ tdep = XCNEW (struct gdbarch_tdep); @@ -8711,6 +8721,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) gdbarch_free (gdbarch); return NULL; } + tdep->xsave_layout = xsave_layout; num_bnd_cooked = (tdep->bnd0r_regnum > 0 ? I387_NUM_BND_REGS : 0); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -22,6 +22,7 @@ #include "gdbarch.h" #include "infrun.h" +#include "gdbsupport/x86-xstate.h" struct frame_info; struct gdbarch; @@ -144,6 +145,9 @@ struct gdbarch_tdep /* Offset of XCR0 in XSAVE extended state. */ int xsave_xcr0_offset; + /* Layout of the XSAVE area extended region. */ + x86_xsave_layout xsave_layout; + /* Register names. */ const char **register_names; diff --git a/gdb/target-debug.h b/gdb/target-debug.h --- a/gdb/target-debug.h +++ b/gdb/target-debug.h @@ -226,4 +226,23 @@ target_debug_print_signals (gdb::array_view sigs) fputs_unfiltered (" }", gdb_stdlog); } +static void +target_debug_print_x86_xsave_layout (const x86_xsave_layout &layout) +{ + fputs_unfiltered ("{", gdb_stdlog); + fprintf_unfiltered (gdb_stdlog, " sizeof_xsave=%d", layout.sizeof_xsave); +#define POFFS(region) \ + if (layout.region##_offset != 0) \ + fprintf_unfiltered (gdb_stdlog, ", %s_offset=%d", #region, \ + layout.region##_offset) + POFFS(avx); + POFFS(bndregs); + POFFS(bndcfg); + POFFS(k); + POFFS(zmm_h); + POFFS(zmm); + POFFS(pkru); +#undef POFFS + fputs_unfiltered (" }", gdb_stdlog); +} #endif /* TARGET_DEBUG_H */ diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -173,6 +173,7 @@ struct dummy_target : public target_ops const struct frame_unwind *get_tailcall_unwinder () override; void prepare_to_generate_core () override; void done_generating_core () override; + x86_xsave_layout fetch_x86_xsave_layout () override; }; struct debug_target : public target_ops @@ -344,6 +345,7 @@ struct debug_target : public target_ops const struct frame_unwind *get_tailcall_unwinder () override; void prepare_to_generate_core () override; void done_generating_core () override; + x86_xsave_layout fetch_x86_xsave_layout () override; }; void @@ -4413,3 +4415,27 @@ debug_target::done_generating_core () fputs_unfiltered (")\n", gdb_stdlog); } +x86_xsave_layout +target_ops::fetch_x86_xsave_layout () +{ + return this->beneath ()->fetch_x86_xsave_layout (); +} + +x86_xsave_layout +dummy_target::fetch_x86_xsave_layout () +{ + return x86_xsave_layout (); +} + +x86_xsave_layout +debug_target::fetch_x86_xsave_layout () +{ + x86_xsave_layout result; + fprintf_unfiltered (gdb_stdlog, "-> %s->fetch_x86_xsave_layout (...)\n", this->beneath ()->shortname ()); + result = this->beneath ()->fetch_x86_xsave_layout (); + fprintf_unfiltered (gdb_stdlog, "<- %s->fetch_x86_xsave_layout (", this->beneath ()->shortname ()); + fputs_unfiltered (") = ", gdb_stdlog); + target_debug_print_x86_xsave_layout (result); + fputs_unfiltered ("\n", gdb_stdlog); + return result; +} diff --git a/gdb/target.c b/gdb/target.c --- a/gdb/target.c +++ b/gdb/target.c @@ -227,6 +227,12 @@ target_has_execution_current (void) return target_has_execution_1 (current_inferior ()); } +x86_xsave_layout +target_fetch_x86_xsave_layout () +{ + return current_inferior ()->top_target ()->fetch_x86_xsave_layout (); +} + /* This is used to implement the various target commands. */ static void diff --git a/gdb/target.h b/gdb/target.h --- a/gdb/target.h +++ b/gdb/target.h @@ -81,6 +81,7 @@ struct inferior; #include "command.h" #include "disasm.h" #include "tracepoint.h" +#include "gdbsupport/x86-xstate.h" #include "gdbsupport/break-common.h" /* For enum target_hw_bp_type. */ @@ -1260,6 +1261,10 @@ struct target_ops /* Cleanup after generating a core file. */ virtual void done_generating_core () TARGET_DEFAULT_IGNORE (); + + /* Return the x86 XSAVE extended state area layout. */ + virtual x86_xsave_layout fetch_x86_xsave_layout () + TARGET_DEFAULT_RETURN (x86_xsave_layout ()); }; /* Deleter for std::unique_ptr. See comments in @@ -2326,6 +2331,8 @@ extern gdb::unique_xmalloc_ptr target_fileio_read_stralloc #define target_augmented_libraries_svr4_read() \ (current_top_target ()->augmented_libraries_svr4_read) () +extern x86_xsave_layout target_fetch_x86_xsave_layout (); + /* Command logging facility. */ #define target_log_command(p) \