diff options
-rw-r--r-- | gdb/NEWS | 4 | ||||
-rw-r--r-- | gdb/amd64-linux-nat.c | 1 | ||||
-rw-r--r-- | gdb/amd64-linux-tdep.c | 9 | ||||
-rw-r--r-- | gdb/amd64-linux-tdep.h | 4 | ||||
-rw-r--r-- | gdb/amd64-tdep.c | 19 | ||||
-rw-r--r-- | gdb/amd64-tdep.h | 1 | ||||
-rw-r--r-- | gdb/common/x86-xstate.h | 19 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 4 | ||||
-rw-r--r-- | gdb/features/Makefile | 34 | ||||
-rw-r--r-- | gdb/features/i386/32bit-pkeys.xml | 13 | ||||
-rw-r--r-- | gdb/features/i386/64bit-pkeys.xml | 13 | ||||
-rw-r--r-- | gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.c (renamed from gdb/features/i386/amd64-avx-mpx-avx512-linux.c) | 11 | ||||
-rw-r--r-- | gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.xml (renamed from gdb/features/i386/amd64-avx-mpx-avx512-linux.xml) | 4 | ||||
-rw-r--r-- | gdb/features/i386/amd64-avx-mpx-avx512-pku.c (renamed from gdb/features/i386/amd64-avx-mpx-avx512.c) | 11 | ||||
-rw-r--r-- | gdb/features/i386/amd64-avx-mpx-avx512-pku.xml (renamed from gdb/features/i386/amd64-avx-mpx-avx512.xml) | 3 | ||||
-rw-r--r-- | gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c (renamed from gdb/features/i386/i386-avx-mpx-avx512-linux.c) | 11 | ||||
-rw-r--r-- | gdb/features/i386/i386-avx-mpx-avx512-pku-linux.xml (renamed from gdb/features/i386/i386-avx-mpx-avx512-linux.xml) | 4 | ||||
-rw-r--r-- | gdb/features/i386/i386-avx-mpx-avx512-pku.c (renamed from gdb/features/i386/i386-avx-mpx-avx512.c) | 11 | ||||
-rw-r--r-- | gdb/features/i386/i386-avx-mpx-avx512-pku.xml (renamed from gdb/features/i386/i386-avx-mpx-avx512.xml) | 3 | ||||
-rw-r--r-- | gdb/gdbserver/Makefile.in | 24 | ||||
-rw-r--r-- | gdb/gdbserver/configure.srv | 24 | ||||
-rw-r--r-- | gdb/gdbserver/i387-fp.c | 43 | ||||
-rw-r--r-- | gdb/gdbserver/linux-amd64-ipa.c | 5 | ||||
-rw-r--r-- | gdb/gdbserver/linux-i386-ipa.c | 6 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-low.c | 28 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-tdesc.h | 12 | ||||
-rw-r--r-- | gdb/i386-linux-nat.c | 2 | ||||
-rw-r--r-- | gdb/i386-linux-tdep.c | 9 | ||||
-rw-r--r-- | gdb/i386-linux-tdep.h | 5 | ||||
-rw-r--r-- | gdb/i386-tdep.c | 61 | ||||
-rw-r--r-- | gdb/i386-tdep.h | 14 | ||||
-rw-r--r-- | gdb/i387-tdep.c | 83 | ||||
-rw-r--r-- | gdb/i387-tdep.h | 5 | ||||
-rw-r--r-- | gdb/regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat (renamed from gdb/regformats/i386/amd64-avx-mpx-avx512.dat) | 6 | ||||
-rw-r--r-- | gdb/regformats/i386/amd64-avx-mpx-avx512-pku.dat (renamed from gdb/regformats/i386/amd64-avx-mpx-avx512-linux.dat) | 7 | ||||
-rw-r--r-- | gdb/regformats/i386/i386-avx-mpx-avx512-pku-linux.dat (renamed from gdb/regformats/i386/i386-avx-mpx-avx512-linux.dat) | 7 | ||||
-rw-r--r-- | gdb/regformats/i386/i386-avx-mpx-avx512-pku.dat (renamed from gdb/regformats/i386/i386-avx-mpx-avx512.dat) | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/i386-pkru.c | 90 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/i386-pkru.exp | 66 | ||||
-rw-r--r-- | gdb/x86-linux-nat.c | 10 |
40 files changed, 560 insertions, 133 deletions
@@ -3,6 +3,10 @@ *** Changes since GDB 7.12 +* GDB now supports access to the PKU register on GNU/Linux. The register is + added by the Memory Protection Keys for Userspace feature which will be + available in future Intel CPUs. + * Python Scripting ** New functions to start, stop and access a running btrace recording. diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index 528984c..4a429ec 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -73,6 +73,7 @@ static int amd64_linux_gregset32_reg_offset[] = -1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */ -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512) */ -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512) */ + -1, /* PKEYS register PKRU */ ORIG_RAX * 8 /* "orig_eax" */ }; diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 21aa3bc..0e2f285 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -45,7 +45,7 @@ #include "features/i386/amd64-mpx-linux.c" #include "features/i386/amd64-avx-mpx-linux.c" #include "features/i386/amd64-avx-avx512-linux.c" -#include "features/i386/amd64-avx-mpx-avx512-linux.c" +#include "features/i386/amd64-avx-mpx-avx512-pku-linux.c" #include "features/i386/x32-linux.c" #include "features/i386/x32-avx-linux.c" @@ -104,6 +104,7 @@ int amd64_linux_gregset_reg_offset[] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, /* PKEYS register pkru */ /* End of hardware registers */ 21 * 8, 22 * 8, /* fs_base and gs_base. */ @@ -1586,12 +1587,12 @@ amd64_linux_core_read_description (struct gdbarch *gdbarch, switch (xcr0 & X86_XSTATE_ALL_MASK) { - case X86_XSTATE_AVX_MPX_AVX512_MASK: + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: if (gdbarch_ptr_bit (gdbarch) == 32) /* No MPX on x32, fallback to AVX-AVX512. */ return tdesc_x32_avx_avx512_linux; else - return tdesc_amd64_avx_mpx_avx512_linux; + return tdesc_amd64_avx_mpx_avx512_pku_linux; case X86_XSTATE_AVX_AVX512_MASK: if (gdbarch_ptr_bit (gdbarch) == 32) return tdesc_x32_avx_avx512_linux; @@ -2305,7 +2306,7 @@ _initialize_amd64_linux_tdep (void) initialize_tdesc_amd64_mpx_linux (); initialize_tdesc_amd64_avx_mpx_linux (); initialize_tdesc_amd64_avx_avx512_linux (); - initialize_tdesc_amd64_avx_mpx_avx512_linux (); + initialize_tdesc_amd64_avx_mpx_avx512_pku_linux (); initialize_tdesc_x32_linux (); initialize_tdesc_x32_avx_linux (); diff --git a/gdb/amd64-linux-tdep.h b/gdb/amd64-linux-tdep.h index 0d4ddac..7453408 100644 --- a/gdb/amd64-linux-tdep.h +++ b/gdb/amd64-linux-tdep.h @@ -26,7 +26,7 @@ /* Register number for the "orig_rax" register. If this register contains a value >= 0 it is interpreted as the system call number that the kernel is supposed to restart. */ -#define AMD64_LINUX_ORIG_RAX_REGNUM AMD64_NUM_REGS +#define AMD64_LINUX_ORIG_RAX_REGNUM (AMD64_GSBASE_REGNUM + 1) /* Total number of registers for GNU/Linux. */ #define AMD64_LINUX_NUM_REGS (AMD64_LINUX_ORIG_RAX_REGNUM + 1) @@ -37,7 +37,7 @@ extern struct target_desc *tdesc_amd64_avx_linux; extern struct target_desc *tdesc_amd64_mpx_linux; extern struct target_desc *tdesc_amd64_avx_mpx_linux; extern struct target_desc *tdesc_amd64_avx_avx512_linux; -extern struct target_desc *tdesc_amd64_avx_mpx_avx512_linux; +extern struct target_desc *tdesc_amd64_avx_mpx_avx512_pku_linux; extern struct target_desc *tdesc_x32_linux; extern struct target_desc *tdesc_x32_avx_linux; diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index c2a1074..4da71e5 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -47,7 +47,7 @@ #include "features/i386/amd64-mpx.c" #include "features/i386/amd64-avx-mpx.c" #include "features/i386/amd64-avx-avx512.c" -#include "features/i386/amd64-avx-mpx-avx512.c" +#include "features/i386/amd64-avx-mpx-avx512-pku.c" #include "features/i386/x32.c" #include "features/i386/x32-avx.c" @@ -157,6 +157,10 @@ static const char *amd64_xmm_avx512_names[] = { "xmm28", "xmm29", "xmm30", "xmm31" }; +static const char *amd64_pkeys_names[] = { + "pkru" +}; + /* DWARF Register Number Mapping as defined in the System V psABI, section 3.6. */ @@ -3061,6 +3065,13 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) AMD64_GSBASE_REGNUM, "gs_base"); } + if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys") != NULL) + { + tdep->pkeys_register_names = amd64_pkeys_names; + tdep->pkru_regnum = AMD64_PKRU_REGNUM; + tdep->num_pkeys_regs = 1; + } + tdep->num_byte_regs = 20; tdep->num_word_regs = 16; tdep->num_dword_regs = 16; @@ -3203,8 +3214,8 @@ amd64_target_description (uint64_t xcr0) { switch (xcr0 & X86_XSTATE_ALL_MASK) { - case X86_XSTATE_AVX_MPX_AVX512_MASK: - return tdesc_amd64_avx_mpx_avx512; + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: + return tdesc_amd64_avx_mpx_avx512_pku; case X86_XSTATE_AVX_AVX512_MASK: return tdesc_amd64_avx_avx512; case X86_XSTATE_MPX_MASK: @@ -3229,7 +3240,7 @@ _initialize_amd64_tdep (void) initialize_tdesc_amd64_mpx (); initialize_tdesc_amd64_avx_mpx (); initialize_tdesc_amd64_avx_avx512 (); - initialize_tdesc_amd64_avx_mpx_avx512 (); + initialize_tdesc_amd64_avx_mpx_avx512_pku (); initialize_tdesc_x32 (); initialize_tdesc_x32_avx (); diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h index 8ccf031..87f0ba3 100644 --- a/gdb/amd64-tdep.h +++ b/gdb/amd64-tdep.h @@ -77,6 +77,7 @@ enum amd64_regnum AMD64_K7_REGNUM = AMD64_K0_REGNUM + 7, AMD64_ZMM0H_REGNUM, AMD64_ZMM31H_REGNUM = AMD64_ZMM0H_REGNUM + 31, + AMD64_PKRU_REGNUM, AMD64_FSBASE_REGNUM, AMD64_GSBASE_REGNUM }; diff --git a/gdb/common/x86-xstate.h b/gdb/common/x86-xstate.h index 4680bd6..b89928a 100644 --- a/gdb/common/x86-xstate.h +++ b/gdb/common/x86-xstate.h @@ -35,6 +35,8 @@ #define X86_XSTATE_AVX512 (X86_XSTATE_K | X86_XSTATE_ZMM_H \ | X86_XSTATE_ZMM) +#define X86_XSTATE_PKRU (1ULL << 9) + /* Supported mask and size of the extended state. */ #define X86_XSTATE_X87_MASK X86_XSTATE_X87 #define X86_XSTATE_SSE_MASK (X86_XSTATE_X87 | X86_XSTATE_SSE) @@ -42,27 +44,32 @@ #define X86_XSTATE_MPX_MASK (X86_XSTATE_SSE_MASK | X86_XSTATE_MPX) #define X86_XSTATE_AVX_MPX_MASK (X86_XSTATE_AVX_MASK | X86_XSTATE_MPX) #define X86_XSTATE_AVX_AVX512_MASK (X86_XSTATE_AVX_MASK | X86_XSTATE_AVX512) -#define X86_XSTATE_AVX_MPX_AVX512_MASK (X86_XSTATE_AVX_MPX_MASK | X86_XSTATE_AVX512) +#define X86_XSTATE_AVX_MPX_AVX512_PKU_MASK (X86_XSTATE_AVX_MPX_MASK\ + | X86_XSTATE_AVX512 | X86_XSTATE_PKRU) + +#define X86_XSTATE_ALL_MASK (X86_XSTATE_AVX_MPX_AVX512_PKU_MASK) -#define X86_XSTATE_ALL_MASK (X86_XSTATE_AVX_MPX_AVX512_MASK) #define X86_XSTATE_SSE_SIZE 576 #define X86_XSTATE_AVX_SIZE 832 #define X86_XSTATE_BNDREGS_SIZE 1024 #define X86_XSTATE_BNDCFG_SIZE 1088 #define X86_XSTATE_AVX512_SIZE 2688 -#define X86_XSTATE_MAX_SIZE 2688 +#define X86_XSTATE_PKRU_SIZE 2696 +#define X86_XSTATE_MAX_SIZE 2696 /* In case one of the MPX XCR0 bits is set we consider we have MPX. */ #define HAS_MPX(XCR0) (((XCR0) & X86_XSTATE_MPX) != 0) #define HAS_AVX(XCR0) (((XCR0) & X86_XSTATE_AVX) != 0) #define HAS_AVX512(XCR0) (((XCR0) & X86_XSTATE_AVX512) != 0) +#define HAS_PKRU(XCR0) (((XCR0) & X86_XSTATE_PKRU) != 0) /* Get I386 XSAVE extended state size. */ #define X86_XSTATE_SIZE(XCR0) \ - (HAS_AVX512 (XCR0) ? X86_XSTATE_AVX512_SIZE : \ - (HAS_MPX (XCR0) ? X86_XSTATE_BNDCFG_SIZE : \ - (HAS_AVX (XCR0) ? X86_XSTATE_AVX_SIZE : X86_XSTATE_SSE_SIZE))) + (HAS_PKRU (XCR0) ? X86_XSTATE_PKRU_SIZE : \ + (HAS_AVX512 (XCR0) ? X86_XSTATE_AVX512_SIZE : \ + (HAS_MPX (XCR0) ? X86_XSTATE_BNDCFG_SIZE : \ + (HAS_AVX (XCR0) ? X86_XSTATE_AVX_SIZE : X86_XSTATE_SSE_SIZE)))) #endif /* X86_XSTATE_H */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f619470..c465dc2 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -41226,6 +41226,10 @@ describe the additional @sc{zmm} registers: @samp{zmm16h} through @samp{zmm31h}, only valid for amd64. @end itemize +The @samp{org.gnu.gdb.i386.pkeys} feature is optional. It should +describe a single register, @samp{pkru}. It is a 32-bit register +valid for i386 and amd64. + @node MicroBlaze Features @subsection MicroBlaze Features @cindex target descriptions, MicroBlaze features diff --git a/gdb/features/Makefile b/gdb/features/Makefile index f25c884..3bc8b5a 100644 --- a/gdb/features/Makefile +++ b/gdb/features/Makefile @@ -53,12 +53,12 @@ WHICH = aarch64 \ i386/i386-mpx i386/i386-mpx-linux \ i386/i386-avx-mpx i386/i386-avx-mpx-linux \ i386/i386-avx-avx512 i386/i386-avx-avx512-linux \ - i386/i386-avx-mpx-avx512 i386/i386-avx-mpx-avx512-linux \ + i386/i386-avx-mpx-avx512-pku i386/i386-avx-mpx-avx512-pku-linux \ i386/amd64-avx i386/amd64-avx-linux \ i386/amd64-mpx i386/amd64-mpx-linux \ i386/amd64-avx-mpx i386/amd64-avx-mpx-linux \ i386/amd64-avx-avx512 i386/amd64-avx-avx512-linux \ - i386/amd64-avx-mpx-avx512 i386/amd64-avx-mpx-avx512-linux \ + i386/amd64-avx-mpx-avx512-pku i386/amd64-avx-mpx-avx512-pku-linux \ i386/x32 i386/x32-linux \ i386/x32-avx i386/x32-avx-linux \ i386/x32-avx-avx512 i386/x32-avx-avx512-linux \ @@ -142,8 +142,8 @@ XMLTOC = \ i386/amd64-avx.xml \ i386/amd64-avx-avx512-linux.xml \ i386/amd64-avx-avx512.xml \ - i386/amd64-avx-mpx-avx512-linux.xml \ - i386/amd64-avx-mpx-avx512.xml \ + i386/amd64-avx-mpx-avx512-pku-linux.xml \ + i386/amd64-avx-mpx-avx512-pku.xml \ i386/amd64-linux.xml \ i386/amd64-mpx-linux.xml \ i386/amd64-mpx.xml \ @@ -154,8 +154,8 @@ XMLTOC = \ i386/i386-avx.xml \ i386/i386-avx-avx512-linux.xml \ i386/i386-avx-avx512.xml \ - i386/i386-avx-mpx-avx512-linux.xml \ - i386/i386-avx-mpx-avx512.xml \ + i386/i386-avx-mpx-avx512-pku-linux.xml \ + i386/i386-avx-mpx-avx512-pku.xml \ i386/i386-linux.xml \ i386/i386-mmx-linux.xml \ i386/i386-mmx.xml \ @@ -281,10 +281,12 @@ $(outdir)/i386/i386-avx-avx512.dat: i386/32bit-core.xml i386/32bit-avx.xml \ i386/32bit-avx512.xml $(outdir)/i386/i386-avx-avx512-linux.dat: i386/32bit-core.xml i386/32bit-avx.xml \ i386/32bit-linux.xml i386/32bit-avx512.xml -$(outdir)/i386/i386-avx-mpx-avx512.dat: i386/32bit-core.xml i386/32bit-avx.xml \ - i386/32bit-mpx.xml i386/32bit-avx512.xml -$(outdir)/i386/i386-avx-mpx-avx512-linux.dat: i386/32bit-core.xml i386/32bit-avx.xml \ - i386/32bit-linux.xml i386/32bit-mpx.xml i386/32bit-avx512.xml +$(outdir)/i386/i386-avx-mpx-avx512-pku.dat: i386/32bit-core.xml + i386/32bit-avx.xml i386/32bit-mpx.xml i386/32bit-avx512.xml \ + i386/32bit-pkeys.xml +$(outdir)/i386/i386-avx-mpx-avx512-pku-linux.dat: i386/32bit-core.xml \ + i386/32bit-avx.xml i386/32bit-mpx.xml i386/32bit-avx512.xml \ + i386/32bit-pkeys.xml i386/32bit-linux.xml $(outdir)/i386/i386-mmx.dat: i386/32bit-core.xml $(outdir)/i386/i386-mmx-linux.dat: i386/32bit-core.xml i386/32bit-linux.xml $(outdir)/i386/amd64-avx.dat: i386/64bit-core.xml i386/64bit-avx.xml @@ -302,11 +304,13 @@ $(outdir)/i386/amd64-avx-avx512.dat: i386/64bit-core.xml i386/64bit-avx.xml \ i386/64bit-avx512.xml $(outdir)/i386/amd64-avx-avx512-linux.dat: i386/64bit-core.xml i386/64bit-avx.xml \ i386/64bit-avx512.xml i386/64bit-linux.xml -$(outdir)/i386/amd64-avx-mpx-avx512.dat: i386/64bit-core.xml i386/64bit-avx.xml \ - i386/64bit-mpx.xml i386/64bit-avx512.xml -$(outdir)/i386/amd64-avx-mpx-avx512-linux.dat: i386/64bit-core.xml i386/64bit-avx.xml \ - i386/64bit-mpx.xml i386/64bit-avx512.xml \ - i386/64bit-linux.xml i386/64bit-segments.xml +$(outdir)/i386/amd64-avx-mpx-avx512-pku.dat: i386/64bit-core.xml \ + i386/64bit-avx.xml i386/64bit-mpx.xml i386/64bit-avx512.xml \ + i386/64bit-pkeys.xml +$(outdir)/i386/amd64-avx-mpx-avx512-pku-linux.dat: i386/64bit-core.xml \ + i386/64bit-avx.xml i386/64bit-mpx.xml i386/64bit-avx512.xml \ + i386/64bit-linux.xml i386/64bit-segments.xml \ + i386/64bit-pkeys.xml $(outdir)/i386/x32.dat: i386/x32-core.xml i386/64bit-sse.xml $(outdir)/i386/x32-linux.dat: i386/x32-core.xml i386/64bit-sse.xml \ i386/64bit-linux.xml i386/64bit-segments.xml diff --git a/gdb/features/i386/32bit-pkeys.xml b/gdb/features/i386/32bit-pkeys.xml new file mode 100644 index 0000000..7ae5cc5 --- /dev/null +++ b/gdb/features/i386/32bit-pkeys.xml @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2016-2017 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.i386.pkeys"> + + <reg name="pkru" bitsize="32" type="uint32"/> + +</feature> diff --git a/gdb/features/i386/64bit-pkeys.xml b/gdb/features/i386/64bit-pkeys.xml new file mode 100644 index 0000000..7ae5cc5 --- /dev/null +++ b/gdb/features/i386/64bit-pkeys.xml @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2016-2017 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.i386.pkeys"> + + <reg name="pkru" bitsize="32" type="uint32"/> + +</feature> diff --git a/gdb/features/i386/amd64-avx-mpx-avx512-linux.c b/gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.c index dd1f100..248eff7 100644 --- a/gdb/features/i386/amd64-avx-mpx-avx512-linux.c +++ b/gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.c @@ -1,13 +1,13 @@ /* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: - Original: amd64-avx-mpx-avx512-linux.xml */ + Original: amd64-avx-mpx-avx512-pku-linux.xml */ #include "defs.h" #include "osabi.h" #include "target-descriptions.h" -struct target_desc *tdesc_amd64_avx_mpx_avx512_linux; +struct target_desc *tdesc_amd64_avx_mpx_avx512_pku_linux; static void -initialize_tdesc_amd64_avx_mpx_avx512_linux (void) +initialize_tdesc_amd64_avx_mpx_avx512_pku_linux (void) { struct target_desc *result = allocate_target_description (); struct tdesc_feature *feature; @@ -322,5 +322,8 @@ initialize_tdesc_amd64_avx_mpx_avx512_linux (void) tdesc_create_reg (feature, "zmm30h", 152, 1, NULL, 256, "v2ui128"); tdesc_create_reg (feature, "zmm31h", 153, 1, NULL, 256, "v2ui128"); - tdesc_amd64_avx_mpx_avx512_linux = result; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys"); + tdesc_create_reg (feature, "pkru", 152, 1, NULL, 32, "uint32"); + + tdesc_amd64_avx_mpx_avx512_pku_linux = result; } diff --git a/gdb/features/i386/amd64-avx-mpx-avx512-linux.xml b/gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.xml index 21d0664..9585606 100644 --- a/gdb/features/i386/amd64-avx-mpx-avx512-linux.xml +++ b/gdb/features/i386/amd64-avx-mpx-avx512-pku-linux.xml @@ -5,7 +5,8 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> -<!-- AMD64 with AVX, MPX, AVX512 - Includes Linux-only special "register". --> +<!-- AMD64 with AVX, MPX, AVX512, PKEYS - Includes Linux-only + special "register". --> <!DOCTYPE target SYSTEM "gdb-target.dtd"> <target> @@ -18,4 +19,5 @@ <xi:include href="64bit-avx.xml"/> <xi:include href="64bit-mpx.xml"/> <xi:include href="64bit-avx512.xml"/> + <xi:include href="64bit-pkeys.xml"/> </target> diff --git a/gdb/features/i386/amd64-avx-mpx-avx512.c b/gdb/features/i386/amd64-avx-mpx-avx512-pku.c index 486931f..dfe7d77 100644 --- a/gdb/features/i386/amd64-avx-mpx-avx512.c +++ b/gdb/features/i386/amd64-avx-mpx-avx512-pku.c @@ -1,13 +1,13 @@ /* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: - Original: amd64-avx-mpx-avx512.xml */ + Original: amd64-avx-mpx-avx512-pku.xml */ #include "defs.h" #include "osabi.h" #include "target-descriptions.h" -struct target_desc *tdesc_amd64_avx_mpx_avx512; +struct target_desc *tdesc_amd64_avx_mpx_avx512_pku; static void -initialize_tdesc_amd64_avx_mpx_avx512 (void) +initialize_tdesc_amd64_avx_mpx_avx512_pku (void) { struct target_desc *result = allocate_target_description (); struct tdesc_feature *feature; @@ -313,5 +313,8 @@ initialize_tdesc_amd64_avx_mpx_avx512 (void) tdesc_create_reg (feature, "zmm30h", 149, 1, NULL, 256, "v2ui128"); tdesc_create_reg (feature, "zmm31h", 150, 1, NULL, 256, "v2ui128"); - tdesc_amd64_avx_mpx_avx512 = result; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys"); + tdesc_create_reg (feature, "pkru", 151, 1, NULL, 32, "uint32"); + + tdesc_amd64_avx_mpx_avx512_pku = result; } diff --git a/gdb/features/i386/amd64-avx-mpx-avx512.xml b/gdb/features/i386/amd64-avx-mpx-avx512-pku.xml index 482111e..e769108 100644 --- a/gdb/features/i386/amd64-avx-mpx-avx512.xml +++ b/gdb/features/i386/amd64-avx-mpx-avx512-pku.xml @@ -5,7 +5,7 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> -<!-- AMD64 with AVX, MPX, AVX512 --> +<!-- AMD64 with AVX, MPX, AVX512, PKEYS --> <!DOCTYPE target SYSTEM "gdb-target.dtd"> <target> @@ -15,4 +15,5 @@ <xi:include href="64bit-avx.xml"/> <xi:include href="64bit-mpx.xml"/> <xi:include href="64bit-avx512.xml"/> + <xi:include href="64bit-pkeys.xml"/> </target> diff --git a/gdb/features/i386/i386-avx-mpx-avx512-linux.c b/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c index 0fa3552..f90c834 100644 --- a/gdb/features/i386/i386-avx-mpx-avx512-linux.c +++ b/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.c @@ -1,13 +1,13 @@ /* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: - Original: i386-avx-mpx-avx512-linux.xml */ + Original: i386-avx-mpx-avx512-pku-linux.xml */ #include "defs.h" #include "osabi.h" #include "target-descriptions.h" -struct target_desc *tdesc_i386_avx_mpx_avx512_linux; +struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux; static void -initialize_tdesc_i386_avx_mpx_avx512_linux (void) +initialize_tdesc_i386_avx_mpx_avx512_pku_linux (void) { struct target_desc *result = allocate_target_description (); struct tdesc_feature *feature; @@ -204,5 +204,8 @@ initialize_tdesc_i386_avx_mpx_avx512_linux (void) tdesc_create_reg (feature, "zmm6h", 70, 1, NULL, 256, "v2ui128"); tdesc_create_reg (feature, "zmm7h", 71, 1, NULL, 256, "v2ui128"); - tdesc_i386_avx_mpx_avx512_linux = result; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys"); + tdesc_create_reg (feature, "pkru", 72, 1, NULL, 32, "uint32"); + + tdesc_i386_avx_mpx_avx512_pku_linux = result; } diff --git a/gdb/features/i386/i386-avx-mpx-avx512-linux.xml b/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.xml index 2617eab..1ef709a 100644 --- a/gdb/features/i386/i386-avx-mpx-avx512-linux.xml +++ b/gdb/features/i386/i386-avx-mpx-avx512-pku-linux.xml @@ -5,7 +5,8 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> -<!-- I386 with AVX, MPX, AVX512 - Includes Linux-only special "register". --> +<!-- I386 with AVX, MPX, AVX512, PKEYS - Includes Linux-only + special "register". --> <!DOCTYPE target SYSTEM "gdb-target.dtd"> <target> @@ -17,4 +18,5 @@ <xi:include href="32bit-avx.xml"/> <xi:include href="32bit-mpx.xml"/> <xi:include href="32bit-avx512.xml"/> + <xi:include href="32bit-pkeys.xml"/> </target> diff --git a/gdb/features/i386/i386-avx-mpx-avx512.c b/gdb/features/i386/i386-avx-mpx-avx512-pku.c index ad5ac3b..08d9b4b 100644 --- a/gdb/features/i386/i386-avx-mpx-avx512.c +++ b/gdb/features/i386/i386-avx-mpx-avx512-pku.c @@ -1,13 +1,13 @@ /* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: - Original: i386-avx-mpx-avx512.xml */ + Original: i386-avx-mpx-avx512-pku.xml */ #include "defs.h" #include "osabi.h" #include "target-descriptions.h" -struct target_desc *tdesc_i386_avx_mpx_avx512; +struct target_desc *tdesc_i386_avx_mpx_avx512_pku; static void -initialize_tdesc_i386_avx_mpx_avx512 (void) +initialize_tdesc_i386_avx_mpx_avx512_pku (void) { struct target_desc *result = allocate_target_description (); struct tdesc_feature *feature; @@ -199,5 +199,8 @@ initialize_tdesc_i386_avx_mpx_avx512 (void) tdesc_create_reg (feature, "zmm6h", 69, 1, NULL, 256, "v2ui128"); tdesc_create_reg (feature, "zmm7h", 70, 1, NULL, 256, "v2ui128"); - tdesc_i386_avx_mpx_avx512 = result; + feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys"); + tdesc_create_reg (feature, "pkru", 71, 1, NULL, 32, "uint32"); + + tdesc_i386_avx_mpx_avx512_pku = result; } diff --git a/gdb/features/i386/i386-avx-mpx-avx512.xml b/gdb/features/i386/i386-avx-mpx-avx512-pku.xml index 392cc1b..cbf78e1 100644 --- a/gdb/features/i386/i386-avx-mpx-avx512.xml +++ b/gdb/features/i386/i386-avx-mpx-avx512-pku.xml @@ -5,7 +5,7 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> -<!-- I386 with AVX, MPX, AVX512 --> +<!-- I386 with AVX, MPX, AVX512, PKEYS --> <!DOCTYPE target SYSTEM "gdb-target.dtd"> <target> @@ -15,4 +15,5 @@ <xi:include href="32bit-avx.xml"/> <xi:include href="32bit-mpx.xml"/> <xi:include href="32bit-avx512.xml"/> + <xi:include href="32bit-pkeys.xml"/> </target> diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 37a9514..c2354d2 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -446,12 +446,12 @@ clean: rm -f i386-mpx.c i386-mpx-linux.c rm -f i386-avx-mpx.c i386-avx-mpx-linux.c rm -f i386-avx-avx512.c i386-avx-avx512-linux.c - rm -f i386-avx-mpx-avx512.c i386-avx-mpx-avx512-linux.c + rm -f i386-avx-mpx-avx512-pku.c i386-avx-mpx-avx512-pku-linux.c rm -f amd64-avx.c amd64-avx-linux.c rm -f amd64-mpx.c amd64-mpx-linux.c rm -f amd64-avx-mpx.c amd64-avx-mpx-linux.c rm -f amd64-avx-avx512.c amd64-avx-avx512-linux.c - rm -f amd64-avx-mpx-avx512.c amd64-avx-mpx-avx512-linux.c + rm -f amd64-avx-mpx-avx512-pku.c amd64-avx-mpx-avx512-pku-linux.c rm -f i386-mmx.c i386-mmx-linux.c rm -f x32.c x32-linux.c rm -f x32-avx.c x32-avx-linux.c @@ -582,7 +582,7 @@ i386-avx-mpx-linux-ipa.o: i386-avx-mpx-linux.c i386-avx-avx512-linux-ipa.o: i386-avx-avx512-linux.c $(IPAGENT_COMPILE) $< $(POSTCOMPILE) -i386-avx-mpx-avx512-linux-ipa.o: i386-avx-mpx-avx512-linux.c +i386-avx-mpx-avx512-pku-linux-ipa.o: i386-avx-mpx-avx512-pku-linux.c $(IPAGENT_COMPILE) $< $(POSTCOMPILE) linux-i386-ipa.o: linux-i386-ipa.c @@ -606,7 +606,7 @@ amd64-avx-mpx-linux-ipa.o: amd64-avx-mpx-linux.c amd64-avx-avx512-linux-ipa.o: amd64-avx-avx512-linux.c $(IPAGENT_COMPILE) $< $(POSTCOMPILE) -amd64-avx-mpx-avx512-linux-ipa.o: amd64-avx-mpx-avx512-linux.c +amd64-avx-mpx-avx512-pku-linux-ipa.o: amd64-avx-mpx-avx512-pku-linux.c $(IPAGENT_COMPILE) $< $(POSTCOMPILE) linux-aarch64-ipa.o: linux-aarch64-ipa.c @@ -906,14 +906,14 @@ i386-avx-avx512.c : $(srcdir)/../regformats/i386/i386-avx-avx512.dat $(regdat_sh $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx-avx512.dat i386-avx-avx512.c i386-avx-avx512-linux.c : $(srcdir)/../regformats/i386/i386-avx-avx512-linux.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx-avx512-linux.dat i386-avx-avx512-linux.c -i386-avx-mpx-avx512.c : $(srcdir)/../regformats/i386/i386-avx-mpx-avx512.dat $(regdat_sh) - $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx-mpx-avx512.dat i386-avx-mpx-avx512.c -i386-avx-mpx-avx512-linux.c : $(srcdir)/../regformats/i386/i386-avx-mpx-avx512-linux.dat $(regdat_sh) - $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx-mpx-avx512-linux.dat i386-avx-mpx-avx512-linux.c i386-mpx.c : $(srcdir)/../regformats/i386/i386-mpx.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-mpx.dat i386-mpx.c i386-mpx-linux.c : $(srcdir)/../regformats/i386/i386-mpx-linux.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-mpx-linux.dat i386-mpx-linux.c +i386-avx-mpx-avx512-pku.c : $(srcdir)/../regformats/i386/i386-avx-mpx-avx512-pku.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx-mpx-avx512-pku.dat i386-avx-mpx-avx512-pku.c +i386-avx-mpx-avx512-pku-linux.c : $(srcdir)/../regformats/i386/i386-avx-mpx-avx512-pku-linux.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx-mpx-avx512-pku-linux.dat i386-avx-mpx-avx512-pku-linux.c i386-avx-mpx.c : $(srcdir)/../regformats/i386/i386-avx-mpx.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-avx-mpx.dat i386-avx-mpx.c i386-avx-mpx-linux.c : $(srcdir)/../regformats/i386/i386-avx-mpx-linux.dat $(regdat_sh) @@ -1028,14 +1028,14 @@ amd64-avx-avx512.c : $(srcdir)/../regformats/i386/amd64-avx-avx512.dat $(regdat_ $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx-avx512.dat amd64-avx-avx512.c amd64-avx-avx512-linux.c : $(srcdir)/../regformats/i386/amd64-avx-avx512-linux.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx-avx512-linux.dat amd64-avx-avx512-linux.c -amd64-avx-mpx-avx512.c : $(srcdir)/../regformats/i386/amd64-avx-mpx-avx512.dat $(regdat_sh) - $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx-mpx-avx512.dat amd64-avx-mpx-avx512.c -amd64-avx-mpx-avx512-linux.c : $(srcdir)/../regformats/i386/amd64-avx-mpx-avx512-linux.dat $(regdat_sh) - $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx-mpx-avx512-linux.dat amd64-avx-mpx-avx512-linux.c amd64-mpx.c : $(srcdir)/../regformats/i386/amd64-mpx.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-mpx.dat amd64-mpx.c amd64-mpx-linux.c : $(srcdir)/../regformats/i386/amd64-mpx-linux.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-mpx-linux.dat amd64-mpx-linux.c +amd64-avx-mpx-avx512-pku.c : $(srcdir)/../regformats/i386/amd64-avx-mpx-avx512-pku.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx-mpx-avx512-pku.dat amd64-avx-mpx-avx512-pku.c +amd64-avx-mpx-avx512-pku-linux.c : $(srcdir)/../regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat amd64-avx-mpx-avx512-pku-linux.c amd64-avx-mpx.c : $(srcdir)/../regformats/i386/amd64-avx-mpx.dat $(regdat_sh) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-avx-mpx.dat amd64-avx-mpx.c amd64-avx-mpx-linux.c : $(srcdir)/../regformats/i386/amd64-avx-mpx-linux.dat $(regdat_sh) diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index 9390cb1..d00d9e2 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -24,21 +24,21 @@ # Default hostio_last_error implementation srv_hostio_err_objs="hostio-errno.o" -srv_i386_regobj="i386.o i386-avx.o i386-avx-avx512.o i386-avx-mpx-avx512.o i386-mpx.o i386-avx-mpx.o i386-mmx.o" -srv_i386_linux_regobj="i386-linux.o i386-avx-linux.o i386-avx-avx512-linux.o i386-avx-mpx-avx512-linux.o i386-mpx-linux.o i386-avx-mpx-linux.o i386-mmx-linux.o" -srv_amd64_regobj="amd64.o amd64-avx.o amd64-avx-avx512.o amd64-avx-mpx-avx512.o amd64-mpx.o amd64-avx-mpx.o x32.o x32-avx.o x32-avx-avx512.o" -srv_amd64_linux_regobj="amd64-linux.o amd64-avx-linux.o amd64-avx-avx512-linux.o amd64-avx-mpx-avx512-linux.o amd64-mpx-linux.o amd64-avx-mpx-linux.o x32-linux.o x32-avx-linux.o x32-avx-avx512-linux.o" +srv_i386_regobj="i386.o i386-avx.o i386-avx-avx512.o i386-avx-mpx-avx512-pku.o i386-mpx.o i386-avx-mpx.o i386-mmx.o" +srv_i386_linux_regobj="i386-linux.o i386-avx-linux.o i386-avx-avx512-linux.o i386-avx-mpx-avx512-pku-linux.o i386-mpx-linux.o i386-avx-mpx-linux.o i386-mmx-linux.o" +srv_amd64_regobj="amd64.o amd64-avx.o amd64-avx-avx512.o amd64-avx-mpx-avx512-pku.o amd64-mpx.o amd64-avx-mpx.o x32.o x32-avx.o x32-avx-avx512.o" +srv_amd64_linux_regobj="amd64-linux.o amd64-avx-linux.o amd64-avx-avx512-linux.o amd64-avx-mpx-avx512-pku-linux.o amd64-mpx-linux.o amd64-avx-mpx-linux.o x32-linux.o x32-avx-linux.o x32-avx-avx512-linux.o" -ipa_i386_linux_regobj="i386-linux-ipa.o i386-avx-linux-ipa.o i386-avx-mpx-linux-ipa.o i386-avx-avx512-linux-ipa.o i386-avx-mpx-avx512-linux-ipa.o i386-mpx-linux-ipa.o i386-mmx-linux-ipa.o" -ipa_amd64_linux_regobj="amd64-linux-ipa.o amd64-avx-linux-ipa.o amd64-avx-mpx-linux-ipa.o amd64-avx-avx512-linux-ipa.o amd64-avx-mpx-avx512-linux-ipa.o amd64-mpx-linux-ipa.o" +ipa_i386_linux_regobj="i386-linux-ipa.o i386-avx-linux-ipa.o i386-avx-mpx-linux-ipa.o i386-avx-avx512-linux-ipa.o i386-avx-mpx-avx512-pku-linux-ipa.o i386-mpx-linux-ipa.o i386-mmx-linux-ipa.o" +ipa_amd64_linux_regobj="amd64-linux-ipa.o amd64-avx-linux-ipa.o amd64-avx-mpx-linux-ipa.o amd64-avx-avx512-linux-ipa.o amd64-avx-mpx-avx512-pku-linux-ipa.o amd64-mpx-linux-ipa.o" ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o" -srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml i386/32bit-avx512.xml i386/32bit-mpx.xml" -srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-segments.xml i386/64bit-sse.xml i386/64bit-avx.xml i386/64bit-avx512.xml i386/x32-core.xml i386/64bit-mpx.xml" -srv_i386_xmlfiles="i386/i386.xml i386/i386-avx.xml i386/i386-avx-avx512.xml i386/i386-avx-mpx-avx512.xml i386/i386-mpx.xml i386/i386-avx-mpx.xml i386/i386-mmx.xml $srv_i386_32bit_xmlfiles" -srv_amd64_xmlfiles="i386/amd64.xml i386/amd64-avx.xml i386/amd64-avx-avx512.xml i386/amd64-avx-mpx-avx512.xml i386/x32.xml i386/x32-avx.xml i386/x32-avx-avx512.xml i386/amd64-mpx.xml i386/amd64-avx-mpx.xml $srv_i386_64bit_xmlfiles" -srv_i386_linux_xmlfiles="i386/i386-linux.xml i386/i386-avx-linux.xml i386/i386-avx-avx512-linux.xml i386/i386-avx-mpx-avx512-linux.xml i386/i386-mmx-linux.xml i386/32bit-linux.xml i386/i386-mpx-linux.xml i386/i386-avx-mpx-linux.xml $srv_i386_32bit_xmlfiles" -srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/amd64-avx-linux.xml i386/amd64-avx-avx512.xml i386/amd64-avx-mpx-avx512-linux.xml i386/64bit-linux.xml i386/amd64-mpx-linux.xml i386/amd64-avx-mpx-linux.xml i386/x32-linux.xml i386/x32-avx-linux.xml i386/x32-avx-avx512-linux.xml $srv_i386_64bit_xmlfiles" +srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml i386/32bit-avx512.xml i386/32bit-mpx.xml i386/32bit-pkeys.xml" +srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-segments.xml i386/64bit-sse.xml i386/64bit-avx.xml i386/64bit-avx512.xml i386/x32-core.xml i386/64bit-mpx.xml i386/64bit-pkeys.xml" +srv_i386_xmlfiles="i386/i386.xml i386/i386-avx.xml i386/i386-avx-avx512.xml i386/i386-avx-mpx-avx512-pku.xml i386/i386-mpx.xml i386/i386-avx-mpx.xml i386/i386-mmx.xml $srv_i386_32bit_xmlfiles" +srv_amd64_xmlfiles="i386/amd64.xml i386/amd64-avx.xml i386/amd64-avx-avx512.xml i386/amd64-avx-mpx-avx512-pku.xml i386/x32.xml i386/x32-avx.xml i386/x32-avx-avx512.xml i386/amd64-mpx.xml i386/amd64-avx-mpx.xml $srv_i386_64bit_xmlfiles" +srv_i386_linux_xmlfiles="i386/i386-linux.xml i386/i386-avx-linux.xml i386/i386-avx-avx512-linux.xml i386/i386-avx-mpx-avx512-pku-linux.xml i386/i386-mmx-linux.xml i386/32bit-linux.xml i386/i386-mpx-linux.xml i386/i386-avx-mpx-linux.xml $srv_i386_32bit_xmlfiles" +srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/amd64-avx-linux.xml i386/amd64-avx-avx512.xml i386/amd64-avx-mpx-avx512-pku-linux.xml i386/64bit-linux.xml i386/amd64-mpx-linux.xml i386/amd64-avx-mpx-linux.xml i386/x32-linux.xml i386/x32-avx-linux.xml i386/x32-avx-avx512-linux.xml $srv_i386_64bit_xmlfiles" # Linux object files. This is so we don't have to repeat diff --git a/gdb/gdbserver/i387-fp.c b/gdb/gdbserver/i387-fp.c index 8267045..5f5cbda 100644 --- a/gdb/gdbserver/i387-fp.c +++ b/gdb/gdbserver/i387-fp.c @@ -27,6 +27,7 @@ static const int num_avx512_zmmh_low_registers = 16; static const int num_avx512_zmmh_high_registers = 16; static const int num_avx512_ymmh_registers = 16; static const int num_avx512_xmm_registers = 16; +static const int num_pkeys_registers = 1; /* Note: These functions preserve the reserved bits in control registers. However, gdbserver promptly throws away that information. */ @@ -136,6 +137,10 @@ struct i387_xsave { /* Space for 16 512-bit zmm16-31 values. */ unsigned char zmmh_high_space[1024]; + + /* Space for 1 32-bit PKRU register. The HW XSTATE size for this feature is + actually 64 bits, but WRPKRU/RDPKRU instructions ignore upper 32 bits. */ + unsigned char pkru_space[8]; }; void @@ -325,6 +330,10 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) for (i = 0; i < num_avx512_ymmh_registers; i++) memset (((char *) &fp->zmmh_high_space[0]) + 16 + i * 64, 0, 16); } + + if ((clear_bv & X86_XSTATE_PKRU)) + for (i = 0; i < num_pkeys_registers; i++) + memset (((char *) &fp->pkru_space[0]) + i * 4, 0, 4); } /* Check if any x87 registers are changed. */ @@ -497,6 +506,23 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) } } + /* Check if any PKEYS registers are changed. */ + if ((x86_xcr0 & X86_XSTATE_PKRU)) + { + int pkru_regnum = find_regno (regcache->tdesc, "pkru"); + + for (i = 0; i < num_pkeys_registers; i++) + { + collect_register (regcache, i + pkru_regnum, raw); + p = ((char *) &fp->pkru_space[0]) + i * 4; + if (memcmp (raw, p, 4) != 0) + { + xstate_bv |= X86_XSTATE_PKRU; + memcpy (p, raw, 4); + } + } + } + /* Update the corresponding bits in xstate_bv if any SSE/AVX registers are changed. */ fp->xstate_bv |= xstate_bv; @@ -801,6 +827,23 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) } } + if ((x86_xcr0 & X86_XSTATE_PKRU) != 0) + { + int pkru_regnum = find_regno (regcache->tdesc, "pkru"); + + if ((clear_bv & X86_XSTATE_PKRU) != 0) + { + for (i = 0; i < num_pkeys_registers; i++) + supply_register_zeroed (regcache, i + pkru_regnum); + } + else + { + p = (gdb_byte *) &fp->pkru_space[0]; + for (i = 0; i < num_pkeys_registers; i++) + supply_register (regcache, i + pkru_regnum, p + i * 4); + } + } + supply_register_by_name (regcache, "fioff", &fp->fioff); supply_register_by_name (regcache, "fooff", &fp->fooff); supply_register_by_name (regcache, "mxcsr", &fp->mxcsr); diff --git a/gdb/gdbserver/linux-amd64-ipa.c b/gdb/gdbserver/linux-amd64-ipa.c index c00b77a..67f36c2 100644 --- a/gdb/gdbserver/linux-amd64-ipa.c +++ b/gdb/gdbserver/linux-amd64-ipa.c @@ -197,8 +197,8 @@ get_ipa_tdesc (int idx) return tdesc_amd64_mpx_linux; case X86_TDESC_AVX_MPX: return tdesc_amd64_avx_mpx_linux; - case X86_TDESC_AVX_MPX_AVX512: - return tdesc_amd64_avx_mpx_avx512_linux; + case X86_TDESC_AVX_MPX_AVX512_PKU: + return tdesc_amd64_avx_mpx_avx512_pku_linux; case X86_TDESC_AVX_AVX512: return tdesc_amd64_avx_avx512_linux; default: @@ -286,5 +286,6 @@ initialize_low_tracepoint (void) init_registers_amd64_mpx_linux (); init_registers_amd64_avx_mpx_linux (); init_registers_amd64_avx_avx512_linux (); + init_registers_amd64_avx_mpx_avx512_pku_linux (); #endif } diff --git a/gdb/gdbserver/linux-i386-ipa.c b/gdb/gdbserver/linux-i386-ipa.c index aa16f85..e9ac78b 100644 --- a/gdb/gdbserver/linux-i386-ipa.c +++ b/gdb/gdbserver/linux-i386-ipa.c @@ -264,8 +264,8 @@ get_ipa_tdesc (int idx) return tdesc_i386_avx_mpx_linux; case X86_TDESC_AVX_AVX512: return tdesc_i386_avx_avx512_linux; - case X86_TDESC_AVX_MPX_AVX512: - return tdesc_i386_avx_mpx_avx512_linux; + case X86_TDESC_AVX_MPX_AVX512_PKU: + return tdesc_i386_avx_mpx_avx512_pku_linux; default: internal_error (__FILE__, __LINE__, "unknown ipa tdesc index: %d", idx); @@ -296,7 +296,7 @@ initialize_low_tracepoint (void) init_registers_i386_avx_linux (); init_registers_i386_mpx_linux (); init_registers_i386_avx_avx512_linux (); - init_registers_i386_avx_mpx_avx512_linux (); + init_registers_i386_avx_mpx_avx512_pku_linux (); initialize_fast_tracepoint_trampoline_buffer (); } diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index f946cf4..6df1d51 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -148,7 +148,8 @@ static const int x86_64_regmap[] = -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm31 (AVX512) */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, + -1 /* pkru */ }; #define X86_64_NUM_REGS (sizeof (x86_64_regmap) / sizeof (x86_64_regmap[0])) @@ -822,8 +823,8 @@ x86_linux_read_description (void) { switch (xcr0 & X86_XSTATE_ALL_MASK) { - case X86_XSTATE_AVX_MPX_AVX512_MASK: - return tdesc_amd64_avx_mpx_avx512_linux; + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: + return tdesc_amd64_avx_mpx_avx512_pku_linux; case X86_XSTATE_AVX_AVX512_MASK: return tdesc_amd64_avx_avx512_linux; @@ -850,7 +851,10 @@ x86_linux_read_description (void) { switch (xcr0 & X86_XSTATE_ALL_MASK) { - case X86_XSTATE_AVX_MPX_AVX512_MASK: /* No MPX on x32. */ + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: + /* No x32 MPX and PKU, fall back to avx_avx512. */ + return tdesc_x32_avx_avx512_linux; + case X86_XSTATE_AVX_AVX512_MASK: return tdesc_x32_avx_avx512_linux; @@ -873,8 +877,8 @@ x86_linux_read_description (void) { switch (xcr0 & X86_XSTATE_ALL_MASK) { - case (X86_XSTATE_AVX_MPX_AVX512_MASK): - return tdesc_i386_avx_mpx_avx512_linux; + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: + return tdesc_i386_avx_mpx_avx512_pku_linux; case (X86_XSTATE_AVX_AVX512_MASK): return tdesc_i386_avx_avx512_linux; @@ -2902,8 +2906,8 @@ x86_get_ipa_tdesc_idx (void) return X86_TDESC_MPX; if (tdesc == tdesc_amd64_avx_mpx_linux) return X86_TDESC_AVX_MPX; - if (tdesc == tdesc_amd64_avx_mpx_avx512_linux || tdesc == tdesc_x32_avx_avx512_linux) - return X86_TDESC_AVX_MPX_AVX512; + if (tdesc == tdesc_amd64_avx_mpx_avx512_pku_linux || tdesc == tdesc_x32_avx_avx512_linux) + return X86_TDESC_AVX_MPX_AVX512_PKU; if (tdesc == tdesc_amd64_avx_avx512_linux) return X86_TDESC_AVX_AVX512; #endif @@ -2918,8 +2922,8 @@ x86_get_ipa_tdesc_idx (void) return X86_TDESC_MPX; if (tdesc == tdesc_i386_avx_mpx_linux) return X86_TDESC_AVX_MPX; - if (tdesc == tdesc_i386_avx_mpx_avx512_linux) - return X86_TDESC_AVX_MPX_AVX512; + if (tdesc == tdesc_i386_avx_mpx_avx512_pku_linux) + return X86_TDESC_AVX_MPX_AVX512_PKU; if (tdesc == tdesc_i386_avx_avx512_linux) return X86_TDESC_AVX_AVX512; @@ -2982,7 +2986,7 @@ initialize_low_arch (void) init_registers_amd64_mpx_linux (); init_registers_amd64_avx_mpx_linux (); init_registers_amd64_avx_avx512_linux (); - init_registers_amd64_avx_mpx_avx512_linux (); + init_registers_amd64_avx_mpx_avx512_pku_linux (); init_registers_x32_linux (); init_registers_x32_avx_linux (); @@ -2998,7 +3002,7 @@ initialize_low_arch (void) init_registers_i386_mpx_linux (); init_registers_i386_avx_mpx_linux (); init_registers_i386_avx_avx512_linux (); - init_registers_i386_avx_mpx_avx512_linux (); + init_registers_i386_avx_mpx_avx512_pku_linux (); tdesc_i386_linux_no_xml = XNEW (struct target_desc); copy_target_description (tdesc_i386_linux_no_xml, tdesc_i386_linux); diff --git a/gdb/gdbserver/linux-x86-tdesc.h b/gdb/gdbserver/linux-x86-tdesc.h index 96966c3..bbe4078 100644 --- a/gdb/gdbserver/linux-x86-tdesc.h +++ b/gdb/gdbserver/linux-x86-tdesc.h @@ -29,7 +29,7 @@ enum x86_linux_tdesc { X86_TDESC_MPX = 3, X86_TDESC_AVX_MPX = 4, X86_TDESC_AVX_AVX512 = 5, - X86_TDESC_AVX_MPX_AVX512 = 6, + X86_TDESC_AVX_MPX_AVX512_PKU = 6, }; #ifdef __x86_64__ @@ -47,9 +47,9 @@ extern const struct target_desc *tdesc_amd64_avx_linux; void init_registers_amd64_avx_avx512_linux (void); extern const struct target_desc *tdesc_amd64_avx_avx512_linux; -/* Defined in auto-generated file amd64-avx-mpx-avx512-linux.c. */ -void init_registers_amd64_avx_mpx_avx512_linux (void); -extern const struct target_desc *tdesc_amd64_avx_mpx_avx512_linux; +/* Defined in auto-generated file amd64-avx-mpx-avx512-pku-linux.c. */ +void init_registers_amd64_avx_mpx_avx512_pku_linux (void); +extern const struct target_desc *tdesc_amd64_avx_mpx_avx512_pku_linux; /* Defined in auto-generated file amd64-avx-mpx-linux.c. */ void init_registers_amd64_avx_mpx_linux (void); @@ -98,8 +98,8 @@ void init_registers_i386_avx_avx512_linux (void); extern const struct target_desc *tdesc_i386_avx_avx512_linux; /* Defined in auto-generated file i386-avx-mpx-avx512-linux.c. */ -void init_registers_i386_avx_mpx_avx512_linux (void); -extern const struct target_desc *tdesc_i386_avx_mpx_avx512_linux; +void init_registers_i386_avx_mpx_avx512_pku_linux (void); +extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux; /* Defined in auto-generated file i386-mpx-linux.c. */ void init_registers_i386_mpx_linux (void); diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index f86fac3..2c4963b 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -59,7 +59,7 @@ (I386_ST0_REGNUM <= (regno) && (regno) < I386_SSE_NUM_REGS) #define GETXSTATEREGS_SUPPLIES(regno) \ - (I386_ST0_REGNUM <= (regno) && (regno) < I386_AVX512_NUM_REGS) + (I386_ST0_REGNUM <= (regno) && (regno) < I386_PKEYS_NUM_REGS) /* Does the current host support the GETREGS request? */ int have_ptrace_getregs = diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 66828f5..1909d61 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -51,7 +51,7 @@ #include "features/i386/i386-avx-mpx-linux.c" #include "features/i386/i386-avx-linux.c" #include "features/i386/i386-avx-avx512-linux.c" -#include "features/i386/i386-avx-mpx-avx512-linux.c" +#include "features/i386/i386-avx-mpx-avx512-pku-linux.c" /* Return non-zero, when the register is in the corresponding register group. Put the LINUX_ORIG_EAX register in the system group. */ @@ -613,6 +613,7 @@ int i386_linux_gregset_reg_offset[] = -1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */ -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512) */ -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512) */ + -1, /* PKRU register */ 11 * 4, /* "orig_eax" */ }; @@ -689,8 +690,8 @@ i386_linux_core_read_description (struct gdbarch *gdbarch, switch ((xcr0 & X86_XSTATE_ALL_MASK)) { - case X86_XSTATE_AVX_MPX_AVX512_MASK: - return tdesc_i386_avx_mpx_avx512_linux; + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: + return tdesc_i386_avx_mpx_avx512_pku_linux; case X86_XSTATE_AVX_AVX512_MASK: return tdesc_i386_avx_avx512_linux; case X86_XSTATE_MPX_MASK: @@ -1089,5 +1090,5 @@ _initialize_i386_linux_tdep (void) initialize_tdesc_i386_mpx_linux (); initialize_tdesc_i386_avx_mpx_linux (); initialize_tdesc_i386_avx_avx512_linux (); - initialize_tdesc_i386_avx_mpx_avx512_linux (); + initialize_tdesc_i386_avx_mpx_avx512_pku_linux (); } diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h index 06190fa..8d4c7ca 100644 --- a/gdb/i386-linux-tdep.h +++ b/gdb/i386-linux-tdep.h @@ -29,7 +29,7 @@ /* Register number for the "orig_eax" pseudo-register. If this pseudo-register contains a value >= 0 it is interpreted as the system call number that the kernel is supposed to restart. */ -#define I386_LINUX_ORIG_EAX_REGNUM (I386_ZMM7H_REGNUM + 1) +#define I386_LINUX_ORIG_EAX_REGNUM (I386_PKRU_REGNUM + 1) /* Total number of registers for GNU/Linux. */ #define I386_LINUX_NUM_REGS (I386_LINUX_ORIG_EAX_REGNUM + 1) @@ -49,7 +49,7 @@ extern struct target_desc *tdesc_i386_avx_linux; extern struct target_desc *tdesc_i386_mpx_linux; extern struct target_desc *tdesc_i386_avx_mpx_linux; extern struct target_desc *tdesc_i386_avx_avx512_linux; -extern struct target_desc *tdesc_i386_avx_mpx_avx512_linux; +extern struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux; /* Format of XSAVE extended state is: struct @@ -63,6 +63,7 @@ extern struct target_desc *tdesc_i386_avx_mpx_avx512_linux; avx512_zmmh_regs0-7[1153..1407] avx512_zmmh_regs8-15[1408..1663] avx512_zmm_regs16-31[1664..2687] + pkru[2688..2752] future_state etc }; diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index ff21549..f2917db 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -55,7 +55,7 @@ #include "features/i386/i386-mpx.c" #include "features/i386/i386-avx-mpx.c" #include "features/i386/i386-avx-avx512.c" -#include "features/i386/i386-avx-mpx-avx512.c" +#include "features/i386/i386-avx-mpx-avx512-pku.c" #include "features/i386/i386-mmx.c" #include "ax.h" @@ -121,6 +121,11 @@ static const char *i386_mpx_names[] = "bnd0raw", "bnd1raw", "bnd2raw", "bnd3raw", "bndcfgu", "bndstatus" }; +static const char* i386_pkeys_names[] = +{ + "pkru" +}; + /* Register names for MPX pseudo-registers. */ static const char *i386_bnd_names[] = @@ -415,6 +420,21 @@ i386_mpx_ctrl_regnum_p (struct gdbarch *gdbarch, int regnum) return regnum >= 0 && regnum < I387_NUM_MPX_CTRL_REGS; } +/* PKRU register? */ + +bool +i386_pkru_regnum_p (struct gdbarch *gdbarch, int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int pkru_regnum = tdep->pkru_regnum; + + if (pkru_regnum < 0) + return false; + + regnum -= pkru_regnum; + return regnum >= 0 && regnum < I387_NUM_PKEYS_REGS; +} + /* Return the name of register REGNUM, or the empty string if it is an anonymous register. */ @@ -4529,7 +4549,7 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum, ymm_regnum_p, ymmh_regnum_p, ymm_avx512_regnum_p, ymmh_avx512_regnum_p, bndr_regnum_p, bnd_regnum_p, k_regnum_p, zmm_regnum_p, zmmh_regnum_p, zmm_avx512_regnum_p, mpx_ctrl_regnum_p, xmm_avx512_regnum_p, - avx512_p, avx_p, sse_p; + avx512_p, avx_p, sse_p, pkru_regnum_p; /* Don't include pseudo registers, except for MMX, in any register groups. */ @@ -4546,6 +4566,7 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum, if (group == i386_mmx_reggroup) return mmx_regnum_p; + pkru_regnum_p = i386_pkru_regnum_p(gdbarch, regnum); xmm_regnum_p = i386_xmm_regnum_p (gdbarch, regnum); xmm_avx512_regnum_p = i386_xmm_avx512_regnum_p (gdbarch, regnum); mxcsr_regnum_p = i386_mxcsr_regnum_p (gdbarch, regnum); @@ -4617,7 +4638,8 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum, && !bnd_regnum_p && !mpx_ctrl_regnum_p && !zmm_regnum_p - && !zmmh_regnum_p); + && !zmmh_regnum_p + && !pkru_regnum_p); return default_register_reggroup_p (gdbarch, regnum, group); } @@ -8201,7 +8223,7 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, const struct tdesc_feature *feature_core; const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx, - *feature_avx512; + *feature_avx512, *feature_pkeys; int i, num_regs, valid_p; if (! tdesc_has_registers (tdesc)) @@ -8224,6 +8246,9 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, /* Try AVX512 registers. */ feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512"); + /* Try PKEYS */ + feature_pkeys = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys"); + valid_p = 1; /* The XCR0 bits. */ @@ -8330,6 +8355,22 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, tdep->mpx_register_names[i]); } + if (feature_pkeys) + { + tdep->xcr0 |= X86_XSTATE_PKRU; + if (tdep->pkru_regnum < 0) + { + tdep->pkeys_register_names = i386_pkeys_names; + tdep->pkru_regnum = I386_PKRU_REGNUM; + tdep->num_pkeys_regs = 1; + } + + for (i = 0; i < I387_NUM_PKEYS_REGS; i++) + valid_p &= tdesc_numbered_register (feature_pkeys, tdesc_data, + I387_PKRU_REGNUM (tdep) + i, + tdep->pkeys_register_names[i]); + } + return valid_p; } @@ -8525,7 +8566,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Even though the default ABI only includes general-purpose registers, floating-point registers and the SSE registers, we have to leave a gap for the upper AVX, MPX and AVX512 registers. */ - set_gdbarch_num_regs (gdbarch, I386_AVX512_NUM_REGS); + set_gdbarch_num_regs (gdbarch, I386_PKEYS_NUM_REGS); set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp); @@ -8570,6 +8611,10 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->num_ymm_avx512_regs = 0; tdep->num_xmm_avx512_regs = 0; + /* No PKEYS registers */ + tdep->pkru_regnum = -1; + tdep->num_pkeys_regs = 0; + tdesc_data = tdesc_data_alloc (); set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction); @@ -8708,8 +8753,8 @@ i386_target_description (uint64_t xcr0) { switch (xcr0 & X86_XSTATE_ALL_MASK) { - case X86_XSTATE_AVX_MPX_AVX512_MASK: - return tdesc_i386_avx_mpx_avx512; + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: + return tdesc_i386_avx_mpx_avx512_pku; case X86_XSTATE_AVX_AVX512_MASK: return tdesc_i386_avx_avx512; case X86_XSTATE_AVX_MPX_MASK: @@ -9054,7 +9099,7 @@ Show Intel Memory Protection Extensions specific variables."), initialize_tdesc_i386_mpx (); initialize_tdesc_i386_avx_mpx (); initialize_tdesc_i386_avx_avx512 (); - initialize_tdesc_i386_avx_mpx_avx512 (); + initialize_tdesc_i386_avx_mpx_avx512_pku (); /* Tell remote stub that we support XML target description. */ register_remote_support_xml ("i386"); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index d4ff7e4..2b11767 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -189,6 +189,15 @@ struct gdbarch_tdep /* YMM16-31 register names. Only used for tdesc_numbered_register. */ const char **ymm_avx512_register_names; + /* Number of PKEYS registers. */ + int num_pkeys_regs; + + /* Register number for PKRU register. */ + int pkru_regnum; + + /* PKEYS register names. */ + const char **pkeys_register_names; + /* Target description. */ const struct target_desc *tdesc; @@ -284,7 +293,8 @@ enum i386_regnum I386_K0_REGNUM, /* %k0 */ I386_K7_REGNUM = I386_K0_REGNUM + 7, I386_ZMM0H_REGNUM, /* %zmm0h */ - I386_ZMM7H_REGNUM = I386_ZMM0H_REGNUM + 7 + I386_ZMM7H_REGNUM = I386_ZMM0H_REGNUM + 7, + I386_PKRU_REGNUM }; /* Register numbers of RECORD_REGMAP. */ @@ -324,6 +334,7 @@ enum record_i386_regnum #define I386_AVX_NUM_REGS (I386_YMM7H_REGNUM + 1) #define I386_MPX_NUM_REGS (I386_BNDSTATUS_REGNUM + 1) #define I386_AVX512_NUM_REGS (I386_ZMM7H_REGNUM + 1) +#define I386_PKEYS_NUM_REGS (I386_PKRU_REGNUM + 1) /* Size of the largest register. */ #define I386_MAX_REGISTER_SIZE 64 @@ -345,6 +356,7 @@ extern int i386_bnd_regnum_p (struct gdbarch *gdbarch, int regnum); extern int i386_k_regnum_p (struct gdbarch *gdbarch, int regnum); extern int i386_zmm_regnum_p (struct gdbarch *gdbarch, int regnum); extern int i386_zmmh_regnum_p (struct gdbarch *gdbarch, int regnum); +extern bool i386_pkru_regnum_p (struct gdbarch *gdbarch, int regnum); extern const char *i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum); diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index e3418d7..b0c48e4 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -888,6 +888,19 @@ static int xsave_avx512_zmm_h_offset[] = #define XSAVE_AVX512_ZMM_H_ADDR(tdep, xsave, regnum) \ (xsave + xsave_avx512_zmm_h_offset[regnum - I387_ZMM0H_REGNUM (tdep)]) +/* At xsave_pkeys_offset[REGNUM] you find the offset to the location + of the PKRU register data structure used by the "xsave" + instruction where GDB register REGNUM is stored. */ + +static int xsave_pkeys_offset[] = +{ +2688 + 0 * 8 /* %pkru (64 bits in XSTATE, 32-bit actually used by + instructions and applications). */ +}; + +#define XSAVE_PKEYS_ADDR(tdep, xsave, regnum) \ + (xsave + xsave_pkeys_offset[regnum - I387_PKRU_REGNUM (tdep)]) + /* Similar to i387_supply_fxsave, but use XSAVE extended state. */ void @@ -911,8 +924,9 @@ i387_supply_xsave (struct regcache *regcache, int regnum, avx512_zmm_h = 0x20, avx512_ymmh_avx512 = 0x40, avx512_xmm_avx512 = 0x80, + pkeys = 0x100, all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h - | avx512_ymmh_avx512 | avx512_xmm_avx512 + | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys } regclass; gdb_assert (regs != NULL); @@ -921,6 +935,9 @@ i387_supply_xsave (struct regcache *regcache, int regnum, if (regnum == -1) regclass = all; + else if (regnum >= I387_PKRU_REGNUM (tdep) + && regnum < I387_PKEYSEND_REGNUM (tdep)) + regclass = pkeys; else if (regnum >= I387_ZMM0H_REGNUM (tdep) && regnum < I387_ZMMENDH_REGNUM (tdep)) regclass = avx512_zmm_h; @@ -977,6 +994,14 @@ i387_supply_xsave (struct regcache *regcache, int regnum, case none: break; + case pkeys: + if ((clear_bv & X86_XSTATE_PKRU)) + regcache_raw_supply (regcache, regnum, zero); + else + regcache_raw_supply (regcache, regnum, + XSAVE_PKEYS_ADDR (tdep, regs, regnum)); + return; + case avx512_zmm_h: if ((clear_bv & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM))) regcache_raw_supply (regcache, regnum, zero); @@ -1042,6 +1067,26 @@ i387_supply_xsave (struct regcache *regcache, int regnum, return; case all: + /* Handle PKEYS registers. */ + if ((tdep->xcr0 & X86_XSTATE_PKRU)) + { + if ((clear_bv & X86_XSTATE_PKRU)) + { + for (i = I387_PKRU_REGNUM (tdep); + i < I387_PKEYSEND_REGNUM (tdep); + i++) + regcache_raw_supply (regcache, i, zero); + } + else + { + for (i = I387_PKRU_REGNUM (tdep); + i < I387_PKEYSEND_REGNUM (tdep); + i++) + regcache_raw_supply (regcache, i, + XSAVE_PKEYS_ADDR (tdep, regs, i)); + } + } + /* Handle the upper ZMM registers. */ if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM))) { @@ -1286,8 +1331,9 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, avx512_zmm_h = 0x40 | check, avx512_ymmh_avx512 = 0x80 | check, avx512_xmm_avx512 = 0x100 | check, + pkeys = 0x200 | check, all = x87 | sse | avxh | mpx | avx512_k | avx512_zmm_h - | avx512_ymmh_avx512 | avx512_xmm_avx512 + | avx512_ymmh_avx512 | avx512_xmm_avx512 | pkeys } regclass; gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM); @@ -1295,6 +1341,9 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, if (regnum == -1) regclass = all; + else if (regnum >= I387_PKRU_REGNUM (tdep) + && regnum < I387_PKEYSEND_REGNUM (tdep)) + regclass = pkeys; else if (regnum >= I387_ZMM0H_REGNUM (tdep) && regnum < I387_ZMMENDH_REGNUM (tdep)) regclass = avx512_zmm_h; @@ -1348,6 +1397,11 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, /* Clear register set if its bit in xstat_bv is zero. */ if (clear_bv) { + if ((clear_bv & X86_XSTATE_PKRU)) + for (i = I387_PKRU_REGNUM (tdep); + i < I387_PKEYSEND_REGNUM (tdep); i++) + memset (XSAVE_PKEYS_ADDR (tdep, regs, i), 0, 4); + if ((clear_bv & X86_XSTATE_BNDREGS)) for (i = I387_BND0R_REGNUM (tdep); i < I387_BNDCFGU_REGNUM (tdep); i++) @@ -1396,6 +1450,20 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, if (regclass == all) { + /* Check if any PKEYS registers are changed. */ + if ((tdep->xcr0 & X86_XSTATE_PKRU)) + for (i = I387_PKRU_REGNUM (tdep); + i < I387_PKEYSEND_REGNUM (tdep); i++) + { + regcache_raw_collect (regcache, i, raw); + p = XSAVE_PKEYS_ADDR (tdep, regs, i); + if (memcmp (raw, p, 4) != 0) + { + xstate_bv |= X86_XSTATE_PKRU; + memcpy (p, raw, 4); + } + } + /* Check if any ZMMH registers are changed. */ if ((tdep->xcr0 & (X86_XSTATE_ZMM_H | X86_XSTATE_ZMM))) for (i = I387_ZMM0H_REGNUM (tdep); @@ -1531,6 +1599,16 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, internal_error (__FILE__, __LINE__, _("invalid i387 regclass")); + case pkeys: + /* This is a PKEYS register. */ + p = XSAVE_PKEYS_ADDR (tdep, regs, regnum); + if (memcmp (raw, p, 4) != 0) + { + xstate_bv |= X86_XSTATE_PKRU; + memcpy (p, raw, 4); + } + break; + case avx512_zmm_h: /* This is a ZMM register. */ p = XSAVE_AVX512_ZMM_H_ADDR (tdep, regs, regnum); @@ -1648,6 +1726,7 @@ i387_collect_xsave (const struct regcache *regcache, int regnum, case avx512_zmm_h: case avx512_ymmh_avx512: case avx512_xmm_avx512: + case pkeys: /* Register REGNUM has been updated. Return. */ return; } diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h index 81d45b7..6a97e4f 100644 --- a/gdb/i387-tdep.h +++ b/gdb/i387-tdep.h @@ -44,7 +44,9 @@ struct ui_file; #define I387_NUM_BND_REGS 4 #define I387_NUM_MPX_CTRL_REGS 2 #define I387_NUM_K_REGS 8 +#define I387_NUM_PKEYS_REGS 1 +#define I387_PKRU_REGNUM(tdep) ((tdep)->pkru_regnum) #define I387_K0_REGNUM(tdep) ((tdep)->k0_regnum) #define I387_NUM_ZMMH_REGS(tdep) ((tdep)->num_zmm_regs) #define I387_ZMM0H_REGNUM(tdep) ((tdep)->zmm0h_regnum) @@ -79,6 +81,9 @@ struct ui_file; #define I387_XMM_AVX512_END_REGNUM(tdep) \ (I387_XMM16_REGNUM (tdep) + I387_NUM_XMM_AVX512_REGS (tdep)) +#define I387_PKEYSEND_REGNUM(tdep) \ + (I387_PKRU_REGNUM (tdep) + I387_NUM_PKEYS_REGS) + /* Print out the i387 floating point state. */ extern void i387_print_float_info (struct gdbarch *gdbarch, diff --git a/gdb/regformats/i386/amd64-avx-mpx-avx512.dat b/gdb/regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat index fc4bd2d..3ae6b0e 100644 --- a/gdb/regformats/i386/amd64-avx-mpx-avx512.dat +++ b/gdb/regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat @@ -1,7 +1,7 @@ # THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/amd64-avx-mpx-avx512.xml -name:amd64_avx_mpx_avx512 -xmltarget:amd64-avx-mpx-avx512.xml +# Generated from: i386/amd64-avx-mpx-avx512-pku-linux.xml +name:amd64_avx_mpx_avx512_pku_linux +xmltarget:amd64-avx-mpx-avx512-pku-linux.xml expedite:rbp,rsp,rip 64:rax 64:rbx diff --git a/gdb/regformats/i386/amd64-avx-mpx-avx512-linux.dat b/gdb/regformats/i386/amd64-avx-mpx-avx512-pku.dat index 526bca4..88185fd 100644 --- a/gdb/regformats/i386/amd64-avx-mpx-avx512-linux.dat +++ b/gdb/regformats/i386/amd64-avx-mpx-avx512-pku.dat @@ -1,7 +1,7 @@ # THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/amd64-avx-mpx-avx512-linux.xml -name:amd64_avx_mpx_avx512_linux -xmltarget:amd64-avx-mpx-avx512-linux.xml +# Generated from: i386/amd64-avx-mpx-avx512-pku.xml +name:amd64_avx_mpx_avx512_pku +xmltarget:amd64-avx-mpx-avx512-pku.xml expedite:rbp,rsp,rip 64:rax 64:rbx @@ -157,3 +157,4 @@ expedite:rbp,rsp,rip 256:zmm29h 256:zmm30h 256:zmm31h +32:pkru diff --git a/gdb/regformats/i386/i386-avx-mpx-avx512-linux.dat b/gdb/regformats/i386/i386-avx-mpx-avx512-pku-linux.dat index 2afffa3..515ee10 100644 --- a/gdb/regformats/i386/i386-avx-mpx-avx512-linux.dat +++ b/gdb/regformats/i386/i386-avx-mpx-avx512-pku-linux.dat @@ -1,7 +1,7 @@ # THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/i386-avx-mpx-avx512-linux.xml -name:i386_avx_mpx_avx512_linux -xmltarget:i386-avx-mpx-avx512-linux.xml +# Generated from: i386/i386-avx-mpx-avx512-pku-linux.xml +name:i386_avx_mpx_avx512_pku_linux +xmltarget:i386-avx-mpx-avx512-pku-linux.xml expedite:ebp,esp,eip 32:eax 32:ecx @@ -75,3 +75,4 @@ expedite:ebp,esp,eip 256:zmm5h 256:zmm6h 256:zmm7h +32:pkru diff --git a/gdb/regformats/i386/i386-avx-mpx-avx512.dat b/gdb/regformats/i386/i386-avx-mpx-avx512-pku.dat index a3c520c..17094b4 100644 --- a/gdb/regformats/i386/i386-avx-mpx-avx512.dat +++ b/gdb/regformats/i386/i386-avx-mpx-avx512-pku.dat @@ -1,7 +1,7 @@ # THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro: -# Generated from: i386/i386-avx-mpx-avx512.xml -name:i386_avx_mpx_avx512 -xmltarget:i386-avx-mpx-avx512.xml +# Generated from: i386/i386-avx-mpx-avx512-pku.xml +name:i386_avx_mpx_avx512_pku +xmltarget:i386-avx-mpx-avx512-pku.xml expedite:ebp,esp,eip 32:eax 32:ecx @@ -74,3 +74,4 @@ expedite:ebp,esp,eip 256:zmm5h 256:zmm6h 256:zmm7h +32:pkru diff --git a/gdb/testsuite/gdb.arch/i386-pkru.c b/gdb/testsuite/gdb.arch/i386-pkru.c new file mode 100644 index 0000000..cec78f5 --- /dev/null +++ b/gdb/testsuite/gdb.arch/i386-pkru.c @@ -0,0 +1,90 @@ +/* Test program for PKEYS registers. + + Copyright 2015-2017 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 <stddef.h> +#include "x86-cpuid.h" + +#ifndef NOINLINE +#define NOINLINE __attribute__ ((noinline)) +#endif + +unsigned int have_pkru (void) NOINLINE; + +static inline unsigned long +rdpkru (void) +{ + unsigned int eax, edx; + unsigned int ecx = 0; + unsigned int pkru; + + asm volatile (".byte 0x0f,0x01,0xee\n\t" + : "=a" (eax), "=d" (edx) + : "c" (ecx)); + pkru = eax; + return pkru; +} + +static inline void +wrpkru (unsigned int pkru) +{ + unsigned int eax = pkru; + unsigned int ecx = 0; + unsigned int edx = 0; + + asm volatile (".byte 0x0f,0x01,0xef\n\t" + : : "a" (eax), "c" (ecx), "d" (edx)); +} + +unsigned int NOINLINE +have_pkru (void) +{ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + if ((ecx & bit_OSXSAVE) == bit_OSXSAVE) + { + if (__get_cpuid_max (0, NULL) < 7) + return 0; + + __cpuid_count (7, 0, eax, ebx, ecx, edx); + + if ((ecx & bit_PKU) == bit_PKU) + return 1; + } + return 0; +} + +int +main (int argc, char **argv) +{ + unsigned int wr_value = 0x12345678; + unsigned int rd_value = 0x0; + + if (have_pkru ()) + { + wrpkru (wr_value); + asm ("nop\n\t"); /* break here 1. */ + + rd_value = rdpkru (); + asm ("nop\n\t"); /* break here 2. */ + } + return 0; +} diff --git a/gdb/testsuite/gdb.arch/i386-pkru.exp b/gdb/testsuite/gdb.arch/i386-pkru.exp new file mode 100644 index 0000000..5f243f1 --- /dev/null +++ b/gdb/testsuite/gdb.arch/i386-pkru.exp @@ -0,0 +1,66 @@ +# Copyright 2015-2017 Free Software Foundation, Inc. +# +# 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/>. + +standard_testfile + +if { ![istarget i?86-*-*] && ![istarget x86_64-*-* ] } { + unsupported "skipping x86 PKEYS tests." + return +} + +set comp_flags "-I${srcdir}/../nat/" + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + [list debug additional_flags=${comp_flags}]] } { + untested "failed to compile x86 PKEYS test. + return -1 +} + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +set supports_pkru 0 +set test "probe PKRU support" +gdb_test_multiple "print have_pkru()" $test { + -re ".. = 1\r\n$gdb_prompt $" { + pass $test + set supports_pkru 1 + } +} + +if { !$supports_pkru } { + unsupported "processor does not support protection key feature." + return +} + +# Test pkru register at startup +# set test_string "0" + +gdb_test "print \$pkru" "= 0" "pkru register" + +# Read values from pseudo registers. +gdb_breakpoint [ gdb_get_line_number "break here 1" ] +gdb_continue_to_breakpoint "break here 1" ".*break here 1.*" + +gdb_test "info register pkru" ".*pkru.*0x12345678.*" "read pkru register" +gdb_test "print /x \$pkru = 0x44444444" "= 0x44444444" "set pkru value" +gdb_test "info register pkru" ".*pkru.*0x44444444.*" "read value after setting value" + +gdb_breakpoint [ gdb_get_line_number "break here 2" ] +gdb_continue_to_breakpoint "break here 2" ".*break here 2.*" + +gdb_test "print /x rd_value" "= 0x44444444" "variable after reading pkru" diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index e6adb4e..40a1b62 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -204,12 +204,12 @@ x86_linux_read_description (struct target_ops *ops) #ifdef __x86_64__ switch (xcr0_features_bits) { - case X86_XSTATE_AVX_MPX_AVX512_MASK: + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: if (is_x32) - /* No MPX on x32, fallback to AVX-AVX512. */ + /* No MPX, PKU on x32, fall back to AVX-AVX512. */ return tdesc_x32_avx_avx512_linux; else - return tdesc_amd64_avx_mpx_avx512_linux; + return tdesc_amd64_avx_mpx_avx512_pku_linux; case X86_XSTATE_AVX_AVX512_MASK: if (is_x32) return tdesc_x32_avx_avx512_linux; @@ -242,8 +242,8 @@ x86_linux_read_description (struct target_ops *ops) { switch (xcr0_features_bits) { - case X86_XSTATE_AVX_MPX_AVX512_MASK: - return tdesc_i386_avx_mpx_avx512_linux; + case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: + return tdesc_i386_avx_mpx_avx512_pku_linux; case X86_XSTATE_AVX_AVX512_MASK: return tdesc_i386_avx_avx512_linux; case X86_XSTATE_MPX_MASK: |