PR29262, memory leak in pr_function_type
[binutils-gdb.git] / gdb / i386-tdep.c
index c2835a2458d11882e75d03622b8a84270b5abc82..8501e12e24119bb9b546e2d193d6b4db3a2a6018 100644 (file)
@@ -1,6 +1,6 @@
 /* Intel 386 target-dependent stuff.
 
-   Copyright (C) 1988-2021 Free Software Foundation, Inc.
+   Copyright (C) 1988-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -67,6 +67,8 @@
 #include <algorithm>
 #include <unordered_set>
 #include "producer.h"
+#include "infcall.h"
+#include "maint.h"
 
 /* Register names.  */
 
@@ -167,7 +169,7 @@ const int num_lower_zmm_regs = 16;
 static int
 i386_mmx_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int mm0_regnum = tdep->mm0_regnum;
 
   if (mm0_regnum < 0)
@@ -182,7 +184,7 @@ i386_mmx_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_byte_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   regnum -= tdep->al_regnum;
   return regnum >= 0 && regnum < tdep->num_byte_regs;
@@ -193,7 +195,7 @@ i386_byte_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_word_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   regnum -= tdep->ax_regnum;
   return regnum >= 0 && regnum < tdep->num_word_regs;
@@ -204,7 +206,7 @@ i386_word_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_dword_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int eax_regnum = tdep->eax_regnum;
 
   if (eax_regnum < 0)
@@ -219,7 +221,7 @@ i386_dword_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_zmmh_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int zmm0h_regnum = tdep->zmm0h_regnum;
 
   if (zmm0h_regnum < 0)
@@ -232,7 +234,7 @@ i386_zmmh_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_zmm_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int zmm0_regnum = tdep->zmm0_regnum;
 
   if (zmm0_regnum < 0)
@@ -245,7 +247,7 @@ i386_zmm_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_k_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int k0_regnum = tdep->k0_regnum;
 
   if (k0_regnum < 0)
@@ -258,7 +260,7 @@ i386_k_regnum_p (struct gdbarch *gdbarch, int regnum)
 static int
 i386_ymmh_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ymm0h_regnum = tdep->ymm0h_regnum;
 
   if (ymm0h_regnum < 0)
@@ -273,7 +275,7 @@ i386_ymmh_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_ymm_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ymm0_regnum = tdep->ymm0_regnum;
 
   if (ymm0_regnum < 0)
@@ -286,7 +288,7 @@ i386_ymm_regnum_p (struct gdbarch *gdbarch, int regnum)
 static int
 i386_ymmh_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ymm16h_regnum = tdep->ymm16h_regnum;
 
   if (ymm16h_regnum < 0)
@@ -299,7 +301,7 @@ i386_ymmh_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_ymm_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int ymm16_regnum = tdep->ymm16_regnum;
 
   if (ymm16_regnum < 0)
@@ -314,7 +316,7 @@ i386_ymm_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_bnd_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int bnd0_regnum = tdep->bnd0_regnum;
 
   if (bnd0_regnum < 0)
@@ -329,7 +331,7 @@ i386_bnd_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_xmm_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int num_xmm_regs = I387_NUM_XMM_REGS (tdep);
 
   if (num_xmm_regs == 0)
@@ -344,7 +346,7 @@ i386_xmm_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_xmm_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int num_xmm_avx512_regs = I387_NUM_XMM_AVX512_REGS (tdep);
 
   if (num_xmm_avx512_regs == 0)
@@ -357,7 +359,7 @@ i386_xmm_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
 static int
 i386_mxcsr_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (I387_NUM_XMM_REGS (tdep) == 0)
     return 0;
@@ -370,7 +372,7 @@ i386_mxcsr_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_fp_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (I387_ST0_REGNUM (tdep) < 0)
     return 0;
@@ -382,7 +384,7 @@ i386_fp_regnum_p (struct gdbarch *gdbarch, int regnum)
 int
 i386_fpc_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (I387_ST0_REGNUM (tdep) < 0)
     return 0;
@@ -396,7 +398,7 @@ i386_fpc_regnum_p (struct gdbarch *gdbarch, int regnum)
 static int
 i386_bndr_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
    if (I387_BND0R_REGNUM (tdep) < 0)
      return 0;
@@ -410,7 +412,7 @@ i386_bndr_regnum_p (struct gdbarch *gdbarch, int regnum)
 static int
 i386_mpx_ctrl_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
    if (I387_BNDCFGU_REGNUM (tdep) < 0)
      return 0;
@@ -424,7 +426,7 @@ i386_mpx_ctrl_regnum_p (struct gdbarch *gdbarch, int regnum)
 bool
 i386_pkru_regnum_p (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int pkru_regnum = tdep->pkru_regnum;
 
   if (pkru_regnum < 0)
@@ -460,7 +462,7 @@ i386_register_name (struct gdbarch *gdbarch, int regnum)
 const char *
 i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   if (i386_bnd_regnum_p (gdbarch, regnum))
     return i386_bnd_names[regnum - tdep->bnd0_regnum];
   if (i386_mmx_regnum_p (gdbarch, regnum))
@@ -483,7 +485,7 @@ i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
 static int
 i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   /* This implements what GCC calls the "default" register map
      (dbx_register_map[]).  */
@@ -530,7 +532,7 @@ i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 static int
 i386_svr4_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   /* This implements the GCC register map that tries to be compatible
      with the SVR4 C compiler for DWARF (svr4_dbx_register_map[]).  */
@@ -1851,9 +1853,9 @@ i386_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
         compilers to emit usable line notes.  */
       if (post_prologue_pc
          && (cust != NULL
-             && COMPUNIT_PRODUCER (cust) != NULL
-             && (producer_is_llvm (COMPUNIT_PRODUCER (cust))
-             || producer_is_icc_ge_19 (COMPUNIT_PRODUCER (cust)))))
+             && cust->producer () != NULL
+             && (producer_is_llvm (cust->producer ())
+             || producer_is_icc_ge_19 (cust->producer ()))))
         return std::max (start_pc, post_prologue_pc);
     }
  
@@ -2220,7 +2222,7 @@ i386_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   struct compunit_symtab *cust;
 
   cust = find_pc_compunit_symtab (pc);
-  if (cust != NULL && COMPUNIT_EPILOGUE_UNWIND_VALID (cust))
+  if (cust != NULL && cust->epilogue_unwind_valid ())
     return 0;
 
   if (target_read_memory (pc, &insn, 1))
@@ -2432,7 +2434,7 @@ static struct i386_frame_cache *
 i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct i386_frame_cache *cache;
   CORE_ADDR addr;
@@ -2521,7 +2523,8 @@ i386_sigtramp_frame_sniffer (const struct frame_unwind *self,
                             struct frame_info *this_frame,
                             void **this_prologue_cache)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
+  gdbarch *arch = get_frame_arch (this_frame);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (arch);
 
   /* We shouldn't even bother if we don't have a sigcontext_addr
      handler.  */
@@ -2608,7 +2611,8 @@ i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
   CORE_ADDR sp, jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  int jb_pc_offset = gdbarch_tdep (gdbarch)->jb_pc_offset;
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+  int jb_pc_offset = tdep->jb_pc_offset;
 
   /* If JB_PC_OFFSET is -1, we have no way to find out where the
      longjmp will land.  */
@@ -2729,7 +2733,7 @@ i386_thiscall_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                args_space_used = align_up (args_space_used, 16);
 
              write_memory (sp + args_space_used,
-                           value_contents_all (args[i]), len);
+                           value_contents_all (args[i]).data (), len);
              /* The System V ABI says that:
 
              "An argument's size is increased, if necessary, to make it a
@@ -2773,7 +2777,49 @@ i386_thiscall_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* The 'this' pointer needs to be in ECX.  */
   if (thiscall)
-    regcache->cooked_write (I386_ECX_REGNUM, value_contents_all (args[0]));
+    regcache->cooked_write (I386_ECX_REGNUM,
+                           value_contents_all (args[0]).data ());
+
+  /* If the PLT is position-independent, the SYSTEM V ABI requires %ebx to be
+     set to the address of the GOT when doing a call to a PLT address.
+     Note that we do not try to determine whether the PLT is
+     position-independent, we just set the register regardless.  */
+  CORE_ADDR func_addr = find_function_addr (function, nullptr, nullptr);
+  if (in_plt_section (func_addr))
+    {
+      struct objfile *objf = nullptr;
+      asection *asect = nullptr;
+      obj_section *osect = nullptr;
+
+      /* Get object file containing func_addr.  */
+      obj_section *func_section = find_pc_section (func_addr);
+      if (func_section != nullptr)
+       objf = func_section->objfile;
+
+      if (objf != nullptr)
+       {
+         /* Get corresponding .got.plt or .got section.  */
+         asect = bfd_get_section_by_name (objf->obfd, ".got.plt");
+         if (asect == nullptr)
+           asect = bfd_get_section_by_name (objf->obfd, ".got");
+       }
+
+      if (asect != nullptr)
+       /* Translate asection to obj_section.  */
+       osect = maint_obj_section_from_bfd_section (objf->obfd, asect, objf);
+
+      if (osect != nullptr)
+       {
+         /* Store the section address in %ebx.  */
+         store_unsigned_integer (buf, 4, byte_order, osect->addr ());
+         regcache->cooked_write (I386_EBX_REGNUM, buf);
+       }
+      else
+       {
+         /* If we would only do this for a position-independent PLT, it would
+            make sense to issue a warning here.  */
+       }
+    }
 
   /* MarkK wrote: This "+ 8" is all over the place:
      (i386_frame_this_id, i386_sigtramp_frame_this_id,
@@ -2814,11 +2860,18 @@ static void
 i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
                           struct regcache *regcache, gdb_byte *valbuf)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int len = TYPE_LENGTH (type);
   gdb_byte buf[I386_MAX_REGISTER_SIZE];
 
-  if (type->code () == TYPE_CODE_FLT)
+  /* _Float16 and _Float16 _Complex values are returned via xmm0.  */
+  if (((type->code () == TYPE_CODE_FLT) && len == 2)
+      || ((type->code () == TYPE_CODE_COMPLEX) && len == 4))
+    {
+       regcache->raw_read (I387_XMM0_REGNUM (tdep), valbuf);
+       return;
+    }
+  else if (type->code () == TYPE_CODE_FLT)
     {
       if (tdep->st0_regnum < 0)
        {
@@ -2865,7 +2918,7 @@ static void
 i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
                         struct regcache *regcache, const gdb_byte *valbuf)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int len = TYPE_LENGTH (type);
 
   if (type->code () == TYPE_CODE_FLT)
@@ -2944,7 +2997,7 @@ static const char *struct_convention = default_struct_convention;
 static int
 i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   enum type_code code = type->code ();
   int len = TYPE_LENGTH (type);
 
@@ -3046,7 +3099,7 @@ i386_return_value (struct gdbarch *gdbarch, struct value *function,
 struct type *
 i387_ext_type (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (!tdep->i387_ext_type)
     {
@@ -3064,7 +3117,7 @@ i387_ext_type (struct gdbarch *gdbarch)
 static struct type *
 i386_bnd_type (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
 
   if (!tdep->i386_bnd_type)
@@ -3100,7 +3153,7 @@ i386_bnd_type (struct gdbarch *gdbarch)
 static struct type *
 i386_zmm_type (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (!tdep->i386_zmm_type)
     {
@@ -3159,7 +3212,7 @@ i386_zmm_type (struct gdbarch *gdbarch)
 static struct type *
 i386_ymm_type (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (!tdep->i386_ymm_type)
     {
@@ -3216,7 +3269,7 @@ i386_ymm_type (struct gdbarch *gdbarch)
 static struct type *
 i386_mmx_type (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (!tdep->i386_mmx_type)
     {
@@ -3292,7 +3345,8 @@ i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 static int
 i386_mmx_regnum_to_fp_regnum (readable_regcache *regcache, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+  gdbarch *arch = regcache->arch ();
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (arch);
   int mmxreg, fpreg;
   ULONGEST fstat;
   int tos;
@@ -3317,7 +3371,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
 {
   gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
   enum register_status status;
-  gdb_byte *buf = value_contents_raw (result_value);
+  gdb_byte *buf = value_contents_raw (result_value).data ();
 
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
@@ -3333,7 +3387,7 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
     }
   else
     {
-      struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+      i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
       if (i386_bnd_regnum_p (gdbarch, regnum))
        {
          regnum -= tdep->bnd0_regnum;
@@ -3523,7 +3577,7 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     }
   else
     {
-      struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+      i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
       if (i386_bnd_regnum_p (gdbarch, regnum))
        {
@@ -3631,7 +3685,7 @@ int
 i386_ax_pseudo_register_collect (struct gdbarch *gdbarch,
                                 struct agent_expr *ax, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (i386_mmx_regnum_p (gdbarch, regnum))
     {
@@ -3848,7 +3902,7 @@ i386_supply_gregset (const struct regset *regset, struct regcache *regcache,
                     int regnum, const void *gregs, size_t len)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   const gdb_byte *regs = (const gdb_byte *) gregs;
   int i;
 
@@ -3873,7 +3927,7 @@ i386_collect_gregset (const struct regset *regset,
                      int regnum, void *gregs, size_t len)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   gdb_byte *regs = (gdb_byte *) gregs;
   int i;
 
@@ -3896,7 +3950,7 @@ i386_supply_fpregset (const struct regset *regset, struct regcache *regcache,
                      int regnum, const void *fpregs, size_t len)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (len == I387_SIZEOF_FXSAVE)
     {
@@ -3919,7 +3973,7 @@ i386_collect_fpregset (const struct regset *regset,
                       int regnum, void *fpregs, size_t len)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (len == I387_SIZEOF_FXSAVE)
     {
@@ -3951,7 +4005,7 @@ i386_iterate_over_regset_sections (struct gdbarch *gdbarch,
                                   void *cb_data,
                                   const struct regcache *regcache)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   cb (".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, &i386_gregset, NULL,
       cb_data);
@@ -4456,7 +4510,7 @@ i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 void
 i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   /* System V Release 4 uses ELF.  */
   i386_elf_init_abi (info, gdbarch);
@@ -4477,8 +4531,8 @@ i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 /* i386 register groups.  In addition to the normal groups, add "mmx"
    and "sse".  */
 
-static struct reggroup *i386_sse_reggroup;
-static struct reggroup *i386_mmx_reggroup;
+static const reggroup *i386_sse_reggroup;
+static const reggroup *i386_mmx_reggroup;
 
 static void
 i386_init_reggroups (void)
@@ -4492,20 +4546,13 @@ i386_add_reggroups (struct gdbarch *gdbarch)
 {
   reggroup_add (gdbarch, i386_sse_reggroup);
   reggroup_add (gdbarch, i386_mmx_reggroup);
-  reggroup_add (gdbarch, general_reggroup);
-  reggroup_add (gdbarch, float_reggroup);
-  reggroup_add (gdbarch, all_reggroup);
-  reggroup_add (gdbarch, save_reggroup);
-  reggroup_add (gdbarch, restore_reggroup);
-  reggroup_add (gdbarch, vector_reggroup);
-  reggroup_add (gdbarch, system_reggroup);
 }
 
 int
 i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-                         struct reggroup *group)
+                         const struct reggroup *group)
 {
-  const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  const i386_gdbarch_tdep *tdep = (i386_gdbarch_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, zmm_regnum_p, zmmh_regnum_p,
@@ -4950,7 +4997,7 @@ static int i386_record_floats (struct gdbarch *gdbarch,
                               struct i386_record_s *ir,
                               uint32_t iregnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   int i;
 
   /* Oza: Because of floating point insn push/pop of fpu stack is going to
@@ -5021,7 +5068,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
   ULONGEST addr;
   gdb_byte buf[I386_MAX_REGISTER_SIZE];
   struct i386_record_s ir;
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   uint8_t rex_w = -1;
   uint8_t rex_r = 0;
 
@@ -5037,9 +5084,9 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
   ir.gdbarch = gdbarch;
 
   if (record_debug > 1)
-    fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
-                                   "addr = %s\n",
-                       paddress (gdbarch, ir.addr));
+    gdb_printf (gdb_stdlog, "Process record: i386_process_record "
+               "addr = %s\n",
+               paddress (gdbarch, ir.addr));
 
   /* prefixes */
   while (1)
@@ -6810,8 +6857,9 @@ Do you want to stop the program?"),
 
       /* XXX */
     case 0xcc:    /* int3 */
-      printf_unfiltered (_("Process record does not support instruction "
-                          "int3.\n"));
+      gdb_printf (gdb_stderr,
+                 _("Process record does not support instruction "
+                   "int3.\n"));
       ir.addr -= 1;
       goto no_support;
       break;
@@ -6827,9 +6875,10 @@ Do you want to stop the program?"),
        if (interrupt != 0x80
            || tdep->i386_intx80_record == NULL)
          {
-           printf_unfiltered (_("Process record does not support "
-                                "instruction int 0x%02x.\n"),
-                              interrupt);
+           gdb_printf (gdb_stderr,
+                       _("Process record does not support "
+                         "instruction int 0x%02x.\n"),
+                       interrupt);
            ir.addr -= 2;
            goto no_support;
          }
@@ -6841,8 +6890,9 @@ Do you want to stop the program?"),
 
       /* XXX */
     case 0xce:    /* into */
-      printf_unfiltered (_("Process record does not support "
-                          "instruction into.\n"));
+      gdb_printf (gdb_stderr,
+                 _("Process record does not support "
+                   "instruction into.\n"));
       ir.addr -= 1;
       goto no_support;
       break;
@@ -6852,8 +6902,9 @@ Do you want to stop the program?"),
       break;
 
     case 0x62:    /* bound */
-      printf_unfiltered (_("Process record does not support "
-                          "instruction bound.\n"));
+      gdb_printf (gdb_stderr,
+                 _("Process record does not support "
+                   "instruction bound.\n"));
       ir.addr -= 1;
       goto no_support;
       break;
@@ -6888,15 +6939,17 @@ Do you want to stop the program?"),
       break;
 
     case 0x0f30:    /* wrmsr */
-      printf_unfiltered (_("Process record does not support "
-                          "instruction wrmsr.\n"));
+      gdb_printf (gdb_stderr,
+                 _("Process record does not support "
+                   "instruction wrmsr.\n"));
       ir.addr -= 2;
       goto no_support;
       break;
 
     case 0x0f32:    /* rdmsr */
-      printf_unfiltered (_("Process record does not support "
-                          "instruction rdmsr.\n"));
+      gdb_printf (gdb_stderr,
+                 _("Process record does not support "
+                   "instruction rdmsr.\n"));
       ir.addr -= 2;
       goto no_support;
       break;
@@ -6916,8 +6969,9 @@ Do you want to stop the program?"),
          }
        if (tdep->i386_sysenter_record == NULL)
          {
-           printf_unfiltered (_("Process record does not support "
-                                "instruction sysenter.\n"));
+           gdb_printf (gdb_stderr,
+                       _("Process record does not support "
+                         "instruction sysenter.\n"));
            ir.addr -= 2;
            goto no_support;
          }
@@ -6928,8 +6982,9 @@ Do you want to stop the program?"),
       break;
 
     case 0x0f35:    /* sysexit */
-      printf_unfiltered (_("Process record does not support "
-                          "instruction sysexit.\n"));
+      gdb_printf (gdb_stderr,
+                 _("Process record does not support "
+                   "instruction sysexit.\n"));
       ir.addr -= 2;
       goto no_support;
       break;
@@ -6939,8 +6994,9 @@ Do you want to stop the program?"),
        int ret;
        if (tdep->i386_syscall_record == NULL)
          {
-           printf_unfiltered (_("Process record does not support "
-                                "instruction syscall.\n"));
+           gdb_printf (gdb_stderr,
+                       _("Process record does not support "
+                         "instruction syscall.\n"));
            ir.addr -= 2;
            goto no_support;
          }
@@ -6951,8 +7007,9 @@ Do you want to stop the program?"),
       break;
 
     case 0x0f07:    /* sysret */
-      printf_unfiltered (_("Process record does not support "
-                          "instruction sysret.\n"));
+      gdb_printf (gdb_stderr,
+                 _("Process record does not support "
+                   "instruction sysret.\n"));
       ir.addr -= 2;
       goto no_support;
       break;
@@ -6965,8 +7022,9 @@ Do you want to stop the program?"),
       break;
 
     case 0xf4:    /* hlt */
-      printf_unfiltered (_("Process record does not support "
-                          "instruction hlt.\n"));
+      gdb_printf (gdb_stderr,
+                 _("Process record does not support "
+                   "instruction hlt.\n"));
       ir.addr -= 1;
       goto no_support;
       break;
@@ -8084,10 +8142,11 @@ reswitch_prefix_add:
   return 0;
 
  no_support:
-  printf_unfiltered (_("Process record does not support instruction 0x%02x "
-                      "at address %s.\n"),
-                    (unsigned int) (opcode),
-                    paddress (gdbarch, ir.orig_addr));
+  gdb_printf (gdb_stderr,
+             _("Process record does not support instruction 0x%02x "
+               "at address %s.\n"),
+             (unsigned int) (opcode),
+             paddress (gdbarch, ir.orig_addr));
   return -1;
 }
 
@@ -8177,13 +8236,13 @@ i386_floatformat_for_type (struct gdbarch *gdbarch,
        || strcmp (name, "real(kind=16)") == 0
        || strcmp (name, "real*16") == 0
        || strcmp (name, "REAL*16") == 0)
-      return floatformats_ia64_quad;
+      return floatformats_ieee_quad;
 
   return default_floatformat_for_type (gdbarch, name, len);
 }
 
 static int
-i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
+i386_validate_tdesc_p (i386_gdbarch_tdep *tdep,
                       struct tdesc_arch_data *tdesc_data)
 {
   const struct target_desc *tdesc = tdep->tdesc;
@@ -8385,7 +8444,6 @@ i386_type_align (struct gdbarch *gdbarch, struct type *type)
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch_tdep *tdep;
   struct gdbarch *gdbarch;
   const struct target_desc *tdesc;
   int mm0_regnum;
@@ -8399,7 +8457,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  Assume i386 for now.  */
-  tdep = XCNEW (struct gdbarch_tdep);
+  i386_gdbarch_tdep *tdep = new i386_gdbarch_tdep;
   gdbarch = gdbarch_alloc (&info, tdep);
 
   /* General-purpose registers.  */
@@ -8643,7 +8701,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   if (!i386_validate_tdesc_p (tdep, tdesc_data.get ()))
     {
-      xfree (tdep);
+      delete tdep;
       gdbarch_free (gdbarch);
       return NULL;
     }
@@ -8776,12 +8834,12 @@ static unsigned long
 i386_mpx_bd_base (void)
 {
   struct regcache *rcache;
-  struct gdbarch_tdep *tdep;
   ULONGEST ret;
   enum register_status regstatus;
 
   rcache = get_current_regcache ();
-  tdep = gdbarch_tdep (rcache->arch ());
+  gdbarch *arch = rcache->arch ();
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (arch);
 
   regstatus = regcache_raw_read_unsigned (rcache, tdep->bndcfgu_regnum, &ret);
 
@@ -8794,7 +8852,8 @@ i386_mpx_bd_base (void)
 int
 i386_mpx_enabled (void)
 {
-  const struct gdbarch_tdep *tdep = gdbarch_tdep (get_current_arch ());
+  gdbarch *arch = get_current_arch ();
+  i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (arch);
   const struct target_desc *tdesc = tdep->tdesc;
 
   return (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.mpx") != NULL);
@@ -8926,14 +8985,14 @@ i386_mpx_info_bounds (const char *args, int from_tty)
   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"));
+      gdb_printf (_("Intel Memory Protection Extensions not "
+                   "supported on this target.\n"));
       return;
     }
 
   if (args == NULL)
     {
-      printf_unfiltered (_("Address of pointer variable expected.\n"));
+      gdb_printf (_("Address of pointer variable expected.\n"));
       return;
     }
 
@@ -9035,19 +9094,13 @@ is \"default\"."),
                        NULL, /* FIXME: i18n: */
                        &setlist, &showlist);
 
-  /* Add "mpx" prefix for the set commands.  */
-
-  add_basic_prefix_cmd ("mpx", class_support, _("\
-Set Intel Memory Protection Extensions specific variables."),
-                       &mpx_set_cmdlist,
-                       0 /* allow-unknown */, &setlist);
-
-  /* Add "mpx" prefix for the show commands.  */
+  /* Add "mpx" prefix for the set and show commands.  */
 
-  add_show_prefix_cmd ("mpx", class_support, _("\
-Show Intel Memory Protection Extensions specific variables."),
-                      &mpx_show_cmdlist,
-                      0 /* allow-unknown */, &showlist);
+  add_setshow_prefix_cmd
+    ("mpx", class_support,
+     _("Set Intel Memory Protection Extensions specific variables."),
+     _("Show Intel Memory Protection Extensions specific variables."),
+     &mpx_set_cmdlist, &mpx_show_cmdlist, &setlist, &showlist);
 
   /* Add "bound" command for the show mpx commands list.  */