Mark Wielaard 7ca9bd
diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c
Mark Wielaard 7ca9bd
index 40da6bf..fba7084 100644
Mark Wielaard 7ca9bd
--- a/VEX/priv/guest_amd64_toIR.c
Mark Wielaard 7ca9bd
+++ b/VEX/priv/guest_amd64_toIR.c
Mark Wielaard 7ca9bd
@@ -767,10 +767,10 @@ static Bool have66orF2orF3 ( Prefix pfx )
Mark Wielaard 7ca9bd
   return toBool( ! haveNo66noF2noF3(pfx) );
Mark Wielaard 7ca9bd
 }
Mark Wielaard 7ca9bd
 
Mark Wielaard 7ca9bd
-/* Return True iff pfx has 66 or F2 set */
Mark Wielaard 7ca9bd
-static Bool have66orF2 ( Prefix pfx )
Mark Wielaard 7ca9bd
+/* Return True iff pfx has 66 or F3 set */
Mark Wielaard 7ca9bd
+static Bool have66orF3 ( Prefix pfx )
Mark Wielaard 7ca9bd
 {
Mark Wielaard 7ca9bd
-   return toBool((pfx & (PFX_66|PFX_F2)) > 0);
Mark Wielaard 7ca9bd
+   return toBool((pfx & (PFX_66|PFX_F3)) > 0);
Mark Wielaard 7ca9bd
 }
Mark Wielaard 7ca9bd
 
Mark Wielaard 7ca9bd
 /* Clear all the segment-override bits in a prefix. */
Mark Wielaard 7ca9bd
@@ -4266,8 +4266,12 @@ ULong dis_Grp5 ( VexAbiInfo* vbi,
Mark Wielaard 7ca9bd
 
Mark Wielaard 7ca9bd
    modrm = getUChar(delta);
Mark Wielaard 7ca9bd
    if (epartIsReg(modrm)) {
Mark Wielaard 7ca9bd
-      /* F2/XACQ and F3/XREL are always invalid in the non-mem case. */
Mark Wielaard 7ca9bd
-      if (haveF2orF3(pfx)) goto unhandledR;
Mark Wielaard 7ca9bd
+      /* F2/XACQ and F3/XREL are always invalid in the non-mem case.
Mark Wielaard 7ca9bd
+         F2/CALL and F2/JMP may have bnd prefix. */
Mark Wielaard 7ca9bd
+     if (haveF2orF3(pfx)
Mark Wielaard 7ca9bd
+         && ! (haveF2(pfx)
Mark Wielaard 7ca9bd
+               && (gregLO3ofRM(modrm) == 2 || gregLO3ofRM(modrm) == 4)))
Mark Wielaard 7ca9bd
+        goto unhandledR;
Mark Wielaard 7ca9bd
       assign(t1, getIRegE(sz,pfx,modrm));
Mark Wielaard 7ca9bd
       switch (gregLO3ofRM(modrm)) {
Mark Wielaard 7ca9bd
          case 0: /* INC */
Mark Wielaard 7ca9bd
@@ -4287,6 +4291,7 @@ ULong dis_Grp5 ( VexAbiInfo* vbi,
Mark Wielaard 7ca9bd
          case 2: /* call Ev */
Mark Wielaard 7ca9bd
             /* Ignore any sz value and operate as if sz==8. */
Mark Wielaard 7ca9bd
             if (!(sz == 4 || sz == 8)) goto unhandledR;
Mark Wielaard 7ca9bd
+            if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
             sz = 8;
Mark Wielaard 7ca9bd
             t3 = newTemp(Ity_I64);
Mark Wielaard 7ca9bd
             assign(t3, getIRegE(sz,pfx,modrm));
Mark Wielaard 7ca9bd
@@ -4302,6 +4307,7 @@ ULong dis_Grp5 ( VexAbiInfo* vbi,
Mark Wielaard 7ca9bd
          case 4: /* jmp Ev */
Mark Wielaard 7ca9bd
             /* Ignore any sz value and operate as if sz==8. */
Mark Wielaard 7ca9bd
             if (!(sz == 4 || sz == 8)) goto unhandledR;
Mark Wielaard 7ca9bd
+            if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
             sz = 8;
Mark Wielaard 7ca9bd
             t3 = newTemp(Ity_I64);
Mark Wielaard 7ca9bd
             assign(t3, getIRegE(sz,pfx,modrm));
Mark Wielaard 7ca9bd
@@ -4334,11 +4340,14 @@ ULong dis_Grp5 ( VexAbiInfo* vbi,
Mark Wielaard 7ca9bd
                        showSz ? nameISize(sz) : ' ', 
Mark Wielaard 7ca9bd
                        nameIRegE(sz, pfx, modrm));
Mark Wielaard 7ca9bd
    } else {
Mark Wielaard 7ca9bd
-      /* Decide if F2/XACQ or F3/XREL might be valid. */
Mark Wielaard 7ca9bd
+      /* Decide if F2/XACQ, F3/XREL, F2/CALL or F2/JMP might be valid. */
Mark Wielaard 7ca9bd
       Bool validF2orF3 = haveF2orF3(pfx) ? False : True;
Mark Wielaard 7ca9bd
       if ((gregLO3ofRM(modrm) == 0/*INC*/ || gregLO3ofRM(modrm) == 1/*DEC*/)
Mark Wielaard 7ca9bd
           && haveF2orF3(pfx) && !haveF2andF3(pfx) && haveLOCK(pfx)) {
Mark Wielaard 7ca9bd
          validF2orF3 = True;
Mark Wielaard 7ca9bd
+      } else if ((gregLO3ofRM(modrm) == 2 || gregLO3ofRM(modrm) == 4)
Mark Wielaard 7ca9bd
+                 && (haveF2(pfx) && !haveF3(pfx))) {
Mark Wielaard 7ca9bd
+         validF2orF3 = True;
Mark Wielaard 7ca9bd
       }
Mark Wielaard 7ca9bd
       if (!validF2orF3) goto unhandledM;
Mark Wielaard 7ca9bd
       /* */
Mark Wielaard 7ca9bd
@@ -4375,6 +4384,7 @@ ULong dis_Grp5 ( VexAbiInfo* vbi,
Mark Wielaard 7ca9bd
          case 2: /* call Ev */
Mark Wielaard 7ca9bd
             /* Ignore any sz value and operate as if sz==8. */
Mark Wielaard 7ca9bd
             if (!(sz == 4 || sz == 8)) goto unhandledM;
Mark Wielaard 7ca9bd
+            if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
             sz = 8;
Mark Wielaard 7ca9bd
             t3 = newTemp(Ity_I64);
Mark Wielaard 7ca9bd
             assign(t3, loadLE(Ity_I64,mkexpr(addr)));
Mark Wielaard 7ca9bd
@@ -4390,6 +4400,7 @@ ULong dis_Grp5 ( VexAbiInfo* vbi,
Mark Wielaard 7ca9bd
          case 4: /* JMP Ev */
Mark Wielaard 7ca9bd
             /* Ignore any sz value and operate as if sz==8. */
Mark Wielaard 7ca9bd
             if (!(sz == 4 || sz == 8)) goto unhandledM;
Mark Wielaard 7ca9bd
+            if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
             sz = 8;
Mark Wielaard 7ca9bd
             t3 = newTemp(Ity_I64);
Mark Wielaard 7ca9bd
             assign(t3, loadLE(Ity_I64,mkexpr(addr)));
Mark Wielaard 7ca9bd
@@ -19716,7 +19727,8 @@ Long dis_ESC_NONE (
Mark Wielaard 7ca9bd
    case 0x7F: { /* JGb/JNLEb (jump greater) */
Mark Wielaard 7ca9bd
       Long   jmpDelta;
Mark Wielaard 7ca9bd
       const HChar* comment  = "";
Mark Wielaard 7ca9bd
-      if (haveF2orF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (haveF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
       jmpDelta = getSDisp8(delta);
Mark Wielaard 7ca9bd
       vassert(-128 <= jmpDelta && jmpDelta < 128);
Mark Wielaard 7ca9bd
       d64 = (guest_RIP_bbstart+delta+1) + jmpDelta;
Mark Wielaard 7ca9bd
@@ -20369,7 +20381,8 @@ Long dis_ESC_NONE (
Mark Wielaard 7ca9bd
    }
Mark Wielaard 7ca9bd
 
Mark Wielaard 7ca9bd
    case 0xC2: /* RET imm16 */
Mark Wielaard 7ca9bd
-      if (have66orF2orF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (have66orF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
       d64 = getUDisp16(delta); 
Mark Wielaard 7ca9bd
       delta += 2;
Mark Wielaard 7ca9bd
       dis_ret(dres, vbi, d64);
Mark Wielaard 7ca9bd
@@ -20377,8 +20390,9 @@ Long dis_ESC_NONE (
Mark Wielaard 7ca9bd
       return delta;
Mark Wielaard 7ca9bd
 
Mark Wielaard 7ca9bd
    case 0xC3: /* RET */
Mark Wielaard 7ca9bd
-      if (have66orF2(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (have66(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
       /* F3 is acceptable on AMD. */
Mark Wielaard 7ca9bd
+      if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
       dis_ret(dres, vbi, 0);
Mark Wielaard 7ca9bd
       DIP(haveF3(pfx) ? "rep ; ret\n" : "ret\n");
Mark Wielaard 7ca9bd
       return delta;
Mark Wielaard 7ca9bd
@@ -20782,7 +20796,8 @@ Long dis_ESC_NONE (
Mark Wielaard 7ca9bd
    }
Mark Wielaard 7ca9bd
 
Mark Wielaard 7ca9bd
    case 0xE8: /* CALL J4 */
Mark Wielaard 7ca9bd
-      if (haveF2orF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (haveF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
       d64 = getSDisp32(delta); delta += 4;
Mark Wielaard 7ca9bd
       d64 += (guest_RIP_bbstart+delta); 
Mark Wielaard 7ca9bd
       /* (guest_RIP_bbstart+delta) == return-to addr, d64 == call-to addr */
Mark Wielaard 7ca9bd
@@ -20805,9 +20820,10 @@ Long dis_ESC_NONE (
Mark Wielaard 7ca9bd
       return delta;
Mark Wielaard 7ca9bd
 
Mark Wielaard 7ca9bd
    case 0xE9: /* Jv (jump, 16/32 offset) */
Mark Wielaard 7ca9bd
-      if (haveF2orF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (haveF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
       if (sz != 4) 
Mark Wielaard 7ca9bd
          goto decode_failure; /* JRS added 2004 July 11 */
Mark Wielaard 7ca9bd
+      if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
       d64 = (guest_RIP_bbstart+delta+sz) + getSDisp(sz,delta); 
Mark Wielaard 7ca9bd
       delta += sz;
Mark Wielaard 7ca9bd
       if (resteerOkFn(callback_opaque,d64)) {
Mark Wielaard 7ca9bd
@@ -21241,7 +21257,8 @@ Long dis_ESC_0F (
Mark Wielaard 7ca9bd
    case 0x8F: { /* JGb/JNLEb (jump greater) */
Mark Wielaard 7ca9bd
       Long   jmpDelta;
Mark Wielaard 7ca9bd
       const HChar* comment  = "";
Mark Wielaard 7ca9bd
-      if (haveF2orF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (haveF3(pfx)) goto decode_failure;
Mark Wielaard 7ca9bd
+      if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */
Mark Wielaard 7ca9bd
       jmpDelta = getSDisp32(delta);
Mark Wielaard 7ca9bd
       d64 = (guest_RIP_bbstart+delta+4) + jmpDelta;
Mark Wielaard 7ca9bd
       delta += 4;
Mark Wielaard 7ca9bd
@@ -21332,6 +21349,66 @@ Long dis_ESC_0F (
Mark Wielaard 7ca9bd
       }
Mark Wielaard 7ca9bd
       return delta;
Mark Wielaard 7ca9bd
 
Mark Wielaard 7ca9bd
+   case 0x1A:
Mark Wielaard 7ca9bd
+   case 0x1B: { /* Future MPX instructions, currently NOPs.
Mark Wielaard 7ca9bd
+                   BNDMK b, m     F3 0F 1B
Mark Wielaard 7ca9bd
+                   BNDCL b, r/m   F3 0F 1A
Mark Wielaard 7ca9bd
+                   BNDCU b, r/m   F2 0F 1A
Mark Wielaard 7ca9bd
+                   BNDCN b, r/m   F2 0F 1B
Mark Wielaard 7ca9bd
+                   BNDMOV b, b/m  66 0F 1A
Mark Wielaard 7ca9bd
+                   BNDMOV b/m, b  66 0F 1B
Mark Wielaard 7ca9bd
+                   BNDLDX b, mib     0F 1A
Mark Wielaard 7ca9bd
+                   BNDSTX mib, b     0F 1B */
Mark Wielaard 7ca9bd
+
Mark Wielaard 7ca9bd
+      /* All instructions have two operands. One operand is always the
Mark Wielaard 7ca9bd
+         bnd register number (bnd0-bnd3, other register numbers are
Mark Wielaard 7ca9bd
+         ignored when MPX isn't enabled, but should generate an
Mark Wielaard 7ca9bd
+         exeception if MPX is enabled) given by gregOfRexRM. The other
Mark Wielaard 7ca9bd
+         operand is either a ModRM:reg, ModRM:r/m or a SIB encoded
Mark Wielaard 7ca9bd
+         address, all of which can be decoded by using either
Mark Wielaard 7ca9bd
+         eregOfRexRM or disAMode. */
Mark Wielaard 7ca9bd
+
Mark Wielaard 7ca9bd
+      modrm = getUChar(delta);
Mark Wielaard 7ca9bd
+      int bnd = gregOfRexRM(pfx,modrm);
Mark Wielaard 7ca9bd
+      const HChar *oper;
Mark Wielaard 7ca9bd
+      if (epartIsReg(modrm)) {
Mark Wielaard 7ca9bd
+         oper = nameIReg64 (eregOfRexRM(pfx,modrm));
Mark Wielaard 7ca9bd
+         delta += 1;
Mark Wielaard 7ca9bd
+      } else {
Mark Wielaard 7ca9bd
+         addr = disAMode ( &alen, vbi, pfx, delta, dis_buf, 0 );
Mark Wielaard 7ca9bd
+         delta += alen;
Mark Wielaard 7ca9bd
+         oper = dis_buf;
Mark Wielaard 7ca9bd
+      }
Mark Wielaard 7ca9bd
+
Mark Wielaard 7ca9bd
+      if (haveF3no66noF2 (pfx)) {
Mark Wielaard 7ca9bd
+         if (opc == 0x1B) {
Mark Wielaard 7ca9bd
+            DIP ("bndmk %s, %%bnd%d\n", oper, bnd);
Mark Wielaard 7ca9bd
+         } else /* opc == 0x1A */ {
Mark Wielaard 7ca9bd
+            DIP ("bndcl %s, %%bnd%d\n", oper, bnd);
Mark Wielaard 7ca9bd
+         }
Mark Wielaard 7ca9bd
+      } else if (haveF2no66noF3 (pfx)) {
Mark Wielaard 7ca9bd
+         if (opc == 0x1A) {
Mark Wielaard 7ca9bd
+            DIP ("bndcu %s, %%bnd%d\n", oper, bnd);
Mark Wielaard 7ca9bd
+         } else /* opc == 0x1B */ {
Mark Wielaard 7ca9bd
+            DIP ("bndcn %s, %%bnd%d\n", oper, bnd);
Mark Wielaard 7ca9bd
+         }
Mark Wielaard 7ca9bd
+      } else if (have66noF2noF3 (pfx)) {
Mark Wielaard 7ca9bd
+         if (opc == 0x1A) {
Mark Wielaard 7ca9bd
+            DIP ("bndmov %s, %%bnd%d\n", oper, bnd);
Mark Wielaard 7ca9bd
+         } else /* opc == 0x1B */ {
Mark Wielaard 7ca9bd
+            DIP ("bndmov %%bnd%d, %s\n", bnd, oper);
Mark Wielaard 7ca9bd
+         }
Mark Wielaard 7ca9bd
+      } else if (haveNo66noF2noF3 (pfx)) {
Mark Wielaard 7ca9bd
+         if (opc == 0x1A) {
Mark Wielaard 7ca9bd
+            DIP ("bndldx %s, %%bnd%d\n", oper, bnd);
Mark Wielaard 7ca9bd
+         } else /* opc == 0x1B */ {
Mark Wielaard 7ca9bd
+            DIP ("bndstx %%bnd%d, %s\n", bnd, oper);
Mark Wielaard 7ca9bd
+         }
Mark Wielaard 7ca9bd
+      } else goto decode_failure;
Mark Wielaard 7ca9bd
+
Mark Wielaard 7ca9bd
+      return delta;
Mark Wielaard 7ca9bd
+   }
Mark Wielaard 7ca9bd
+
Mark Wielaard 7ca9bd
    case 0xA2: { /* CPUID */
Mark Wielaard 7ca9bd
       /* Uses dirty helper: 
Mark Wielaard 7ca9bd
             void amd64g_dirtyhelper_CPUID ( VexGuestAMD64State* )