Chromium Code Reviews| Index: src/trusted/validator_ragel/validator_x86_32.rl |
| =================================================================== |
| --- src/trusted/validator_ragel/validator_x86_32.rl (revision 9944) |
| +++ src/trusted/validator_ragel/validator_x86_32.rl (working copy) |
| @@ -4,6 +4,14 @@ |
| * found in the LICENSE file. |
| */ |
| +/* |
| + * This is the core of ia32-mode validator. Please note that this file |
| + * combines ragel machine description and C language actions. Please read |
| + * validator_internals.html first to understand how the whole thing is built: |
| + * it explains how the byte sequences are constructed, what constructs like |
| + * “@{}” or “REX_WRX?” mean, etc. |
| + */ |
| + |
| #include <assert.h> |
| #include <errno.h> |
| #include <stddef.h> |
| @@ -11,7 +19,7 @@ |
| #include <stdlib.h> |
| #include <string.h> |
| -#include "native_client/src/trusted/validator_ragel/unreviewed/validator_internal.h" |
| +#include "native_client/src/trusted/validator_ragel/validator_internal.h" |
| /* Ignore this information: it's not used by security model in IA32 mode. */ |
| #undef GET_VEX_PREFIX3 |
| @@ -47,13 +55,20 @@ |
| "native_client/src/trusted/validator_ragel/unreviewed/parse_instruction.rl"; |
| include immediate_fields_parsing_ia32 |
| "native_client/src/trusted/validator_ragel/unreviewed/parse_instruction.rl"; |
| + # rel8 actions are used in relative jumps with 8-bit offset. |
| action rel8_operand { |
| rel8_operand(current_position + 1, data, jump_dests, size, |
| &instruction_info_collected); |
| } |
| + # rel16 actions are used in relative jums with 16-bit offset. |
| + # |
| + # Such instructions should be included in the validator's DFA, but we can not |
| + # just exlude them because they are refenced in relative_fields_parsing ragel |
| + # machine. Ensure compilations error in case of usage. |
| action rel16_operand { |
| #error rel16_operand should never be used in nacl |
| } |
| + # rel32 actions are used in relative calls and jumps with 32-bit offset. |
| action rel32_operand { |
| rel32_operand(current_position + 1, data, jump_dests, size, |
| &instruction_info_collected); |
| @@ -63,6 +78,10 @@ |
| include cpuid_actions |
| "native_client/src/trusted/validator_ragel/unreviewed/parse_instruction.rl"; |
| + # 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. |
| action last_byte_is_not_immediate { |
| instruction_info_collected |= LAST_BYTE_IS_NOT_IMMEDIATE; |
| } |
| @@ -70,16 +89,20 @@ |
| include decode_x86_32 "validator_x86_32_instruction.rl"; |
| special_instruction = |
| - (0x83 0xe0 0xe0 0xff (0xd0|0xe0) | # naclcall/jmp %eax |
| - 0x83 0xe1 0xe0 0xff (0xd1|0xe1) | # naclcall/jmp %ecx |
| - 0x83 0xe2 0xe0 0xff (0xd2|0xe2) | # naclcall/jmp %edx |
| - 0x83 0xe3 0xe0 0xff (0xd3|0xe3) | # naclcall/jmp %ebx |
| - 0x83 0xe4 0xe0 0xff (0xd4|0xe4) | # naclcall/jmp %esp |
| - 0x83 0xe5 0xe0 0xff (0xd5|0xe5) | # naclcall/jmp %ebp |
| - 0x83 0xe6 0xe0 0xff (0xd6|0xe6) | # naclcall/jmp %esi |
| - 0x83 0xe7 0xe0 0xff (0xd7|0xe7)) # naclcall/jmp %edi |
| + # and $~0x1f, %eXX call %eXX |
| + # ↓↓↓↓↓↓↓↓↓↓ |
|
Brad Chen
2012/10/22 21:29:05
What character are you using to generate the up an
khim
2013/03/08 17:59:53
Done.
|
| + (0x83 0xe0 0xe0 0xff (0xd0|0xe0) | # naclcall/jmp %eax |
| + 0x83 0xe1 0xe0 0xff (0xd1|0xe1) | # naclcall/jmp %ecx |
| + 0x83 0xe2 0xe0 0xff (0xd2|0xe2) | # naclcall/jmp %edx |
| + 0x83 0xe3 0xe0 0xff (0xd3|0xe3) | # naclcall/jmp %ebx |
| + 0x83 0xe4 0xe0 0xff (0xd4|0xe4) | # naclcall/jmp %esp |
| + 0x83 0xe5 0xe0 0xff (0xd5|0xe5) | # naclcall/jmp %ebp |
| + 0x83 0xe6 0xe0 0xff (0xd6|0xe6) | # naclcall/jmp %esi |
| + 0x83 0xe7 0xe0 0xff (0xd7|0xe7)) # naclcall/jmp %edi |
| + # ↑↑↑↑ ↑↑↑↑ |
| + # and $~0x1f, %eXX jmp %eXX |
| @{ |
| - BitmapClearBit(valid_targets, (current_position - data) - 1); |
| + MakeInvalidJumpTarget((current_position - data) - 1, valid_targets); |
| instruction_start -= 3; |
| instruction_info_collected |= SPECIAL_INSTRUCTION; |
| } | |
| @@ -88,6 +111,9 @@ |
| (0x00|0x04) 0x00 0x00 0x00); # mov %gs:0x0/0x4,%reg |
| # Check 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. |
| call_alignment = |
| ((one_instruction & |
| # Direct call |
| @@ -97,15 +123,26 @@ |
| # Indirect call |
| (any* data16? 0xff ((opcode_2 | opcode_3) any* & |
| (modrm_memory | modrm_registers))))) |
| + # Call instruction must aligned to the end of bundle. Previously this was |
| + # strict requirement, today it's just warning to aid with debugging. |
| @{ |
| if (((current_position - data) & kBundleMask) != kBundleMask) |
| instruction_info_collected |= BAD_CALL_ALIGNMENT; |
| }; |
| main := ((call_alignment | one_instruction | special_instruction) |
| + # Beginning of the instruction is always valid target for jump. If this |
| + # instruction is, in fact, part of the superinstruction then we'll clear |
| + # that bit later. |
| >{ |
| - BitmapSetBit(valid_targets, current_position - data); |
| + MakeJumpTargetValid(current_position - data, valid_targets); |
| } |
| + # Here we call the user callback if there are validation errors or if the |
| + # CALL_USER_CALLBACK_ON_EACH_INSTRUCTION option is used. |
| + # |
| + # After that we move instruction_start and clean all the variables which |
| + # only used in the processing of a single instruction (prefixes, operand |
| + # states and instruction_info_collected). |
| @{ |
| if ((instruction_info_collected & VALIDATION_ERRORS_MASK) || |
| (options & CALL_USER_CALLBACK_ON_EACH_INSTRUCTION)) { |