• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisión1dbcd68cf12168c359df2da36b5b612100310a30 (tree)
Tiempo2013-11-20 22:42:50
AutorWalfred Tedeschi <walfred.tedeschi@inte...>
CommiterWalfred Tedeschi

Log Message

Add MPX support for i386

2013-11-20 Walfred Tedeschi <walfred.tedeschi@intel.com>

* i386-linux-nat.c (GETXSTATEREGS_SUPPLIES): Add MPX
registers on the range of registers to be read from
xsave buffer.
(i386_linux_read_description): Add case for MPX.
* i386-linux-tdep.c: Include features/i386/i386-mpx-linux.c.
(i386_linux_gregset_reg_offset): Add MPX registers.
(i386_linux_core_read_description): Initialize also MPX.
(_initialize_i386_linux_tdep): Add mpx initialization.
* i386-tdep.h (gdbarch_tdep): Add fields bnd0r_regnum, bnd0_regnum,
mpx_register_names.
(i386_regnum): Add MPX registers.
(I386_MPX_NUM_REGS): New macro.
(i386_bnd_regnum_p): New function.
* i386-linux-tdep.h (I386_LINUX_NUM_REGS): Set
number of registers to be the number of BNDSTATUS.
(tdesc_i386_mpx_linux): Add description for MPX Linux registers.
* i386-tdep.c: Include features/i386/i386-mpx.c.
(i386_mpx_names): Add MPX register names array.
(i386_bnd_names): Add bnd pseudo register names array.
(i386_bndr_regnum_p): Lookup register numbers for bnd raw
registers.
(i386_bndr_regnum_p): Lookup register numbers for bnd raw registers.
(386_mpx_ctrl_regnum_p): Lookup register numbers for MPX control
registers.
(i386_bnd_type): New function.
(i386_pseudo_register_type): Use i386_bnd_type for bnd pseudo
register types.
(i386_pseudo_register_read_into_value): Add bnd case.
(i386_pseudo_register_write): Add bnd pseudo registers.
(i386_register_reggroup_p): Add MPX register to the group all.
(i386_validate_tdesc_p): Add MPX to the target description
validation.
(i386_pseudo_register_name): Add bnd pseudo registers.
(i386_gdbarch_init): Add MPX for architecture initialization.
(_initia_initialize_i386_tdep): Add mpx initialization.
* i387-tdep.c (xsave_mpx_offset): New vector for MPX offsets on
XSAVE buffer.
(XSAVE_MPX_ADDR): New macro.
(i387_supply_xsave): Add MPX case.
(i387_collect_xsave): Add MPX case.
* i387-tdep.h (I387_BND0R_REGNUM): New macro.
(I387_BNDCFGU_REGNUM): New macro.
(I387_NUM_MPX_REGS): New macro.
(I387_NUM_BND_REGS): New macro.
(I387_NUM_MPX_CTRL_REGS): New macro.
(I387_MPXEND_REGNUM): New macro.
* common/i386-xstate.h (I386_XSTATE_BNDREGS): New macro.
(I386_XSTATE_BNDCFG): Likewise.
(I386_XSTATE_MPX_MASK): Likewise.
(I386_XSTATE_ALL_MASK): New macro represents flags for all states.
(I386_XSTATE_BNDREGS_SIZE): New macro.
(I386_XSTATE_BNDCFG_SIZE): Likewise.
(I386_XSTATE_SIZE): Adapt for MPX.
(I386_XSTATE_MAX_SIZE): Likewise.

Change-Id: I9ddb7d49434d86fa18eb6b99515203d7c567aefd
Signed-off-by: Walfred Tedeschi <walfred.tedeschi@intel.com>

Conflicts:

gdb/ChangeLog

Cambiar Resumen

Diferencia incremental

--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,62 @@
11 2013-11-20 Walfred Tedeschi <walfred.tedeschi@intel.com>
22
3+ * i386-linux-nat.c (GETXSTATEREGS_SUPPLIES): Add MPX
4+ registers on the range of registers to be read from
5+ xsave buffer.
6+ (i386_linux_read_description): Add case for MPX.
7+ * i386-linux-tdep.c: Include features/i386/i386-mpx-linux.c.
8+ (i386_linux_gregset_reg_offset): Add MPX registers.
9+ (i386_linux_core_read_description): Initialize also MPX.
10+ (_initialize_i386_linux_tdep): Add mpx initialization.
11+ * i386-tdep.h (gdbarch_tdep): Add fields bnd0r_regnum, bnd0_regnum,
12+ mpx_register_names.
13+ (i386_regnum): Add MPX registers.
14+ (I386_MPX_NUM_REGS): New macro.
15+ (i386_bnd_regnum_p): New function.
16+ * i386-linux-tdep.h (I386_LINUX_NUM_REGS): Set
17+ number of registers to be the number of BNDSTATUS.
18+ (tdesc_i386_mpx_linux): Add description for MPX Linux registers.
19+ * i386-tdep.c: Include features/i386/i386-mpx.c.
20+ (i386_mpx_names): Add MPX register names array.
21+ (i386_bnd_names): Add bnd pseudo register names array.
22+ (i386_bndr_regnum_p): Lookup register numbers for bnd raw
23+ registers.
24+ (i386_bndr_regnum_p): Lookup register numbers for bnd raw registers.
25+ (386_mpx_ctrl_regnum_p): Lookup register numbers for MPX control
26+ registers.
27+ (i386_bnd_type): New function.
28+ (i386_pseudo_register_type): Use i386_bnd_type for bnd pseudo
29+ register types.
30+ (i386_pseudo_register_read_into_value): Add bnd case.
31+ (i386_pseudo_register_write): Add bnd pseudo registers.
32+ (i386_register_reggroup_p): Add MPX register to the group all.
33+ (i386_validate_tdesc_p): Add MPX to the target description
34+ validation.
35+ (i386_pseudo_register_name): Add bnd pseudo registers.
36+ (i386_gdbarch_init): Add MPX for architecture initialization.
37+ (_initia_initialize_i386_tdep): Add mpx initialization.
38+ * i387-tdep.c (xsave_mpx_offset): New vector for MPX offsets on
39+ XSAVE buffer.
40+ (XSAVE_MPX_ADDR): New macro.
41+ (i387_supply_xsave): Add MPX case.
42+ (i387_collect_xsave): Add MPX case.
43+ * i387-tdep.h (I387_BND0R_REGNUM): New macro.
44+ (I387_BNDCFGU_REGNUM): New macro.
45+ (I387_NUM_MPX_REGS): New macro.
46+ (I387_NUM_BND_REGS): New macro.
47+ (I387_NUM_MPX_CTRL_REGS): New macro.
48+ (I387_MPXEND_REGNUM): New macro.
49+ * common/i386-xstate.h (I386_XSTATE_BNDREGS): New macro.
50+ (I386_XSTATE_BNDCFG): Likewise.
51+ (I386_XSTATE_MPX_MASK): Likewise.
52+ (I386_XSTATE_ALL_MASK): New macro represents flags for all states.
53+ (I386_XSTATE_BNDREGS_SIZE): New macro.
54+ (I386_XSTATE_BNDCFG_SIZE): Likewise.
55+ (I386_XSTATE_SIZE): Adapt for MPX.
56+ (I386_XSTATE_MAX_SIZE): Likewise.
57+
58+2013-11-20 Walfred Tedeschi <walfred.tedeschi@intel.com>
59+
360 * features/i386/Makefile: Adapts for using MPX registers.
461 * features/i386/32bit-mpx.xml: New file.
562 * features/i386/64bit-mpx.xml: Likewise.
--- a/gdb/common/i386-xstate.h
+++ b/gdb/common/i386-xstate.h
@@ -24,19 +24,31 @@
2424 #define I386_XSTATE_X87 (1ULL << 0)
2525 #define I386_XSTATE_SSE (1ULL << 1)
2626 #define I386_XSTATE_AVX (1ULL << 2)
27+#define I386_XSTATE_BNDREGS (1ULL << 3)
28+#define I386_XSTATE_BNDCFG (1ULL << 4)
2729
2830 /* Supported mask and size of the extended state. */
2931 #define I386_XSTATE_X87_MASK I386_XSTATE_X87
3032 #define I386_XSTATE_SSE_MASK (I386_XSTATE_X87 | I386_XSTATE_SSE)
3133 #define I386_XSTATE_AVX_MASK (I386_XSTATE_SSE_MASK | I386_XSTATE_AVX)
34+#define I386_XSTATE_MPX_MASK (I386_XSTATE_AVX_MASK \
35+ | I386_XSTATE_BNDREGS \
36+ | I386_XSTATE_BNDCFG)
37+
38+#define I386_XSTATE_ALL_MASK I386_XSTATE_MPX_MASK
3239
3340 #define I386_XSTATE_SSE_SIZE 576
3441 #define I386_XSTATE_AVX_SIZE 832
35-#define I386_XSTATE_MAX_SIZE 832
42+#define I386_XSTATE_BNDREGS_SIZE 1024
43+#define I386_XSTATE_BNDCFG_SIZE 1088
44+
45+#define I386_XSTATE_MAX_SIZE 1088
3646
3747 /* Get I386 XSAVE extended state size. */
38-#define I386_XSTATE_SIZE(XCR0) \
39- (((XCR0) & I386_XSTATE_AVX) != 0 \
40- ? I386_XSTATE_AVX_SIZE : I386_XSTATE_SSE_SIZE)
48+#define I386_XSTATE_SIZE(XCR0) \
49+ (((XCR0) & I386_XSTATE_BNDCFG) != 0 ? I386_XSTATE_BNDCFG_SIZE \
50+ : (((XCR0) & I386_XSTATE_BNDREGS) != 0 ? I386_XSTATE_BNDCFG_SIZE \
51+ : (((XCR0) & I386_XSTATE_AVX_SIZE) != 0 ? I386_XSTATE_AVX_SIZE \
52+ : I386_XSTATE_SSE_SIZE)))
4153
4254 #endif /* I386_XSTATE_H */
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -102,7 +102,7 @@ static int have_ptrace_getregset = -1;
102102 (I386_ST0_REGNUM <= (regno) && (regno) < I386_SSE_NUM_REGS)
103103
104104 #define GETXSTATEREGS_SUPPLIES(regno) \
105- (I386_ST0_REGNUM <= (regno) && (regno) < I386_AVX_NUM_REGS)
105+ (I386_ST0_REGNUM <= (regno) && (regno) < I386_MPX_NUM_REGS)
106106
107107 /* Does the current host support the GETREGS request? */
108108 int have_ptrace_getregs =
@@ -1041,9 +1041,18 @@ i386_linux_read_description (struct target_ops *ops)
10411041 }
10421042
10431043 /* Check the native XCR0 only if PTRACE_GETREGSET is available. */
1044- if (have_ptrace_getregset
1045- && (xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK)
1046- return tdesc_i386_avx_linux;
1044+ if (have_ptrace_getregset)
1045+ {
1046+ switch ((xcr0 & I386_XSTATE_ALL_MASK))
1047+ {
1048+ case I386_XSTATE_MPX_MASK:
1049+ return tdesc_i386_mpx_linux;
1050+ case I386_XSTATE_AVX_MASK:
1051+ return tdesc_i386_avx_linux;
1052+ default:
1053+ return tdesc_i386_linux;
1054+ }
1055+ }
10471056 else
10481057 return tdesc_i386_linux;
10491058 }
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -50,6 +50,7 @@
5050
5151 #include "features/i386/i386-linux.c"
5252 #include "features/i386/i386-mmx-linux.c"
53+#include "features/i386/i386-mpx-linux.c"
5354 #include "features/i386/i386-avx-linux.c"
5455
5556 /* Supported register note sections. */
@@ -569,6 +570,8 @@ int i386_linux_gregset_reg_offset[] =
569570 -1, -1, -1, -1, -1, -1, -1, -1,
570571 -1,
571572 -1, -1, -1, -1, -1, -1, -1, -1,
573+ -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */
574+ -1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */
572575 11 * 4 /* "orig_eax" */
573576 };
574577
@@ -642,8 +645,11 @@ i386_linux_core_read_description (struct gdbarch *gdbarch,
642645 {
643646 /* Linux/i386. */
644647 uint64_t xcr0 = i386_linux_core_read_xcr0 (abfd);
645- switch ((xcr0 & I386_XSTATE_AVX_MASK))
648+
649+ switch ((xcr0 & I386_XSTATE_ALL_MASK))
646650 {
651+ case I386_XSTATE_MPX_MASK:
652+ return tdesc_i386_mpx_linux;
647653 case I386_XSTATE_AVX_MASK:
648654 return tdesc_i386_avx_linux;
649655 case I386_XSTATE_SSE_MASK:
@@ -979,4 +985,5 @@ _initialize_i386_linux_tdep (void)
979985 initialize_tdesc_i386_linux ();
980986 initialize_tdesc_i386_mmx_linux ();
981987 initialize_tdesc_i386_avx_linux ();
988+ initialize_tdesc_i386_mpx_linux ();
982989 }
--- a/gdb/i386-linux-tdep.h
+++ b/gdb/i386-linux-tdep.h
@@ -29,7 +29,7 @@
2929 /* Register number for the "orig_eax" pseudo-register. If this
3030 pseudo-register contains a value >= 0 it is interpreted as the
3131 system call number that the kernel is supposed to restart. */
32-#define I386_LINUX_ORIG_EAX_REGNUM I386_AVX_NUM_REGS
32+#define I386_LINUX_ORIG_EAX_REGNUM I386_MPX_NUM_REGS
3333
3434 /* Total number of registers for GNU/Linux. */
3535 #define I386_LINUX_NUM_REGS (I386_LINUX_ORIG_EAX_REGNUM + 1)
@@ -41,6 +41,7 @@ extern uint64_t i386_linux_core_read_xcr0 (bfd *abfd);
4141 extern struct target_desc *tdesc_i386_linux;
4242 extern struct target_desc *tdesc_i386_mmx_linux;
4343 extern struct target_desc *tdesc_i386_avx_linux;
44+extern struct target_desc *tdesc_i386_mpx_linux;
4445
4546 /* Format of XSAVE extended state is:
4647 struct
@@ -49,6 +50,7 @@ extern struct target_desc *tdesc_i386_avx_linux;
4950 sw_usable_bytes[464..511]
5051 xstate_hdr_bytes[512..575]
5152 avx_bytes[576..831]
53+ mpx_bytes [960..1032]
5254 future_state etc
5355 };
5456
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -57,6 +57,7 @@
5757
5858 #include "features/i386/i386.c"
5959 #include "features/i386/i386-avx.c"
60+#include "features/i386/i386-mpx.c"
6061 #include "features/i386/i386-mmx.c"
6162
6263 #include "ax.h"
@@ -98,6 +99,18 @@ static const char *i386_ymmh_names[] =
9899 "ymm4h", "ymm5h", "ymm6h", "ymm7h",
99100 };
100101
102+static const char *i386_mpx_names[] =
103+{
104+ "bnd0raw", "bnd1raw", "bnd2raw", "bnd3raw", "bndcfgu", "bndstatus"
105+};
106+
107+/* Register names for MPX pseudo-registers. */
108+
109+static const char *i386_bnd_names[] =
110+{
111+ "bnd0", "bnd1", "bnd2", "bnd3"
112+};
113+
101114 /* Register names for MMX pseudo-registers. */
102115
103116 static const char *i386_mmx_names[] =
@@ -202,6 +215,21 @@ i386_ymm_regnum_p (struct gdbarch *gdbarch, int regnum)
202215 return regnum >= 0 && regnum < tdep->num_ymm_regs;
203216 }
204217
218+/* BND register? */
219+
220+int
221+i386_bnd_regnum_p (struct gdbarch *gdbarch, int regnum)
222+{
223+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
224+ int bnd0_regnum = tdep->bnd0_regnum;
225+
226+ if (bnd0_regnum < 0)
227+ return 0;
228+
229+ regnum -= bnd0_regnum;
230+ return regnum >= 0 && regnum < I387_NUM_BND_REGS;
231+}
232+
205233 /* SSE register? */
206234
207235 int
@@ -254,6 +282,34 @@ i386_fpc_regnum_p (struct gdbarch *gdbarch, int regnum)
254282 && regnum < I387_XMM0_REGNUM (tdep));
255283 }
256284
285+/* BNDr (raw) register? */
286+
287+static int
288+i386_bndr_regnum_p (struct gdbarch *gdbarch, int regnum)
289+{
290+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
291+
292+ if (I387_BND0R_REGNUM (tdep) < 0)
293+ return 0;
294+
295+ regnum -= tdep->bnd0r_regnum;
296+ return regnum >= 0 && regnum < I387_NUM_BND_REGS;
297+}
298+
299+/* BND control register? */
300+
301+static int
302+i386_mpx_ctrl_regnum_p (struct gdbarch *gdbarch, int regnum)
303+{
304+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
305+
306+ if (I387_BNDCFGU_REGNUM (tdep) < 0)
307+ return 0;
308+
309+ regnum -= I387_BNDCFGU_REGNUM (tdep);
310+ return regnum >= 0 && regnum < I387_NUM_MPX_CTRL_REGS;
311+}
312+
257313 /* Return the name of register REGNUM, or the empty string if it is
258314 an anonymous register. */
259315
@@ -273,6 +329,8 @@ const char *
273329 i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
274330 {
275331 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
332+ if (i386_bnd_regnum_p (gdbarch, regnum))
333+ return i386_bnd_names[regnum - tdep->bnd0_regnum];
276334 if (i386_mmx_regnum_p (gdbarch, regnum))
277335 return i386_mmx_names[regnum - I387_MM0_REGNUM (tdep)];
278336 else if (i386_ymm_regnum_p (gdbarch, regnum))
@@ -2750,6 +2808,43 @@ i387_ext_type (struct gdbarch *gdbarch)
27502808 return tdep->i387_ext_type;
27512809 }
27522810
2811+/* Construct type for pseudo BND registers. We can't use
2812+ tdesc_find_type since a complement of one value has to be used
2813+ to describe the upper bound. */
2814+
2815+static struct type *
2816+i386_bnd_type (struct gdbarch *gdbarch)
2817+{
2818+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2819+
2820+
2821+ if (!tdep->i386_bnd_type)
2822+ {
2823+ struct type *t, *bound_t;
2824+ const struct builtin_type *bt = builtin_type (gdbarch);
2825+
2826+ /* The type we're building is described bellow: */
2827+#if 0
2828+ struct __bound128
2829+ {
2830+ void *lbound;
2831+ void *ubound; /* One complement of raw ubound field. */
2832+ };
2833+#endif
2834+
2835+ t = arch_composite_type (gdbarch,
2836+ "__gdb_builtin_type_bound128", TYPE_CODE_STRUCT);
2837+
2838+ append_composite_type_field (t, "lbound", bt->builtin_data_ptr);
2839+ append_composite_type_field (t, "ubound", bt->builtin_data_ptr);
2840+
2841+ TYPE_NAME (t) = "builtin_type_bound128";
2842+ tdep->i386_bnd_type = t;
2843+ }
2844+
2845+ return tdep->i386_bnd_type;
2846+}
2847+
27532848 /* Construct vector type for pseudo YMM registers. We can't use
27542849 tdesc_find_type since YMM isn't described in target description. */
27552850
@@ -2851,6 +2946,8 @@ i386_mmx_type (struct gdbarch *gdbarch)
28512946 struct type *
28522947 i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
28532948 {
2949+ if (i386_bnd_regnum_p (gdbarch, regnum))
2950+ return i386_bnd_type (gdbarch);
28542951 if (i386_mmx_regnum_p (gdbarch, regnum))
28552952 return i386_mmx_type (gdbarch);
28562953 else if (i386_ymm_regnum_p (gdbarch, regnum))
@@ -2917,8 +3014,31 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
29173014 else
29183015 {
29193016 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
3017+ if (i386_bnd_regnum_p (gdbarch, regnum))
3018+ {
3019+ regnum -= tdep->bnd0_regnum;
29203020
2921- if (i386_ymm_regnum_p (gdbarch, regnum))
3021+ /* Extract (always little endian). Read lower 128bits. */
3022+ status = regcache_raw_read (regcache,
3023+ I387_BND0R_REGNUM (tdep) + regnum,
3024+ raw_buf);
3025+ if (status != REG_VALID)
3026+ mark_value_bytes_unavailable (result_value, 0, 16);
3027+ else
3028+ {
3029+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
3030+ LONGEST upper, lower;
3031+ int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
3032+
3033+ lower = extract_unsigned_integer (raw_buf, 8, byte_order);
3034+ upper = extract_unsigned_integer (raw_buf + 8, 8, byte_order);
3035+ upper = ~upper;
3036+
3037+ memcpy (buf, &lower, size);
3038+ memcpy (buf + size, &upper, size);
3039+ }
3040+ }
3041+ else if (i386_ymm_regnum_p (gdbarch, regnum))
29223042 {
29233043 regnum -= tdep->ymm0_regnum;
29243044
@@ -3011,7 +3131,34 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
30113131 {
30123132 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
30133133
3014- if (i386_ymm_regnum_p (gdbarch, regnum))
3134+ if (i386_bnd_regnum_p (gdbarch, regnum))
3135+ {
3136+ ULONGEST upper, lower;
3137+ int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
3138+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
3139+
3140+ /* New values from input value. */
3141+ regnum -= tdep->bnd0_regnum;
3142+ lower = extract_unsigned_integer (buf, size, byte_order);
3143+ upper = extract_unsigned_integer (buf + size, size, byte_order);
3144+
3145+ /* Fetching register buffer. */
3146+ regcache_raw_read (regcache,
3147+ I387_BND0R_REGNUM (tdep) + regnum,
3148+ raw_buf);
3149+
3150+ upper = ~upper;
3151+
3152+ /* Set register bits. */
3153+ memcpy (raw_buf, &lower, 8);
3154+ memcpy (raw_buf + 8, &upper, 8);
3155+
3156+
3157+ regcache_raw_write (regcache,
3158+ I387_BND0R_REGNUM (tdep) + regnum,
3159+ raw_buf);
3160+ }
3161+ else if (i386_ymm_regnum_p (gdbarch, regnum))
30153162 {
30163163 regnum -= tdep->ymm0_regnum;
30173164
@@ -3866,7 +4013,8 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
38664013 {
38674014 const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
38684015 int fp_regnum_p, mmx_regnum_p, xmm_regnum_p, mxcsr_regnum_p,
3869- ymm_regnum_p, ymmh_regnum_p;
4016+ ymm_regnum_p, ymmh_regnum_p, bndr_regnum_p, bnd_regnum_p,
4017+ mpx_ctrl_regnum_p;
38704018
38714019 /* Don't include pseudo registers, except for MMX, in any register
38724020 groups. */
@@ -3911,13 +4059,31 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
39114059 || ymmh_regnum_p))
39124060 return 0;
39134061
4062+ bnd_regnum_p = i386_bnd_regnum_p (gdbarch, regnum);
4063+ if (group == all_reggroup
4064+ && ((bnd_regnum_p && (tdep->xcr0 & I386_XSTATE_MPX_MASK))))
4065+ return bnd_regnum_p;
4066+
4067+ bndr_regnum_p = i386_bndr_regnum_p (gdbarch, regnum);
4068+ if (group == all_reggroup
4069+ && ((bndr_regnum_p && (tdep->xcr0 & I386_XSTATE_MPX_MASK))))
4070+ return 0;
4071+
4072+ mpx_ctrl_regnum_p = i386_mpx_ctrl_regnum_p (gdbarch, regnum);
4073+ if (group == all_reggroup
4074+ && ((mpx_ctrl_regnum_p && (tdep->xcr0 & I386_XSTATE_MPX_MASK))))
4075+ return mpx_ctrl_regnum_p;
4076+
39144077 if (group == general_reggroup)
39154078 return (!fp_regnum_p
39164079 && !mmx_regnum_p
39174080 && !mxcsr_regnum_p
39184081 && !xmm_regnum_p
39194082 && !ymm_regnum_p
3920- && !ymmh_regnum_p);
4083+ && !ymmh_regnum_p
4084+ && !bndr_regnum_p
4085+ && !bnd_regnum_p
4086+ && !mpx_ctrl_regnum_p);
39214087
39224088 return default_register_reggroup_p (gdbarch, regnum, group);
39234089 }
@@ -7496,7 +7662,7 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
74967662 {
74977663 const struct target_desc *tdesc = tdep->tdesc;
74987664 const struct tdesc_feature *feature_core;
7499- const struct tdesc_feature *feature_sse, *feature_avx;
7665+ const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx;
75007666 int i, num_regs, valid_p;
75017667
75027668 if (! tdesc_has_registers (tdesc))
@@ -7513,6 +7679,9 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
75137679 /* Try AVX registers. */
75147680 feature_avx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx");
75157681
7682+ /* Try MPX registers. */
7683+ feature_mpx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.mpx");
7684+
75167685 valid_p = 1;
75177686
75187687 /* The XCR0 bits. */
@@ -7559,6 +7728,23 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
75597728 tdep->register_names[i]);
75607729 }
75617730
7731+ if (feature_mpx)
7732+ {
7733+ tdep->xcr0 = I386_XSTATE_MPX_MASK;
7734+
7735+ if (tdep->bnd0r_regnum < 0)
7736+ {
7737+ tdep->mpx_register_names = i386_mpx_names;
7738+ tdep->bnd0r_regnum = I386_BND0R_REGNUM;
7739+ tdep->bndcfgu_regnum = I386_BNDCFGU_REGNUM;
7740+ }
7741+
7742+ for (i = 0; i < I387_NUM_MPX_REGS; i++)
7743+ valid_p &= tdesc_numbered_register (feature_mpx, tdesc_data,
7744+ I387_BND0R_REGNUM (tdep) + i,
7745+ tdep->mpx_register_names[i]);
7746+ }
7747+
75627748 return valid_p;
75637749 }
75647750
@@ -7572,6 +7758,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
75727758 const struct target_desc *tdesc;
75737759 int mm0_regnum;
75747760 int ymm0_regnum;
7761+ int bnd0_regnum;
7762+ int num_bnd_cooked;
75757763
75767764 /* If there is already a candidate, use it. */
75777765 arches = gdbarch_list_lookup_by_info (arches, &info);
@@ -7745,8 +7933,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
77457933
77467934 /* Even though the default ABI only includes general-purpose registers,
77477935 floating-point registers and the SSE registers, we have to leave a
7748- gap for the upper AVX registers. */
7749- set_gdbarch_num_regs (gdbarch, I386_AVX_NUM_REGS);
7936+ gap for the upper AVX registers and the MPX registers. */
7937+ set_gdbarch_num_regs (gdbarch, I386_MPX_NUM_REGS);
77507938
77517939 /* Get the x86 target description from INFO. */
77527940 tdesc = info.target_desc;
@@ -7767,6 +7955,10 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
77677955 tdep->num_mmx_regs = 8;
77687956 tdep->num_ymm_regs = 0;
77697957
7958+ /* No MPX registers. */
7959+ tdep->bnd0r_regnum = -1;
7960+ tdep->bndcfgu_regnum = -1;
7961+
77707962 tdesc_data = tdesc_data_alloc ();
77717963
77727964 set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction);
@@ -7785,13 +7977,16 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
77857977 return NULL;
77867978 }
77877979
7980+ num_bnd_cooked = (tdep->bnd0r_regnum > 0 ? I387_NUM_BND_REGS : 0);
7981+
77887982 /* Wire in pseudo registers. Number of pseudo registers may be
77897983 changed. */
77907984 set_gdbarch_num_pseudo_regs (gdbarch, (tdep->num_byte_regs
77917985 + tdep->num_word_regs
77927986 + tdep->num_dword_regs
77937987 + tdep->num_mmx_regs
7794- + tdep->num_ymm_regs));
7988+ + tdep->num_ymm_regs
7989+ + num_bnd_cooked));
77957990
77967991 /* Target description may be changed. */
77977992 tdesc = tdep->tdesc;
@@ -7825,14 +8020,21 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
78258020 else
78268021 tdep->ymm0_regnum = -1;
78278022
8023+ bnd0_regnum = mm0_regnum;
78288024 if (tdep->num_mmx_regs != 0)
78298025 {
78308026 /* Support MMX pseudo-register if MMX hasn't been disabled. */
78318027 tdep->mm0_regnum = mm0_regnum;
8028+ bnd0_regnum += tdep->num_mmx_regs;
78328029 }
78338030 else
78348031 tdep->mm0_regnum = -1;
78358032
8033+ if (tdep->bnd0r_regnum > 0)
8034+ tdep->bnd0_regnum = bnd0_regnum;
8035+ else
8036+ tdep-> bnd0_regnum = -1;
8037+
78368038 /* Hook in the legacy prologue-based unwinders last (fallback). */
78378039 frame_unwind_append_unwinder (gdbarch, &i386_stack_tramp_frame_unwind);
78388040 frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
@@ -7910,6 +8112,7 @@ is \"default\"."),
79108112 initialize_tdesc_i386 ();
79118113 initialize_tdesc_i386_mmx ();
79128114 initialize_tdesc_i386_avx ();
8115+ initialize_tdesc_i386_mpx ();
79138116
79148117 /* Tell remote stub that we support XML target description. */
79158118 register_remote_support_xml ("i386");
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -130,6 +130,21 @@ struct gdbarch_tdep
130130 /* Upper YMM register names. Only used for tdesc_numbered_register. */
131131 const char **ymmh_register_names;
132132
133+ /* Register number for %bnd0r. Set this to -1 to indicate the absence
134+ bound registers. */
135+ int bnd0r_regnum;
136+
137+ /* Register number for pseudo register %bnd0. Set this to -1 to indicate the absence
138+ bound registers. */
139+ int bnd0_regnum;
140+
141+ /* Register number for %bndcfgu. Set this to -1 to indicate the absence
142+ bound control registers. */
143+ int bndcfgu_regnum;
144+
145+ /* MPX register names. Only used for tdesc_numbered_register. */
146+ const char **mpx_register_names;
147+
133148 /* Target description. */
134149 const struct target_desc *tdesc;
135150
@@ -165,6 +180,7 @@ struct gdbarch_tdep
165180 struct type *i386_mmx_type;
166181 struct type *i386_ymm_type;
167182 struct type *i387_ext_type;
183+ struct type *i386_bnd_type;
168184
169185 /* Process record/replay target. */
170186 /* The map for registers because the AMD64's registers order
@@ -212,7 +228,11 @@ enum i386_regnum
212228 I386_ST0_REGNUM, /* %st(0) */
213229 I386_MXCSR_REGNUM = 40, /* %mxcsr */
214230 I386_YMM0H_REGNUM, /* %ymm0h */
215- I386_YMM7H_REGNUM = I386_YMM0H_REGNUM + 7
231+ I386_YMM7H_REGNUM = I386_YMM0H_REGNUM + 7,
232+ I386_BND0R_REGNUM,
233+ I386_BND3R_REGNUM = I386_BND0R_REGNUM + 3,
234+ I386_BNDCFGU_REGNUM,
235+ I386_BNDSTATUS_REGNUM
216236 };
217237
218238 /* Register numbers of RECORD_REGMAP. */
@@ -250,6 +270,7 @@ enum record_i386_regnum
250270
251271 #define I386_SSE_NUM_REGS (I386_MXCSR_REGNUM + 1)
252272 #define I386_AVX_NUM_REGS (I386_YMM7H_REGNUM + 1)
273+#define I386_MPX_NUM_REGS (I386_BNDSTATUS_REGNUM + 1)
253274
254275 /* Size of the largest register. */
255276 #define I386_MAX_REGISTER_SIZE 16
@@ -263,6 +284,7 @@ extern int i386_word_regnum_p (struct gdbarch *gdbarch, int regnum);
263284 extern int i386_dword_regnum_p (struct gdbarch *gdbarch, int regnum);
264285 extern int i386_xmm_regnum_p (struct gdbarch *gdbarch, int regnum);
265286 extern int i386_ymm_regnum_p (struct gdbarch *gdbarch, int regnum);
287+extern int i386_bnd_regnum_p (struct gdbarch *gdbarch, int regnum);
266288
267289 extern const char *i386_pseudo_register_name (struct gdbarch *gdbarch,
268290 int regnum);
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -763,9 +763,22 @@ static int xsave_avxh_offset[] =
763763 576 + 15 * 16 /* Upper 128bit of ... %ymm15 (128 bits each). */
764764 };
765765
766+static int xsave_mpx_offset[] =
767+{
768+ 960 + 0 * 16, /* bnd0r...bnd3r registers. */
769+ 960 + 1 * 16,
770+ 960 + 2 * 16,
771+ 960 + 3 * 16,
772+ 1024 + 0 * 8, /* bndcfg ... bndstatus. */
773+ 1024 + 1 * 8,
774+};
775+
766776 #define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
767777 (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
768778
779+#define XSAVE_MPX_ADDR(tdep, xsave, regnum) \
780+ (xsave + xsave_mpx_offset[regnum - I387_BND0R_REGNUM (tdep)])
781+
769782 /* Similar to i387_supply_fxsave, but use XSAVE extended state. */
770783
771784 void
@@ -783,7 +796,8 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
783796 x87 = 0x1,
784797 sse = 0x2,
785798 avxh = 0x4,
786- all = x87 | sse | avxh
799+ mpx = 0x8,
800+ all = x87 | sse | avxh | mpx
787801 } regclass;
788802
789803 gdb_assert (regs != NULL);
@@ -795,6 +809,9 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
795809 else if (regnum >= I387_YMM0H_REGNUM (tdep)
796810 && regnum < I387_YMMENDH_REGNUM (tdep))
797811 regclass = avxh;
812+ else if (regnum >= I387_BND0R_REGNUM (tdep)
813+ && regnum < I387_MPXEND_REGNUM (tdep))
814+ regclass = mpx;
798815 else if (regnum >= I387_XMM0_REGNUM(tdep)
799816 && regnum < I387_MXCSR_REGNUM (tdep))
800817 regclass = sse;
@@ -814,7 +831,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
814831 clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
815832 }
816833 else
817- clear_bv = I386_XSTATE_AVX_MASK;
834+ clear_bv = I386_XSTATE_ALL_MASK;
818835
819836 /* With the delayed xsave mechanism, in between the program
820837 starting, and the program accessing the vector registers for the
@@ -838,6 +855,14 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
838855 XSAVE_AVXH_ADDR (tdep, regs, regnum));
839856 return;
840857
858+ case mpx:
859+ if ((clear_bv & I386_XSTATE_BNDREGS))
860+ regcache_raw_supply (regcache, regnum, zero);
861+ else
862+ regcache_raw_supply (regcache, regnum,
863+ XSAVE_MPX_ADDR (tdep, regs, regnum));
864+ return;
865+
841866 case sse:
842867 if ((clear_bv & I386_XSTATE_SSE))
843868 regcache_raw_supply (regcache, regnum, zero);
@@ -875,6 +900,42 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
875900 }
876901 }
877902
903+ /* Handle the MPX registers. */
904+ if ((tdep->xcr0 & I386_XSTATE_BNDREGS))
905+ {
906+ if (clear_bv & I386_XSTATE_BNDREGS)
907+ {
908+ for (i = I387_BND0R_REGNUM (tdep);
909+ i < I387_BNDCFGU_REGNUM (tdep); i++)
910+ regcache_raw_supply (regcache, i, zero);
911+ }
912+ else
913+ {
914+ for (i = I387_BND0R_REGNUM (tdep);
915+ i < I387_BNDCFGU_REGNUM (tdep); i++)
916+ regcache_raw_supply (regcache, i,
917+ XSAVE_MPX_ADDR (tdep, regs, i));
918+ }
919+ }
920+
921+ /* Handle the MPX registers. */
922+ if ((tdep->xcr0 & I386_XSTATE_BNDCFG))
923+ {
924+ if (clear_bv & I386_XSTATE_BNDCFG)
925+ {
926+ for (i = I387_BNDCFGU_REGNUM (tdep);
927+ i < I387_MPXEND_REGNUM (tdep); i++)
928+ regcache_raw_supply (regcache, i, zero);
929+ }
930+ else
931+ {
932+ for (i = I387_BNDCFGU_REGNUM (tdep);
933+ i < I387_MPXEND_REGNUM (tdep); i++)
934+ regcache_raw_supply (regcache, i,
935+ XSAVE_MPX_ADDR (tdep, regs, i));
936+ }
937+ }
938+
878939 /* Handle the XMM registers. */
879940 if ((tdep->xcr0 & I386_XSTATE_SSE))
880941 {
@@ -989,7 +1050,8 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
9891050 x87 = 0x2 | check,
9901051 sse = 0x4 | check,
9911052 avxh = 0x8 | check,
992- all = x87 | sse | avxh
1053+ mpx = 0x10 | check,
1054+ all = x87 | sse | avxh | mpx
9931055 } regclass;
9941056
9951057 gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
@@ -1000,7 +1062,10 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
10001062 else if (regnum >= I387_YMM0H_REGNUM (tdep)
10011063 && regnum < I387_YMMENDH_REGNUM (tdep))
10021064 regclass = avxh;
1003- else if (regnum >= I387_XMM0_REGNUM(tdep)
1065+ else if (regnum >= I387_BND0R_REGNUM (tdep)
1066+ && regnum < I387_MPXEND_REGNUM (tdep))
1067+ regclass = mpx;
1068+ else if (regnum >= I387_XMM0_REGNUM (tdep)
10041069 && regnum < I387_MXCSR_REGNUM (tdep))
10051070 regclass = sse;
10061071 else if (regnum >= I387_ST0_REGNUM (tdep)
@@ -1032,6 +1097,16 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
10321097 /* Clear register set if its bit in xstat_bv is zero. */
10331098 if (clear_bv)
10341099 {
1100+ if ((clear_bv & I386_XSTATE_BNDREGS))
1101+ for (i = I387_BND0R_REGNUM (tdep);
1102+ i < I387_BNDCFGU_REGNUM (tdep); i++)
1103+ memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 16);
1104+
1105+ if ((clear_bv & I386_XSTATE_BNDCFG))
1106+ for (i = I387_BNDCFGU_REGNUM (tdep);
1107+ i < I387_MPXEND_REGNUM (tdep); i++)
1108+ memset (XSAVE_MPX_ADDR (tdep, regs, i), 0, 8);
1109+
10351110 if ((clear_bv & I386_XSTATE_AVX))
10361111 for (i = I387_YMM0H_REGNUM (tdep);
10371112 i < I387_YMMENDH_REGNUM (tdep); i++)
@@ -1063,6 +1138,33 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
10631138 memcpy (p, raw, 16);
10641139 }
10651140 }
1141+ /* Check if any upper MPX registers are changed. */
1142+ if ((tdep->xcr0 & I386_XSTATE_BNDREGS))
1143+ for (i = I387_BND0R_REGNUM (tdep);
1144+ i < I387_BNDCFGU_REGNUM (tdep); i++)
1145+ {
1146+ regcache_raw_collect (regcache, i, raw);
1147+ p = XSAVE_MPX_ADDR (tdep, regs, i);
1148+ if (memcmp (raw, p, 16))
1149+ {
1150+ xstate_bv |= I386_XSTATE_BNDREGS;
1151+ memcpy (p, raw, 16);
1152+ }
1153+ }
1154+
1155+ /* Check if any upper MPX registers are changed. */
1156+ if ((tdep->xcr0 & I386_XSTATE_BNDCFG))
1157+ for (i = I387_BNDCFGU_REGNUM (tdep);
1158+ i < I387_MPXEND_REGNUM (tdep); i++)
1159+ {
1160+ regcache_raw_collect (regcache, i, raw);
1161+ p = XSAVE_MPX_ADDR (tdep, regs, i);
1162+ if (memcmp (raw, p, 8))
1163+ {
1164+ xstate_bv |= I386_XSTATE_BNDCFG;
1165+ memcpy (p, raw, 8);
1166+ }
1167+ }
10661168
10671169 /* Check if any SSE registers are changed. */
10681170 if ((tdep->xcr0 & I386_XSTATE_SSE))
@@ -1113,6 +1215,25 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
11131215 }
11141216 break;
11151217
1218+ case mpx:
1219+ if (regnum < I387_BNDCFGU_REGNUM (tdep))
1220+ {
1221+ regcache_raw_collect (regcache, regnum, raw);
1222+ p = XSAVE_MPX_ADDR (tdep, regs, regnum);
1223+ if (memcmp (raw, p, 16))
1224+ {
1225+ xstate_bv |= I386_XSTATE_BNDREGS;
1226+ memcpy (p, raw, 16);
1227+ }
1228+ }
1229+ else
1230+ {
1231+ p = XSAVE_MPX_ADDR (tdep, regs, regnum);
1232+ xstate_bv |= I386_XSTATE_BNDCFG;
1233+ memcpy (p, raw, 8);
1234+ }
1235+ break;
1236+
11161237 case sse:
11171238 /* This is an SSE register. */
11181239 p = FXSAVE_ADDR (tdep, regs, regnum);
@@ -1154,6 +1275,7 @@ i387_collect_xsave (const struct regcache *regcache, int regnum,
11541275 case x87:
11551276 case sse:
11561277 case avxh:
1278+ case mpx:
11571279 /* Register REGNUM has been updated. Return. */
11581280 return;
11591281 }
--- a/gdb/i387-tdep.h
+++ b/gdb/i387-tdep.h
@@ -34,6 +34,13 @@ struct ui_file;
3434 #define I387_MM0_REGNUM(tdep) ((tdep)->mm0_regnum)
3535 #define I387_NUM_YMM_REGS(tdep) ((tdep)->num_ymm_regs)
3636 #define I387_YMM0H_REGNUM(tdep) ((tdep)->ymm0h_regnum)
37+#define I387_BND0R_REGNUM(tdep) ((tdep)->bnd0r_regnum)
38+#define I387_BNDCFGU_REGNUM(tdep) ((tdep)->bndcfgu_regnum)
39+
40+/* Set of constants used for 32 and 64-bit. */
41+#define I387_NUM_MPX_REGS 6
42+#define I387_NUM_BND_REGS 4
43+#define I387_NUM_MPX_CTRL_REGS 2
3744
3845 #define I387_FCTRL_REGNUM(tdep) (I387_ST0_REGNUM (tdep) + 8)
3946 #define I387_FSTAT_REGNUM(tdep) (I387_FCTRL_REGNUM (tdep) + 1)
@@ -48,6 +55,8 @@ struct ui_file;
4855 (I387_XMM0_REGNUM (tdep) + I387_NUM_XMM_REGS (tdep))
4956 #define I387_YMMENDH_REGNUM(tdep) \
5057 (I387_YMM0H_REGNUM (tdep) + I387_NUM_YMM_REGS (tdep))
58+#define I387_MPXEND_REGNUM(tdep) \
59+ (I387_BND0R_REGNUM (tdep) + I387_NUM_MPX_REGS)
5160
5261 /* Print out the i387 floating point state. */
5362