| Index: src/trusted/validator_ragel/validator_x86_64.rl
|
| ===================================================================
|
| --- src/trusted/validator_ragel/validator_x86_64.rl (revision 10967)
|
| +++ src/trusted/validator_ragel/validator_x86_64.rl (working copy)
|
| @@ -20,7 +20,7 @@
|
| #include <string.h>
|
|
|
| #include "native_client/src/trusted/validator_ragel/bitmap.h"
|
| -#include "native_client/src/trusted/validator_ragel/unreviewed/validator_internal.h"
|
| +#include "native_client/src/trusted/validator_ragel/validator_internal.h"
|
|
|
| %%{
|
| machine x86_64_validator;
|
| @@ -71,9 +71,10 @@
|
| }
|
|
|
| # Action which marks last byte as not immediate. Most 3DNow! instructions,
|
| - # some AVX and XOP instructions have this proerty. It's referenced by
|
| - # decode_x86_32 machine in [autogenerated] "validator_x86_32_instruction.rl"
|
| - # file.
|
| + # some AVX and XOP instructions have this property.
|
| + #
|
| + # This action is referenced by decode_x86_32 ragel machine in [autogenerated]
|
| + # "validator_x86_64_instruction.rl" file.
|
| action last_byte_is_not_immediate {
|
| instruction_info_collected |= LAST_BYTE_IS_NOT_IMMEDIATE;
|
| }
|
| @@ -138,7 +139,7 @@
|
| # But since these instructions are "second half" of the %rbp sandboxing they
|
| # can be used *only* when %rbp is restricted.
|
| #
|
| - # That is (normal instruction):
|
| + # Compare:
|
| # mov %eax,%ebp
|
| # mov %esi,%edi <- Error: %ebp is restricted
|
| # vs
|
| @@ -151,8 +152,10 @@
|
| # Check this precondition and mark the beginning of the instruction as
|
| # invalid jump for target.
|
| @{ if (restricted_register == REG_RBP)
|
| + /* RESTRICTED_REGISTER_USED is informational flag used in tests. */
|
| instruction_info_collected |= RESTRICTED_REGISTER_USED;
|
| else
|
| + /* UNRESTRICTED_RSP_PROCESSED is error flag used in production. */
|
| instruction_info_collected |= UNRESTRICTED_RBP_PROCESSED;
|
| restricted_register = NO_REG;
|
| UnmarkValidJumpTarget((instruction_begin - data), valid_targets);
|
| @@ -221,7 +224,7 @@
|
| # and RBASE, %rXX
|
| # jmpq *%rXX (or: callq *%rXX)
|
| # Note: first "and $~0x1f, %eXX" is a normal instruction (it can occur not
|
| - # just as part of the naclcall/nacljmp, but also as a standolene instruction).
|
| + # just as part of the naclcall/nacljmp, but also as a standalene instruction).
|
| #
|
| # This means that when naclcall_or_nacljmp ragel machine will be combined with
|
| # "normal_instruction*" regular action process_1_operand_zero_extends will be
|
| @@ -241,7 +244,7 @@
|
| # byte for the dst while last one uses field RM of the ModR/M byte for the src
|
| # and field REG of the ModR/M byte for dst. Both should be allowed.
|
| #
|
| - # See AMD/Intel manual for clarification "add" instruction encoding.
|
| + # See AMD/Intel manual for clarification about “add” instruction encoding.
|
| #
|
| # REGISTER USAGE ABBREVIATIONS:
|
| # E86: legacy ia32 registers (all eight: %eax to %edi)
|
| @@ -372,20 +375,18 @@
|
| data, valid_targets);
|
| };
|
|
|
| - # EMMS/SSE2/AVX instructions which have implicit %ds:(%rsi) operand
|
| - # maskmovq %mmX,%mmY
|
| - maskmovq =
|
| - REX_WRXB? (0x0f 0xf7)
|
| - @CPUFeature_EMMX modrm_registers;
|
| - # maskmovdqu %xmmX, %xmmY
|
| - maskmovdqu =
|
| - 0x66 REX_WRXB? (0x0f 0xf7) @not_data16_prefix
|
| - @CPUFeature_SSE2 modrm_registers;
|
| - # vmaskmovdqu %xmmX, %xmmY
|
| - vmaskmovdqu =
|
| - ((0xc4 (VEX_RB & VEX_map00001) 0x79 @vex_prefix3) |
|
| - (0xc5 (0x79 | 0xf9) @vex_prefix_short)) 0xf7
|
| - @CPUFeature_AVX modrm_registers;
|
| + # EMMX/SSE/SSE2/AVX instructions which have implicit %ds:(%rsi) operand
|
| +
|
| + # maskmovq %mmX,%mmY (EMMX or SSE)
|
| + maskmovq = REX_WRXB? 0x0f 0xf7 @CPUFeature_EMMXSSE modrm_registers;
|
| +
|
| + # maskmovdqu %xmmX, %xmmY (SSE2)
|
| + maskmovdqu = 0x66 REX_WRXB? 0x0f 0xf7 @CPUFeature_SSE2 modrm_registers;
|
| +
|
| + # vmaskmovdqu %xmmX, %xmmY (AVX)
|
| + vmaskmovdqu = ((0xc4 (VEX_RB & VEX_map00001) b_0_1111_0_01) |
|
| + (0xc5 b_X_1111_0_01)) 0xf7 @CPUFeature_AVX modrm_registers;
|
| +
|
| mmx_sse_rdi_instruction = maskmovq | maskmovdqu | vmaskmovdqu;
|
|
|
| # Temporary fix: for string instructions combination of data16 and rep(ne)
|
| @@ -553,7 +554,7 @@
|
| # Remove special instructions which are only allowed in special cases.
|
| normal_instruction = one_instruction - special_instruction;
|
|
|
| - # Check if call is properly aligned.
|
| + # Ragel machine which checks if call is properly aligned.
|
| #
|
| # For direct call we explicitly encode all variations. For indirect call
|
| # we accept all the special instructions which ends with indirect call.
|
| @@ -633,7 +634,7 @@
|
| }
|
|
|
| # This is main ragel machine: it does 99% of validation work. There are only
|
| - # one thing to do with bundle if this machine accepts the bundle:
|
| + # one thing to do with bundle if this ragel machine accepts the bundle:
|
| # * check for the state of the restricted_register at the end of the bundle.
|
| # It's an error is %rbp or %rsp is restricted at the end of the bundle.
|
| # Additionally if all the bundles are fine you need to check that direct jumps
|
| @@ -648,6 +649,10 @@
|
|
|
| }%%
|
|
|
| +/*
|
| + * The "write data" statement causes Ragel to emit the constant static data
|
| + * needed by the ragel machine.
|
| + */
|
| %% write data;
|
|
|
| enum OperandKind {
|
| @@ -1171,7 +1176,7 @@
|
| /*
|
| * This option is usually used in tests: we will process the whole chunk
|
| * in one pass. Usually each bundle is processed separately which means
|
| - * instructions (and super-instructions) can not cross borders of the bundle.
|
| + * instructions (and "superinstructions") can not cross borders of the bundle.
|
| */
|
| if (options & PROCESS_CHUNK_AS_A_CONTIGUOUS_STREAM)
|
| end_of_bundle = data + size;
|
| @@ -1207,7 +1212,15 @@
|
| uint8_t vex_prefix2 = VEX_R | VEX_X | VEX_B;
|
| uint8_t vex_prefix3 = 0x00;
|
|
|
| + /*
|
| + * The "write init" statement causes Ragel to emit initialization code.
|
| + * This should be executed once before the ragel machine is started.
|
| + */
|
| %% write init;
|
| + /*
|
| + * The "write exec" statement causes Ragel to emit the ragel machine's
|
| + * execution code.
|
| + */
|
| %% write exec;
|
|
|
| /*
|
|
|