Index: src/trusted/validator_ragel/dfa_validate_common.c |
diff --git a/src/trusted/validator_ragel/dfa_validate_common.c b/src/trusted/validator_ragel/dfa_validate_common.c |
index 4972cbd654b3fcd0d884dec0099db63750991802..2f28a7461529849e60a5b06526d813d33973d012 100644 |
--- a/src/trusted/validator_ragel/dfa_validate_common.c |
+++ b/src/trusted/validator_ragel/dfa_validate_common.c |
@@ -33,6 +33,51 @@ Bool NaClDfaProcessValidationError(const uint8_t *begin, const uint8_t *end, |
return FALSE; |
} |
+static Bool IsREX(uint8_t byte) { |
+ return byte >= 0x40 && byte <= 0x4f; |
+} |
+ |
+static Bool RewriteUnsupportedInstruction(const uint8_t *begin, |
+ const uint8_t *end) { |
+ uint8_t *ptr = (uint8_t *) begin; |
+ /* We usually only check and rewrite the first few bytes without examining |
+ * further because this function is only called when the validator tells us |
+ * that it is an 'unsupported instruction' and there are no other validation |
+ * failures. |
+ */ |
+ if (memcmp(begin, "\x0f\xe7", 2) == 0) { |
+ /* ia32: movntq => movq */ |
+ ptr[1] = 0x7f; |
+ return TRUE; |
+ } else if (memcmp(begin, "\x66\x0f\xe7", 3) == 0) { |
+ /* ia32: movntdq => movdqa */ |
+ ptr[2] = 0x7f; |
+ return TRUE; |
+ } else if (IsREX(begin[0])) { |
bradn
2015/08/04 22:03:30
Make this arch conditional (#ifdef), so you don't
ruiq
2015/08/05 20:11:03
Done.
|
+ if (memcmp(begin + 1, "\x0f\x2b", 2) == 0) { |
+ /* amd64: movntps => movaps */ |
+ ptr[2] = 0x29; |
+ return TRUE; |
+ } else if (memcmp(begin + 1, "\x0f\xc3", 2) == 0) { |
+ /* amd64: movnti => mov */ |
+ ptr[1] = 0x89; |
+ memmove(ptr + 2, ptr + 3, end - begin - 3); |
+ ptr[end - begin - 1] = 0x90; |
+ return TRUE; |
+ } else if (memcmp(begin + 1, "\x0f\x18", 2) == 0) { |
+ /* amd64: prefetchnta => nop */ |
+ memset(ptr, 0x90, end - begin); |
+ return TRUE; |
+ } |
+ } else if (begin[0] == 0x66 && IsREX(begin[1]) && |
+ memcmp(begin + 2, "\x0f\xe7", 2) == 0) { |
+ /* amd64: movntdq => movdqa */ |
+ ptr[3] = 0x7f; |
+ return TRUE; |
+ } |
+ return FALSE; |
+} |
+ |
Bool NaClDfaStubOutUnsupportedInstruction(const uint8_t *begin, |
const uint8_t *end, |
uint32_t info, |
@@ -47,11 +92,13 @@ Bool NaClDfaStubOutUnsupportedInstruction(const uint8_t *begin, |
if (data->flags & NACL_DISABLE_NONTEMPORALS_X86) { |
return FALSE; |
} else { |
- /* TODO(ruiq): rewrite instruction. For now, we keep the original |
- * instruction and indicate validation success, which is consistent |
- * with current validation results. */ |
- data->did_rewrite = 0; |
- return TRUE; |
+ if (RewriteUnsupportedInstruction(begin, end)) { |
+ data->did_rewrite = 1; |
+ return TRUE; |
+ } else { |
+ data->did_rewrite = 0; |
+ return FALSE; |
+ } |
} |
} else { |
return FALSE; |