x86-64: bndmk, bndldx, and bndstx don't allow RIP-relative addressing
authorJan Beulich <jbeulich@novell.com>
Thu, 13 Sep 2018 09:03:35 +0000 (11:03 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 13 Sep 2018 09:03:35 +0000 (11:03 +0200)
gas/ChangeLog
gas/testsuite/gas/i386/x86-64-mpx.d
gas/testsuite/gas/i386/x86-64-mpx.s
opcodes/ChangeLog
opcodes/i386-dis.c

index 84895be..8675e2f 100644 (file)
@@ -1,3 +1,9 @@
+2018-09-13  Jan Beulich  <jbeulich@suse.com>
+
+       * testsuite/gas/i386/x86-64-mpx.s: And BNDMK case with RIP-
+       relative memory operand.
+       * testsuite/gas/i386/x86-64-mpx.d: Adjust expectations.
+
 2018-09-13  Nick Clifton  <nickc@redhat.com>
 
        * dwarf2dbg.c (generic_dwarf2_emit_offset): Use memset to
index e2a7828..bb83adc 100644 (file)
@@ -186,4 +186,5 @@ Disassembly of section .text:
 [a-f0-9]+ <bad>:
 [      ]*[a-f0-9]+:    0f 1a 30                bndldx \(%rax\),\(bad\)
 [      ]*[a-f0-9]+:    66 0f 1a c4             bndmov \(bad\),%bnd0
+[      ]*[a-f0-9]+:    f3 0f 1b 05 90 90 90 90         bndmk  \(bad\),%bnd0
 #pass
index 1263408..726e35a 100644 (file)
@@ -221,3 +221,10 @@ bad:
        .byte 0x0f
        .byte 0x1a
        .byte 0xc4
+
+       # bndmk (bad),%bnd0
+       .byte 0xf3
+       .byte 0x0f
+       .byte 0x1b
+       .byte 0x05
+       .long 0x90909090
index 1e59d00..870e8fc 100644 (file)
@@ -1,3 +1,10 @@
+2018-09-13  Jan Beulich  <jbeulich@suse.com>
+
+       * i386-dis.c (Mv_bnd, v_bndmk_mode): New.
+       (mod_table): Use Mv_bnd for bndldx, bndstx, and bndmk.
+       (intel_operand_size): Handle v_bndmk_mode.
+       (OP_E_memory): Likewise. Produce (bad) when also riprel.
+
 2018-09-08  John Darrington  <john@darrington.wattle.id.au>
 
        * disassemble.c (ARCH_s12z): Define if ARCH_all.
index 77f2e2a..930569e 100644 (file)
@@ -273,6 +273,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Mo { OP_M, o_mode }
 #define Mp { OP_M, f_mode }            /* 32 or 48 bit memory operand for LDS, LES etc */
 #define Mq { OP_M, q_mode }
+#define Mv_bnd { OP_M, v_bndmk_mode }
 #define Mx { OP_M, x_mode }
 #define Mxmm { OP_M, xmm_mode }
 #define Gb { OP_G, b_mode }
@@ -561,6 +562,8 @@ enum
   cond_jump_mode,
   loop_jcxz_mode,
   v_bnd_mode,
+  /* like v_bnd_mode in 32bit, no RIP-rel in 64bit mode.  */
+  v_bndmk_mode,
   /* operand size depends on REX prefixes.  */
   dq_mode,
   /* registers like dq_mode, memory like w_mode.  */
@@ -11646,17 +11649,17 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_0F1A_PREFIX_0 */
-    { "bndldx",                { Gbnd, Ev_bnd }, 0 },
+    { "bndldx",                { Gbnd, Mv_bnd }, 0 },
     { "nopQ",          { Ev }, 0 },
   },
   {
     /* MOD_0F1B_PREFIX_0 */
-    { "bndstx",                { Ev_bnd, Gbnd }, 0 },
+    { "bndstx",                { Mv_bnd, Gbnd }, 0 },
     { "nopQ",          { Ev }, 0 },
   },
   {
     /* MOD_0F1B_PREFIX_1 */
-    { "bndmk",         { Gbnd, Ev_bnd }, 0 },
+    { "bndmk",         { Gbnd, Mv_bnd }, 0 },
     { "nopQ",          { Ev }, 0 },
   },
   {
@@ -15083,6 +15086,7 @@ intel_operand_size (int bytemode, int sizeflag)
        oappend ("WORD PTR ");
       break;
     case v_bnd_mode:
+    case v_bndmk_mode:
     default:
       break;
     }
@@ -15343,6 +15347,7 @@ OP_E_memory (int bytemode, int sizeflag)
       int scale = 0;
       int addr32flag = !((sizeflag & AFLAG)
                         || bytemode == v_bnd_mode
+                        || bytemode == v_bndmk_mode
                         || bytemode == bnd_mode
                         || bytemode == bnd_swap_mode);
       const char **indexes64 = names64;
@@ -15419,6 +15424,11 @@ OP_E_memory (int bytemode, int sizeflag)
              if (address_mode == mode_64bit && !havesib)
                riprel = 1;
              disp = get32s ();
+             if (riprel && bytemode == v_bndmk_mode)
+               {
+                 oappend ("(bad)");
+                 return;
+               }
            }
          break;
        case 1:
@@ -15476,6 +15486,7 @@ OP_E_memory (int bytemode, int sizeflag)
 
       if ((havebase || haveindex || needaddr32 || riprel)
          && (bytemode != v_bnd_mode)
+         && (bytemode != v_bndmk_mode)
          && (bytemode != bnd_mode)
          && (bytemode != bnd_swap_mode))
        used_prefixes |= PREFIX_ADDR;