Automatic date update in version.in
[external/binutils.git] / gdb / amd64-tdep.c
index d555465..3f61997 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for AMD64.
 
-   Copyright (C) 2001-2018 Free Software Foundation, Inc.
+   Copyright (C) 2001-2019 Free Software Foundation, Inc.
 
    Contributed by Jiri Smid, SuSE Labs.
 
@@ -39,7 +39,7 @@
 #include "disasm.h"
 #include "amd64-tdep.h"
 #include "i387-tdep.h"
-#include "x86-xstate.h"
+#include "common/x86-xstate.h"
 #include <algorithm>
 #include "target-descriptions.h"
 #include "arch/amd64.h"
@@ -352,16 +352,12 @@ amd64_pseudo_register_read_value (struct gdbarch *gdbarch,
                                  readable_regcache *regcache,
                                  int regnum)
 {
-  gdb_byte *raw_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  enum register_status status;
-  struct value *result_value;
-  gdb_byte *buf;
 
-  result_value = allocate_value (register_type (gdbarch, regnum));
+  value *result_value = allocate_value (register_type (gdbarch, regnum));
   VALUE_LVAL (result_value) = lval_register;
   VALUE_REGNUM (result_value) = regnum;
-  buf = value_contents_raw (result_value);
+  gdb_byte *buf = value_contents_raw (result_value);
 
   if (i386_byte_regnum_p (gdbarch, regnum))
     {
@@ -370,9 +366,11 @@ amd64_pseudo_register_read_value (struct gdbarch *gdbarch,
       /* Extract (always little endian).  */
       if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
        {
+         gpnum -= AMD64_NUM_LOWER_BYTE_REGS;
+         gdb_byte raw_buf[register_size (gdbarch, gpnum)];
+
          /* Special handling for AH, BH, CH, DH.  */
-         status = regcache->raw_read (gpnum - AMD64_NUM_LOWER_BYTE_REGS,
-                                      raw_buf);
+         register_status status = regcache->raw_read (gpnum, raw_buf);
          if (status == REG_VALID)
            memcpy (buf, raw_buf + 1, 1);
          else
@@ -381,7 +379,8 @@ amd64_pseudo_register_read_value (struct gdbarch *gdbarch,
        }
       else
        {
-         status = regcache->raw_read (gpnum, raw_buf);
+         gdb_byte raw_buf[register_size (gdbarch, gpnum)];
+         register_status status = regcache->raw_read (gpnum, raw_buf);
          if (status == REG_VALID)
            memcpy (buf, raw_buf, 1);
          else
@@ -392,8 +391,9 @@ amd64_pseudo_register_read_value (struct gdbarch *gdbarch,
   else if (i386_dword_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->eax_regnum;
+      gdb_byte raw_buf[register_size (gdbarch, gpnum)];
       /* Extract (always little endian).  */
-      status = regcache->raw_read (gpnum, raw_buf);
+      register_status status = regcache->raw_read (gpnum, raw_buf);
       if (status == REG_VALID)
        memcpy (buf, raw_buf, 4);
       else
@@ -412,7 +412,6 @@ amd64_pseudo_register_write (struct gdbarch *gdbarch,
                             struct regcache *regcache,
                             int regnum, const gdb_byte *buf)
 {
-  gdb_byte *raw_buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   if (i386_byte_regnum_p (gdbarch, regnum))
@@ -421,35 +420,39 @@ amd64_pseudo_register_write (struct gdbarch *gdbarch,
 
       if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
        {
+         gpnum -= AMD64_NUM_LOWER_BYTE_REGS;
+         gdb_byte raw_buf[register_size (gdbarch, gpnum)];
+
          /* Read ... AH, BH, CH, DH.  */
-         regcache_raw_read (regcache,
-                            gpnum - AMD64_NUM_LOWER_BYTE_REGS, raw_buf);
+         regcache->raw_read (gpnum, raw_buf);
          /* ... Modify ... (always little endian).  */
          memcpy (raw_buf + 1, buf, 1);
          /* ... Write.  */
-         regcache_raw_write (regcache,
-                             gpnum - AMD64_NUM_LOWER_BYTE_REGS, raw_buf);
+         regcache->raw_write (gpnum, raw_buf);
        }
       else
        {
+         gdb_byte raw_buf[register_size (gdbarch, gpnum)];
+
          /* Read ...  */
-         regcache_raw_read (regcache, gpnum, raw_buf);
+         regcache->raw_read (gpnum, raw_buf);
          /* ... Modify ... (always little endian).  */
          memcpy (raw_buf, buf, 1);
          /* ... Write.  */
-         regcache_raw_write (regcache, gpnum, raw_buf);
+         regcache->raw_write (gpnum, raw_buf);
        }
     }
   else if (i386_dword_regnum_p (gdbarch, regnum))
     {
       int gpnum = regnum - tdep->eax_regnum;
+      gdb_byte raw_buf[register_size (gdbarch, gpnum)];
 
       /* Read ...  */
-      regcache_raw_read (regcache, gpnum, raw_buf);
+      regcache->raw_read (gpnum, raw_buf);
       /* ... Modify ... (always little endian).  */
       memcpy (raw_buf, buf, 4);
       /* ... Write.  */
-      regcache_raw_write (regcache, gpnum, raw_buf);
+      regcache->raw_write (gpnum, raw_buf);
     }
   else
     i386_pseudo_register_write (gdbarch, regcache, regnum, buf);
@@ -771,15 +774,15 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function,
     {
       if (readbuf)
        {
-         regcache_raw_read (regcache, AMD64_ST0_REGNUM, readbuf);
-         regcache_raw_read (regcache, AMD64_ST1_REGNUM, readbuf + 16);
+         regcache->raw_read (AMD64_ST0_REGNUM, readbuf);
+         regcache->raw_read (AMD64_ST1_REGNUM, readbuf + 16);
        }
 
       if (writebuf)
        {
          i387_return_value (gdbarch, regcache);
-         regcache_raw_write (regcache, AMD64_ST0_REGNUM, writebuf);
-         regcache_raw_write (regcache, AMD64_ST1_REGNUM, writebuf + 16);
+         regcache->raw_write (AMD64_ST0_REGNUM, writebuf);
+         regcache->raw_write (AMD64_ST1_REGNUM, writebuf + 16);
 
          /* Fix up the tag word such that both %st(0) and %st(1) are
             marked as valid.  */
@@ -846,11 +849,11 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function,
       gdb_assert (regnum != -1);
 
       if (readbuf)
-       regcache_raw_read_part (regcache, regnum, offset, std::min (len, 8),
-                               readbuf + i * 8);
+       regcache->raw_read_part (regnum, offset, std::min (len, 8),
+                                readbuf + i * 8);
       if (writebuf)
-       regcache_raw_write_part (regcache, regnum, offset, std::min (len, 8),
-                                writebuf + i * 8);
+       regcache->raw_write_part (regnum, offset, std::min (len, 8),
+                                 writebuf + i * 8);
     }
 
   return RETURN_VALUE_REGISTER_CONVENTION;
@@ -858,8 +861,8 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function,
 \f
 
 static CORE_ADDR
-amd64_push_arguments (struct regcache *regcache, int nargs,
-                     struct value **args, CORE_ADDR sp, int struct_return)
+amd64_push_arguments (struct regcache *regcache, int nargs, struct value **args,
+                     CORE_ADDR sp, function_call_return_method return_method)
 {
   static int integer_regnum[] =
   {
@@ -887,7 +890,7 @@ amd64_push_arguments (struct regcache *regcache, int nargs,
   int i;
 
   /* Reserve a register for the "hidden" argument.  */
-  if (struct_return)
+if (return_method == return_method_struct)
     integer_reg++;
 
   for (i = 0; i < nargs; i++)
@@ -958,7 +961,7 @@ amd64_push_arguments (struct regcache *regcache, int nargs,
              gdb_assert (regnum != -1);
              memset (buf, 0, sizeof buf);
              memcpy (buf, valbuf + j * 8, std::min (len, 8));
-             regcache_raw_write_part (regcache, regnum, offset, 8, buf);
+             regcache->raw_write_part (regnum, offset, 8, buf);
            }
        }
     }
@@ -993,7 +996,8 @@ static CORE_ADDR
 amd64_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)
+                      function_call_return_method return_method,
+                      CORE_ADDR struct_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[8];
@@ -1006,13 +1010,13 @@ amd64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   i387_reset_bnd_regs (gdbarch, regcache);
 
   /* Pass arguments.  */
-  sp = amd64_push_arguments (regcache, nargs, args, sp, struct_return);
+  sp = amd64_push_arguments (regcache, nargs, args, sp, return_method);
 
   /* Pass "hidden" argument".  */
-  if (struct_return)
+  if (return_method == return_method_struct)
     {
       store_unsigned_integer (buf, 8, byte_order, struct_addr);
-      regcache_cooked_write (regcache, AMD64_RDI_REGNUM, buf);
+      regcache->cooked_write (AMD64_RDI_REGNUM, buf);
     }
 
   /* Store return address.  */
@@ -1022,10 +1026,10 @@ amd64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* Finally, update the stack pointer...  */
   store_unsigned_integer (buf, 8, byte_order, sp);
-  regcache_cooked_write (regcache, AMD64_RSP_REGNUM, buf);
+  regcache->cooked_write (AMD64_RSP_REGNUM, buf);
 
   /* ...and fake a frame pointer.  */
-  regcache_cooked_write (regcache, AMD64_RBP_REGNUM, buf);
+  regcache->cooked_write (AMD64_RBP_REGNUM, buf);
 
   return sp + 16;
 }
@@ -3227,7 +3231,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
 static void
 amd64_none_init_abi (gdbarch_info info, gdbarch *arch)
 {
-  amd64_init_abi (info, arch, amd64_target_description (X86_XSTATE_SSE_MASK));
+  amd64_init_abi (info, arch, amd64_target_description (X86_XSTATE_SSE_MASK,
+                                                       true));
 }
 
 static struct type *
@@ -3268,25 +3273,27 @@ static void
 amd64_x32_none_init_abi (gdbarch_info info, gdbarch *arch)
 {
   amd64_x32_init_abi (info, arch,
-                     amd64_target_description (X86_XSTATE_SSE_MASK));
+                     amd64_target_description (X86_XSTATE_SSE_MASK, true));
 }
 
 /* Return the target description for a specified XSAVE feature mask.  */
 
 const struct target_desc *
-amd64_target_description (uint64_t xcr0)
+amd64_target_description (uint64_t xcr0, bool segments)
 {
   static target_desc *amd64_tdescs \
-    [2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {};
+    [2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {};
   target_desc **tdesc;
 
   tdesc = &amd64_tdescs[(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 = amd64_create_target_description (xcr0, false, false);
+    *tdesc = amd64_create_target_description (xcr0, false, false,
+                                             segments);
 
   return *tdesc;
 }
@@ -3316,7 +3323,7 @@ _initialize_amd64_tdep (void)
 
   for (auto &a : xml_masks)
     {
-      auto tdesc = amd64_target_description (a.mask);
+      auto tdesc = amd64_target_description (a.mask, true);
 
       selftests::record_xml_tdesc (a.xml, tdesc);
     }
@@ -3351,9 +3358,9 @@ amd64_supply_fxsave (struct regcache *regcache, int regnum,
       const gdb_byte *regs = (const gdb_byte *) fxsave;
 
       if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
-       regcache_raw_supply (regcache, I387_FISEG_REGNUM (tdep), regs + 12);
+       regcache->raw_supply (I387_FISEG_REGNUM (tdep), regs + 12);
       if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
-       regcache_raw_supply (regcache, I387_FOSEG_REGNUM (tdep), regs + 20);
+       regcache->raw_supply (I387_FOSEG_REGNUM (tdep), regs + 20);
     }
 }
 
@@ -3372,7 +3379,6 @@ amd64_supply_xsave (struct regcache *regcache, int regnum,
       && gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
     {
       const gdb_byte *regs = (const gdb_byte *) xsave;
-      static const gdb_byte zero[I386_MAX_REGISTER_SIZE] = { 0 };
       ULONGEST clear_bv;
 
       clear_bv = i387_xsave_get_clear_bv (gdbarch, xsave);
@@ -3383,11 +3389,9 @@ amd64_supply_xsave (struct regcache *regcache, int regnum,
       if (!(clear_bv & X86_XSTATE_X87))
        {
          if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
-           regcache_raw_supply (regcache, I387_FISEG_REGNUM (tdep),
-                                regs + 12);
+           regcache->raw_supply (I387_FISEG_REGNUM (tdep), regs + 12);
          if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
-           regcache_raw_supply (regcache, I387_FOSEG_REGNUM (tdep),
-                                regs + 20);
+           regcache->raw_supply (I387_FOSEG_REGNUM (tdep), regs + 20);
        }
     }
 }
@@ -3410,9 +3414,9 @@ amd64_collect_fxsave (const struct regcache *regcache, int regnum,
   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
     {
       if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
-       regcache_raw_collect (regcache, I387_FISEG_REGNUM (tdep), regs + 12);
+       regcache->raw_collect (I387_FISEG_REGNUM (tdep), regs + 12);
       if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
-       regcache_raw_collect (regcache, I387_FOSEG_REGNUM (tdep), regs + 20);
+       regcache->raw_collect (I387_FOSEG_REGNUM (tdep), regs + 20);
     }
 }
 
@@ -3431,10 +3435,10 @@ amd64_collect_xsave (const struct regcache *regcache, int regnum,
   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
     {
       if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
-       regcache_raw_collect (regcache, I387_FISEG_REGNUM (tdep),
+       regcache->raw_collect (I387_FISEG_REGNUM (tdep),
                              regs + 12);
       if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
-       regcache_raw_collect (regcache, I387_FOSEG_REGNUM (tdep),
+       regcache->raw_collect (I387_FOSEG_REGNUM (tdep),
                              regs + 20);
     }
 }