Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(752)

Unified Diff: src/trusted/validator_ragel/validator_x86_32.rl

Issue 11000033: Move validator_x86_XX.rl out of unreviewed. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/trusted/validator_ragel/validator_x86_32.rl
===================================================================
--- src/trusted/validator_ragel/validator_x86_32.rl (revision 11020)
+++ src/trusted/validator_ragel/validator_x86_32.rl (working copy)
@@ -20,13 +20,14 @@
#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"
/* Ignore this information: it's not used by security model in IA32 mode. */
+/* TODO(khim): change gen_dfa to remove needs for these lines. */
#undef GET_VEX_PREFIX3
#define GET_VEX_PREFIX3 0
#undef SET_VEX_PREFIX3
-#define SET_VEX_PREFIX3(P)
+#define SET_VEX_PREFIX3(PREFIX_BYTE)
%%{
machine x86_32_validator;
@@ -57,14 +58,6 @@
include cpuid_actions
"native_client/src/trusted/validator_ragel/parse_instruction.rl";
- # Action which marks last byte as not immediate. Most 3DNow! instructions,
- # some AVX and XOP instructions have this property. 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;
- }
-
include decode_x86_32 "validator_x86_32_instruction.rl";
special_instruction =
@@ -81,7 +74,7 @@
# ^^^^ ^^^^
# and $~0x1f, %eXX jmp %eXX
@{
- UnmarkValidJumpTarget((current_position - data) - 1, valid_targets);
+ UnmarkValidJumpTarget((current_position - codeblock) - 1, valid_targets);
instruction_begin -= 3;
instruction_info_collected |= SPECIAL_INSTRUCTION;
} |
@@ -89,39 +82,38 @@
0x65 0x8b (0x05|0x0d|0x015|0x1d|0x25|0x2d|0x35|0x3d)
(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 register-addressed
- # indirect call.
+ # For direct call we explicitly encode all variations.
+ direct_call = (data16 0xe8 rel16) | (0xe8 rel32);
+
+ # For indirect call we accept only near register-addressed indirect call.
+ indirect_call_register = data16? 0xff (opcode_2 & modrm_registers);
+
+ # Ragel machine that accepts one call instruction or call superinstruction and
+ # checks if call is properly aligned.
call_alignment =
- ((one_instruction &
- # Direct call
- ((data16 0xe8 rel16) |
- (0xe8 rel32))) |
- (special_instruction &
- # Indirect call
- (any* data16? 0xff ((opcode_2 | opcode_3) any* &
- modrm_registers))))
+ ((one_instruction & direct_call) |
+ # For indirect calls we accept all the special instructions which ends with
+ # register-addressed indirect call.
+ (special_instruction & (any* indirect_call_register)))
# 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)
+ if (((current_position - codeblock) & kBundleMask) != kBundleMask)
instruction_info_collected |= BAD_CALL_ALIGNMENT;
};
- # This action calls user's callback (if needed) and cleans up validator's
+ # This action calls user callback (if needed) and cleans up validator
# internal state.
#
- # We call the user callback if there are validation errors or if the
- # CALL_USER_CALLBACK_ON_EACH_INSTRUCTION option is used.
+ # We call the user callback either on validation errors or on every
+ # instruction, depending on CALL_USER_CALLBACK_ON_EACH_INSTRUTION option.
#
# After that we move instruction_begin and clean all the variables which
- # only used in the processing of a single instruction (prefixes, operand
- # states and instruction_info_collected).
+ # are only used in the processing of a single instruction (here it's just
+ # instruction_info_collected, there are more state in x86-64 case).
action end_of_instruction_cleanup {
/* Mark start of this instruction as a valid target for jump. */
- MarkValidJumpTarget(instruction_begin - data, valid_targets);
+ MarkValidJumpTarget(instruction_begin - codeblock, valid_targets);
/* Call user-supplied callback. */
instruction_end = current_position + 1;
@@ -131,9 +123,11 @@
instruction_info_collected, callback_data);
}
- /* On successful match the instruction_begin must point to the next byte
- * to be able to report the new offset as the start of instruction
- * causing error. */
+ /*
+ * We may set instruction_begin at the first byte of the instruction instead
+ * of here but in the case of incorrect one byte instructions user callback
+ * may be called before instruction_begin is set.
+ */
instruction_begin = instruction_end;
/* Clear variables (well, one variable currently). */
@@ -156,8 +150,8 @@
}
# This is main ragel machine: it does 99% of validation work. There are only
- # one thing to do if this machine accepts the bundles - check that direct
- # jumps are correct. This is done in the following way:
+ # one thing to do if this ragel machine accepts the bundles - check that
+ # direct jumps are correct. This is done in the following way:
# * DFA fills two arrays: valid_targets and jump_dests.
# * ProcessInvalidJumpTargets checks that "jump_dests & !valid_targets == 0".
# All other checks are done here.
@@ -167,10 +161,14 @@
}%%
+/*
+ * The "write data" statement causes Ragel to emit the constant static data
+ * needed by the ragel machine.
+ */
%% write data;
-
-Bool ValidateChunkIA32(const uint8_t *data, size_t size,
+Bool ValidateChunkIA32(const uint8_t codeblock[],
+ size_t size,
uint32_t options,
const NaClCPUFeaturesX86 *cpu_features,
ValidationCallbackFunc user_callback,
@@ -206,12 +204,12 @@
/*
* 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;
+ end_of_bundle = codeblock + size;
else
- end_of_bundle = data + kBundleSize;
+ end_of_bundle = codeblock + kBundleSize;
/*
* Main loop. Here we process the data array bundle-after-bundle.
@@ -219,8 +217,8 @@
* It collects the two arrays: valid_targets and jump_dests which are used
* to test direct jumps later.
*/
- for (current_position = data;
- current_position < data + size;
+ for (current_position = codeblock;
+ current_position < codeblock + size;
current_position = end_of_bundle,
end_of_bundle = current_position + kBundleSize) {
/* Start of the instruction being processed. */
@@ -230,7 +228,15 @@
uint32_t instruction_info_collected = 0;
int current_state;
+ /*
+ * 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;
}
@@ -238,8 +244,12 @@
* Check the direct jumps. All the targets from jump_dests must be in
* valid_targets.
*/
- result &= ProcessInvalidJumpTargets(data, size, valid_targets, jump_dests,
- user_callback, callback_data);
+ result &= ProcessInvalidJumpTargets(codeblock,
+ size,
+ valid_targets,
+ jump_dests,
+ user_callback,
+ callback_data);
/* We only use malloc for a large code sequences */
if (jump_dests != &jump_dests_small) free(jump_dests);

Powered by Google App Engine
This is Rietveld 408576698