PR server/18081: gdbserver crashes when providing an unexisting binary
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index 1841488f11262e3ab371827f81e583bbde743b39..88c17583d2b11b7eda0f0dbb479db4906a0c1f77 100644 (file)
@@ -222,12 +222,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 }
 
 /* Possible values for prefix requirement.  */
-#define PREFIX_UD_SHIFT                8
-#define PREFIX_UD_REPZ         (PREFIX_REPZ << PREFIX_UD_SHIFT)
-#define PREFIX_UD_REPNZ                (PREFIX_REPNZ << PREFIX_UD_SHIFT)
-#define PREFIX_UD_DATA         (PREFIX_DATA << PREFIX_UD_SHIFT)
-#define PREFIX_UD_ADDR         (PREFIX_ADDR << PREFIX_UD_SHIFT)
-#define PREFIX_UD_LOCK         (PREFIX_LOCK << PREFIX_UD_SHIFT)
 #define PREFIX_IGNORED_SHIFT   16
 #define PREFIX_IGNORED_REPZ    (PREFIX_REPZ << PREFIX_IGNORED_SHIFT)
 #define PREFIX_IGNORED_REPNZ   (PREFIX_REPNZ << PREFIX_IGNORED_SHIFT)
@@ -933,7 +927,9 @@ enum
   PREFIX_0FBD,
   PREFIX_0FC2,
   PREFIX_0FC3,
-  PREFIX_0FC7_REG_6,
+  PREFIX_MOD_0_0FC7_REG_6,
+  PREFIX_MOD_3_0FC7_REG_6,
+  PREFIX_MOD_3_0FC7_REG_7,
   PREFIX_0FD0,
   PREFIX_0FD6,
   PREFIX_0FE6,
@@ -2417,8 +2413,10 @@ struct dis386 {
    '%' => add 1 upper case letter to the macro.
 
    2 upper case letter macros:
-   "XY" => print 'x' or 'y' if no register operands or suffix_always
-          is true.
+   "XY" => print 'x' or 'y' if suffix_always is true or no register
+          operands and no broadcast.
+   "XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
+          register operands and no broadcast.
    "XW" => print 's', 'd' depending on the VEX.W bit (for FMA)
    "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand
           or suffix_always is true
@@ -3080,8 +3078,6 @@ static int last_addr_prefix;
 static int last_rex_prefix;
 static int last_seg_prefix;
 static int fwait_prefix;
-/* The PREFIX_REPZ/PREFIX_REPNZ/PREFIX_DATA prefix is mandatory.  */
-static int prefix_requirement;
 /* The active segment register prefix.  */
 static int active_seg_prefix;
 #define MAX_CODE_LENGTH 15
@@ -4047,13 +4043,27 @@ static const struct dis386 prefix_table[][4] = {
     { "movntiS", { Ma, Gv }, PREFIX_OPCODE },
   },
 
-  /* PREFIX_0FC7_REG_6 */
+  /* PREFIX_MOD_0_0FC7_REG_6 */
   {
     { "vmptrld",{ Mq }, 0 },
     { "vmxon", { Mq }, 0 },
     { "vmclear",{ Mq }, 0 },
   },
 
+  /* PREFIX_MOD_3_0FC7_REG_6 */
+  {
+    { "rdrand",        { Ev }, 0 },
+    { Bad_Opcode },
+    { "rdrand",        { Ev }, 0 }
+  },
+
+  /* PREFIX_MOD_3_0FC7_REG_7 */
+  {
+    { "rdseed",        { Ev }, 0 },
+    { Bad_Opcode },
+    { "rdseed",        { Ev }, 0 },
+  },
+
   /* PREFIX_0FD0 */
   {
     { Bad_Opcode },
@@ -11808,13 +11818,13 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_0FC7_REG_6 */
-    { PREFIX_TABLE (PREFIX_0FC7_REG_6) },
-    { "rdrand",                { Ev }, 0 },
+    { PREFIX_TABLE (PREFIX_MOD_0_0FC7_REG_6) },
+    { PREFIX_TABLE (PREFIX_MOD_3_0FC7_REG_6) }
   },
   {
     /* MOD_0FC7_REG_7 */
     { "vmptrst",       { Mq }, 0 },
-    { "rdseed",                { Ev }, 0 },
+    { PREFIX_TABLE (PREFIX_MOD_3_0FC7_REG_7) }
   },
   {
     /* MOD_0FD7 */
@@ -13037,14 +13047,12 @@ print_insn (bfd_vma pc, disassemble_info *info)
       threebyte = *++codep;
       dp = &dis386_twobyte[threebyte];
       need_modrm = twobyte_has_modrm[*codep];
-      prefix_requirement = dp->prefix_requirement;
       codep++;
     }
   else
     {
       dp = &dis386[*codep];
       need_modrm = onebyte_has_modrm[*codep];
-      prefix_requirement = 0;
       codep++;
     }
 
@@ -13144,7 +13152,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
      used by putop and MMX/SSE operand and may be overriden by the
      PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
      separately.  */
-  if (prefix_requirement == PREFIX_OPCODE
+  if (dp->prefix_requirement == PREFIX_OPCODE
       && dp != &bad_opcode
       && (((prefixes
            & (PREFIX_REPZ | PREFIX_REPNZ)) != 0
@@ -13789,6 +13797,34 @@ case_B:
            *obufp++ = 'd';
          break;
        case 'Z':
+         if (l != 0 || len != 1)
+           {
+             if (l != 1 || len != 2 || last[0] != 'X')
+               {
+                 SAVE_LAST (*p);
+                 break;
+               }
+             if (!need_vex || !vex.evex)
+               abort ();
+             if (intel_syntax
+                 || ((modrm.mod == 3 || vex.b) && !(sizeflag & SUFFIX_ALWAYS)))
+               break;
+             switch (vex.length)
+               {
+               case 128:
+                 *obufp++ = 'x';
+                 break;
+               case 256:
+                 *obufp++ = 'y';
+                 break;
+               case 512:
+                 *obufp++ = 'z';
+                 break;
+               default:
+                 abort ();
+               }
+             break;
+           }
          if (intel_syntax)
            break;
          if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
@@ -14087,7 +14123,7 @@ case_S:
              if (!need_vex)
                abort ();
              if (intel_syntax
-                 || (modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS)))
+                 || ((modrm.mod == 3 || vex.b) && !(sizeflag & SUFFIX_ALWAYS)))
                break;
              switch (vex.length)
                {
@@ -14097,8 +14133,10 @@ case_S:
                case 256:
                  *obufp++ = 'y';
                  break;
+               case 512:
+                 if (!vex.evex)
                default:
-                 abort ();
+                   abort ();
                }
            }
          break;
This page took 0.026467 seconds and 4 git commands to generate.