MPX: Add BND prefix for branch instructions
authorJin Kyu Song <jin.kyu.song@intel.com>
Wed, 16 Oct 2013 02:38:51 +0000 (19:38 -0700)
committerJin Kyu Song <jin.kyu.song@intel.com>
Wed, 20 Nov 2013 19:29:42 +0000 (11:29 -0800)
BND prefix is used for adding bounds checking protection
across flow control changes such as call, ret, jmp and jcc calls.

Signed-off-by: Jin Kyu Song <jin.kyu.song@intel.com>
assemble.c
disasm.c
insns.dat
insns.pl
nasm.h
nasmlib.c
parser.c
tokens.dat

index d913495..d1234ee 100644 (file)
  * \367          - address-size prefix (0x67) used as opcode extension
  * \370,\371     - match only if operand 0 meets byte jump criteria.
  *                 370 is used for Jcc, 371 is used for JMP.
+ * \372          - BND prefix (0xF2 byte) used for preserving bnd0..3
  * \373          - assemble 0x03 if bits==16, 0x05 if bits==32;
  *                 used for conditional jump over longer jump
  * \374          - this instruction takes an XMM VSIB memory EA
@@ -193,6 +194,7 @@ enum match_result {
     MERR_BADMODE,
     MERR_BADHLE,
     MERR_ENCMISMATCH,
+    MERR_BADBND,
     /*
      * Matching success; the conditional ones first
      */
@@ -547,6 +549,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, iflags_t cp,
                     case P_REPNE:
                     case P_REPNZ:
                     case P_XACQUIRE:
+                    case P_BND:
                         c = 0xF2;
                         break;
                     case P_REPE:
@@ -1739,8 +1742,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
             offset += 1;
             break;
 
-        case 0370:
-        case 0371:
+        case3(0370):
             break;
 
         case 0373:
@@ -2227,6 +2229,13 @@ static enum match_result matches(const struct itemplate *itemp,
     if ((itemp->code[0] & ~1) == 0370)
         return MOK_JUMP;
 
+    /*
+     * Check if BND prefix is allowed
+     */
+    if ((itemp->code[0] != 0372) &&
+        has_prefix(instruction, PPS_REP, P_BND))
+        return MERR_BADBND;
+
     return MOK_GOOD;
 }
 
index f50ceb9..eace1e9 100644 (file)
--- a/disasm.c
+++ b/disasm.c
@@ -862,6 +862,11 @@ static int matches(const struct itemplate *t, uint8_t *data,
         case 0371:
             break;
 
+        case 0372:
+            if (prefix->rep == 0xF2)
+                drep = P_BND;
+            break;
+
         case 0374:
             eat = EA_XMMVSIB;
             break;
index b1a1aac..8462211 100644 (file)
--- a/insns.dat
+++ b/insns.dat
@@ -275,6 +275,24 @@ CALL               mem                             [m:     odf ff /2]                              8086
 CALL           rm16                            [m:     o16 ff /2]                              8086,NOLONG
 CALL           rm32                            [m:     o32 ff /2]                              386,NOLONG
 CALL           rm64                            [m:     o64nw ff /2]                            X64
+; BND + CALL
+CALL           imm                             [i:     bnd odf e8 rel]                         8086,MPX
+CALL           imm|near                        [i:     bnd odf e8 rel]                         8086,ND,MPX
+CALL           imm16                           [i:     bnd o16 e8 rel]                         8086,NOLONG,MPX
+CALL           imm16|near                      [i:     bnd o16 e8 rel]                         8086,ND,NOLONG,MPX
+CALL           imm32                           [i:     bnd o32 e8 rel]                         386,NOLONG,MPX
+CALL           imm32|near                      [i:     bnd o32 e8 rel]                         386,ND,NOLONG,MPX
+CALL           imm64                           [i:     bnd o64nw e8 rel]                       X64,MPX
+CALL           imm64|near                      [i:     bnd o64nw e8 rel]                       X64,ND,MPX
+CALL           mem|near                        [m:     bnd odf ff /2]                          8086,ND,MPX
+CALL           rm16|near                       [m:     bnd o16 ff /2]                          8086,NOLONG,ND,MPX
+CALL           rm32|near                       [m:     bnd o32 ff /2]                          386,NOLONG,ND,MPX
+CALL           rm64|near                       [m:     bnd o64nw ff /2]                        X64,ND,MPX
+CALL           mem                             [m:     bnd odf ff /2]                          8086,MPX
+CALL           rm16                            [m:     bnd o16 ff /2]                          8086,NOLONG,MPX
+CALL           rm32                            [m:     bnd o32 ff /2]                          386,NOLONG,MPX
+CALL           rm64                            [m:     bnd o64nw ff /2]                        X64,MPX
+
 CBW            void                            [       o16 98]                                 8086
 CDQ            void                            [       o32 99]                                 386
 CDQE           void                            [       o64 98]                                 X64
@@ -708,6 +726,24 @@ JMP                mem                             [m:     odf ff /4]                              8086
 JMP            rm16                            [m:     o16 ff /4]                              8086,NOLONG
 JMP            rm32                            [m:     o32 ff /4]                              386,NOLONG
 JMP            rm64                            [m:     o64nw ff /4]                            X64
+; BND + JMP
+JMP            imm                             [i:     bnd odf e9 rel]                         8086,MPX
+JMP            imm|near                        [i:     bnd odf e9 rel]                         8086,ND,MPX
+JMP            imm16                           [i:     bnd o16 e9 rel]                         8086,NOLONG,MPX
+JMP            imm16|near                      [i:     bnd o16 e9 rel]                         8086,ND,NOLONG,MPX
+JMP            imm32                           [i:     bnd o32 e9 rel]                         386,NOLONG,MPX
+JMP            imm32|near                      [i:     bnd o32 e9 rel]                         386,ND,NOLONG,MPX
+JMP            imm64                           [i:     bnd o64nw e9 rel]                       X64,MPX
+JMP            imm64|near                      [i:     bnd o64nw e9 rel]                       X64,ND,MPX
+JMP            mem|near                        [m:     bnd odf ff /4]                          8086,ND,MPX
+JMP            rm16|near                       [m:     bnd o16 ff /4]                          8086,NOLONG,ND,MPX
+JMP            rm32|near                       [m:     bnd o32 ff /4]                          386,NOLONG,ND,MPX
+JMP            rm64|near                       [m:     bnd o64nw ff /4]                        X64,ND,MPX
+JMP            mem                             [m:     bnd odf ff /4]                          8086,MPX
+JMP            rm16                            [m:     bnd o16 ff /4]                          8086,NOLONG,MPX
+JMP            rm32                            [m:     bnd o32 ff /4]                          386,NOLONG,MPX
+JMP            rm64                            [m:     bnd o64nw ff /4]                        X64,MPX
+
 JMPE           imm                             [i:     odf 0f b8 rel]                          IA64
 JMPE           imm16                           [i:     o16 0f b8 rel]                          IA64
 JMPE           imm32                           [i:     o32 0f b8 rel]                          IA64
@@ -1119,6 +1155,12 @@ RETF             void                            [       cb]                                     8086
 RETF           imm                             [i:     ca iw]                                  8086,SW
 RETN           void                            [       c3]                                     8086
 RETN           imm                             [i:     c2 iw]                                  8086,SW
+; BND + RET
+RET            void                            [       bnd c3]                                 8086,MPX
+RET            imm                             [i:     bnd c2 iw]                              8086,SW,MPX
+RETN           void                            [       bnd c3]                                 8086,MPX
+RETN           imm                             [i:     bnd c2 iw]                              8086,SW,MPX
+
 ROL            rm8,unity                       [m-:    d0 /0]                                  8086
 ROL            rm8,reg_cl                      [m-:    d2 /0]                                  8086
 ROL            rm8,imm8                        [mi:    c0 /0 ib,u]                             186
@@ -1485,6 +1527,18 @@ Jcc              imm                             [i:     jcc8 70+c rel8]                         8086,ND
 Jcc            imm                             [i:     0f 80+c rel]                            386,ND
 Jcc            imm                             [i:     71+c jlen e9 rel]                       8086,ND
 Jcc            imm                             [i:     70+c rel8]                              8086
+; BND + Jcc
+Jcc            imm|near                        [i:     bnd odf 0f 80+c rel]            386,MPX
+Jcc            imm16|near                      [i:     bnd o16 0f 80+c rel]            386,NOLONG,MPX
+Jcc            imm32|near                      [i:     bnd o32 0f 80+c rel]            386,NOLONG,MPX
+Jcc            imm64|near                      [i:     bnd o64nw 0f 80+c rel]          X64,MPX
+Jcc            imm|short                       [i:     bnd 70+c rel8]                  8086,ND,MPX
+; TODO: check if bnd and jcc8 can be used together
+;Jcc           imm                             [i:     bnd jcc8 70+c rel8]             8086,ND,MPX
+Jcc            imm                             [i:     bnd 0f 80+c rel]                386,ND,MPX
+Jcc            imm                             [i:     bnd 71+c jlen e9 rel]           8086,ND,MPX
+Jcc            imm                             [i:     bnd 70+c rel8]                  8086,MPX
+
 SETcc          mem                             [m:     0f 90+c /0]                             386,SB
 SETcc          reg8                            [m:     0f 90+c /0]                             386
 
index 8bd76ab..2953a4d 100755 (executable)
--- a/insns.pl
+++ b/insns.pl
@@ -765,6 +765,7 @@ sub byte_code_compile($$) {
         'resb'      => 0340,
         'jcc8'      => 0370,    # Match only if Jcc possible with single byte
         'jmp8'      => 0371,    # Match only if JMP possible with single byte
+        'bnd'       => 0372,    # BND (0xF2) prefix available
         'jlen'      => 0373,    # Length of jump
         'hlexr'     => 0271,
         'hlenl'     => 0272,
diff --git a/nasm.h b/nasm.h
index 50e4b63..5ca2aa5 100644 (file)
--- a/nasm.h
+++ b/nasm.h
@@ -552,6 +552,7 @@ enum prefixes { /* instruction prefixes */
     P_WAIT,
     P_XACQUIRE,
     P_XRELEASE,
+    P_BND,
     PREFIX_ENUM_LIMIT
 };
 
index e145a76..ec1460b 100644 (file)
--- a/nasmlib.c
+++ b/nasmlib.c
@@ -564,7 +564,7 @@ void standard_extension(char *inname, char *outname, char *extension)
 static const char *prefix_names[] = {
     "a16", "a32", "a64", "asp", "lock", "o16", "o32", "o64", "osp",
     "rep", "repe", "repne", "repnz", "repz", "times", "wait",
-    "xacquire", "xrelease"
+    "xacquire", "xrelease", "bnd"
 };
 
 const char *prefix_name(int token)
index 0068ca3..e61d0a6 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -89,6 +89,7 @@ static int prefix_slot(int prefix)
     case P_REPNZ:
     case P_XACQUIRE:
     case P_XRELEASE:
+    case P_BND:
         return PPS_REP;
     case P_O16:
     case P_O32:
index d12b296..211eb09 100644 (file)
@@ -54,6 +54,7 @@ times
 wait
 xacquire
 xrelease
+bnd
 
 % TOKEN_SPECIAL, 0, 0, S_*
 abs