aboutsummaryrefslogtreecommitdiff
path: root/gdb/i386-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/i386-tdep.c')
-rw-r--r--gdb/i386-tdep.c902
1 files changed, 376 insertions, 526 deletions
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index f1f909e..9be4748 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -1,6 +1,6 @@
/* Intel 386 target-dependent stuff.
- Copyright (C) 1988-2024 Free Software Foundation, Inc.
+ Copyright (C) 1988-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -117,23 +117,12 @@ static const char * const i386_ymmh_names[] =
"ymm4h", "ymm5h", "ymm6h", "ymm7h",
};
-static const char * const i386_mpx_names[] =
-{
- "bnd0raw", "bnd1raw", "bnd2raw", "bnd3raw", "bndcfgu", "bndstatus"
-};
static const char * const i386_pkeys_names[] =
{
"pkru"
};
-/* Register names for MPX pseudo-registers. */
-
-static const char * const i386_bnd_names[] =
-{
- "bnd0", "bnd1", "bnd2", "bnd3"
-};
-
/* Register names for MMX pseudo-registers. */
static const char * const i386_mmx_names[] =
@@ -311,21 +300,6 @@ i386_ymm_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
return regnum >= 0 && regnum < tdep->num_ymm_avx512_regs;
}
-/* BND register? */
-
-int
-i386_bnd_regnum_p (struct gdbarch *gdbarch, int regnum)
-{
- i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
- int bnd0_regnum = tdep->bnd0_regnum;
-
- if (bnd0_regnum < 0)
- return 0;
-
- regnum -= bnd0_regnum;
- return regnum >= 0 && regnum < I387_NUM_BND_REGS;
-}
-
/* SSE register? */
int
@@ -393,34 +367,6 @@ i386_fpc_regnum_p (struct gdbarch *gdbarch, int regnum)
&& regnum < I387_XMM0_REGNUM (tdep));
}
-/* BNDr (raw) register? */
-
-static int
-i386_bndr_regnum_p (struct gdbarch *gdbarch, int regnum)
-{
- i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
-
- if (I387_BND0R_REGNUM (tdep) < 0)
- return 0;
-
- regnum -= tdep->bnd0r_regnum;
- return regnum >= 0 && regnum < I387_NUM_BND_REGS;
-}
-
-/* BND control register? */
-
-static int
-i386_mpx_ctrl_regnum_p (struct gdbarch *gdbarch, int regnum)
-{
- i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
-
- if (I387_BNDCFGU_REGNUM (tdep) < 0)
- return 0;
-
- regnum -= I387_BNDCFGU_REGNUM (tdep);
- return regnum >= 0 && regnum < I387_NUM_MPX_CTRL_REGS;
-}
-
/* PKRU register? */
bool
@@ -463,8 +409,6 @@ const char *
i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
{
i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
- if (i386_bnd_regnum_p (gdbarch, regnum))
- return i386_bnd_names[regnum - tdep->bnd0_regnum];
if (i386_mmx_regnum_p (gdbarch, regnum))
return i386_mmx_names[regnum - I387_MM0_REGNUM (tdep)];
else if (i386_ymm_regnum_p (gdbarch, regnum))
@@ -922,7 +866,7 @@ i386_displaced_step_fixup (struct gdbarch *gdbarch,
ULONGEST eip = (pc - insn_offset) & 0xffffffffUL;
/* If we just stepped over a breakpoint insn, we don't backup
- the pc on purpose; this is to match behaviour without
+ the pc on purpose; this is to match behavior without
stepping. */
regcache_write_pc (regs, eip);
@@ -1946,12 +1890,11 @@ i386_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
/* Make sure address is computed correctly as a 32bit
integer even if CORE_ADDR is 64 bit wide. */
- struct bound_minimal_symbol s;
CORE_ADDR call_dest;
call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order);
call_dest = call_dest & 0xffffffffU;
- s = lookup_minimal_symbol_by_pc (call_dest);
+ bound_minimal_symbol s = lookup_minimal_symbol_by_pc (call_dest);
if (s.minsym != NULL
&& s.minsym->linkage_name () != NULL
&& strcmp (s.minsym->linkage_name (), "__main") == 0)
@@ -2196,16 +2139,16 @@ i386_frame_prev_register (const frame_info_ptr &this_frame, void **this_cache,
return frame_unwind_got_register (this_frame, regnum, regnum);
}
-static const struct frame_unwind i386_frame_unwind =
-{
+static const struct frame_unwind_legacy i386_frame_unwind (
"i386 prologue",
NORMAL_FRAME,
+ FRAME_UNWIND_ARCH,
i386_frame_unwind_stop_reason,
i386_frame_this_id,
i386_frame_prev_register,
NULL,
default_frame_sniffer
-};
+);
/* Normal frames, but in a function epilogue. */
@@ -2351,27 +2294,27 @@ i386_epilogue_frame_prev_register (const frame_info_ptr &this_frame,
return i386_frame_prev_register (this_frame, this_cache, regnum);
}
-static const struct frame_unwind i386_epilogue_override_frame_unwind =
-{
+static const struct frame_unwind_legacy i386_epilogue_override_frame_unwind (
"i386 epilogue override",
NORMAL_FRAME,
+ FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register,
NULL,
i386_epilogue_override_frame_sniffer
-};
+);
-static const struct frame_unwind i386_epilogue_frame_unwind =
-{
+static const struct frame_unwind_legacy i386_epilogue_frame_unwind (
"i386 epilogue",
NORMAL_FRAME,
+ FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register,
NULL,
i386_epilogue_frame_sniffer
-};
+);
/* Stack-based trampolines. */
@@ -2379,7 +2322,7 @@ static const struct frame_unwind i386_epilogue_frame_unwind =
/* These trampolines are used on cross x86 targets, when taking the
address of a nested function. When executing these trampolines,
no stack frame is set up, so we are in a similar situation as in
- epilogues and i386_epilogue_frame_this_id can be re-used. */
+ epilogues and i386_epilogue_frame_this_id can be reused. */
/* Static chain passed in register. */
@@ -2444,16 +2387,16 @@ i386_stack_tramp_frame_sniffer (const struct frame_unwind *self,
return 0;
}
-static const struct frame_unwind i386_stack_tramp_frame_unwind =
-{
+static const struct frame_unwind_legacy i386_stack_tramp_frame_unwind (
"i386 stack tramp",
NORMAL_FRAME,
+ FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register,
NULL,
i386_stack_tramp_frame_sniffer
-};
+);
/* Generate a bytecode expression to get the value of the saved PC. */
@@ -2593,16 +2536,16 @@ i386_sigtramp_frame_sniffer (const struct frame_unwind *self,
return 0;
}
-static const struct frame_unwind i386_sigtramp_frame_unwind =
-{
+static const struct frame_unwind_legacy i386_sigtramp_frame_unwind (
"i386 sigtramp",
SIGTRAMP_FRAME,
+ FRAME_UNWIND_ARCH,
i386_sigtramp_frame_unwind_stop_reason,
i386_sigtramp_frame_this_id,
i386_sigtramp_frame_prev_register,
NULL,
i386_sigtramp_frame_sniffer
-};
+);
static CORE_ADDR
@@ -2739,13 +2682,6 @@ i386_thiscall_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
int write_pass;
int args_space = 0;
- /* BND registers can be in arbitrary values at the moment of the
- inferior call. This can cause boundary violations that are not
- due to a real bug or even desired by the user. The best to be done
- is set the BND registers to allow access to the whole memory, INIT
- state, before pushing the inferior call. */
- i387_reset_bnd_regs (gdbarch, regcache);
-
/* Determine the total space required for arguments and struct
return address in a first pass (allowing for 16-byte-aligned
arguments), then push arguments in a second pass. */
@@ -3162,43 +3098,6 @@ i387_ext_type (struct gdbarch *gdbarch)
return tdep->i387_ext_type;
}
-/* Construct type for pseudo BND registers. We can't use
- tdesc_find_type since a complement of one value has to be used
- to describe the upper bound. */
-
-static struct type *
-i386_bnd_type (struct gdbarch *gdbarch)
-{
- i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
-
-
- if (!tdep->i386_bnd_type)
- {
- struct type *t;
- const struct builtin_type *bt = builtin_type (gdbarch);
-
- /* The type we're building is described bellow: */
-#if 0
- struct __bound128
- {
- void *lbound;
- void *ubound; /* One complement of raw ubound field. */
- };
-#endif
-
- t = arch_composite_type (gdbarch,
- "__gdb_builtin_type_bound128", TYPE_CODE_STRUCT);
-
- append_composite_type_field (t, "lbound", bt->builtin_data_ptr);
- append_composite_type_field (t, "ubound", bt->builtin_data_ptr);
-
- t->set_name ("builtin_type_bound128");
- tdep->i386_bnd_type = t;
- }
-
- return tdep->i386_bnd_type;
-}
-
/* Construct vector type for pseudo ZMM registers. We can't use
tdesc_find_type since ZMM isn't described in target description. */
@@ -3365,8 +3264,6 @@ i386_mmx_type (struct gdbarch *gdbarch)
struct type *
i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
{
- if (i386_bnd_regnum_p (gdbarch, regnum))
- return i386_bnd_type (gdbarch);
if (i386_mmx_regnum_p (gdbarch, regnum))
return i386_mmx_type (gdbarch);
else if (i386_ymm_regnum_p (gdbarch, regnum))
@@ -3426,39 +3323,7 @@ i386_pseudo_register_read_value (gdbarch *gdbarch, const frame_info_ptr &next_fr
else
{
i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
- if (i386_bnd_regnum_p (gdbarch, pseudo_reg_num))
- {
- int i = pseudo_reg_num - tdep->bnd0_regnum;
-
- /* Extract (always little endian). Read lower 128bits. */
- value *bndr_value
- = value_of_register (I387_BND0R_REGNUM (tdep) + i, next_frame);
- int size = builtin_type (gdbarch)->builtin_data_ptr->length ();
- value *result
- = value::allocate_register (next_frame, pseudo_reg_num);
-
- /* Copy the lower. */
- bndr_value->contents_copy (result, 0, 0, size);
-
- /* Copy the upper. */
- bndr_value->contents_copy (result, size, 8, size);
-
- /* If upper bytes are available, compute ones' complement. */
- if (result->bytes_available (size, size))
- {
- bfd_endian byte_order
- = gdbarch_byte_order (frame_unwind_arch (next_frame));
- gdb::array_view<gdb_byte> upper_bytes
- = result->contents_raw ().slice (size, size);
- ULONGEST upper
- = extract_unsigned_integer (upper_bytes, byte_order);
- upper = ~upper;
- store_unsigned_integer (upper_bytes, byte_order, upper);
- }
-
- return result;
- }
- else if (i386_zmm_regnum_p (gdbarch, pseudo_reg_num))
+ if (i386_zmm_regnum_p (gdbarch, pseudo_reg_num))
{
/* Which register is it, relative to zmm0. */
int i_0 = pseudo_reg_num - tdep->zmm0_regnum;
@@ -3531,33 +3396,7 @@ i386_pseudo_register_write (gdbarch *gdbarch, const frame_info_ptr &next_frame,
{
i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
- if (i386_bnd_regnum_p (gdbarch, pseudo_reg_num))
- {
- int size = builtin_type (gdbarch)->builtin_data_ptr->length ();
- bfd_endian byte_order
- = gdbarch_byte_order (current_inferior ()->arch ());
-
- /* New values from input value. */
- int reg_index = pseudo_reg_num - tdep->bnd0_regnum;
- int raw_regnum = I387_BND0R_REGNUM (tdep) + reg_index;
-
- value *bndr_value = value_of_register (raw_regnum, next_frame);
- gdb::array_view<gdb_byte> bndr_view
- = bndr_value->contents_writeable ();
-
- /* Copy lower bytes directly. */
- copy (buf.slice (0, size), bndr_view.slice (0, size));
-
- /* Convert and then copy upper bytes. */
- ULONGEST upper
- = extract_unsigned_integer (buf.slice (size, size), byte_order);
- upper = ~upper;
- store_unsigned_integer (bndr_view.slice (8, size), byte_order,
- upper);
-
- put_frame_register (next_frame, raw_regnum, bndr_view);
- }
- else if (i386_zmm_regnum_p (gdbarch, pseudo_reg_num))
+ if (i386_zmm_regnum_p (gdbarch, pseudo_reg_num))
{
/* Which register is it, relative to zmm0. */
int reg_index_0 = pseudo_reg_num - tdep->zmm0_regnum;
@@ -3628,12 +3467,6 @@ i386_ax_pseudo_register_collect (struct gdbarch *gdbarch,
ax_reg_mask (ax, I387_ST0_REGNUM (tdep) + i);
return 0;
}
- else if (i386_bnd_regnum_p (gdbarch, regnum))
- {
- regnum -= tdep->bnd0_regnum;
- ax_reg_mask (ax, I387_BND0R_REGNUM (tdep) + regnum);
- return 0;
- }
else if (i386_zmm_regnum_p (gdbarch, regnum))
{
regnum -= tdep->zmm0_regnum;
@@ -4481,9 +4314,8 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int fp_regnum_p, mmx_regnum_p, xmm_regnum_p, mxcsr_regnum_p,
ymm_regnum_p, ymmh_regnum_p, ymm_avx512_regnum_p, ymmh_avx512_regnum_p,
- bndr_regnum_p, bnd_regnum_p, zmm_regnum_p, zmmh_regnum_p,
- mpx_ctrl_regnum_p, xmm_avx512_regnum_p,
- avx512_p, avx_p, sse_p, pkru_regnum_p;
+ zmm_regnum_p, zmmh_regnum_p, xmm_avx512_regnum_p, avx512_p, avx_p,
+ sse_p, pkru_regnum_p;
/* Don't include pseudo registers, except for MMX, in any register
groups. */
@@ -4543,21 +4375,6 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
|| zmmh_regnum_p))
return 0;
- bnd_regnum_p = i386_bnd_regnum_p (gdbarch, regnum);
- if (group == all_reggroup
- && ((bnd_regnum_p && (tdep->xcr0 & X86_XSTATE_MPX_MASK))))
- return bnd_regnum_p;
-
- bndr_regnum_p = i386_bndr_regnum_p (gdbarch, regnum);
- if (group == all_reggroup
- && ((bndr_regnum_p && (tdep->xcr0 & X86_XSTATE_MPX_MASK))))
- return 0;
-
- mpx_ctrl_regnum_p = i386_mpx_ctrl_regnum_p (gdbarch, regnum);
- if (group == all_reggroup
- && ((mpx_ctrl_regnum_p && (tdep->xcr0 & X86_XSTATE_MPX_MASK))))
- return mpx_ctrl_regnum_p;
-
if (group == general_reggroup)
return (!fp_regnum_p
&& !mmx_regnum_p
@@ -4568,9 +4385,6 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
&& !ymmh_regnum_p
&& !ymm_avx512_regnum_p
&& !ymmh_avx512_regnum_p
- && !bndr_regnum_p
- && !bnd_regnum_p
- && !mpx_ctrl_regnum_p
&& !zmm_regnum_p
&& !zmmh_regnum_p
&& !pkru_regnum_p);
@@ -4637,6 +4451,12 @@ struct i386_record_s
int rip_offset;
int popl_esp_hack;
const int *regmap;
+
+ /* These are used by VEX and XOP prefixes. */
+ uint8_t map_select;
+ uint8_t vvvv;
+ uint8_t pp;
+ uint8_t l;
};
/* Parse the "modrm" part of the memory address irp->addr points at.
@@ -4975,6 +4795,288 @@ static int i386_record_floats (struct gdbarch *gdbarch,
return 0;
}
+/* i386_process_record helper to deal with instructions that start
+ with VEX prefix. */
+
+static int
+i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
+ int opcode, struct gdbarch *gdbarch)
+{
+ /* We need this to find YMM (and once AVX-512 is supported, ZMM) registers.
+ We should always save the largest available register, since an
+ instruction that handles a smaller reg may zero out the higher bits,
+ so we must have them saved. */
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+
+ /* Since we are reading pseudo registers, we need to tell GDB that it is
+ safe to do so, by saying we aren't _really_ running the inferior right
+ now. */
+ SCOPE_EXIT { inferior_thread ()->set_executing (true); };
+ inferior_thread () -> set_executing (false);
+
+ switch (opcode)
+ {
+ case 0x10: /* VMOVS[S|D] XMM, mem. */
+ /* VMOVUP[S|D] XMM, mem. */
+ case 0x28: /* VMOVAP[S|D] XMM, mem. */
+ /* Moving from memory region or XMM registers into an XMM register. */
+ i386_record_modrm (ir);
+ record_full_arch_list_add_reg (ir->regcache,
+ ir->regmap[X86_RECORD_XMM0_REGNUM]
+ + ir->reg + vex_r * 8);
+ break;
+ case 0x11: /* VMOVS[S|D] mem, XMM. */
+ /* VMOVUP[S|D] mem, XMM. */
+ case 0x29: /* VMOVAP[S|D] mem, XMM. */
+ /* Moving from memory region into an XMM register. */
+ /* This can also be used for XMM -> XMM in some scenarios. */
+ i386_record_modrm (ir);
+ if (ir->mod == 3)
+ {
+ /* In this case the destination register is encoded differently
+ to any other AVX instruction I've seen so far. In this one,
+ VEX.B is the most important bit of the destination. */
+ record_full_arch_list_add_reg (ir->regcache,
+ ir->regmap[X86_RECORD_XMM0_REGNUM]
+ + ir->rm + ir->rex_b * 8);
+ }
+ else
+ {
+ /* Opcode 0x29 is trivial, the size of memory written is defined by
+ VEX.L. Opcode 0x11 can refer to vmovs[s|d] or vmovup[s|d]; they
+ are differentiated by the most significant bit of VEX.pp, and the
+ latter works exactly like 0x29, but the former encodes the size
+ on VEX.pp itself. */
+ if (opcode == 0x11 && (ir->pp & 2) != 0)
+ ir->ot = ir->pp;
+ else
+ ir->ot = 4 + ir->l;
+ i386_record_lea_modrm (ir);
+ }
+ break;
+ case 0x14: /* VUNPCKL[PS|PD]. */
+ case 0x15: /* VUNPCKH [PS|PD]. */
+ i386_record_modrm (ir);
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum + ir->reg + vex_r * 8);
+ break;
+ case 0x6e: /* VMOVD XMM, reg/mem */
+ /* This is moving from a regular register or memory region into an
+ XMM register. */
+ i386_record_modrm (ir);
+ /* ModR/M only has the 3 least significant bits of the destination
+ register, the last one is indicated by VEX.R (stored inverted). */
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum
+ + ir->reg + vex_r * 8);
+ break;
+ case 0x7e: /* VMOV(D/Q) */
+ i386_record_modrm (ir);
+ /* Both the intel and AMD manual are wrong about this. According to
+ it, the only difference between vmovq and vmovd should be the rex_w
+ bit, but in empirical testing, it seems that they share this opcode,
+ and the way to differentiate it here is looking at VEX.PP. */
+ if (ir->pp == 2)
+ {
+ /* This is vmovq moving from a regular register or memory
+ into an XMM register. As above, VEX.R is the final bit for
+ destination register. */
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum
+ + ir->reg + vex_r * 8);
+ }
+ else if (ir->pp == 1)
+ {
+ /* This is the vmovd version that stores into a regular register
+ or memory region. */
+ /* If ModRM.mod is 11 we are saving into a register. */
+ if (ir->mod == 3)
+ record_full_arch_list_add_reg (ir->regcache, ir->regmap[ir->rm]);
+ else
+ {
+ /* Calculate the size of memory that will be modified
+ and store it in the form of 1 << ir->ot, since that
+ is how the function uses it. In theory, VEX.W is supposed
+ to indicate the size of the memory. In practice, I only
+ ever seen it set to 0, and for 16 bytes, 0xD6 opcode
+ is used. */
+ if (vex_w)
+ ir->ot = 4;
+ else
+ ir->ot = 3;
+
+ i386_record_lea_modrm (ir);
+ }
+ }
+ else
+ {
+ gdb_printf ("Unrecognized VEX.PP value %d at address %s.",
+ ir->pp, paddress(gdbarch, ir->orig_addr));
+ return -1;
+ }
+ break;
+ case 0xd6: /* VMOVQ reg/mem XMM */
+ i386_record_modrm (ir);
+ /* This is the vmovq version that stores into a regular register
+ or memory region. */
+ /* If ModRM.mod is 11 we are saving into a register. */
+ if (ir->mod == 3)
+ record_full_arch_list_add_reg (ir->regcache, ir->regmap[ir->rm]);
+ else
+ {
+ /* We know that this operation is always 64 bits. */
+ ir->ot = 4;
+ i386_record_lea_modrm (ir);
+ }
+ break;
+
+ case 0x6f: /* VMOVDQ (U|A) */
+ case 0x7f: /* VMOVDQ (U|A) */
+ /* vmovdq instructions have information about source/destination
+ spread over many places, so this code ended up messier than
+ I'd like. */
+ /* The VEX.pp bits identify if the move is aligned or not, but this
+ doesn't influence the recording so we can ignore it. */
+ i386_record_modrm (ir);
+ /* The first bit of modrm identifies if both operands of the instruction
+ are registers (bit = 1) or if one of the operands is memory. */
+ if (ir->mod & 2)
+ {
+ if (opcode == 0x6f)
+ {
+ /* vex_r will identify the high bit of the destination
+ register. Source is identified by ir->rex_b, but that
+ doesn't matter for recording. */
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum + 8*vex_r + ir->reg);
+ }
+ else
+ {
+ /* The origin operand is >7 and destination operand is <= 7.
+ This is special cased because in this one vex_r is used to
+ identify the high bit of the SOURCE operand, not destination
+ which would mess the previous expression. */
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum + ir->rm);
+ }
+ }
+ else
+ {
+ /* This is the easy branch. We just need to check the opcode
+ to see if the source or destination is memory. */
+ if (opcode == 0x6f)
+ {
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum
+ + ir->reg + vex_r * 8);
+ }
+ else
+ {
+ /* We're writing 256 bits, so 1<<8. */
+ ir->ot = 8;
+ i386_record_lea_modrm (ir);
+ }
+ }
+ break;
+
+ case 0x60: /* VPUNPCKLBW */
+ case 0x61: /* VPUNPCKLWD */
+ case 0x62: /* VPUNPCKLDQ */
+ case 0x6c: /* VPUNPCKLQDQ */
+ case 0x68: /* VPUNPCKHBW */
+ case 0x69: /* VPUNPCKHWD */
+ case 0x6a: /* VPUNPCKHDQ */
+ case 0x6d: /* VPUNPCKHQDQ */
+ {
+ i386_record_modrm (ir);
+ int reg_offset = ir->reg + vex_r * 8;
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum + reg_offset);
+ }
+ break;
+
+ case 0x74: /* VPCMPEQB */
+ case 0x75: /* VPCMPEQB */
+ case 0x76: /* VPCMPEQB */
+ {
+ i386_record_modrm (ir);
+ int reg_offset = ir->reg + vex_r * 8;
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum + reg_offset);
+ }
+ break;
+
+ case 0x78: /* VPBROADCASTB */
+ case 0x79: /* VPBROADCASTW */
+ case 0x58: /* VPBROADCASTD and VADD[P|S][S|D] */
+ case 0x59: /* VPBROADCASTQ and VMUL[P|S][S|D] */
+ case 0x5c: /* VSUB[P|S][S|D] */
+ case 0x5d: /* VMIN[P|S][S|D] */
+ case 0x5e: /* VDIV[P|S][S|D] */
+ case 0x5f: /* VMAX[P|S][S|D] */
+ {
+ /* vpbroadcast and arithmetic operations are differentiated
+ by map_select, but it doesn't change the recording mechanics. */
+ i386_record_modrm (ir);
+ int reg_offset = ir->reg + vex_r * 8;
+ gdb_assert (tdep->num_ymm_regs > reg_offset);
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum + reg_offset);
+ }
+ break;
+
+ case 0x77:/* VZEROUPPER */
+ {
+ int num_regs = tdep->num_ymm_regs;
+ /* This instruction only works on ymm0..15, even if 16..31 are
+ available. */
+ if (num_regs > 16)
+ num_regs = 16;
+ for (int i = 0; i < num_regs; i++)
+ {
+ /* We only need to record ymm_h, because the low bits
+ are not touched. */
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0h_regnum + i);
+ }
+ break;
+ }
+
+ case 0xd7: /* VPMOVMSKB */
+ {
+ i386_record_modrm (ir);
+ record_full_arch_list_add_reg (ir->regcache,
+ ir->regmap[X86_RECORD_REAX_REGNUM
+ + ir->reg + 8 * vex_r]);
+ }
+ break;
+
+ case 0xef: /* VPXOR */
+ case 0xeb: /* VPOR */
+ {
+ i386_record_modrm (ir);
+ int reg_offset = ir->reg + vex_r * 8;
+ record_full_arch_list_add_reg (ir->regcache,
+ tdep->ymm0_regnum + reg_offset);
+ break;
+ }
+
+ default:
+ gdb_printf (gdb_stderr,
+ _("Process record does not support VEX instruction 0x%02x "
+ "at address %s.\n"),
+ (unsigned int) (opcode),
+ paddress (gdbarch, ir->orig_addr));
+ return -1;
+ }
+
+ record_full_arch_list_add_reg (ir->regcache, ir->regmap[X86_RECORD_REIP_REGNUM]);
+ if (record_full_arch_list_add_end ())
+ return -1;
+
+ return 0;
+}
+
/* Parse the current instruction, and record the values of the
registers and memory that will be changed by the current
instruction. Returns -1 if something goes wrong, 0 otherwise. */
@@ -4997,6 +5099,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
uint8_t rex_w = -1;
uint8_t rex_r = 0;
+ bool vex_prefix = false;
memset (&ir, 0, sizeof (struct i386_record_s));
ir.regcache = regcache;
@@ -5082,6 +5185,53 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
else /* 32 bit target */
goto out_prefixes;
break;
+ case 0xc4: /* 3-byte VEX prefixes (for AVX/AVX2 instructions). */
+ {
+ /* The first byte just identifies the VEX prefix. Data is stored
+ on the following 2 bytes. */
+ uint8_t byte;
+ if (record_read_memory (gdbarch, ir.addr, &byte, 1))
+ return -1;
+ ir.addr++;
+
+ rex_r = !((byte >> 7) & 0x1);
+ ir.rex_x = !((byte >> 6) & 0x1);
+ ir.rex_b = !((byte >> 5) & 0x1);
+ ir.map_select = byte & 0x1f;
+ /* Collect the last byte of the prefix. */
+ if (record_read_memory (gdbarch, ir.addr, &byte, 1))
+ return -1;
+ ir.addr++;
+ rex_w = (byte >> 7) & 0x1;
+ ir.vvvv = (~(byte >> 3) & 0xf);
+ ir.l = (byte >> 2) & 0x1;
+ ir.pp = byte & 0x3;
+ vex_prefix = true;
+
+ break;
+ }
+ case 0xc5: /* 2-byte VEX prefix for AVX/AVX2 instructions. */
+ {
+ /* The first byte just identifies the VEX prefix. Data is stored
+ on the following 2 bytes. */
+ uint8_t byte;
+ if (record_read_memory (gdbarch, ir.addr, &byte, 1))
+ return -1;
+ ir.addr++;
+
+ /* On the 2-byte versions, these are pre-defined. */
+ ir.rex_x = 0;
+ ir.rex_b = 0;
+ rex_w = 0;
+ ir.map_select = 1;
+
+ rex_r = !((byte >> 7) & 0x1);
+ ir.vvvv = (~(byte >> 3) & 0xf);
+ ir.l = (byte >> 2) & 0x1;
+ ir.pp = byte & 0x3;
+ vex_prefix = true;
+ break;
+ }
default:
goto out_prefixes;
break;
@@ -5104,6 +5254,12 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
/* Now check op code. */
opcode = (uint32_t) opcode8;
+ if (vex_prefix)
+ {
+ /* If we found the VEX prefix, i386 will either record or warn that
+ the instruction isn't supported, so we can return the VEX result. */
+ return i386_record_vex (&ir, rex_w, rex_r, opcode, gdbarch);
+ }
reswitch:
switch (opcode)
{
@@ -8088,9 +8244,11 @@ static const int i386_record_regmap[] =
{
I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
- I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+ I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM,
+ /* xmm0_regnum */ 0
};
/* Check that the given address appears suitable for a fast
@@ -8187,7 +8345,7 @@ i386_xcr0_from_tdesc (const struct target_desc *tdesc)
const struct tdesc_feature *feature_core;
- const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx,
+ const struct tdesc_feature *feature_sse, *feature_avx,
*feature_avx512, *feature_pkeys;
/* Get core registers. */
@@ -8201,9 +8359,6 @@ i386_xcr0_from_tdesc (const struct target_desc *tdesc)
/* Try AVX registers. */
feature_avx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx");
- /* Try MPX registers. */
- feature_mpx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.mpx");
-
/* Try AVX512 registers. */
feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512");
@@ -8225,9 +8380,6 @@ i386_xcr0_from_tdesc (const struct target_desc *tdesc)
xcr0 |= X86_XSTATE_AVX;
}
- if (feature_mpx)
- xcr0 |= X86_XSTATE_MPX_MASK;
-
if (feature_avx512)
{
/* AVX512 register description requires AVX register description. */
@@ -8250,8 +8402,8 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep,
const struct target_desc *tdesc = tdep->tdesc;
const struct tdesc_feature *feature_core;
- const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx,
- *feature_avx512, *feature_pkeys, *feature_segments;
+ const struct tdesc_feature *feature_sse, *feature_avx, *feature_avx512,
+ *feature_pkeys, *feature_segments;
int i, num_regs, valid_p;
if (! tdesc_has_registers (tdesc))
@@ -8268,9 +8420,6 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep,
/* Try AVX registers. */
feature_avx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx");
- /* Try MPX registers. */
- feature_mpx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.mpx");
-
/* Try AVX512 registers. */
feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512");
@@ -8369,23 +8518,6 @@ i386_validate_tdesc_p (i386_gdbarch_tdep *tdep,
tdep->register_names[i]);
}
- if (feature_mpx)
- {
- tdep->xcr0 |= X86_XSTATE_MPX_MASK;
-
- if (tdep->bnd0r_regnum < 0)
- {
- tdep->mpx_register_names = i386_mpx_names;
- tdep->bnd0r_regnum = I386_BND0R_REGNUM;
- tdep->bndcfgu_regnum = I386_BNDCFGU_REGNUM;
- }
-
- for (i = 0; i < I387_NUM_MPX_REGS; i++)
- valid_p &= tdesc_numbered_register (feature_mpx, tdesc_data,
- I387_BND0R_REGNUM (tdep) + i,
- tdep->mpx_register_names[i]);
- }
-
if (feature_segments)
{
if (tdep->fsbase_regnum < 0)
@@ -8449,8 +8581,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
const struct target_desc *tdesc;
int mm0_regnum;
int ymm0_regnum;
- int bnd0_regnum;
- int num_bnd_cooked;
x86_xsave_layout xsave_layout = target_fetch_x86_xsave_layout ();
@@ -8499,7 +8629,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->st0_regnum = I386_ST0_REGNUM;
- /* I386_NUM_XREGS includes %mxcsr, so substract one. */
+ /* I386_NUM_XREGS includes %mxcsr, so subtract one. */
tdep->num_xmm_regs = I386_NUM_XREGS - 1;
tdep->jb_pc_offset = -1;
@@ -8656,7 +8786,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. */
+ gap for the upper AVX, (deprecated) MPX and AVX512 registers. */
set_gdbarch_num_regs (gdbarch, I386_NUM_REGS);
set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp);
@@ -8692,10 +8822,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->num_mmx_regs = 8;
tdep->num_ymm_regs = 0;
- /* No MPX registers. */
- tdep->bnd0r_regnum = -1;
- tdep->bndcfgu_regnum = -1;
-
/* No AVX512 registers. */
tdep->k0_regnum = -1;
tdep->num_zmm_regs = 0;
@@ -8732,8 +8858,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
}
tdep->xsave_layout = xsave_layout;
- num_bnd_cooked = (tdep->bnd0r_regnum > 0 ? I387_NUM_BND_REGS : 0);
-
/* Wire in pseudo registers. Number of pseudo registers may be
changed. */
set_gdbarch_num_pseudo_regs (gdbarch, (tdep->num_byte_regs
@@ -8741,7 +8865,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+ tdep->num_dword_regs
+ tdep->num_mmx_regs
+ tdep->num_ymm_regs
- + num_bnd_cooked
+ tdep->num_ymm_avx512_regs
+ tdep->num_zmm_regs));
@@ -8795,21 +8918,14 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
else
tdep->zmm0_regnum = -1;
- bnd0_regnum = mm0_regnum;
if (tdep->num_mmx_regs != 0)
{
/* Support MMX pseudo-register if MMX hasn't been disabled. */
tdep->mm0_regnum = mm0_regnum;
- bnd0_regnum += tdep->num_mmx_regs;
}
else
tdep->mm0_regnum = -1;
- if (tdep->bnd0r_regnum > 0)
- tdep->bnd0_regnum = bnd0_regnum;
- else
- tdep-> bnd0_regnum = -1;
-
/* Hook in the legacy prologue-based unwinders last (fallback). */
if (info.bfd_arch_info->bits_per_word == 32)
{
@@ -8839,12 +8955,11 @@ const struct target_desc *
i386_target_description (uint64_t xcr0, bool segments)
{
static target_desc *i386_tdescs \
- [2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {};
+ [2/*SSE*/][2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {};
target_desc **tdesc;
tdesc = &i386_tdescs[(xcr0 & X86_XSTATE_SSE) ? 1 : 0]
[(xcr0 & X86_XSTATE_AVX) ? 1 : 0]
- [(xcr0 & X86_XSTATE_MPX) ? 1 : 0]
[(xcr0 & X86_XSTATE_AVX512) ? 1 : 0]
[(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]
[segments ? 1 : 0];
@@ -8855,248 +8970,7 @@ i386_target_description (uint64_t xcr0, bool segments)
return *tdesc;
}
-#define MPX_BASE_MASK (~(ULONGEST) 0xfff)
-
-/* Find the bound directory base address. */
-
-static unsigned long
-i386_mpx_bd_base (void)
-{
- ULONGEST ret;
- enum register_status regstatus;
-
- regcache *rcache = get_thread_regcache (inferior_thread ());
- gdbarch *arch = rcache->arch ();
- i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch);
-
- regstatus = regcache_raw_read_unsigned (rcache, tdep->bndcfgu_regnum, &ret);
-
- if (regstatus != REG_VALID)
- error (_("BNDCFGU register invalid, read status %d."), regstatus);
-
- return ret & MPX_BASE_MASK;
-}
-
-int
-i386_mpx_enabled (void)
-{
- gdbarch *arch = get_current_arch ();
- i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch);
- const struct target_desc *tdesc = tdep->tdesc;
-
- return (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.mpx") != NULL);
-}
-
-#define MPX_BD_MASK 0xfffffff00000ULL /* select bits [47:20] */
-#define MPX_BT_MASK 0x0000000ffff8 /* select bits [19:3] */
-#define MPX_BD_MASK_32 0xfffff000 /* select bits [31:12] */
-#define MPX_BT_MASK_32 0x00000ffc /* select bits [11:2] */
-
-/* Find the bound table entry given the pointer location and the base
- address of the table. */
-
-static CORE_ADDR
-i386_mpx_get_bt_entry (CORE_ADDR ptr, CORE_ADDR bd_base)
-{
- CORE_ADDR offset1;
- CORE_ADDR offset2;
- CORE_ADDR mpx_bd_mask, bd_ptr_r_shift, bd_ptr_l_shift;
- CORE_ADDR bt_mask, bt_select_r_shift, bt_select_l_shift;
- CORE_ADDR bd_entry_addr;
- CORE_ADDR bt_addr;
- CORE_ADDR bd_entry;
- struct gdbarch *gdbarch = get_current_arch ();
- struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-
-
- if (gdbarch_ptr_bit (gdbarch) == 64)
- {
- mpx_bd_mask = (CORE_ADDR) MPX_BD_MASK;
- bd_ptr_r_shift = 20;
- bd_ptr_l_shift = 3;
- bt_select_r_shift = 3;
- bt_select_l_shift = 5;
- bt_mask = (CORE_ADDR) MPX_BT_MASK;
-
- if ( sizeof (CORE_ADDR) == 4)
- error (_("bound table examination not supported\
- for 64-bit process with 32-bit GDB"));
- }
- else
- {
- mpx_bd_mask = MPX_BD_MASK_32;
- bd_ptr_r_shift = 12;
- bd_ptr_l_shift = 2;
- bt_select_r_shift = 2;
- bt_select_l_shift = 4;
- bt_mask = MPX_BT_MASK_32;
- }
-
- offset1 = ((ptr & mpx_bd_mask) >> bd_ptr_r_shift) << bd_ptr_l_shift;
- bd_entry_addr = bd_base + offset1;
- bd_entry = read_memory_typed_address (bd_entry_addr, data_ptr_type);
-
- if ((bd_entry & 0x1) == 0)
- error (_("Invalid bounds directory entry at %s."),
- paddress (get_current_arch (), bd_entry_addr));
-
- /* Clearing status bit. */
- bd_entry--;
- bt_addr = bd_entry & ~bt_select_r_shift;
- offset2 = ((ptr & bt_mask) >> bt_select_r_shift) << bt_select_l_shift;
-
- return bt_addr + offset2;
-}
-
-/* Print routine for the mpx bounds. */
-
-static void
-i386_mpx_print_bounds (const CORE_ADDR bt_entry[4])
-{
- struct ui_out *uiout = current_uiout;
- LONGEST size;
- struct gdbarch *gdbarch = get_current_arch ();
- CORE_ADDR onecompl = ~((CORE_ADDR) 0);
- int bounds_in_map = ((~bt_entry[1] == 0 && bt_entry[0] == onecompl) ? 1 : 0);
-
- if (bounds_in_map == 1)
- {
- uiout->text ("Null bounds on map:");
- uiout->text (" pointer value = ");
- uiout->field_core_addr ("pointer-value", gdbarch, bt_entry[2]);
- uiout->text (".");
- uiout->text ("\n");
- }
- else
- {
- uiout->text ("{lbound = ");
- uiout->field_core_addr ("lower-bound", gdbarch, bt_entry[0]);
- uiout->text (", ubound = ");
-
- /* The upper bound is stored in 1's complement. */
- uiout->field_core_addr ("upper-bound", gdbarch, ~bt_entry[1]);
- uiout->text ("}: pointer value = ");
- uiout->field_core_addr ("pointer-value", gdbarch, bt_entry[2]);
-
- if (gdbarch_ptr_bit (gdbarch) == 64)
- size = ( (~(int64_t) bt_entry[1]) - (int64_t) bt_entry[0]);
- else
- size = ( ~((int32_t) bt_entry[1]) - (int32_t) bt_entry[0]);
-
- /* In case the bounds are 0x0 and 0xffff... the difference will be -1.
- -1 represents in this sense full memory access, and there is no need
- one to the size. */
-
- size = (size > -1 ? size + 1 : size);
- uiout->text (", size = ");
- uiout->field_string ("size", plongest (size));
-
- uiout->text (", metadata = ");
- uiout->field_core_addr ("metadata", gdbarch, bt_entry[3]);
- uiout->text ("\n");
- }
-}
-
-/* Implement the command "show mpx bound". */
-
-static void
-i386_mpx_info_bounds (const char *args, int from_tty)
-{
- CORE_ADDR bd_base = 0;
- CORE_ADDR addr;
- CORE_ADDR bt_entry_addr = 0;
- CORE_ADDR bt_entry[4];
- int i;
- struct gdbarch *gdbarch = get_current_arch ();
- struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-
- if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_i386
- || !i386_mpx_enabled ())
- {
- gdb_printf (_("Intel Memory Protection Extensions not "
- "supported on this target.\n"));
- return;
- }
-
- if (args == NULL)
- {
- gdb_printf (_("Address of pointer variable expected.\n"));
- return;
- }
-
- addr = parse_and_eval_address (args);
-
- bd_base = i386_mpx_bd_base ();
- bt_entry_addr = i386_mpx_get_bt_entry (addr, bd_base);
-
- memset (bt_entry, 0, sizeof (bt_entry));
-
- for (i = 0; i < 4; i++)
- bt_entry[i] = read_memory_typed_address (bt_entry_addr
- + i * data_ptr_type->length (),
- data_ptr_type);
-
- i386_mpx_print_bounds (bt_entry);
-}
-
-/* Implement the command "set mpx bound". */
-
-static void
-i386_mpx_set_bounds (const char *args, int from_tty)
-{
- CORE_ADDR bd_base = 0;
- CORE_ADDR addr, lower, upper;
- CORE_ADDR bt_entry_addr = 0;
- CORE_ADDR bt_entry[2];
- const char *input = args;
- int i;
- struct gdbarch *gdbarch = get_current_arch ();
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-
- if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_i386
- || !i386_mpx_enabled ())
- error (_("Intel Memory Protection Extensions not supported\
- on this target."));
-
- if (args == NULL)
- error (_("Pointer value expected."));
-
- addr = value_as_address (parse_to_comma_and_eval (&input));
-
- if (input[0] == ',')
- ++input;
- if (input[0] == '\0')
- error (_("wrong number of arguments: missing lower and upper bound."));
- lower = value_as_address (parse_to_comma_and_eval (&input));
-
- if (input[0] == ',')
- ++input;
- if (input[0] == '\0')
- error (_("Wrong number of arguments; Missing upper bound."));
- upper = value_as_address (parse_to_comma_and_eval (&input));
-
- bd_base = i386_mpx_bd_base ();
- bt_entry_addr = i386_mpx_get_bt_entry (addr, bd_base);
- for (i = 0; i < 2; i++)
- bt_entry[i] = read_memory_typed_address (bt_entry_addr
- + i * data_ptr_type->length (),
- data_ptr_type);
- bt_entry[0] = (uint64_t) lower;
- bt_entry[1] = ~(uint64_t) upper;
-
- for (i = 0; i < 2; i++)
- write_memory_unsigned_integer (bt_entry_addr
- + i * data_ptr_type->length (),
- data_ptr_type->length (), byte_order,
- bt_entry[i]);
-}
-
-static struct cmd_list_element *mpx_set_cmdlist, *mpx_show_cmdlist;
-
-void _initialize_i386_tdep ();
-void
-_initialize_i386_tdep ()
+INIT_GDB_FILE (i386_tdep)
{
gdbarch_register (bfd_arch_i386, i386_gdbarch_init);
@@ -9122,30 +8996,6 @@ is \"default\"."),
NULL, /* FIXME: i18n: */
&setlist, &showlist);
- /* Add "mpx" prefix for the set and show commands. */
-
- add_setshow_prefix_cmd
- ("mpx", class_support,
- _("Set Intel Memory Protection Extensions specific variables."),
- _("Show Intel Memory Protection Extensions specific variables."),
- &mpx_set_cmdlist, &mpx_show_cmdlist, &setlist, &showlist);
-
- /* Add "bound" command for the show mpx commands list. */
-
- cmd_list_element *c = add_cmd ("bound", no_class, i386_mpx_info_bounds,
- "Show the memory bounds for a given array/pointer storage\
- in the bound table.",
- &mpx_show_cmdlist);
- deprecate_cmd (c, nullptr);
-
- /* Add "bound" command for the set mpx commands list. */
-
- c = add_cmd ("bound", no_class, i386_mpx_set_bounds,
- "Set the memory bounds for a given array/pointer storage\
- in the bound table.",
- &mpx_set_cmdlist);
- deprecate_cmd (c, nullptr);
-
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SVR4,
i386_svr4_init_abi);