]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge r1742 and r1743 (x86 and amd64 front ends: synthesise SIGILL in
authorJulian Seward <jseward@acm.org>
Sun, 29 Apr 2007 10:20:05 +0000 (10:20 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 29 Apr 2007 10:20:05 +0000 (10:20 +0000)
the normal way for some obscure invalid instruction cases, rather than
asserting, as happened in #143079 and #142279.)

git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_2_BRANCH@1755

VEX/priv/guest-amd64/toIR.c
VEX/priv/guest-x86/toIR.c

index 9265a251345201db048c365c209de598d46c60e3..d07598bdd1be384e421c289b551efdbb5f09b617 100644 (file)
@@ -2924,6 +2924,7 @@ ULong dis_Grp1 ( Prefix pfx,
       case 3: break;  // SBB
       case 4: op8 = Iop_And8; break;  case 5: op8 = Iop_Sub8; break;
       case 6: op8 = Iop_Xor8; break;  case 7: op8 = Iop_Sub8; break;
+      /*NOTREACHED*/
       default: vpanic("dis_Grp1(amd64): unhandled case");
    }
 
@@ -2991,7 +2992,7 @@ static
 ULong dis_Grp2 ( Prefix pfx,
                  Long delta, UChar modrm,
                  Int am_sz, Int d_sz, Int sz, IRExpr* shift_expr,
-                 HChar* shift_expr_txt )
+                 HChar* shift_expr_txt, Bool* decode_OK )
 {
    /* delta on entry points at the modrm byte. */
    HChar  dis_buf[50];
@@ -3002,6 +3003,8 @@ ULong dis_Grp2 ( Prefix pfx,
    IRTemp dst1  = newTemp(ty);
    IRTemp addr  = IRTemp_INVALID;
 
+   *decode_OK = True;
+
    vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
 
    /* Put value to shift/rotate in dst0. */
@@ -3023,8 +3026,13 @@ ULong dis_Grp2 ( Prefix pfx,
    isRotateC = False;
    switch (gregLO3ofRM(modrm)) { case 2: case 3: isRotateC = True; }
 
+   if (gregLO3ofRM(modrm) == 6) {
+      *decode_OK = False;
+      return delta;
+   }
+
    if (!isShift && !isRotate && !isRotateC) {
-      vex_printf("\ncase %d\n", gregLO3ofRM(modrm));
+      /*NOTREACHED*/
       vpanic("dis_Grp2(Reg): unhandled case(amd64)");
    }
 
@@ -3098,6 +3106,7 @@ ULong dis_Grp2 ( Prefix pfx,
          case 4: op64 = Iop_Shl64; break;
          case 5: op64 = Iop_Shr64; break;
          case 7: op64 = Iop_Sar64; break;
+         /*NOTREACHED*/
          default: vpanic("dis_Grp2:shift"); break;
       }
 
@@ -3432,7 +3441,7 @@ static void codegen_mulL_A_D ( Int sz, Bool syned,
 
 /* Group 3 extended opcodes. */
 static 
-ULong dis_Grp3 ( Prefix pfx, Int sz, Long delta )
+ULong dis_Grp3 ( Prefix pfx, Int sz, Long delta, Bool* decode_OK )
 {
    Long    d64;
    UChar   modrm;
@@ -3442,6 +3451,7 @@ ULong dis_Grp3 ( Prefix pfx, Int sz, Long delta )
    IRType  ty = szToITy(sz);
    IRTemp  t1 = newTemp(ty);
    IRTemp dst1, src, dst0;
+   *decode_OK = True;
    modrm = getUChar(delta);
    if (epartIsReg(modrm)) {
       switch (gregLO3ofRM(modrm)) {
@@ -3459,6 +3469,9 @@ ULong dis_Grp3 ( Prefix pfx, Int sz, Long delta )
                 nameIRegE(sz, pfx, modrm));
             break;
          }
+         case 1:
+            *decode_OK = False;
+            return delta;
          case 2: /* NOT */
             delta++;
             putIRegE(sz, pfx, modrm,
@@ -3508,9 +3521,8 @@ ULong dis_Grp3 ( Prefix pfx, Int sz, Long delta )
                                nameIRegE(sz, pfx, modrm));
             break;
          default: 
-            vex_printf(
-               "unhandled Grp3(R) case %d\n", (Int)gregLO3ofRM(modrm));
-            vpanic("Grp3(amd64)");
+            /*NOTREACHED*/
+            vpanic("Grp3(amd64,R)");
       }
    } else {
       addr = disAMode ( &len, pfx, delta, dis_buf,
@@ -3535,7 +3547,9 @@ ULong dis_Grp3 ( Prefix pfx, Int sz, Long delta )
             DIP("test%c $%lld, %s\n", nameISize(sz), d64, dis_buf);
             break;
          }
-         /* probably OK, but awaiting test case */
+         case 1:
+            *decode_OK = False;
+            return delta;
          case 2: /* NOT */
             storeLE( mkexpr(addr), unop(mkSizedOp(ty,Iop_Not8), mkexpr(t1)));
             DIP("not%c %s\n", nameISize(sz), dis_buf);
@@ -3566,9 +3580,8 @@ ULong dis_Grp3 ( Prefix pfx, Int sz, Long delta )
             DIP("idiv%c %s\n", nameISize(sz), dis_buf);
             break;
          default: 
-            vex_printf(
-               "unhandled Grp3(M) case %d\n", (Int)gregLO3ofRM(modrm));
-            vpanic("Grp3(amd64)");
+            /*NOTREACHED*/
+            vpanic("Grp3(amd64,M)");
       }
    }
    return delta;
@@ -3577,7 +3590,7 @@ ULong dis_Grp3 ( Prefix pfx, Int sz, Long delta )
 
 /* Group 4 extended opcodes. */
 static
-ULong dis_Grp4 ( Prefix pfx, Long delta )
+ULong dis_Grp4 ( Prefix pfx, Long delta, Bool* decode_OK )
 {
    Int   alen;
    UChar modrm;
@@ -3586,6 +3599,8 @@ ULong dis_Grp4 ( Prefix pfx, Long delta )
    IRTemp t1 = newTemp(ty);
    IRTemp t2 = newTemp(ty);
 
+   *decode_OK = True;
+
    modrm = getUChar(delta);
    if (epartIsReg(modrm)) {
       assign(t1, getIRegE(1, pfx, modrm));
@@ -3601,9 +3616,8 @@ ULong dis_Grp4 ( Prefix pfx, Long delta )
             setFlags_INC_DEC( False, t2, ty );
             break;
          default: 
-            vex_printf(
-               "unhandled Grp4(R) case %d\n", (Int)gregLO3ofRM(modrm));
-            vpanic("Grp4(amd64,R)");
+            *decode_OK = False;
+            return delta;
       }
       delta++;
       DIP("%sb %s\n", nameGrp4(gregLO3ofRM(modrm)),
@@ -3623,9 +3637,8 @@ ULong dis_Grp4 ( Prefix pfx, Long delta )
             setFlags_INC_DEC( False, t2, ty );
             break;
          default: 
-            vex_printf(
-               "unhandled Grp4(M) case %d\n", (Int)gregLO3ofRM(modrm));
-            vpanic("Grp4(amd64,M)");
+            *decode_OK = False;
+            return delta;
       }
       delta += alen;
       DIP("%sb %s\n", nameGrp4(gregLO3ofRM(modrm)), dis_buf);
@@ -3636,7 +3649,8 @@ ULong dis_Grp4 ( Prefix pfx, Long delta )
 
 /* Group 5 extended opcodes. */
 static
-ULong dis_Grp5 ( Prefix pfx, Int sz, Long delta, DisResult* dres )
+ULong dis_Grp5 ( Prefix pfx, Int sz, Long delta,
+                 DisResult* dres, Bool* decode_OK )
 {
    Int     len;
    UChar   modrm;
@@ -3648,6 +3662,8 @@ ULong dis_Grp5 ( Prefix pfx, Int sz, Long delta, DisResult* dres )
    IRTemp  t3 = IRTemp_INVALID;
    Bool    showSz = True;
 
+   *decode_OK = True;
+
    modrm = getUChar(delta);
    if (epartIsReg(modrm)) {
       assign(t1, getIRegE(sz,pfx,modrm));
@@ -3692,9 +3708,8 @@ ULong dis_Grp5 ( Prefix pfx, Int sz, Long delta, DisResult* dres )
             showSz = False;
             break;
          default: 
-            vex_printf(
-               "unhandled Grp5(R) case %d\n", (Int)gregLO3ofRM(modrm));
-            vpanic("Grp5(amd64)");
+            *decode_OK = False;
+            return delta;
       }
       delta++;
       DIP("%s%c %s\n", nameGrp5(gregLO3ofRM(modrm)),
@@ -3763,9 +3778,8 @@ ULong dis_Grp5 ( Prefix pfx, Int sz, Long delta, DisResult* dres )
            }
          default: 
          unhandled:
-            vex_printf(
-               "unhandled Grp5(M) case %d\n", (Int)gregLO3ofRM(modrm));
-            vpanic("Grp5(amd64)");
+            *decode_OK = False;
+            return delta;
       }
       delta += len;
       DIP("%s%c %s\n", nameGrp5(gregLO3ofRM(modrm)),
@@ -13657,7 +13671,8 @@ DisResult disInstr_AMD64_WRK (
 
    /* ------------------------ (Grp2 extensions) ---------- */
 
-   case 0xC0: /* Grp2 Ib,Eb */
+   case 0xC0: { /* Grp2 Ib,Eb */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
       modrm = getUChar(delta);
       am_sz = lengthAMode(pfx,delta);
@@ -13665,20 +13680,24 @@ DisResult disInstr_AMD64_WRK (
       d64   = getUChar(delta + am_sz);
       sz    = 1;
       delta = dis_Grp2 ( pfx, delta, modrm, am_sz, d_sz, sz, 
-                         mkU8(d64 & 0xFF), NULL );
+                         mkU8(d64 & 0xFF), NULL, &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
-
-   case 0xC1: /* Grp2 Ib,Ev */
+   }
+   case 0xC1: { /* Grp2 Ib,Ev */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
       modrm = getUChar(delta);
       am_sz = lengthAMode(pfx,delta);
       d_sz  = 1;
       d64   = getUChar(delta + am_sz);
       delta = dis_Grp2 ( pfx, delta, modrm, am_sz, d_sz, sz, 
-                         mkU8(d64 & 0xFF), NULL );
+                         mkU8(d64 & 0xFF), NULL, &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
-
-   case 0xD0: /* Grp2 1,Eb */
+   }
+   case 0xD0: { /* Grp2 1,Eb */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
       modrm = getUChar(delta);
       am_sz = lengthAMode(pfx,delta);
@@ -13686,62 +13705,82 @@ DisResult disInstr_AMD64_WRK (
       d64   = 1;
       sz    = 1;
       delta = dis_Grp2 ( pfx, delta, modrm, am_sz, d_sz, sz, 
-                         mkU8(d64), NULL );
+                         mkU8(d64), NULL, &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
-
-   case 0xD1: /* Grp2 1,Ev */
+   }
+   case 0xD1: { /* Grp2 1,Ev */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
       modrm = getUChar(delta);
       am_sz = lengthAMode(pfx,delta);
       d_sz  = 0;
       d64   = 1;
       delta = dis_Grp2 ( pfx, delta, modrm, am_sz, d_sz, sz, 
-                         mkU8(d64), NULL );
+                         mkU8(d64), NULL, &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
-
-   case 0xD2: /* Grp2 CL,Eb */
+   }
+   case 0xD2: { /* Grp2 CL,Eb */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
       modrm = getUChar(delta);
       am_sz = lengthAMode(pfx,delta);
       d_sz  = 0;
       sz    = 1;
       delta = dis_Grp2 ( pfx, delta, modrm, am_sz, d_sz, sz, 
-                         getIRegCL(), "%cl" );
+                         getIRegCL(), "%cl", &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
-
-   case 0xD3: /* Grp2 CL,Ev */
+   }
+   case 0xD3: { /* Grp2 CL,Ev */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
       modrm = getUChar(delta);
       am_sz = lengthAMode(pfx,delta);
       d_sz  = 0;
       delta = dis_Grp2 ( pfx, delta, modrm, am_sz, d_sz, sz, 
-                         getIRegCL(), "%cl" );
+                         getIRegCL(), "%cl", &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
+   }
 
    /* ------------------------ (Grp3 extensions) ---------- */
 
-   case 0xF6: /* Grp3 Eb */
+   case 0xF6: { /* Grp3 Eb */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
-      delta = dis_Grp3 ( pfx, 1, delta );
+      delta = dis_Grp3 ( pfx, 1, delta, &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
-   case 0xF7: /* Grp3 Ev */
+   }
+   case 0xF7: { /* Grp3 Ev */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
-      delta = dis_Grp3 ( pfx, sz, delta );
+      delta = dis_Grp3 ( pfx, sz, delta, &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
+   }
 
    /* ------------------------ (Grp4 extensions) ---------- */
 
-   case 0xFE: /* Grp4 Eb */
+   case 0xFE: { /* Grp4 Eb */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
-      delta = dis_Grp4 ( pfx, delta );
+      delta = dis_Grp4 ( pfx, delta, &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
+   }
 
    /* ------------------------ (Grp5 extensions) ---------- */
 
-   case 0xFF: /* Grp5 Ev */
+   case 0xFF: { /* Grp5 Ev */
+      Bool decode_OK = True;
       if (haveF2orF3(pfx)) goto decode_failure;
-      delta = dis_Grp5 ( pfx, sz, delta, &dres );
+      delta = dis_Grp5 ( pfx, sz, delta, &dres, &decode_OK );
+      if (!decode_OK) goto decode_failure;
       break;
+   }
 
    /* ------------------------ Escapes to 2-byte opcodes -- */
 
index fee7cb1cf4e7db71540d7a76269b8dda064770af..2258de824ab28fecb89d6a81047f3850debbc490 100644 (file)
@@ -2126,6 +2126,7 @@ UInt dis_Grp1 ( UChar sorb,
       case 3: break;  // SBB
       case 4: op8 = Iop_And8; break;  case 5: op8 = Iop_Sub8; break;
       case 6: op8 = Iop_Xor8; break;  case 7: op8 = Iop_Sub8; break;
+      /*NOTREACHED*/
       default: vpanic("dis_Grp1: unhandled case");
    }
 
@@ -2191,7 +2192,7 @@ static
 UInt dis_Grp2 ( UChar sorb,
                 Int delta, UChar modrm,
                 Int am_sz, Int d_sz, Int sz, IRExpr* shift_expr,
-                HChar* shift_expr_txt )
+                HChar* shift_expr_txt, Bool* decode_OK )
 {
    /* delta on entry points at the modrm byte. */
    HChar  dis_buf[50];
@@ -2202,6 +2203,8 @@ UInt dis_Grp2 ( UChar sorb,
    IRTemp dst1  = newTemp(ty);
    IRTemp addr  = IRTemp_INVALID;
 
+   *decode_OK = True;
+
    vassert(sz == 1 || sz == 2 || sz == 4);
 
    /* Put value to shift/rotate in dst0. */
@@ -2223,8 +2226,13 @@ UInt dis_Grp2 ( UChar sorb,
    isRotateC = False;
    switch (gregOfRM(modrm)) { case 2: case 3: isRotateC = True; }
 
+   if (gregOfRM(modrm) == 6) {
+      *decode_OK = False;
+      return delta;
+   }
+
    if (!isShift && !isRotate && !isRotateC) {
-      vex_printf("\ncase %d\n", gregOfRM(modrm));
+      /*NOTREACHED*/
       vpanic("dis_Grp2(Reg): unhandled case(x86)");
    }
 
@@ -2268,6 +2276,7 @@ UInt dis_Grp2 ( UChar sorb,
          case 4: op32 = Iop_Shl32; break;
          case 5: op32 = Iop_Shr32; break;
          case 7: op32 = Iop_Sar32; break;
+         /*NOTREACHED*/
          default: vpanic("dis_Grp2:shift"); break;
       }
 
@@ -2583,7 +2592,7 @@ static void codegen_mulL_A_D ( Int sz, Bool syned,
 
 /* Group 3 extended opcodes. */
 static 
-UInt dis_Grp3 ( UChar sorb, Int sz, Int delta )
+UInt dis_Grp3 ( UChar sorb, Int sz, Int delta, Bool* decode_OK )
 {
    UInt    d32;
    UChar   modrm;
@@ -2592,8 +2601,10 @@ UInt dis_Grp3 ( UChar sorb, Int sz, Int delta )
    IRTemp  addr;
    IRType  ty = szToITy(sz);
    IRTemp  t1 = newTemp(ty);
-   //   IRTemp  t2 = IRTemp_INVALID;
    IRTemp dst1, src, dst0;
+
+   *decode_OK = True; /* may change this later */
+
    modrm = getIByte(delta);
    if (epartIsReg(modrm)) {
       switch (gregOfRM(modrm)) {
@@ -2608,6 +2619,13 @@ UInt dis_Grp3 ( UChar sorb, Int sz, Int delta )
                                       nameIReg(sz, eregOfRM(modrm)));
             break;
          }
+         case 1: /* UNDEFINED */
+           /* The Intel docs imply this insn is undefined and binutils
+              agrees.  Unfortunately Core 2 will run it (with who
+              knows what result?)  sandpile.org reckons it's an alias
+              for case 0.  We play safe. */
+           *decode_OK = False;
+           break;
          case 2: /* NOT */
             delta++;
             putIReg(sz, eregOfRM(modrm),
@@ -2652,8 +2670,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, Int delta )
             DIP("idiv%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm)));
             break;
          default: 
-            vex_printf(
-               "unhandled Grp3(R) case %d\n", (Int)gregOfRM(modrm));
+            /* This can't happen - gregOfRM should return 0 .. 7 only */
             vpanic("Grp3(x86)");
       }
    } else {
@@ -2671,6 +2688,10 @@ UInt dis_Grp3 ( UChar sorb, Int sz, Int delta )
             DIP("test%c $0x%x, %s\n", nameISize(sz), d32, dis_buf);
             break;
          }
+         case 1: /* UNDEFINED */
+           /* See comment above on R case */
+           *decode_OK = False;
+           break;
          case 2: /* NOT */
             storeLE( mkexpr(addr), unop(mkSizedOp(ty,Iop_Not8), mkexpr(t1)));
             DIP("not%c %s\n", nameISize(sz), dis_buf);
@@ -2701,8 +2722,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, Int delta )
             DIP("idiv%c %s\n", nameISize(sz), dis_buf);
             break;
          default: 
-            vex_printf(
-               "unhandled Grp3(M) case %d\n", (Int)gregOfRM(modrm));
+            /* This can't happen - gregOfRM should return 0 .. 7 only */
             vpanic("Grp3(x86)");
       }
    }
@@ -2712,7 +2732,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, Int delta )
 
 /* Group 4 extended opcodes. */
 static
-UInt dis_Grp4 ( UChar sorb, Int delta )
+UInt dis_Grp4 ( UChar sorb, Int delta, Bool* decode_OK )
 {
    Int   alen;
    UChar modrm;
@@ -2721,6 +2741,8 @@ UInt dis_Grp4 ( UChar sorb, Int delta )
    IRTemp t1 = newTemp(ty);
    IRTemp t2 = newTemp(ty);
 
+   *decode_OK = True;
+
    modrm = getIByte(delta);
    if (epartIsReg(modrm)) {
       assign(t1, getIReg(1, eregOfRM(modrm)));
@@ -2736,9 +2758,8 @@ UInt dis_Grp4 ( UChar sorb, Int delta )
             setFlags_INC_DEC( False, t2, ty );
             break;
          default: 
-            vex_printf(
-               "unhandled Grp4(R) case %d\n", (Int)gregOfRM(modrm));
-            vpanic("Grp4(x86,R)");
+            *decode_OK = False;
+            return delta;
       }
       delta++;
       DIP("%sb %s\n", nameGrp4(gregOfRM(modrm)),
@@ -2758,9 +2779,8 @@ UInt dis_Grp4 ( UChar sorb, Int delta )
             setFlags_INC_DEC( False, t2, ty );
             break;
          default: 
-            vex_printf(
-               "unhandled Grp4(M) case %d\n", (Int)gregOfRM(modrm));
-            vpanic("Grp4(x86,M)");
+            *decode_OK = False;
+            return delta;
       }
       delta += alen;
       DIP("%sb %s\n", nameGrp4(gregOfRM(modrm)), dis_buf);
@@ -2771,7 +2791,8 @@ UInt dis_Grp4 ( UChar sorb, Int delta )
 
 /* Group 5 extended opcodes. */
 static
-UInt dis_Grp5 ( UChar sorb, Int sz, Int delta, DisResult* dres )
+UInt dis_Grp5 ( UChar sorb, Int sz, Int delta, 
+                DisResult* dres, Bool* decode_OK )
 {
    Int     len;
    UChar   modrm;
@@ -2781,6 +2802,8 @@ UInt dis_Grp5 ( UChar sorb, Int sz, Int delta, DisResult* dres )
    IRTemp  t1 = newTemp(ty);
    IRTemp  t2 = IRTemp_INVALID;
 
+   *decode_OK = True;
+
    modrm = getIByte(delta);
    if (epartIsReg(modrm)) {
       assign(t1, getIReg(sz,eregOfRM(modrm)));
@@ -2823,9 +2846,8 @@ UInt dis_Grp5 ( UChar sorb, Int sz, Int delta, DisResult* dres )
             storeLE( mkexpr(t2), mkexpr(t1) );
             break;
          default: 
-            vex_printf(
-               "unhandled Grp5(R) case %d\n", (Int)gregOfRM(modrm));
-            vpanic("Grp5(x86)");
+            *decode_OK = False;
+            return delta;
       }
       delta++;
       DIP("%s%c %s\n", nameGrp5(gregOfRM(modrm)),
@@ -2870,9 +2892,8 @@ UInt dis_Grp5 ( UChar sorb, Int sz, Int delta, DisResult* dres )
             storeLE( mkexpr(t2), mkexpr(t1) );
             break;
          default: 
-            vex_printf(
-               "unhandled Grp5(M) case %d\n", (Int)gregOfRM(modrm));
-            vpanic("Grp5(x86)");
+            *decode_OK = False;
+            return delta;
       }
       delta += len;
       DIP("%s%c %s\n", nameGrp5(gregOfRM(modrm)),
@@ -12331,81 +12352,116 @@ DisResult disInstr_X86_WRK (
 
    /* ------------------------ (Grp2 extensions) ---------- */
 
-   case 0xC0: /* Grp2 Ib,Eb */
+   case 0xC0: { /* Grp2 Ib,Eb */
+      Bool decode_OK = True;
       modrm = getIByte(delta);
       am_sz = lengthAMode(delta);
       d_sz  = 1;
       d32   = getUChar(delta + am_sz);
       sz    = 1;
       delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
-                         mkU8(d32 & 0xFF), NULL );
+                         mkU8(d32 & 0xFF), NULL, &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
-
-   case 0xC1: /* Grp2 Ib,Ev */
+   }
+   case 0xC1: { /* Grp2 Ib,Ev */
+      Bool decode_OK = True;
       modrm = getIByte(delta);
       am_sz = lengthAMode(delta);
       d_sz  = 1;
       d32   = getUChar(delta + am_sz);
       delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
-                         mkU8(d32 & 0xFF), NULL );
+                         mkU8(d32 & 0xFF), NULL, &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
-
-   case 0xD0: /* Grp2 1,Eb */
+   }
+   case 0xD0: { /* Grp2 1,Eb */
+      Bool decode_OK = True;
       modrm = getIByte(delta);
       am_sz = lengthAMode(delta);
       d_sz  = 0;
       d32   = 1;
       sz    = 1;
       delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
-                         mkU8(d32), NULL );
+                         mkU8(d32), NULL, &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
-
-   case 0xD1: /* Grp2 1,Ev */
+   }
+   case 0xD1: { /* Grp2 1,Ev */
+      Bool decode_OK = True;
       modrm = getUChar(delta);
       am_sz = lengthAMode(delta);
       d_sz  = 0;
       d32   = 1;
       delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
-                         mkU8(d32), NULL );
+                         mkU8(d32), NULL, &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
-
-   case 0xD2: /* Grp2 CL,Eb */
+   }
+   case 0xD2: { /* Grp2 CL,Eb */
+      Bool decode_OK = True;
       modrm = getUChar(delta);
       am_sz = lengthAMode(delta);
       d_sz  = 0;
       sz    = 1;
       delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
-                         getIReg(1,R_ECX), "%cl" );
+                         getIReg(1,R_ECX), "%cl", &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
-
-   case 0xD3: /* Grp2 CL,Ev */
+   }
+   case 0xD3: { /* Grp2 CL,Ev */
+      Bool decode_OK = True;
       modrm = getIByte(delta);
       am_sz = lengthAMode(delta);
       d_sz  = 0;
       delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
-                         getIReg(1,R_ECX), "%cl" );
+                         getIReg(1,R_ECX), "%cl", &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
+   }
 
    /* ------------------------ (Grp3 extensions) ---------- */
 
-   case 0xF6: /* Grp3 Eb */
-      delta = dis_Grp3 ( sorb, 1, delta );
+   case 0xF6: { /* Grp3 Eb */
+      Bool decode_OK = True;
+      delta = dis_Grp3 ( sorb, 1, delta, &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
-   case 0xF7: /* Grp3 Ev */
-      delta = dis_Grp3 ( sorb, sz, delta );
+   }
+   case 0xF7: { /* Grp3 Ev */
+      Bool decode_OK = True;
+      delta = dis_Grp3 ( sorb, sz, delta, &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
+   }
 
    /* ------------------------ (Grp4 extensions) ---------- */
 
-   case 0xFE: /* Grp4 Eb */
-      delta = dis_Grp4 ( sorb, delta );
+   case 0xFE: { /* Grp4 Eb */
+      Bool decode_OK = True;
+      delta = dis_Grp4 ( sorb, delta, &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
+   }
 
    /* ------------------------ (Grp5 extensions) ---------- */
 
-   case 0xFF: /* Grp5 Ev */
-      delta = dis_Grp5 ( sorb, sz, delta, &dres );
+   case 0xFF: { /* Grp5 Ev */
+      Bool decode_OK = True;
+      delta = dis_Grp5 ( sorb, sz, delta, &dres, &decode_OK );
+      if (!decode_OK)
+         goto decode_failure;
       break;
+   }
 
    /* ------------------------ Escapes to 2-byte opcodes -- */