+/* 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 ())
+ {
+ printf_unfiltered (_("Intel Memory Protection Extensions not "
+ "supported on this target.\n"));
+ return;
+ }
+
+ if (args == NULL)
+ {
+ printf_unfiltered (_("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 * TYPE_LENGTH (data_ptr_type),
+ 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 * TYPE_LENGTH (data_ptr_type),
+ 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 * TYPE_LENGTH (data_ptr_type),
+ TYPE_LENGTH (data_ptr_type), byte_order,
+ bt_entry[i]);
+}
+
+static struct cmd_list_element *mpx_set_cmdlist, *mpx_show_cmdlist;
+
+/* Helper function for the CLI commands. */
+
+static void
+set_mpx_cmd (const char *args, int from_tty)
+{
+ help_list (mpx_set_cmdlist, "set mpx ", all_commands, gdb_stdout);
+}
+
+/* Helper function for the CLI commands. */
+
+static void
+show_mpx_cmd (const char *args, int from_tty)
+{
+ cmd_show_list (mpx_show_cmdlist, from_tty, "");
+}