gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index 9eb1192ff5b18f499c915fdddca3587f3b608a32..1f2acae4e5c6f67a31f166eb1e0b6c92967f825e 100644 (file)
@@ -1,6 +1,6 @@
 /* Intel 386 target-dependent stuff.
 
-   Copyright (C) 1988-2017 Free Software Foundation, Inc.
+   Copyright (C) 1988-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -22,8 +22,7 @@
 #include "arch-utils.h"
 #include "command.h"
 #include "dummy-frame.h"
-#include "dwarf2-frame.h"
-#include "doublest.h"
+#include "dwarf2/frame.h"
 #include "frame.h"
 #include "frame-base.h"
 #include "frame-unwind.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 "x86-xstate.h"
+#include "gdbsupport/x86-xstate.h"
+#include "x86-tdep.h"
 
 #include "record.h"
 #include "record-full.h"
@@ -63,6 +64,7 @@
 #include "parser-defs.h"
 #include <ctype.h>
 #include <algorithm>
+#include <unordered_set>
 
 /* Register names.  */
 
@@ -517,7 +519,7 @@ i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg)
     }
 
   /* 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
@@ -574,7 +576,7 @@ 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;
 }
 
@@ -794,16 +796,17 @@ i386_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr)
   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 *
+displaced_step_copy_insn_closure_up
 i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
                               CORE_ADDR from, CORE_ADDR to,
                               struct regcache *regs)
 {
   size_t len = gdbarch_max_insn_length (gdbarch);
-  gdb_byte *buf = (gdb_byte *) xmalloc (len);
+  std::unique_ptr<i386_displaced_step_copy_insn_closure> closure
+    (new i386_displaced_step_copy_insn_closure (len));
+  gdb_byte *buf = closure->buf.data ();
 
   read_memory (from, buf, len);
 
@@ -828,7 +831,8 @@ i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
       displaced_step_dump_bytes (gdb_stdlog, buf, len);
     }
 
-  return (struct displaced_step_closure *) buf;
+  /* This is a work around for a problem with g++ 4.8.  */
+  return displaced_step_copy_insn_closure_up (closure.release ());
 }
 
 /* Fix up the state of registers and memory after having single-stepped
@@ -836,7 +840,7 @@ i386_displaced_step_copy_insn (struct gdbarch *gdbarch,
 
 void
 i386_displaced_step_fixup (struct gdbarch *gdbarch,
-                           struct displaced_step_closure *closure,
+                           struct displaced_step_copy_insn_closure *closure_,
                            CORE_ADDR from, CORE_ADDR to,
                            struct regcache *regs)
 {
@@ -848,9 +852,9 @@ i386_displaced_step_fixup (struct gdbarch *gdbarch,
      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_copy_insn_closure *closure
+    = (i386_displaced_step_copy_insn_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;
 
@@ -1503,7 +1507,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'.
 
-     ??? Should we handle SIB adressing here?
+     ??? Should we handle SIB addressing here?
      ??? Should we handle 16-bit operand-sizes here?  */
 
   /* `movl m32, %eax' */
@@ -1620,7 +1624,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,
-        %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
@@ -1946,8 +1950,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
-             && 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;
        }
     }
@@ -2081,16 +2085,15 @@ i386_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache = i386_alloc_frame_cache ();
   *this_cache = cache;
 
-  TRY
+  try
     {
       i386_frame_cache_1 (this_frame, cache);
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
-  END_CATCH
 
   return cache;
 }
@@ -2251,7 +2254,7 @@ i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache = i386_alloc_frame_cache ();
   *this_cache = cache;
 
-  TRY
+  try
     {
       cache->pc = get_frame_func (this_frame);
 
@@ -2265,12 +2268,11 @@ i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
 
       cache->base_p = 1;
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
-  END_CATCH
 
   return cache;
 }
@@ -2437,7 +2439,7 @@ i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_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;
@@ -2461,12 +2463,11 @@ i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 
       cache->base_p = 1;
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (ex.error != NOT_AVAILABLE_ERROR)
-       throw_exception (ex);
+       throw;
     }
-  END_CATCH
 
   *this_cache = cache;
   return cache;
@@ -2632,17 +2633,17 @@ static int
 i386_16_byte_align_p (struct type *type)
 {
   type = check_typedef (type);
-  if ((TYPE_CODE (type) == TYPE_CODE_DECFLOAT
-       || (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)))
+  if ((type->code () == TYPE_CODE_DECFLOAT
+       || (type->code () == TYPE_CODE_ARRAY && TYPE_VECTOR (type)))
       && TYPE_LENGTH (type) == 16)
     return 1;
-  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+  if (type->code () == TYPE_CODE_ARRAY)
     return i386_16_byte_align_p (TYPE_TARGET_TYPE (type));
-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
-      || TYPE_CODE (type) == TYPE_CODE_UNION)
+  if (type->code () == TYPE_CODE_STRUCT
+      || type->code () == TYPE_CODE_UNION)
     {
       int i;
-      for (i = 0; i < TYPE_NFIELDS (type); i++)
+      for (i = 0; i < type->num_fields (); i++)
        {
          if (i386_16_byte_align_p (TYPE_FIELD_TYPE (type, i)))
            return 1;
@@ -2667,11 +2668,15 @@ i386_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr,
   return sp - 16;
 }
 
-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,
-                     CORE_ADDR struct_addr)
+/* The "push_dummy_call" gdbarch method, optionally with the thiscall
+   calling convention.  */
+
+CORE_ADDR
+i386_thiscall_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+                              struct regcache *regcache, CORE_ADDR bp_addr,
+                              int nargs, struct value **args, CORE_ADDR sp,
+                              function_call_return_method return_method,
+                              CORE_ADDR struct_addr, bool thiscall)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[4];
@@ -2694,7 +2699,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
     {
       int args_space_used = 0;
 
-      if (struct_return)
+      if (return_method == return_method_struct)
        {
          if (write_pass)
            {
@@ -2707,7 +2712,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
            args_space += 4;
        }
 
-      for (i = 0; i < nargs; i++)
+      for (i = thiscall ? 1 : 0; i < nargs; i++)
        {
          int len = TYPE_LENGTH (value_enclosing_type (args[i]));
 
@@ -2754,10 +2759,14 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* 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.  */
-  regcache_cooked_write (regcache, I386_EBP_REGNUM, buf);
+  regcache->cooked_write (I386_EBP_REGNUM, buf);
+
+  /* The 'this' pointer needs to be in ECX.  */
+  if (thiscall)
+    regcache->cooked_write (I386_ECX_REGNUM, value_contents_all (args[0]));
 
   /* MarkK wrote: This "+ 8" is all over the place:
      (i386_frame_this_id, i386_sigtramp_frame_this_id,
@@ -2771,6 +2780,20 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   return sp + 8;
 }
 
+/* Implement the "push_dummy_call" gdbarch method.  */
+
+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,
+                     function_call_return_method return_method,
+                     CORE_ADDR struct_addr)
+{
+  return i386_thiscall_push_dummy_call (gdbarch, function, regcache, bp_addr,
+                                       nargs, args, sp, return_method,
+                                       struct_addr, false);
+}
+
 /* These registers are used for returning integers (and on some
    targets also for returning `struct' and `union' values when their
    size and alignment match an integer type).  */
@@ -2788,7 +2811,7 @@ i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
   int len = TYPE_LENGTH (type);
   gdb_byte buf[I386_MAX_REGISTER_SIZE];
 
-  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+  if (type->code () == TYPE_CODE_FLT)
     {
       if (tdep->st0_regnum < 0)
        {
@@ -2801,8 +2824,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.  */
-      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
     {
@@ -2811,14 +2834,14 @@ i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
 
       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))
        {
-         regcache_raw_read (regcache, LOW_RETURN_REGNUM, buf);
+         regcache->raw_read (LOW_RETURN_REGNUM, buf);
          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
@@ -2838,7 +2861,7 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int len = TYPE_LENGTH (type);
 
-  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+  if (type->code () == TYPE_CODE_FLT)
     {
       ULONGEST fstat;
       gdb_byte buf[I386_MAX_REGISTER_SIZE];
@@ -2857,8 +2880,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.  */
-      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
@@ -2879,12 +2902,12 @@ i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
       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))
        {
-         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__,
@@ -2915,7 +2938,7 @@ static int
 i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  enum type_code code = TYPE_CODE (type);
+  enum type_code code = type->code ();
   int len = TYPE_LENGTH (type);
 
   gdb_assert (code == TYPE_CODE_STRUCT
@@ -2929,10 +2952,10 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
 
   /* Structures consisting of a single `float', `double' or 'long
      double' member are returned in %st(0).  */
-  if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
+  if (code == TYPE_CODE_STRUCT && type->num_fields () == 1)
     {
       type = check_typedef (TYPE_FIELD_TYPE (type, 0));
-      if (TYPE_CODE (type) == TYPE_CODE_FLT)
+      if (type->code () == TYPE_CODE_FLT)
        return (len == 4 || len == 8 || len == 12);
     }
 
@@ -2950,13 +2973,13 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
                   struct type *type, struct regcache *regcache,
                   gdb_byte *readbuf, const gdb_byte *writebuf)
 {
-  enum type_code code = TYPE_CODE (type);
+  enum type_code code = type->code ();
 
   if (((code == TYPE_CODE_STRUCT
        || 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.  */
@@ -2997,7 +3020,7 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
      the structure.  Since that should work for all structures that
      have only one member, we don't bother to check the member's type
      here.  */
-  if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
+  if (code == TYPE_CODE_STRUCT && type->num_fields () == 1)
     {
       type = check_typedef (TYPE_FIELD_TYPE (type, 0));
       return i386_return_value (gdbarch, function, type, regcache,
@@ -3057,7 +3080,7 @@ i386_bnd_type (struct gdbarch *gdbarch)
       append_composite_type_field (t, "lbound", bt->builtin_data_ptr);
       append_composite_type_field (t, "ubound", bt->builtin_data_ptr);
 
-      TYPE_NAME (t) = "builtin_type_bound128";
+      t->set_name ("builtin_type_bound128");
       tdep->i386_bnd_type = t;
     }
 
@@ -3110,7 +3133,7 @@ i386_zmm_type (struct gdbarch *gdbarch)
                                   init_vector_type (bt->builtin_int128, 4));
 
       TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "builtin_type_vec512i";
+      t->set_name ("builtin_type_vec512i");
       tdep->i386_zmm_type = t;
     }
 
@@ -3163,7 +3186,7 @@ i386_ymm_type (struct gdbarch *gdbarch)
                                   init_vector_type (bt->builtin_int128, 2));
 
       TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "builtin_type_vec256i";
+      t->set_name ("builtin_type_vec256i");
       tdep->i386_ymm_type = t;
     }
 
@@ -3205,7 +3228,7 @@ i386_mmx_type (struct gdbarch *gdbarch)
                                   init_vector_type (bt->builtin_int8, 8));
 
       TYPE_VECTOR (t) = 1;
-      TYPE_NAME (t) = "builtin_type_vec64i";
+      t->set_name ("builtin_type_vec64i");
       tdep->i386_mmx_type = t;
     }
 
@@ -3248,15 +3271,15 @@ i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
    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;
-  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;
 
@@ -3269,7 +3292,7 @@ i386_mmx_regnum_to_fp_regnum (struct regcache *regcache, int regnum)
 
 void
 i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
-                                     struct regcache *regcache,
+                                     readable_regcache *regcache,
                                      int regnum,
                                      struct value *result_value)
 {
@@ -3282,7 +3305,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
       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)));
@@ -3297,9 +3320,8 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          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
@@ -3321,9 +3343,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          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
@@ -3336,18 +3356,16 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          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.  */
-             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
@@ -3356,20 +3374,18 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          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.  */
-             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
@@ -3377,9 +3393,8 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
            }
 
          /* 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
@@ -3390,17 +3405,15 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          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.  */
-         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
@@ -3410,17 +3423,15 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
        {
          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.  */
-         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
@@ -3431,7 +3442,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
          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)));
@@ -3444,7 +3455,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 
          /* 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)));
@@ -3460,7 +3471,7 @@ i386_pseudo_register_read_into_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;
@@ -3485,11 +3496,11 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       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.  */
-      regcache_raw_write (regcache, fpnum, raw_buf);
+      regcache->raw_write (fpnum, raw_buf);
     }
   else
     {
@@ -3507,9 +3518,8 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
          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;
 
@@ -3517,18 +3527,13 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
          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;
 
-         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))
        {
@@ -3537,82 +3542,64 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
          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.  */
-             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.  */
-             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.  */
-             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.  */
-         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.  */
-         regcache_raw_write (regcache,
-                            I387_XMM0_REGNUM (tdep) + regnum,
-                            buf);
+         regcache->raw_write (I387_XMM0_REGNUM (tdep) + regnum, buf);
          /* ... 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.  */
-         regcache_raw_write (regcache,
-                             I387_XMM16_REGNUM (tdep) + regnum,
-                             buf);
+         regcache->raw_write (I387_XMM16_REGNUM (tdep) + regnum, buf);
          /* ... 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 ...  */
-         regcache_raw_read (regcache, gpnum, raw_buf);
+         regcache->raw_read (gpnum, raw_buf);
          /* ... 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.  */
-         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.  */
-         regcache_raw_write (regcache, gpnum % 4, raw_buf);
+         regcache->raw_write (gpnum % 4, raw_buf);
        }
       else
        internal_error (__FILE__, __LINE__, _("invalid regnum"));
@@ -3839,7 +3826,7 @@ void
 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;
@@ -3850,7 +3837,7 @@ i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
     {
       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]);
     }
 }
 
@@ -3864,7 +3851,7 @@ i386_collect_gregset (const struct regset *regset,
                      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;
@@ -3875,7 +3862,7 @@ i386_collect_gregset (const struct regset *regset,
     {
       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]);
     }
 }
 
@@ -3887,7 +3874,7 @@ static void
 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)
@@ -3910,7 +3897,7 @@ i386_collect_fpregset (const struct regset *regset,
                       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)
@@ -3945,9 +3932,11 @@ i386_iterate_over_regset_sections (struct gdbarch *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)
-    cb (".reg2", tdep->sizeof_fpregset, tdep->fpregset, NULL, cb_data);
+    cb (".reg2", tdep->sizeof_fpregset, tdep->sizeof_fpregset, tdep->fpregset,
+       NULL, cb_data);
 }
 \f
 
@@ -3967,7 +3956,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;
-      const char *symname = indsym ? MSYMBOL_LINKAGE_NAME (indsym) : 0;
+      const char *symname = indsym ? indsym->linkage_name () : 0;
 
       if (symname)
        {
@@ -4068,10 +4057,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)'.
 
-   Return 1 if the operand was parsed successfully, zero
+   Return true if the operand was parsed successfully, false
    otherwise.  */
 
-static int
+static bool
 i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
                                       struct stap_parse_info *p)
 {
@@ -4079,7 +4068,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
 
   if (isdigit (*s) || *s == '-' || *s == '+')
     {
-      int got_minus[3];
+      bool got_minus[3];
       int i;
       long displacements[3];
       const char *start;
@@ -4088,17 +4077,17 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
       struct stoken str;
       char *endp;
 
-      got_minus[0] = 0;
+      got_minus[0] = false;
       if (*s == '+')
        ++s;
       else if (*s == '-')
        {
          ++s;
-         got_minus[0] = 1;
+         got_minus[0] = true;
        }
 
       if (!isdigit ((unsigned char) *s))
-       return 0;
+       return false;
 
       displacements[0] = strtol (s, &endp, 10);
       s = endp;
@@ -4106,20 +4095,20 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
       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;
-         got_minus[1] = 1;
+         got_minus[1] = true;
        }
 
       if (!isdigit ((unsigned char) *s))
-       return 0;
+       return false;
 
       displacements[1] = strtol (s, &endp, 10);
       s = endp;
@@ -4127,26 +4116,26 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
       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;
-         got_minus[2] = 1;
+         got_minus[2] = true;
        }
 
       if (!isdigit ((unsigned char) *s))
-       return 0;
+       return false;
 
       displacements[2] = strtol (s, &endp, 10);
       s = endp;
 
       if (*s != '(' || s[1] != '%')
-       return 0;
+       return false;
 
       s += 2;
       start = s;
@@ -4155,7 +4144,7 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
        ++s;
 
       if (*s++ != ')')
-       return 0;
+       return false;
 
       len = s - start - 1;
       regname = (char *) alloca (len + 1);
@@ -4202,10 +4191,10 @@ i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
 
       p->arg = s;
 
-      return 1;
+      return true;
     }
 
-  return 0;
+  return false;
 }
 
 /* Helper function for i386_stap_parse_special_token.
@@ -4214,10 +4203,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])'.
 
-   Return 1 if the operand was parsed successfully, zero
+   Return true if the operand was parsed successfully, false
    otherwise.  */
 
-static int
+static bool
 i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
                                              struct stap_parse_info *p)
 {
@@ -4225,9 +4214,9 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
 
   if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
     {
-      int offset_minus = 0;
+      bool offset_minus = false;
       long offset = 0;
-      int size_minus = 0;
+      bool size_minus = false;
       long size = 0;
       const char *start;
       char *base;
@@ -4241,11 +4230,11 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
       else if (*s == '-')
        {
          ++s;
-         offset_minus = 1;
+         offset_minus = true;
        }
 
       if (offset_minus && !isdigit (*s))
-       return 0;
+       return false;
 
       if (isdigit (*s))
        {
@@ -4256,7 +4245,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
        }
 
       if (*s != '(' || s[1] != '%')
-       return 0;
+       return false;
 
       s += 2;
       start = s;
@@ -4265,7 +4254,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
        ++s;
 
       if (*s != ',' || s[1] != '%')
-       return 0;
+       return false;
 
       len_base = s - start;
       base = (char *) alloca (len_base + 1);
@@ -4292,7 +4281,7 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
               index, p->saved_arg);
 
       if (*s != ',' && *s != ')')
-       return 0;
+       return false;
 
       if (*s == ',')
        {
@@ -4304,14 +4293,14 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
          else if (*s == '-')
            {
              ++s;
-             size_minus = 1;
+             size_minus = true;
            }
 
          size = strtol (s, &endp, 10);
          s = endp;
 
          if (*s != ')')
-           return 0;
+           return false;
        }
 
       ++s;
@@ -4365,10 +4354,10 @@ i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
 
       p->arg = s;
 
-      return 1;
+      return true;
     }
 
-  return 0;
+  return false;
 }
 
 /* Implementation of `gdbarch_stap_parse_special_token', as defined in
@@ -4420,6 +4409,29 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
   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
@@ -4433,6 +4445,15 @@ i386_gnu_triplet_regexp (struct gdbarch *gdbarch)
 
 \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
@@ -4459,6 +4480,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);
+  set_gdbarch_stap_adjust_register (gdbarch,
+                                   i386_stap_adjust_register);
+
+  set_gdbarch_in_indirect_branch_thunk (gdbarch,
+                                       i386_in_indirect_branch_thunk);
 }
 
 /* System V Release 4 (SVR4).  */
@@ -4518,8 +4544,8 @@ 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,
-      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,
+      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
@@ -7129,6 +7155,7 @@ Do you want to stop the program?"),
              else if (ir.rm == 1)
                break;
            }
+         /* Fall through.  */
        case 3:  /* lidt */
          if (ir.mod == 3)
            {
@@ -8123,7 +8150,7 @@ static const int i386_record_regmap[] =
 
 static int
 i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr,
-                              char **msg)
+                              std::string *msg)
 {
   int len, jumplen;
 
@@ -8156,15 +8183,15 @@ i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr,
       /* 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)
-       *msg = NULL;
+       msg->clear ();
       return 1;
     }
 }
@@ -8173,14 +8200,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.  */
 
-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
-       || 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);
@@ -8194,7 +8223,7 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
   const struct tdesc_feature *feature_core;
 
   const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx,
-                            *feature_avx512, *feature_pkeys;
+                            *feature_avx512, *feature_pkeys, *feature_segments;
   int i, num_regs, valid_p;
 
   if (! tdesc_has_registers (tdesc))
@@ -8217,6 +8246,9 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
   /* Try AVX512 registers.  */
   feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512");
 
+  /* Try 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");
 
@@ -8326,6 +8358,16 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
            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;
@@ -8345,6 +8387,31 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
   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_CODE_INT
+          || type->code () == TYPE_CODE_FLT)
+         && TYPE_LENGTH (type) > 4)
+       return 4;
+
+      /* Handle x86's funny long double.  */
+      if (type->code () == 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.  */
 
@@ -8403,7 +8470,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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
@@ -8537,14 +8604,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.  */
-  set_gdbarch_num_regs (gdbarch, I386_PKEYS_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))
-    tdesc = i386_target_description (X86_XSTATE_SSE_MASK);
+    tdesc = i386_target_description (X86_XSTATE_SSE_MASK, false);
   tdep->tdesc = tdesc;
 
   tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS;
@@ -8586,6 +8653,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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);
@@ -8711,20 +8781,21 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 /* Return the target description for a specified XSAVE feature mask.  */
 
 const struct target_desc *
-i386_target_description (uint64_t xcr0)
+i386_target_description (uint64_t xcr0, bool segments)
 {
   static target_desc *i386_tdescs \
-    [2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {};
+    [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];
+    [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]
+    [segments ? 1 : 0];
 
   if (*tdesc == NULL)
-    *tdesc = i386_create_target_description (xcr0, false);
+    *tdesc = i386_create_target_description (xcr0, false, segments);
 
   return *tdesc;
 }
@@ -8742,7 +8813,7 @@ i386_mpx_bd_base (void)
   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);
 
@@ -8863,7 +8934,7 @@ i386_mpx_print_bounds (const CORE_ADDR bt_entry[4])
 
       size = (size > -1 ? size + 1 : size);
       uiout->text (", size = ");
-      uiout->field_fmt ("size", "%s", plongest (size));
+      uiout->field_string ("size", plongest (size));
 
       uiout->text (", metadata = ");
       uiout->field_core_addr ("metadata", gdbarch, bt_entry[3]);
@@ -8968,24 +9039,9 @@ i386_mpx_set_bounds (const char *args, int from_tty)
 
 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, "");
-}
-
+void _initialize_i386_tdep ();
 void
-_initialize_i386_tdep (void)
+_initialize_i386_tdep ()
 {
   register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
 
@@ -9013,17 +9069,17 @@ is \"default\"."),
 
   /* Add "mpx" prefix for the set commands.  */
 
-  add_prefix_cmd ("mpx", class_support, set_mpx_cmd, _("\
+  add_basic_prefix_cmd ("mpx", class_support, _("\
 Set Intel Memory Protection Extensions specific variables."),
-                 &mpx_set_cmdlist, "set mpx ",
-                 0 /* allow-unknown */, &setlist);
+                       &mpx_set_cmdlist, "set mpx ",
+                       0 /* allow-unknown */, &setlist);
 
   /* Add "mpx" prefix for the show commands.  */
 
-  add_prefix_cmd ("mpx", class_support, show_mpx_cmd, _("\
+  add_show_prefix_cmd ("mpx", class_support, _("\
 Show Intel Memory Protection Extensions specific variables."),
-                 &mpx_show_cmdlist, "show mpx ",
-                 0 /* allow-unknown */, &showlist);
+                      &mpx_show_cmdlist, "show mpx ",
+                      0 /* allow-unknown */, &showlist);
 
   /* Add "bound" command for the show mpx commands list.  */
 
@@ -9047,28 +9103,4 @@ Show Intel Memory Protection Extensions specific variables."),
 
   /* Tell remote stub that we support XML target description.  */
   register_remote_support_xml ("i386");
-
-#if GDB_SELF_TEST
-  struct
-  {
-    const char *xml;
-    uint64_t mask;
-  } xml_masks[] = {
-    { "i386/i386.xml", X86_XSTATE_SSE_MASK },
-    { "i386/i386-mmx.xml", X86_XSTATE_X87_MASK },
-    { "i386/i386-avx.xml", X86_XSTATE_AVX_MASK },
-    { "i386/i386-mpx.xml", X86_XSTATE_MPX_MASK },
-    { "i386/i386-avx-mpx.xml", X86_XSTATE_AVX_MPX_MASK },
-    { "i386/i386-avx-avx512.xml", X86_XSTATE_AVX_AVX512_MASK },
-    { "i386/i386-avx-mpx-avx512-pku.xml",
-      X86_XSTATE_AVX_MPX_AVX512_PKU_MASK },
-  };
-
-  for (auto &a : xml_masks)
-    {
-      auto tdesc = i386_target_description (a.mask);
-
-      selftests::record_xml_tdesc (a.xml, tdesc);
-    }
-#endif /* GDB_SELF_TEST */
 }
This page took 0.066718 seconds and 4 git commands to generate.