tfile_target::close: trace_fd can't be -1
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index 9ed24cff663323d270f632d8cef696a5cad6c9d2..a19fc62e8d4ac3801c653bf810876184e2ca9a2d 100644 (file)
@@ -1,6 +1,6 @@
 /* Intel 386 target-dependent stuff.
 
 /* Intel 386 target-dependent stuff.
 
-   Copyright (C) 1988-2016 Free Software Foundation, Inc.
+   Copyright (C) 1988-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
@@ -23,7 +23,6 @@
 #include "command.h"
 #include "dummy-frame.h"
 #include "dwarf2-frame.h"
 #include "command.h"
 #include "dummy-frame.h"
 #include "dwarf2-frame.h"
-#include "doublest.h"
 #include "frame.h"
 #include "frame-base.h"
 #include "frame-unwind.h"
 #include "frame.h"
 #include "frame-base.h"
 #include "frame-unwind.h"
 #include "symfile.h"
 #include "symtab.h"
 #include "target.h"
 #include "symfile.h"
 #include "symtab.h"
 #include "target.h"
+#include "target-float.h"
 #include "value.h"
 #include "dis-asm.h"
 #include "disasm.h"
 #include "remote.h"
 #include "i386-tdep.h"
 #include "i387-tdep.h"
 #include "value.h"
 #include "dis-asm.h"
 #include "disasm.h"
 #include "remote.h"
 #include "i386-tdep.h"
 #include "i387-tdep.h"
-#include "x86-xstate.h"
+#include "gdbsupport/x86-xstate.h"
+#include "x86-tdep.h"
 
 #include "record.h"
 #include "record-full.h"
 
 #include "record.h"
 #include "record-full.h"
-#include "features/i386/i386.c"
-#include "features/i386/i386-avx.c"
-#include "features/i386/i386-mpx.c"
-#include "features/i386/i386-avx-mpx.c"
-#include "features/i386/i386-avx512.c"
-#include "features/i386/i386-mmx.c"
+#include "target-descriptions.h"
+#include "arch/i386.h"
 
 #include "ax.h"
 #include "ax-gdb.h"
 
 #include "ax.h"
 #include "ax-gdb.h"
@@ -66,6 +63,8 @@
 #include "expression.h"
 #include "parser-defs.h"
 #include <ctype.h>
 #include "expression.h"
 #include "parser-defs.h"
 #include <ctype.h>
+#include <algorithm>
+#include <unordered_set>
 
 /* Register names.  */
 
 
 /* Register names.  */
 
@@ -119,6 +118,11 @@ static const char *i386_mpx_names[] =
   "bnd0raw", "bnd1raw", "bnd2raw", "bnd3raw", "bndcfgu", "bndstatus"
 };
 
   "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[] =
 /* Register names for MPX pseudo-registers.  */
 
 static const char *i386_bnd_names[] =
@@ -413,6 +417,21 @@ i386_mpx_ctrl_regnum_p (struct gdbarch *gdbarch, int regnum)
   return regnum >= 0 && regnum < I387_NUM_MPX_CTRL_REGS;
 }
 
   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.  */
 
 /* Return the name of register REGNUM, or the empty string if it is
    an anonymous register.  */
 
@@ -500,7 +519,7 @@ i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg)
     }
 
   /* This will hopefully provoke a warning.  */
     }
 
   /* This will hopefully provoke a warning.  */
-  return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
+  return gdbarch_num_cooked_regs (gdbarch);
 }
 
 /* Convert SVR4 DWARF register number REG to the appropriate register number
 }
 
 /* Convert SVR4 DWARF register number REG to the appropriate register number
@@ -551,13 +570,13 @@ i386_svr4_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 /* Wrapper on i386_svr4_dwarf_reg_to_regnum to return
    num_regs + num_pseudo_regs for other debug formats.  */
 
 /* Wrapper on i386_svr4_dwarf_reg_to_regnum to return
    num_regs + num_pseudo_regs for other debug formats.  */
 
-static int
+int
 i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
   int regnum = i386_svr4_dwarf_reg_to_regnum (gdbarch, reg);
 
   if (regnum == -1)
 i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
   int regnum = i386_svr4_dwarf_reg_to_regnum (gdbarch, reg);
 
   if (regnum == -1)
-    return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
+    return gdbarch_num_cooked_regs (gdbarch);
   return regnum;
 }
 
   return regnum;
 }
 
@@ -587,14 +606,10 @@ static const char *disassembly_flavor = att_flavor;
 
    This function is 64-bit safe.  */
 
 
    This function is 64-bit safe.  */
 
-static const gdb_byte *
-i386_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len)
-{
-  static gdb_byte break_insn[] = { 0xcc }; /* int 3 */
+constexpr gdb_byte i386_break_insn[] = { 0xcc }; /* int 3 */
+
+typedef BP_MANIPULATION (i386_break_insn) i386_breakpoint;
 
 
-  *len = sizeof (break_insn);
-  return break_insn;
-}
 \f
 /* Displaced instruction handling.  */
 
 \f
 /* Displaced instruction handling.  */
 
@@ -781,8 +796,7 @@ i386_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr)
   return i386_jmp_p (insn);
 }
 
   return i386_jmp_p (insn);
 }
 
-/* Some kernels may run one past a syscall insn, so we have to cope.
-   Otherwise this is just simple_displaced_step_copy_insn.  */
+/* Some kernels may run one past a syscall insn, so we have to cope.  */
 
 struct displaced_step_closure *
 i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
 
 struct displaced_step_closure *
 i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
@@ -790,7 +804,8 @@ i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
                               struct regcache *regs)
 {
   size_t len = gdbarch_max_insn_length (gdbarch);
                               struct regcache *regs)
 {
   size_t len = gdbarch_max_insn_length (gdbarch);
-  gdb_byte *buf = (gdb_byte *) xmalloc (len);
+  i386_displaced_step_closure *closure = new i386_displaced_step_closure (len);
+  gdb_byte *buf = closure->buf.data ();
 
   read_memory (from, buf, len);
 
 
   read_memory (from, buf, len);
 
@@ -815,7 +830,7 @@ i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
       displaced_step_dump_bytes (gdb_stdlog, buf, len);
     }
 
       displaced_step_dump_bytes (gdb_stdlog, buf, len);
     }
 
-  return (struct displaced_step_closure *) buf;
+  return closure;
 }
 
 /* Fix up the state of registers and memory after having single-stepped
 }
 
 /* Fix up the state of registers and memory after having single-stepped
@@ -823,7 +838,7 @@ i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
 
 void
 i386_displaced_step_fixup (struct gdbarch *gdbarch,
 
 void
 i386_displaced_step_fixup (struct gdbarch *gdbarch,
-                           struct displaced_step_closure *closure,
+                           struct displaced_step_closure *closure_,
                            CORE_ADDR from, CORE_ADDR to,
                            struct regcache *regs)
 {
                            CORE_ADDR from, CORE_ADDR to,
                            struct regcache *regs)
 {
@@ -835,9 +850,9 @@ i386_displaced_step_fixup (struct gdbarch *gdbarch,
      applying it.  */
   ULONGEST insn_offset = to - from;
 
      applying it.  */
   ULONGEST insn_offset = to - from;
 
-  /* Since we use simple_displaced_step_copy_insn, our closure is a
-     copy of the instruction.  */
-  gdb_byte *insn = (gdb_byte *) closure;
+  i386_displaced_step_closure *closure
+    = (i386_displaced_step_closure *) closure_;
+  gdb_byte *insn = closure->buf.data ();
   /* The start of the insn, needed in case we see some prefixes.  */
   gdb_byte *insn_start = insn;
 
   /* The start of the insn, needed in case we see some prefixes.  */
   gdb_byte *insn_start = insn;
 
@@ -1365,7 +1380,7 @@ i386_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
   if (current_pc > pc + offset_and)
     cache->saved_sp_reg = regnums[reg];
 
   if (current_pc > pc + offset_and)
     cache->saved_sp_reg = regnums[reg];
 
-  return min (pc + offset + 3, current_pc);
+  return std::min (pc + offset + 3, current_pc);
 }
 
 /* Maximum instruction length we need to handle.  */
 }
 
 /* Maximum instruction length we need to handle.  */
@@ -1490,7 +1505,7 @@ struct i386_insn i386_frame_setup_skip_insns[] =
   /* Check for `mov imm32, r32'.  Note that there is an alternative
      encoding for `mov m32, %eax'.
 
   /* Check for `mov imm32, r32'.  Note that there is an alternative
      encoding for `mov m32, %eax'.
 
-     ??? Should we handle SIB adressing here?
+     ??? Should we handle SIB addressing here?
      ??? Should we handle 16-bit operand-sizes here?  */
 
   /* `movl m32, %eax' */
      ??? Should we handle 16-bit operand-sizes here?  */
 
   /* `movl m32, %eax' */
@@ -1607,7 +1622,7 @@ i386_analyze_frame_setup (struct gdbarch *gdbarch,
       /* Check for some special instructions that might be migrated by
         GCC into the prologue and skip them.  At this point in the
         prologue, code should only touch the scratch registers %eax,
       /* Check for some special instructions that might be migrated by
         GCC into the prologue and skip them.  At this point in the
         prologue, code should only touch the scratch registers %eax,
-        %ecx and %edx, so while the number of posibilities is sheer,
+        %ecx and %edx, so while the number of possibilities is sheer,
         it is limited.
 
         Make sure we only skip these instructions if we later see the
         it is limited.
 
         Make sure we only skip these instructions if we later see the
@@ -1836,7 +1851,7 @@ i386_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
          && (cust != NULL
              && COMPUNIT_PRODUCER (cust) != NULL
              && startswith (COMPUNIT_PRODUCER (cust), "clang ")))
          && (cust != NULL
              && COMPUNIT_PRODUCER (cust) != NULL
              && startswith (COMPUNIT_PRODUCER (cust), "clang ")))
-        return max (start_pc, post_prologue_pc);
+        return std::max (start_pc, post_prologue_pc);
     }
  
   cache.locals = -1;
     }
  
   cache.locals = -1;
@@ -1933,8 +1948,8 @@ i386_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
          call_dest = call_dest & 0xffffffffU;
          s = lookup_minimal_symbol_by_pc (call_dest);
          if (s.minsym != NULL
          call_dest = call_dest & 0xffffffffU;
          s = lookup_minimal_symbol_by_pc (call_dest);
          if (s.minsym != NULL
-             && MSYMBOL_LINKAGE_NAME (s.minsym) != NULL
-             && strcmp (MSYMBOL_LINKAGE_NAME (s.minsym), "__main") == 0)
+             && s.minsym->linkage_name () != NULL
+             && strcmp (s.minsym->linkage_name (), "__main") == 0)
            pc += 5;
        }
     }
            pc += 5;
        }
     }
@@ -2068,16 +2083,15 @@ i386_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache = i386_alloc_frame_cache ();
   *this_cache = cache;
 
   cache = i386_alloc_frame_cache ();
   *this_cache = cache;
 
-  TRY
+  try
     {
       i386_frame_cache_1 (this_frame, cache);
     }
     {
       i386_frame_cache_1 (this_frame, cache);
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
     }
-  END_CATCH
 
   return cache;
 }
 
   return cache;
 }
@@ -2238,7 +2252,7 @@ i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache = i386_alloc_frame_cache ();
   *this_cache = cache;
 
   cache = i386_alloc_frame_cache ();
   *this_cache = cache;
 
-  TRY
+  try
     {
       cache->pc = get_frame_func (this_frame);
 
     {
       cache->pc = get_frame_func (this_frame);
 
@@ -2252,12 +2266,11 @@ i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
 
       cache->base_p = 1;
     }
 
       cache->base_p = 1;
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
     }
-  END_CATCH
 
   return cache;
 }
 
   return cache;
 }
@@ -2424,7 +2437,7 @@ i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 
   cache = i386_alloc_frame_cache ();
 
 
   cache = i386_alloc_frame_cache ();
 
-  TRY
+  try
     {
       get_frame_register (this_frame, I386_ESP_REGNUM, buf);
       cache->base = extract_unsigned_integer (buf, 4, byte_order) - 4;
     {
       get_frame_register (this_frame, I386_ESP_REGNUM, buf);
       cache->base = extract_unsigned_integer (buf, 4, byte_order) - 4;
@@ -2448,12 +2461,11 @@ i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 
       cache->base_p = 1;
     }
 
       cache->base_p = 1;
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
     }
-  END_CATCH
 
   *this_cache = cache;
   return cache;
 
   *this_cache = cache;
   return cache;
@@ -2657,7 +2669,8 @@ i386_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr,
 static CORE_ADDR
 i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
 static CORE_ADDR
 i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
-                     struct value **args, CORE_ADDR sp, int struct_return,
+                     struct value **args, CORE_ADDR sp,
+                     function_call_return_method return_method,
                      CORE_ADDR struct_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
                      CORE_ADDR struct_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -2666,6 +2679,13 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int write_pass;
   int args_space = 0;
 
   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.  */
   /* 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.  */
@@ -2674,7 +2694,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
     {
       int args_space_used = 0;
 
     {
       int args_space_used = 0;
 
-      if (struct_return)
+      if (return_method == return_method_struct)
        {
          if (write_pass)
            {
        {
          if (write_pass)
            {
@@ -2734,10 +2754,10 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* Finally, update the stack pointer...  */
   store_unsigned_integer (buf, 4, byte_order, sp);
 
   /* Finally, update the stack pointer...  */
   store_unsigned_integer (buf, 4, byte_order, sp);
-  regcache_cooked_write (regcache, I386_ESP_REGNUM, buf);
+  regcache->cooked_write (I386_ESP_REGNUM, buf);
 
   /* ...and fake a frame pointer.  */
 
   /* ...and fake a frame pointer.  */
-  regcache_cooked_write (regcache, I386_EBP_REGNUM, buf);
+  regcache->cooked_write (I386_EBP_REGNUM, buf);
 
   /* MarkK wrote: This "+ 8" is all over the place:
      (i386_frame_this_id, i386_sigtramp_frame_this_id,
 
   /* MarkK wrote: This "+ 8" is all over the place:
      (i386_frame_this_id, i386_sigtramp_frame_this_id,
@@ -2781,8 +2801,8 @@ i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
         its contents to the desired type.  This is probably not
         exactly how it would happen on the target itself, but it is
         the best we can do.  */
         its contents to the desired type.  This is probably not
         exactly how it would happen on the target itself, but it is
         the best we can do.  */
-      regcache_raw_read (regcache, I386_ST0_REGNUM, buf);
-      convert_typed_floating (buf, i387_ext_type (gdbarch), valbuf, type);
+      regcache->raw_read (I386_ST0_REGNUM, buf);
+      target_float_convert (buf, i387_ext_type (gdbarch), valbuf, type);
     }
   else
     {
     }
   else
     {
@@ -2791,14 +2811,14 @@ i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
 
       if (len <= low_size)
        {
 
       if (len <= low_size)
        {
-         regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf);
+         regcache->raw_read (LOW_RETURN_REGNUM, buf);
          memcpy (valbuf, buf, len);
        }
       else if (len <= (low_size + high_size))
        {
          memcpy (valbuf, buf, len);
        }
       else if (len <= (low_size + high_size))
        {
-         regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf);
+         regcache->raw_read (LOW_RETURN_REGNUM, buf);
          memcpy (valbuf, buf, low_size);
          memcpy (valbuf, buf, low_size);
-         regcache_raw_read (regcache, HIGH_RETURN_REGNUM, buf);
+         regcache->raw_read (HIGH_RETURN_REGNUM, buf);
          memcpy (valbuf + low_size, buf, len - low_size);
        }
       else
          memcpy (valbuf + low_size, buf, len - low_size);
        }
       else
@@ -2837,8 +2857,8 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
         floating-point format used by the FPU.  This is probably
         not exactly how it would happen on the target itself, but
         it is the best we can do.  */
         floating-point format used by the FPU.  This is probably
         not exactly how it would happen on the target itself, but
         it is the best we can do.  */
-      convert_typed_floating (valbuf, type, buf, i387_ext_type (gdbarch));
-      regcache_raw_write (regcache, I386_ST0_REGNUM, buf);
+      target_float_convert (valbuf, type, buf, i387_ext_type (gdbarch));
+      regcache->raw_write (I386_ST0_REGNUM, buf);
 
       /* Set the top of the floating-point register stack to 7.  The
          actual value doesn't really matter, but 7 is what a normal
 
       /* Set the top of the floating-point register stack to 7.  The
          actual value doesn't really matter, but 7 is what a normal
@@ -2859,12 +2879,12 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
       int high_size = register_size (gdbarch, HIGH_RETURN_REGNUM);
 
       if (len <= low_size)
       int high_size = register_size (gdbarch, HIGH_RETURN_REGNUM);
 
       if (len <= low_size)
-       regcache_raw_write_part (regcache, LOW_RETURN_REGNUM, 0, len, valbuf);
+       regcache->raw_write_part (LOW_RETURN_REGNUM, 0, len, valbuf);
       else if (len <= (low_size + high_size))
        {
       else if (len <= (low_size + high_size))
        {
-         regcache_raw_write (regcache, LOW_RETURN_REGNUM, valbuf);
-         regcache_raw_write_part (regcache, HIGH_RETURN_REGNUM, 0,
-                                  len - low_size, valbuf + low_size);
+         regcache->raw_write (LOW_RETURN_REGNUM, valbuf);
+         regcache->raw_write_part (HIGH_RETURN_REGNUM, 0, len - low_size,
+                                   valbuf + low_size);
        }
       else
        internal_error (__FILE__, __LINE__,
        }
       else
        internal_error (__FILE__, __LINE__,
@@ -2936,7 +2956,7 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
        || code == TYPE_CODE_UNION
        || code == TYPE_CODE_ARRAY)
        && !i386_reg_struct_return_p (gdbarch, type))
        || code == TYPE_CODE_UNION
        || code == TYPE_CODE_ARRAY)
        && !i386_reg_struct_return_p (gdbarch, type))
-      /* Complex double and long double uses the struct return covention.  */
+      /* Complex double and long double uses the struct return convention.  */
       || (code == TYPE_CODE_COMPLEX && TYPE_LENGTH (type) == 16)
       || (code == TYPE_CODE_COMPLEX && TYPE_LENGTH (type) == 24)
       /* 128-bit decimal float uses the struct return convention.  */
       || (code == TYPE_CODE_COMPLEX && TYPE_LENGTH (type) == 16)
       || (code == TYPE_CODE_COMPLEX && TYPE_LENGTH (type) == 24)
       /* 128-bit decimal float uses the struct return convention.  */
@@ -3228,15 +3248,15 @@ i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
    the MMX registers need to be mapped onto floating point registers.  */
 
 static int
    the MMX registers need to be mapped onto floating point registers.  */
 
 static int
-i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
+i386_mmx_regnum_to_fp_regnum (readable_regcache *regcache, int regnum)
 {
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
   int mmxreg, fpreg;
   ULONGEST fstat;
   int tos;
 
   mmxreg = regnum - tdep->mm0_regnum;
   int mmxreg, fpreg;
   ULONGEST fstat;
   int tos;
 
   mmxreg = regnum - tdep->mm0_regnum;
-  regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
+  regcache->raw_read (I387_FSTAT_REGNUM (tdep), &fstat);
   tos = (fstat >> 11) & 0x7;
   fpreg = (mmxreg + tos) % 8;
 
   tos = (fstat >> 11) & 0x7;
   fpreg = (mmxreg + tos) % 8;
 
@@ -3249,11 +3269,11 @@ i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
 
 void
 i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 
 void
 i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
-                                     struct regcache *regcache,
+                                     readable_regcache *regcache,
                                      int regnum,
                                      struct value *result_value)
 {
                                      int regnum,
                                      struct value *result_value)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
   enum register_status status;
   gdb_byte *buf = value_contents_raw (result_value);
 
   enum register_status status;
   gdb_byte *buf = value_contents_raw (result_value);
 
@@ -3262,7 +3282,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Extract (always little endian).  */
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Extract (always little endian).  */
-      status = regcache_raw_read (regcache, fpnum, raw_buf);
+      status = regcache->raw_read (fpnum, raw_buf);
       if (status != REG_VALID)
        mark_value_bytes_unavailable (result_value, 0,
                                      TYPE_LENGTH (value_type (result_value)));
       if (status != REG_VALID)
        mark_value_bytes_unavailable (result_value, 0,
                                      TYPE_LENGTH (value_type (result_value)));
@@ -3277,9 +3297,8 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          regnum -= tdep->bnd0_regnum;
 
          /* Extract (always little endian).  Read lower 128bits.  */
          regnum -= tdep->bnd0_regnum;
 
          /* Extract (always little endian).  Read lower 128bits.  */
-         status = regcache_raw_read (regcache,
-                                     I387_BND0R_REGNUM (tdep) + regnum,
-                                     raw_buf);
+         status = regcache->raw_read (I387_BND0R_REGNUM (tdep) + regnum,
+                                      raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0, 16);
          else
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0, 16);
          else
@@ -3301,9 +3320,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          regnum -= tdep->k0_regnum;
 
          /* Extract (always little endian).  */
          regnum -= tdep->k0_regnum;
 
          /* Extract (always little endian).  */
-         status = regcache_raw_read (regcache,
-                                     tdep->k0_regnum + regnum,
-                                     raw_buf);
+         status = regcache->raw_read (tdep->k0_regnum + regnum, raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0, 8);
          else
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0, 8);
          else
@@ -3316,18 +3333,16 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          if (regnum < num_lower_zmm_regs)
            {
              /* Extract (always little endian).  Read lower 128bits.  */
          if (regnum < num_lower_zmm_regs)
            {
              /* Extract (always little endian).  Read lower 128bits.  */
-             status = regcache_raw_read (regcache,
-                                         I387_XMM0_REGNUM (tdep) + regnum,
-                                         raw_buf);
+             status = regcache->raw_read (I387_XMM0_REGNUM (tdep) + regnum,
+                                          raw_buf);
              if (status != REG_VALID)
                mark_value_bytes_unavailable (result_value, 0, 16);
              else
                memcpy (buf, raw_buf, 16);
 
              /* Extract (always little endian).  Read upper 128bits.  */
              if (status != REG_VALID)
                mark_value_bytes_unavailable (result_value, 0, 16);
              else
                memcpy (buf, raw_buf, 16);
 
              /* Extract (always little endian).  Read upper 128bits.  */
-             status = regcache_raw_read (regcache,
-                                         tdep->ymm0h_regnum + regnum,
-                                         raw_buf);
+             status = regcache->raw_read (tdep->ymm0h_regnum + regnum,
+                                          raw_buf);
              if (status != REG_VALID)
                mark_value_bytes_unavailable (result_value, 16, 16);
              else
              if (status != REG_VALID)
                mark_value_bytes_unavailable (result_value, 16, 16);
              else
@@ -3336,20 +3351,18 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          else
            {
              /* Extract (always little endian).  Read lower 128bits.  */
          else
            {
              /* Extract (always little endian).  Read lower 128bits.  */
-             status = regcache_raw_read (regcache,
-                                         I387_XMM16_REGNUM (tdep) + regnum
-                                         - num_lower_zmm_regs,
-                                         raw_buf);
+             status = regcache->raw_read (I387_XMM16_REGNUM (tdep) + regnum
+                                          - num_lower_zmm_regs,
+                                          raw_buf);
              if (status != REG_VALID)
                mark_value_bytes_unavailable (result_value, 0, 16);
              else
                memcpy (buf, raw_buf, 16);
 
              /* Extract (always little endian).  Read upper 128bits.  */
              if (status != REG_VALID)
                mark_value_bytes_unavailable (result_value, 0, 16);
              else
                memcpy (buf, raw_buf, 16);
 
              /* Extract (always little endian).  Read upper 128bits.  */
-             status = regcache_raw_read (regcache,
-                                         I387_YMM16H_REGNUM (tdep) + regnum
-                                         - num_lower_zmm_regs,
-                                         raw_buf);
+             status = regcache->raw_read (I387_YMM16H_REGNUM (tdep) + regnum
+                                          - num_lower_zmm_regs,
+                                          raw_buf);
              if (status != REG_VALID)
                mark_value_bytes_unavailable (result_value, 16, 16);
              else
              if (status != REG_VALID)
                mark_value_bytes_unavailable (result_value, 16, 16);
              else
@@ -3357,9 +3370,8 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
            }
 
          /* Read upper 256bits.  */
            }
 
          /* Read upper 256bits.  */
-         status = regcache_raw_read (regcache,
-                                     tdep->zmm0h_regnum + regnum,
-                                     raw_buf);
+         status = regcache->raw_read (tdep->zmm0h_regnum + regnum,
+                                      raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 32, 32);
          else
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 32, 32);
          else
@@ -3370,17 +3382,15 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          regnum -= tdep->ymm0_regnum;
 
          /* Extract (always little endian).  Read lower 128bits.  */
          regnum -= tdep->ymm0_regnum;
 
          /* Extract (always little endian).  Read lower 128bits.  */
-         status = regcache_raw_read (regcache,
-                                     I387_XMM0_REGNUM (tdep) + regnum,
-                                     raw_buf);
+         status = regcache->raw_read (I387_XMM0_REGNUM (tdep) + regnum,
+                                      raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0, 16);
          else
            memcpy (buf, raw_buf, 16);
          /* Read upper 128bits.  */
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0, 16);
          else
            memcpy (buf, raw_buf, 16);
          /* Read upper 128bits.  */
-         status = regcache_raw_read (regcache,
-                                     tdep->ymm0h_regnum + regnum,
-                                     raw_buf);
+         status = regcache->raw_read (tdep->ymm0h_regnum + regnum,
+                                      raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 16, 32);
          else
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 16, 32);
          else
@@ -3390,17 +3400,15 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
        {
          regnum -= tdep->ymm16_regnum;
          /* Extract (always little endian).  Read lower 128bits.  */
        {
          regnum -= tdep->ymm16_regnum;
          /* Extract (always little endian).  Read lower 128bits.  */
-         status = regcache_raw_read (regcache,
-                                     I387_XMM16_REGNUM (tdep) + regnum,
-                                     raw_buf);
+         status = regcache->raw_read (I387_XMM16_REGNUM (tdep) + regnum,
+                                      raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0, 16);
          else
            memcpy (buf, raw_buf, 16);
          /* Read upper 128bits.  */
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0, 16);
          else
            memcpy (buf, raw_buf, 16);
          /* Read upper 128bits.  */
-         status = regcache_raw_read (regcache,
-                                     tdep->ymm16h_regnum + regnum,
-                                     raw_buf);
+         status = regcache->raw_read (tdep->ymm16h_regnum + regnum,
+                                      raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 16, 16);
          else
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 16, 16);
          else
@@ -3411,7 +3419,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          int gpnum = regnum - tdep->ax_regnum;
 
          /* Extract (always little endian).  */
          int gpnum = regnum - tdep->ax_regnum;
 
          /* Extract (always little endian).  */
-         status = regcache_raw_read (regcache, gpnum, raw_buf);
+         status = regcache->raw_read (gpnum, raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0,
                                          TYPE_LENGTH (value_type (result_value)));
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0,
                                          TYPE_LENGTH (value_type (result_value)));
@@ -3424,7 +3432,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 
          /* Extract (always little endian).  We read both lower and
             upper registers.  */
 
          /* Extract (always little endian).  We read both lower and
             upper registers.  */
-         status = regcache_raw_read (regcache, gpnum % 4, raw_buf);
+         status = regcache->raw_read (gpnum % 4, raw_buf);
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0,
                                          TYPE_LENGTH (value_type (result_value)));
          if (status != REG_VALID)
            mark_value_bytes_unavailable (result_value, 0,
                                          TYPE_LENGTH (value_type (result_value)));
@@ -3440,7 +3448,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 
 static struct value *
 i386_pseudo_register_read_value (struct gdbarch *gdbarch,
 
 static struct value *
 i386_pseudo_register_read_value (struct gdbarch *gdbarch,
-                                struct regcache *regcache,
+                                readable_regcache *regcache,
                                 int regnum)
 {
   struct value *result;
                                 int regnum)
 {
   struct value *result;
@@ -3458,18 +3466,18 @@ void
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int regnum, const gdb_byte *buf)
 {
 i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                            int regnum, const gdb_byte *buf)
 {
-  gdb_byte raw_buf[MAX_REGISTER_SIZE];
+  gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
 
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Read ...  */
 
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
       int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
 
       /* Read ...  */
-      regcache_raw_read (regcache, fpnum, raw_buf);
+      regcache->raw_read (fpnum, raw_buf);
       /* ... Modify ... (always little endian).  */
       memcpy (raw_buf, buf, register_size (gdbarch, regnum));
       /* ... Write.  */
       /* ... Modify ... (always little endian).  */
       memcpy (raw_buf, buf, register_size (gdbarch, regnum));
       /* ... Write.  */
-      regcache_raw_write (regcache, fpnum, raw_buf);
+      regcache->raw_write (fpnum, raw_buf);
     }
   else
     {
     }
   else
     {
@@ -3487,9 +3495,8 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
          upper = extract_unsigned_integer (buf + size, size, byte_order);
 
          /* Fetching register buffer.  */
          upper = extract_unsigned_integer (buf + size, size, byte_order);
 
          /* Fetching register buffer.  */
-         regcache_raw_read (regcache,
-                            I387_BND0R_REGNUM (tdep) + regnum,
-                            raw_buf);
+         regcache->raw_read (I387_BND0R_REGNUM (tdep) + regnum,
+                             raw_buf);
 
          upper = ~upper;
 
 
          upper = ~upper;
 
@@ -3497,18 +3504,13 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
          memcpy (raw_buf, &lower, 8);
          memcpy (raw_buf + 8, &upper, 8);
 
          memcpy (raw_buf, &lower, 8);
          memcpy (raw_buf + 8, &upper, 8);
 
-
-         regcache_raw_write (regcache,
-                             I387_BND0R_REGNUM (tdep) + regnum,
-                             raw_buf);
+         regcache->raw_write (I387_BND0R_REGNUM (tdep) + regnum, raw_buf);
        }
       else if (i386_k_regnum_p (gdbarch, regnum))
        {
          regnum -= tdep->k0_regnum;
 
        }
       else if (i386_k_regnum_p (gdbarch, regnum))
        {
          regnum -= tdep->k0_regnum;
 
-         regcache_raw_write (regcache,
-                             tdep->k0_regnum + regnum,
-                             buf);
+         regcache->raw_write (tdep->k0_regnum + regnum, buf);
        }
       else if (i386_zmm_regnum_p (gdbarch, regnum))
        {
        }
       else if (i386_zmm_regnum_p (gdbarch, regnum))
        {
@@ -3517,82 +3519,64 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
          if (regnum < num_lower_zmm_regs)
            {
              /* Write lower 128bits.  */
          if (regnum < num_lower_zmm_regs)
            {
              /* Write lower 128bits.  */
-             regcache_raw_write (regcache,
-                                 I387_XMM0_REGNUM (tdep) + regnum,
-                                 buf);
+             regcache->raw_write (I387_XMM0_REGNUM (tdep) + regnum, buf);
              /* Write upper 128bits.  */
              /* Write upper 128bits.  */
-             regcache_raw_write (regcache,
-                                 I387_YMM0_REGNUM (tdep) + regnum,
-                                 buf + 16);
+             regcache->raw_write (I387_YMM0_REGNUM (tdep) + regnum, buf + 16);
            }
          else
            {
              /* Write lower 128bits.  */
            }
          else
            {
              /* Write lower 128bits.  */
-             regcache_raw_write (regcache,
-                                 I387_XMM16_REGNUM (tdep) + regnum
-                                 - num_lower_zmm_regs,
-                                 buf);
+             regcache->raw_write (I387_XMM16_REGNUM (tdep) + regnum
+                                  - num_lower_zmm_regs, buf);
              /* Write upper 128bits.  */
              /* Write upper 128bits.  */
-             regcache_raw_write (regcache,
-                                 I387_YMM16H_REGNUM (tdep) + regnum
-                                 - num_lower_zmm_regs,
-                                 buf + 16);
+             regcache->raw_write (I387_YMM16H_REGNUM (tdep) + regnum
+                                  - num_lower_zmm_regs, buf + 16);
            }
          /* Write upper 256bits.  */
            }
          /* Write upper 256bits.  */
-         regcache_raw_write (regcache,
-                             tdep->zmm0h_regnum + regnum,
-                             buf + 32);
+         regcache->raw_write (tdep->zmm0h_regnum + regnum, buf + 32);
        }
       else if (i386_ymm_regnum_p (gdbarch, regnum))
        {
          regnum -= tdep->ymm0_regnum;
 
          /* ... Write lower 128bits.  */
        }
       else if (i386_ymm_regnum_p (gdbarch, regnum))
        {
          regnum -= tdep->ymm0_regnum;
 
          /* ... Write lower 128bits.  */
-         regcache_raw_write (regcache,
-                            I387_XMM0_REGNUM (tdep) + regnum,
-                            buf);
+         regcache->raw_write (I387_XMM0_REGNUM (tdep) + regnum, buf);
          /* ... Write upper 128bits.  */
          /* ... Write upper 128bits.  */
-         regcache_raw_write (regcache,
-                            tdep->ymm0h_regnum + regnum,
-                            buf + 16);
+         regcache->raw_write (tdep->ymm0h_regnum + regnum, buf + 16);
        }
       else if (i386_ymm_avx512_regnum_p (gdbarch, regnum))
        {
          regnum -= tdep->ymm16_regnum;
 
          /* ... Write lower 128bits.  */
        }
       else if (i386_ymm_avx512_regnum_p (gdbarch, regnum))
        {
          regnum -= tdep->ymm16_regnum;
 
          /* ... Write lower 128bits.  */
-         regcache_raw_write (regcache,
-                             I387_XMM16_REGNUM (tdep) + regnum,
-                             buf);
+         regcache->raw_write (I387_XMM16_REGNUM (tdep) + regnum, buf);
          /* ... Write upper 128bits.  */
          /* ... Write upper 128bits.  */
-         regcache_raw_write (regcache,
-                             tdep->ymm16h_regnum + regnum,
-                             buf + 16);
+         regcache->raw_write (tdep->ymm16h_regnum + regnum, buf + 16);
        }
       else if (i386_word_regnum_p (gdbarch, regnum))
        {
          int gpnum = regnum - tdep->ax_regnum;
 
          /* Read ...  */
        }
       else if (i386_word_regnum_p (gdbarch, regnum))
        {
          int gpnum = regnum - tdep->ax_regnum;
 
          /* Read ...  */
-         regcache_raw_read (regcache, gpnum, raw_buf);
+         regcache->raw_read (gpnum, raw_buf);
          /* ... Modify ... (always little endian).  */
          memcpy (raw_buf, buf, 2);
          /* ... Write.  */
          /* ... Modify ... (always little endian).  */
          memcpy (raw_buf, buf, 2);
          /* ... Write.  */
-         regcache_raw_write (regcache, gpnum, raw_buf);
+         regcache->raw_write (gpnum, raw_buf);
        }
       else if (i386_byte_regnum_p (gdbarch, regnum))
        {
          int gpnum = regnum - tdep->al_regnum;
 
          /* Read ...  We read both lower and upper registers.  */
        }
       else if (i386_byte_regnum_p (gdbarch, regnum))
        {
          int gpnum = regnum - tdep->al_regnum;
 
          /* Read ...  We read both lower and upper registers.  */
-         regcache_raw_read (regcache, gpnum % 4, raw_buf);
+         regcache->raw_read (gpnum % 4, raw_buf);
          /* ... Modify ... (always little endian).  */
          if (gpnum >= 4)
            memcpy (raw_buf + 1, buf, 1);
          else
            memcpy (raw_buf, buf, 1);
          /* ... Write.  */
          /* ... Modify ... (always little endian).  */
          if (gpnum >= 4)
            memcpy (raw_buf + 1, buf, 1);
          else
            memcpy (raw_buf, buf, 1);
          /* ... Write.  */
-         regcache_raw_write (regcache, gpnum % 4, raw_buf);
+         regcache->raw_write (gpnum % 4, raw_buf);
        }
       else
        internal_error (__FILE__, __LINE__, _("invalid regnum"));
        }
       else
        internal_error (__FILE__, __LINE__, _("invalid regnum"));
@@ -3819,7 +3803,7 @@ void
 i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
                     int regnum, const void *gregs, size_t len)
 {
 i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
                     int regnum, const void *gregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   const gdb_byte *regs = (const gdb_byte *) gregs;
   int i;
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   const gdb_byte *regs = (const gdb_byte *) gregs;
   int i;
@@ -3830,7 +3814,7 @@ i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
     {
       if ((regnum == i || regnum == -1)
          && tdep->gregset_reg_offset[i] != -1)
     {
       if ((regnum == i || regnum == -1)
          && tdep->gregset_reg_offset[i] != -1)
-       regcache_raw_supply (regcache, i, regs + tdep->gregset_reg_offset[i]);
+       regcache->raw_supply (i, regs + tdep->gregset_reg_offset[i]);
     }
 }
 
     }
 }
 
@@ -3844,7 +3828,7 @@ i386_collect_gregset (const struct regset *regset,
                      const struct regcache *regcache,
                      int regnum, void *gregs, size_t len)
 {
                      const struct regcache *regcache,
                      int regnum, void *gregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   gdb_byte *regs = (gdb_byte *) gregs;
   int i;
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   gdb_byte *regs = (gdb_byte *) gregs;
   int i;
@@ -3855,7 +3839,7 @@ i386_collect_gregset (const struct regset *regset,
     {
       if ((regnum == i || regnum == -1)
          && tdep->gregset_reg_offset[i] != -1)
     {
       if ((regnum == i || regnum == -1)
          && tdep->gregset_reg_offset[i] != -1)
-       regcache_raw_collect (regcache, i, regs + tdep->gregset_reg_offset[i]);
+       regcache->raw_collect (i, regs + tdep->gregset_reg_offset[i]);
     }
 }
 
     }
 }
 
@@ -3867,7 +3851,7 @@ static void
 i386_supply_fpregset (const struct regset *regset, struct regcache *regcache,
                      int regnum, const void *fpregs, size_t len)
 {
 i386_supply_fpregset (const struct regset *regset, struct regcache *regcache,
                      int regnum, const void *fpregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (len == I387_SIZEOF_FXSAVE)
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (len == I387_SIZEOF_FXSAVE)
@@ -3890,7 +3874,7 @@ i386_collect_fpregset (const struct regset *regset,
                       const struct regcache *regcache,
                       int regnum, void *fpregs, size_t len)
 {
                       const struct regcache *regcache,
                       int regnum, void *fpregs, size_t len)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (len == I387_SIZEOF_FXSAVE)
   const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (len == I387_SIZEOF_FXSAVE)
@@ -3925,9 +3909,11 @@ i386_iterate_over_regset_sections (struct gdbarch *gdbarch,
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  cb (".reg", tdep->sizeof_gregset, &i386_gregset, NULL, cb_data);
+  cb (".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, &i386_gregset, NULL,
+      cb_data);
   if (tdep->sizeof_fpregset)
   if (tdep->sizeof_fpregset)
-    cb (".reg2", tdep->sizeof_fpregset, tdep->fpregset, NULL, cb_data);
+    cb (".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, tdep->fpregset,
+       NULL, cb_data);
 }
 \f
 
 }
 \f
 
@@ -3947,7 +3933,7 @@ i386_pe_skip_trampoline_code (struct frame_info *frame,
        read_memory_unsigned_integer (pc + 2, 4, byte_order);
       struct minimal_symbol *indsym =
        indirect ? lookup_minimal_symbol_by_pc (indirect).minsym : 0;
        read_memory_unsigned_integer (pc + 2, 4, byte_order);
       struct minimal_symbol *indsym =
        indirect ? lookup_minimal_symbol_by_pc (indirect).minsym : 0;
-      const char *symname = indsym ? MSYMBOL_LINKAGE_NAME (indsym) : 0;
+      const char *symname = indsym ? indsym->linkage_name () : 0;
 
       if (symname)
        {
 
       if (symname)
        {
@@ -3984,11 +3970,9 @@ i386_print_insn (bfd_vma pc, struct disassemble_info *info)
   gdb_assert (disassembly_flavor == att_flavor
              || disassembly_flavor == intel_flavor);
 
   gdb_assert (disassembly_flavor == att_flavor
              || disassembly_flavor == intel_flavor);
 
-  /* FIXME: kettenis/20020915: Until disassembler_options is properly
-     constified, cast to prevent a compiler warning.  */
-  info->disassembler_options = (char *) disassembly_flavor;
+  info->disassembler_options = disassembly_flavor;
 
 
-  return print_insn_i386 (pc, info);
+  return default_print_insn (pc, info);
 }
 \f
 
 }
 \f
 
@@ -4050,10 +4034,10 @@ i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
    This function parses operands of the form `-8+3+1(%rbp)', which
    must be interpreted as `*(-8 + 3 - 1 + (void *) $eax)'.
 
    This function parses operands of the form `-8+3+1(%rbp)', which
    must be interpreted as `*(-8 + 3 - 1 + (void *) $eax)'.
 
-   Return 1 if the operand was parsed successfully, zero
+   Return true if the operand was parsed successfully, false
    otherwise.  */
 
    otherwise.  */
 
-static int
+static bool
 i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
                                       struct stap_parse_info *p)
 {
 i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
                                       struct stap_parse_info *p)
 {
@@ -4061,7 +4045,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
 
   if (isdigit (*s) || *s == '-' || *s == '+')
     {
 
   if (isdigit (*s) || *s == '-' || *s == '+')
     {
-      int got_minus[3];
+      bool got_minus[3];
       int i;
       long displacements[3];
       const char *start;
       int i;
       long displacements[3];
       const char *start;
@@ -4070,17 +4054,17 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
       struct stoken str;
       char *endp;
 
       struct stoken str;
       char *endp;
 
-      got_minus[0] = 0;
+      got_minus[0] = false;
       if (*s == '+')
        ++s;
       else if (*s == '-')
        {
          ++s;
       if (*s == '+')
        ++s;
       else if (*s == '-')
        {
          ++s;
-         got_minus[0] = 1;
+         got_minus[0] = true;
        }
 
       if (!isdigit ((unsigned char) *s))
        }
 
       if (!isdigit ((unsigned char) *s))
-       return 0;
+       return false;
 
       displacements[0] = strtol (s, &endp, 10);
       s = endp;
 
       displacements[0] = strtol (s, &endp, 10);
       s = endp;
@@ -4088,20 +4072,20 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
       if (*s != '+' && *s != '-')
        {
          /* We are not dealing with a triplet.  */
       if (*s != '+' && *s != '-')
        {
          /* We are not dealing with a triplet.  */
-         return 0;
+         return false;
        }
 
        }
 
-      got_minus[1] = 0;
+      got_minus[1] = false;
       if (*s == '+')
        ++s;
       else
        {
          ++s;
       if (*s == '+')
        ++s;
       else
        {
          ++s;
-         got_minus[1] = 1;
+         got_minus[1] = true;
        }
 
       if (!isdigit ((unsigned char) *s))
        }
 
       if (!isdigit ((unsigned char) *s))
-       return 0;
+       return false;
 
       displacements[1] = strtol (s, &endp, 10);
       s = endp;
 
       displacements[1] = strtol (s, &endp, 10);
       s = endp;
@@ -4109,26 +4093,26 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
       if (*s != '+' && *s != '-')
        {
          /* We are not dealing with a triplet.  */
       if (*s != '+' && *s != '-')
        {
          /* We are not dealing with a triplet.  */
-         return 0;
+         return false;
        }
 
        }
 
-      got_minus[2] = 0;
+      got_minus[2] = false;
       if (*s == '+')
        ++s;
       else
        {
          ++s;
       if (*s == '+')
        ++s;
       else
        {
          ++s;
-         got_minus[2] = 1;
+         got_minus[2] = true;
        }
 
       if (!isdigit ((unsigned char) *s))
        }
 
       if (!isdigit ((unsigned char) *s))
-       return 0;
+       return false;
 
       displacements[2] = strtol (s, &endp, 10);
       s = endp;
 
       if (*s != '(' || s[1] != '%')
 
       displacements[2] = strtol (s, &endp, 10);
       s = endp;
 
       if (*s != '(' || s[1] != '%')
-       return 0;
+       return false;
 
       s += 2;
       start = s;
 
       s += 2;
       start = s;
@@ -4137,7 +4121,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
        ++s;
 
       if (*s++ != ')')
        ++s;
 
       if (*s++ != ')')
-       return 0;
+       return false;
 
       len = s - start - 1;
       regname = (char *) alloca (len + 1);
 
       len = s - start - 1;
       regname = (char *) alloca (len + 1);
@@ -4184,10 +4168,10 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
 
       p->arg = s;
 
 
       p->arg = s;
 
-      return 1;
+      return true;
     }
 
     }
 
-  return 0;
+  return false;
 }
 
 /* Helper function for i386_stap_parse_special_token.
 }
 
 /* Helper function for i386_stap_parse_special_token.
@@ -4196,10 +4180,10 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
    (register index * size) + offset', as represented in
    `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
 
    (register index * size) + offset', as represented in
    `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
 
-   Return 1 if the operand was parsed successfully, zero
+   Return true if the operand was parsed successfully, false
    otherwise.  */
 
    otherwise.  */
 
-static int
+static bool
 i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
                                              struct stap_parse_info *p)
 {
 i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
                                              struct stap_parse_info *p)
 {
@@ -4207,9 +4191,9 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
 
   if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
     {
 
   if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
     {
-      int offset_minus = 0;
+      bool offset_minus = false;
       long offset = 0;
       long offset = 0;
-      int size_minus = 0;
+      bool size_minus = false;
       long size = 0;
       const char *start;
       char *base;
       long size = 0;
       const char *start;
       char *base;
@@ -4223,11 +4207,11 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
       else if (*s == '-')
        {
          ++s;
       else if (*s == '-')
        {
          ++s;
-         offset_minus = 1;
+         offset_minus = true;
        }
 
       if (offset_minus && !isdigit (*s))
        }
 
       if (offset_minus && !isdigit (*s))
-       return 0;
+       return false;
 
       if (isdigit (*s))
        {
 
       if (isdigit (*s))
        {
@@ -4238,7 +4222,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
        }
 
       if (*s != '(' || s[1] != '%')
        }
 
       if (*s != '(' || s[1] != '%')
-       return 0;
+       return false;
 
       s += 2;
       start = s;
 
       s += 2;
       start = s;
@@ -4247,7 +4231,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
        ++s;
 
       if (*s != ',' || s[1] != '%')
        ++s;
 
       if (*s != ',' || s[1] != '%')
-       return 0;
+       return false;
 
       len_base = s - start;
       base = (char *) alloca (len_base + 1);
 
       len_base = s - start;
       base = (char *) alloca (len_base + 1);
@@ -4274,7 +4258,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
               index, p->saved_arg);
 
       if (*s != ',' && *s != ')')
               index, p->saved_arg);
 
       if (*s != ',' && *s != ')')
-       return 0;
+       return false;
 
       if (*s == ',')
        {
 
       if (*s == ',')
        {
@@ -4286,14 +4270,14 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
          else if (*s == '-')
            {
              ++s;
          else if (*s == '-')
            {
              ++s;
-             size_minus = 1;
+             size_minus = true;
            }
 
          size = strtol (s, &endp, 10);
          s = endp;
 
          if (*s != ')')
            }
 
          size = strtol (s, &endp, 10);
          s = endp;
 
          if (*s != ')')
-           return 0;
+           return false;
        }
 
       ++s;
        }
 
       ++s;
@@ -4347,10 +4331,10 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
 
       p->arg = s;
 
 
       p->arg = s;
 
-      return 1;
+      return true;
     }
 
     }
 
-  return 0;
+  return false;
 }
 
 /* Implementation of `gdbarch_stap_parse_special_token', as defined in
 }
 
 /* Implementation of `gdbarch_stap_parse_special_token', as defined in
@@ -4402,6 +4386,29 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
   return 0;
 }
 
   return 0;
 }
 
+/* Implementation of 'gdbarch_stap_adjust_register', as defined in
+   gdbarch.h.  */
+
+static std::string
+i386_stap_adjust_register (struct gdbarch *gdbarch, struct stap_parse_info *p,
+                          const std::string &regname, int regnum)
+{
+  static const std::unordered_set<std::string> reg_assoc
+    = { "ax", "bx", "cx", "dx",
+       "si", "di", "bp", "sp" };
+
+  /* If we are dealing with a register whose size is less than the size
+     specified by the "[-]N@" prefix, and it is one of the registers that
+     we know has an extended variant available, then use the extended
+     version of the register instead.  */
+  if (register_size (gdbarch, regnum) < TYPE_LENGTH (p->arg_type)
+      && reg_assoc.find (regname) != reg_assoc.end ())
+    return "e" + regname;
+
+  /* Otherwise, just use the requested register.  */
+  return regname;
+}
+
 \f
 
 /* gdbarch gnu_triplet_regexp method.  Both arches are acceptable as GDB always
 \f
 
 /* gdbarch gnu_triplet_regexp method.  Both arches are acceptable as GDB always
@@ -4415,6 +4422,15 @@ i386_gnu_triplet_regexp (struct gdbarch *gdbarch)
 
 \f
 
 
 \f
 
+/* Implement the "in_indirect_branch_thunk" gdbarch function.  */
+
+static bool
+i386_in_indirect_branch_thunk (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  return x86_in_indirect_branch_thunk (pc, i386_register_names,
+                                      I386_EAX_REGNUM, I386_EIP_REGNUM);
+}
+
 /* Generic ELF.  */
 
 void
 /* Generic ELF.  */
 
 void
@@ -4441,8 +4457,11 @@ i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
                                      i386_stap_is_single_operand);
   set_gdbarch_stap_parse_special_token (gdbarch,
                                        i386_stap_parse_special_token);
                                      i386_stap_is_single_operand);
   set_gdbarch_stap_parse_special_token (gdbarch,
                                        i386_stap_parse_special_token);
+  set_gdbarch_stap_adjust_register (gdbarch,
+                                   i386_stap_adjust_register);
 
 
-  set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp);
+  set_gdbarch_in_indirect_branch_thunk (gdbarch,
+                                       i386_in_indirect_branch_thunk);
 }
 
 /* System V Release 4 (SVR4).  */
 }
 
 /* System V Release 4 (SVR4).  */
@@ -4466,33 +4485,6 @@ i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->jb_pc_offset = 20;
 }
 
   tdep->jb_pc_offset = 20;
 }
 
-/* DJGPP.  */
-
-static void
-i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
-  /* DJGPP doesn't have any special frames for signal handlers.  */
-  tdep->sigtramp_p = NULL;
-
-  tdep->jb_pc_offset = 36;
-
-  /* DJGPP does not support the SSE registers.  */
-  if (! tdesc_has_registers (info.target_desc))
-    tdep->tdesc = tdesc_i386_mmx;
-
-  /* Native compiler is GCC, which uses the SVR4 register numbering
-     even in COFF and STABS.  See the comment in i386_gdbarch_init,
-     before the calls to set_gdbarch_stab_reg_to_regnum and
-     set_gdbarch_sdb_reg_to_regnum.  */
-  set_gdbarch_stab_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
-  set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
-
-  set_gdbarch_has_dos_based_file_system (gdbarch, 1);
-
-  set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp);
-}
 \f
 
 /* i386 register groups.  In addition to the normal groups, add "mmx"
 \f
 
 /* i386 register groups.  In addition to the normal groups, add "mmx"
@@ -4529,9 +4521,9 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   const struct gdbarch_tdep *tdep = 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,
   const struct gdbarch_tdep *tdep = 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, 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;
+      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;
 
   /* Don't include pseudo registers, except for MMX, in any register
      groups.  */
 
   /* Don't include pseudo registers, except for MMX, in any register
      groups.  */
@@ -4548,6 +4540,7 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   if (group == i386_mmx_reggroup)
     return mmx_regnum_p;
 
   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);
   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);
@@ -4558,11 +4551,11 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   ymm_avx512_regnum_p = i386_ymm_avx512_regnum_p (gdbarch, regnum);
   zmm_regnum_p = i386_zmm_regnum_p (gdbarch, regnum);
 
   ymm_avx512_regnum_p = i386_ymm_avx512_regnum_p (gdbarch, regnum);
   zmm_regnum_p = i386_zmm_regnum_p (gdbarch, regnum);
 
-  avx512_p = ((tdep->xcr0 & X86_XSTATE_AVX512_MASK)
-             == X86_XSTATE_AVX512_MASK);
-  avx_p = ((tdep->xcr0 & X86_XSTATE_AVX512_MASK)
+  avx512_p = ((tdep->xcr0 & X86_XSTATE_AVX_AVX512_MASK)
+             == X86_XSTATE_AVX_AVX512_MASK);
+  avx_p = ((tdep->xcr0 & X86_XSTATE_AVX_AVX512_MASK)
           == X86_XSTATE_AVX_MASK) && !avx512_p;
           == X86_XSTATE_AVX_MASK) && !avx512_p;
-  sse_p = ((tdep->xcr0 & X86_XSTATE_AVX512_MASK)
+  sse_p = ((tdep->xcr0 & X86_XSTATE_AVX_AVX512_MASK)
           == X86_XSTATE_SSE_MASK) && !avx512_p && ! avx_p;
 
   if (group == vector_reggroup)
           == X86_XSTATE_SSE_MASK) && !avx512_p && ! avx_p;
 
   if (group == vector_reggroup)
@@ -4619,7 +4612,8 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
            && !bnd_regnum_p
            && !mpx_ctrl_regnum_p
            && !zmm_regnum_p
            && !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);
 }
 
   return default_register_reggroup_p (gdbarch, regnum, group);
 }
@@ -5040,7 +5034,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
   uint32_t opcode;
   uint8_t opcode8;
   ULONGEST addr;
   uint32_t opcode;
   uint8_t opcode8;
   ULONGEST addr;
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  gdb_byte buf[I386_MAX_REGISTER_SIZE];
   struct i386_record_s ir;
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint8_t rex_w = -1;
   struct i386_record_s ir;
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   uint8_t rex_w = -1;
@@ -5504,14 +5498,36 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
       I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
       I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
       break;
 
-    case 0x0fc7:    /* cmpxchg8b */
+    case 0x0fc7:    /* cmpxchg8b / rdrand / rdseed */
       if (i386_record_modrm (&ir))
        return -1;
       if (ir.mod == 3)
        {
       if (i386_record_modrm (&ir))
        return -1;
       if (ir.mod == 3)
        {
-         ir.addr -= 2;
-         opcode = opcode << 8 | ir.modrm;
-         goto no_support;
+         /* rdrand and rdseed use the 3 bits of the REG field of ModR/M as
+            an extended opcode.  rdrand has bits 110 (/6) and rdseed
+            has bits 111 (/7).  */
+         if (ir.reg == 6 || ir.reg == 7)
+           {
+             /* The storage register is described by the 3 R/M bits, but the
+                REX.B prefix may be used to give access to registers
+                R8~R15.  In this case ir.rex_b + R/M will give us the register
+                in the range R8~R15.
+
+                REX.W may also be used to access 64-bit registers, but we
+                already record entire registers and not just partial bits
+                of them.  */
+             I386_RECORD_FULL_ARCH_LIST_ADD_REG (ir.rex_b + ir.rm);
+             /* These instructions also set conditional bits.  */
+             I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+             break;
+           }
+         else
+           {
+             /* We don't handle this particular instruction yet.  */
+             ir.addr -= 2;
+             opcode = opcode << 8 | ir.modrm;
+             goto no_support;
+           }
        }
       I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
        }
       I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
       I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
@@ -7116,6 +7132,7 @@ Do you want to stop the program?"),
              else if (ir.rm == 1)
                break;
            }
              else if (ir.rm == 1)
                break;
            }
+         /* Fall through.  */
        case 3:  /* lidt */
          if (ir.mod == 3)
            {
        case 3:  /* lidt */
          if (ir.mod == 3)
            {
@@ -8110,10 +8127,9 @@ static const int i386_record_regmap[] =
 
 static int
 i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr,
 
 static int
 i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr,
-                              char **msg)
+                              std::string *msg)
 {
   int len, jumplen;
 {
   int len, jumplen;
-  static struct ui_file *gdb_null = NULL;
 
   /*  Ask the target for the minimum instruction length supported.  */
   jumplen = target_get_min_fast_tracepoint_insn_len ();
 
   /*  Ask the target for the minimum instruction length supported.  */
   jumplen = target_get_min_fast_tracepoint_insn_len ();
@@ -8136,27 +8152,23 @@ i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr,
       jumplen = (register_size (gdbarch, 0) == 8) ? 5 : 4;
     }
 
       jumplen = (register_size (gdbarch, 0) == 8) ? 5 : 4;
     }
 
-  /* Dummy file descriptor for the disassembler.  */
-  if (!gdb_null)
-    gdb_null = ui_file_new ();
-
   /* Check for fit.  */
   /* Check for fit.  */
-  len = gdb_print_insn (gdbarch, addr, gdb_null, NULL);
+  len = gdb_insn_length (gdbarch, addr);
 
   if (len < jumplen)
     {
       /* Return a bit of target-specific detail to add to the caller's
         generic failure message.  */
       if (msg)
 
   if (len < jumplen)
     {
       /* Return a bit of target-specific detail to add to the caller's
         generic failure message.  */
       if (msg)
-       *msg = xstrprintf (_("; instruction is only %d bytes long, "
-                            "need at least %d bytes for the jump"),
-                          len, jumplen);
+       *msg = string_printf (_("; instruction is only %d bytes long, "
+                               "need at least %d bytes for the jump"),
+                             len, jumplen);
       return 0;
     }
   else
     {
       if (msg)
       return 0;
     }
   else
     {
       if (msg)
-       *msg = NULL;
+       msg->clear ();
       return 1;
     }
 }
       return 1;
     }
 }
@@ -8165,14 +8177,16 @@ i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr,
    length LEN in bits.  If non-NULL, NAME is the name of its type.
    If no suitable type is found, return NULL.  */
 
    length LEN in bits.  If non-NULL, NAME is the name of its type.
    If no suitable type is found, return NULL.  */
 
-const struct floatformat **
+static const struct floatformat **
 i386_floatformat_for_type (struct gdbarch *gdbarch,
                           const char *name, int len)
 {
   if (len == 128 && name)
     if (strcmp (name, "__float128") == 0
        || strcmp (name, "_Float128") == 0
 i386_floatformat_for_type (struct gdbarch *gdbarch,
                           const char *name, int len)
 {
   if (len == 128 && name)
     if (strcmp (name, "__float128") == 0
        || strcmp (name, "_Float128") == 0
-       || strcmp (name, "complex _Float128") == 0)
+       || strcmp (name, "complex _Float128") == 0
+       || strcmp (name, "complex(kind=16)") == 0
+       || strcmp (name, "real(kind=16)") == 0)
       return floatformats_ia64_quad;
 
   return default_floatformat_for_type (gdbarch, name, len);
       return floatformats_ia64_quad;
 
   return default_floatformat_for_type (gdbarch, name, len);
@@ -8186,7 +8200,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,
   const struct tdesc_feature *feature_core;
 
   const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx,
-                            *feature_avx512;
+                            *feature_avx512, *feature_pkeys, *feature_segments;
   int i, num_regs, valid_p;
 
   if (! tdesc_has_registers (tdesc))
   int i, num_regs, valid_p;
 
   if (! tdesc_has_registers (tdesc))
@@ -8209,6 +8223,12 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
   /* Try AVX512 registers.  */
   feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512");
 
   /* Try AVX512 registers.  */
   feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512");
 
+  /* Try segment base registers.  */
+  feature_segments = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments");
+
+  /* Try PKEYS  */
+  feature_pkeys = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys");
+
   valid_p = 1;
 
   /* The XCR0 bits.  */
   valid_p = 1;
 
   /* The XCR0 bits.  */
@@ -8218,7 +8238,7 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
       if (!feature_avx)
        return 0;
 
       if (!feature_avx)
        return 0;
 
-      tdep->xcr0 = X86_XSTATE_MPX_AVX512_MASK;
+      tdep->xcr0 = X86_XSTATE_AVX_AVX512_MASK;
 
       /* It may have been set by OSABI initialization function.  */
       if (tdep->k0_regnum < 0)
 
       /* It may have been set by OSABI initialization function.  */
       if (tdep->k0_regnum < 0)
@@ -8315,10 +8335,63 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
            tdep->mpx_register_names[i]);
     }
 
            tdep->mpx_register_names[i]);
     }
 
+  if (feature_segments)
+    {
+      if (tdep->fsbase_regnum < 0)
+       tdep->fsbase_regnum = I386_FSBASE_REGNUM;
+      valid_p &= tdesc_numbered_register (feature_segments, tdesc_data,
+                                         tdep->fsbase_regnum, "fs_base");
+      valid_p &= tdesc_numbered_register (feature_segments, tdesc_data,
+                                         tdep->fsbase_regnum + 1, "gs_base");
+    }
+
+  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;
 }
 
 \f
   return valid_p;
 }
 
 \f
+
+/* Implement the type_align gdbarch function.  */
+
+static ULONGEST
+i386_type_align (struct gdbarch *gdbarch, struct type *type)
+{
+  type = check_typedef (type);
+
+  if (gdbarch_ptr_bit (gdbarch) == 32)
+    {
+      if ((TYPE_CODE (type) == TYPE_CODE_INT
+          || TYPE_CODE (type) == TYPE_CODE_FLT)
+         && TYPE_LENGTH (type) > 4)
+       return 4;
+
+      /* Handle x86's funny long double.  */
+      if (TYPE_CODE (type) == TYPE_CODE_FLT
+         && gdbarch_long_double_bit (gdbarch) == TYPE_LENGTH (type) * 8)
+       return 4;
+    }
+
+  return 0;
+}
+
+\f
+/* Note: This is called for both i386 and amd64.  */
+
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
@@ -8336,7 +8409,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (arches != NULL)
     return arches->gdbarch;
 
   if (arches != NULL)
     return arches->gdbarch;
 
-  /* Allocate space for the new architecture.  */
+  /* Allocate space for the new architecture.  Assume i386 for now.  */
   tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
   tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
@@ -8374,7 +8447,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   tdep->record_regmap = i386_record_regmap;
 
 
   tdep->record_regmap = i386_record_regmap;
 
-  set_gdbarch_long_long_align_bit (gdbarch, 32);
+  set_gdbarch_type_align (gdbarch, i386_type_align);
 
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
 
   /* The format used for `long double' on almost all i386 targets is
      the i387 extended floating-point format.  In fact, of all targets
@@ -8457,7 +8530,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Stack grows downward.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
   /* Stack grows downward.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
 
-  set_gdbarch_breakpoint_from_pc (gdbarch, i386_breakpoint_from_pc);
+  set_gdbarch_breakpoint_kind_from_pc (gdbarch, i386_breakpoint::kind_from_pc);
+  set_gdbarch_sw_breakpoint_from_kind (gdbarch, i386_breakpoint::bp_from_kind);
+
   set_gdbarch_decr_pc_after_break (gdbarch, 1);
   set_gdbarch_max_insn_length (gdbarch, I386_MAX_INSN_LEN);
 
   set_gdbarch_decr_pc_after_break (gdbarch, 1);
   set_gdbarch_max_insn_length (gdbarch, I386_MAX_INSN_LEN);
 
@@ -8506,14 +8581,14 @@ 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.  */
   /* 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_NUM_REGS);
 
   set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp);
 
   /* Get the x86 target description from INFO.  */
   tdesc = info.target_desc;
   if (! tdesc_has_registers (tdesc))
 
   set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp);
 
   /* Get the x86 target description from INFO.  */
   tdesc = info.target_desc;
   if (! tdesc_has_registers (tdesc))
-    tdesc = tdesc_i386;
+    tdesc = i386_target_description (X86_XSTATE_SSE_MASK, false);
   tdep->tdesc = tdesc;
 
   tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS;
   tdep->tdesc = tdesc;
 
   tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS;
@@ -8551,6 +8626,13 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->num_ymm_avx512_regs = 0;
   tdep->num_xmm_avx512_regs = 0;
 
   tdep->num_ymm_avx512_regs = 0;
   tdep->num_xmm_avx512_regs = 0;
 
+  /* No PKEYS registers  */
+  tdep->pkru_regnum = -1;
+  tdep->num_pkeys_regs = 0;
+
+  /* No segment base registers.  */
+  tdep->fsbase_regnum = -1;
+
   tdesc_data = tdesc_data_alloc ();
 
   set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction);
   tdesc_data = tdesc_data_alloc ();
 
   set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction);
@@ -8561,8 +8643,10 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_insn_is_ret (gdbarch, i386_insn_is_ret);
   set_gdbarch_insn_is_jump (gdbarch, i386_insn_is_jump);
 
   set_gdbarch_insn_is_ret (gdbarch, i386_insn_is_ret);
   set_gdbarch_insn_is_jump (gdbarch, i386_insn_is_jump);
 
-  /* Hook in ABI-specific overrides, if they have been registered.  */
-  info.tdep_info = tdesc_data;
+  /* Hook in ABI-specific overrides, if they have been registered.
+     Note: If INFO specifies a 64 bit arch, this is where we turn
+     a 32-bit i386 into a 64-bit amd64.  */
+  info.tdesc_data = tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
   if (!i386_validate_tdesc_p (tdep, tdesc_data))
   gdbarch_init_osabi (info, gdbarch);
 
   if (!i386_validate_tdesc_p (tdep, tdesc_data))
@@ -8669,36 +8753,28 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   return gdbarch;
 }
 
   return gdbarch;
 }
 
-static enum gdb_osabi
-i386_coff_osabi_sniffer (bfd *abfd)
-{
-  if (strcmp (bfd_get_target (abfd), "coff-go32-exe") == 0
-      || strcmp (bfd_get_target (abfd), "coff-go32") == 0)
-    return GDB_OSABI_GO32;
-
-  return GDB_OSABI_UNKNOWN;
-}
 \f
 
 /* Return the target description for a specified XSAVE feature mask.  */
 
 const struct target_desc *
 \f
 
 /* Return the target description for a specified XSAVE feature mask.  */
 
 const struct target_desc *
-i386_target_description (uint64_t xcr0)
-{
-  switch (xcr0 & X86_XSTATE_ALL_MASK)
-    {
-    case X86_XSTATE_MPX_AVX512_MASK:
-    case X86_XSTATE_AVX512_MASK:
-      return tdesc_i386_avx512;
-    case X86_XSTATE_AVX_MPX_MASK:
-      return tdesc_i386_avx_mpx;
-    case X86_XSTATE_MPX_MASK:
-      return tdesc_i386_mpx;
-    case X86_XSTATE_AVX_MASK:
-      return tdesc_i386_avx;
-    default:
-      return tdesc_i386;
-    }
+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*/] = {};
+  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];
+
+  if (*tdesc == NULL)
+    *tdesc = i386_create_target_description (xcr0, false, segments);
+
+  return *tdesc;
 }
 
 #define MPX_BASE_MASK (~(ULONGEST) 0xfff)
 }
 
 #define MPX_BASE_MASK (~(ULONGEST) 0xfff)
@@ -8714,7 +8790,7 @@ i386_mpx_bd_base (void)
   enum register_status regstatus;
 
   rcache = get_current_regcache ();
   enum register_status regstatus;
 
   rcache = get_current_regcache ();
-  tdep = gdbarch_tdep (get_regcache_arch (rcache));
+  tdep = gdbarch_tdep (rcache->arch ());
 
   regstatus = regcache_raw_read_unsigned (rcache, tdep->bndcfgu_regnum, &ret);
 
 
   regstatus = regcache_raw_read_unsigned (rcache, tdep->bndcfgu_regnum, &ret);
 
@@ -8807,22 +8883,22 @@ i386_mpx_print_bounds (const CORE_ADDR bt_entry[4])
 
   if (bounds_in_map == 1)
     {
 
   if (bounds_in_map == 1)
     {
-      ui_out_text (uiout, "Null bounds on map:");
-      ui_out_text (uiout, " pointer value = ");
-      ui_out_field_core_addr (uiout, "pointer-value", gdbarch, bt_entry[2]);
-      ui_out_text (uiout, ".");
-      ui_out_text (uiout, "\n");
+      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
     {
     }
   else
     {
-      ui_out_text (uiout, "{lbound = ");
-      ui_out_field_core_addr (uiout, "lower-bound", gdbarch, bt_entry[0]);
-      ui_out_text (uiout, ", ubound = ");
+      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.  */
 
       /* The upper bound is stored in 1's complement.  */
-      ui_out_field_core_addr (uiout, "upper-bound", gdbarch, ~bt_entry[1]);
-      ui_out_text (uiout, "}: pointer value = ");
-      ui_out_field_core_addr (uiout, "pointer-value", gdbarch, bt_entry[2]);
+      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]);
 
       if (gdbarch_ptr_bit (gdbarch) == 64)
        size = ( (~(int64_t) bt_entry[1]) - (int64_t) bt_entry[0]);
@@ -8834,19 +8910,19 @@ i386_mpx_print_bounds (const CORE_ADDR bt_entry[4])
         one to the size.  */
 
       size = (size > -1 ? size + 1 : size);
         one to the size.  */
 
       size = (size > -1 ? size + 1 : size);
-      ui_out_text (uiout, ", size = ");
-      ui_out_field_fmt (uiout, "size", "%s", plongest (size));
+      uiout->text (", size = ");
+      uiout->field_string ("size", plongest (size));
 
 
-      ui_out_text (uiout, ", metadata = ");
-      ui_out_field_core_addr (uiout, "metadata", gdbarch, bt_entry[3]);
-      ui_out_text (uiout, "\n");
+      uiout->text (", metadata = ");
+      uiout->field_core_addr ("metadata", gdbarch, bt_entry[3]);
+      uiout->text ("\n");
     }
 }
 
 /* Implement the command "show mpx bound".  */
 
 static void
     }
 }
 
 /* Implement the command "show mpx bound".  */
 
 static void
-i386_mpx_info_bounds (char *args, int from_tty)
+i386_mpx_info_bounds (const char *args, int from_tty)
 {
   CORE_ADDR bd_base = 0;
   CORE_ADDR addr;
 {
   CORE_ADDR bd_base = 0;
   CORE_ADDR addr;
@@ -8856,7 +8932,8 @@ i386_mpx_info_bounds (char *args, int from_tty)
   struct gdbarch *gdbarch = get_current_arch ();
   struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 
   struct gdbarch *gdbarch = get_current_arch ();
   struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 
-  if (!i386_mpx_enabled ())
+  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"));
     {
       printf_unfiltered (_("Intel Memory Protection Extensions not "
                           "supported on this target.\n"));
@@ -8887,7 +8964,7 @@ i386_mpx_info_bounds (char *args, int from_tty)
 /* Implement the command "set mpx bound".  */
 
 static void
 /* Implement the command "set mpx bound".  */
 
 static void
-i386_mpx_set_bounds (char *args, int from_tty)
+i386_mpx_set_bounds (const char *args, int from_tty)
 {
   CORE_ADDR bd_base = 0;
   CORE_ADDR addr, lower, upper;
 {
   CORE_ADDR bd_base = 0;
   CORE_ADDR addr, lower, upper;
@@ -8899,7 +8976,8 @@ i386_mpx_set_bounds (char *args, int from_tty)
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 
-  if (!i386_mpx_enabled ())
+  if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_i386
+      || !i386_mpx_enabled ())
     error (_("Intel Memory Protection Extensions not supported\
  on this target."));
 
     error (_("Intel Memory Protection Extensions not supported\
  on this target."));
 
@@ -8941,7 +9019,7 @@ static struct cmd_list_element *mpx_set_cmdlist, *mpx_show_cmdlist;
 /* Helper function for the CLI commands.  */
 
 static void
 /* Helper function for the CLI commands.  */
 
 static void
-set_mpx_cmd (char *args, int from_tty)
+set_mpx_cmd (const char *args, int from_tty)
 {
   help_list (mpx_set_cmdlist, "set mpx ", all_commands, gdb_stdout);
 }
 {
   help_list (mpx_set_cmdlist, "set mpx ", all_commands, gdb_stdout);
 }
@@ -8949,14 +9027,11 @@ set_mpx_cmd (char *args, int from_tty)
 /* Helper function for the CLI commands.  */
 
 static void
 /* Helper function for the CLI commands.  */
 
 static void
-show_mpx_cmd (char *args, int from_tty)
+show_mpx_cmd (const char *args, int from_tty)
 {
   cmd_show_list (mpx_show_cmdlist, from_tty, "");
 }
 
 {
   cmd_show_list (mpx_show_cmdlist, from_tty, "");
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-void _initialize_i386_tdep (void);
-
 void
 _initialize_i386_tdep (void)
 {
 void
 _initialize_i386_tdep (void)
 {
@@ -9012,25 +9087,12 @@ Show Intel Memory Protection Extensions specific variables."),
  in the bound table.",
           &mpx_set_cmdlist);
 
  in the bound table.",
           &mpx_set_cmdlist);
 
-  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
-                                 i386_coff_osabi_sniffer);
-
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SVR4,
                          i386_svr4_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SVR4,
                          i386_svr4_init_abi);
-  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_GO32,
-                         i386_go32_init_abi);
 
   /* Initialize the i386-specific register groups.  */
   i386_init_reggroups ();
 
 
   /* Initialize the i386-specific register groups.  */
   i386_init_reggroups ();
 
-  /* Initialize the standard target descriptions.  */
-  initialize_tdesc_i386 ();
-  initialize_tdesc_i386_mmx ();
-  initialize_tdesc_i386_avx ();
-  initialize_tdesc_i386_mpx ();
-  initialize_tdesc_i386_avx_mpx ();
-  initialize_tdesc_i386_avx512 ();
-
   /* Tell remote stub that we support XML target description.  */
   register_remote_support_xml ("i386");
 }
   /* Tell remote stub that we support XML target description.  */
   register_remote_support_xml ("i386");
 }
This page took 0.049142 seconds and 4 git commands to generate.