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

Side by Side Diff: src/trusted/validator/x86/testing/enuminsts/vdiff.c

Issue 10871078: Enable vdiff test on validator bots (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Fixing a few nits Created 8 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /* vdiff.c 7 /* vdiff.c
8 * exhaustive instruction enumeration test for x86 Native Client validators. 8 * exhaustive instruction enumeration test for x86 Native Client validators.
9 * 9 *
10 * This file is based on enuminsts.c, but specialized to comparing two 10 * This file is based on enuminsts.c, but specialized to comparing two
11 * validators instead of decoders. The enuminsts.c implementation also 11 * validators instead of decoders. The enuminsts.c implementation also
12 * had a bunch of Xed-specific logic which complicated the validator 12 * had a bunch of Xed-specific logic which complicated the validator
13 * comparison in unhelpful ways. 13 * comparison in unhelpful ways.
14 */ 14 */
15 15
16 #ifndef NACL_TRUSTED_BUT_NOT_TCB 16 #ifndef NACL_TRUSTED_BUT_NOT_TCB
17 #error("This file is not meant for use in the TCB.") 17 #error("This file is not meant for use in the TCB.")
18 #endif 18 #endif
19 #if NACL_WINDOWS
20 #define _CRT_RAND_S /* enable decl of rand_s() */
21 #endif
19 22
20 #include "native_client/src/trusted/validator/x86/testing/enuminsts/enuminsts.h" 23 #include "native_client/src/trusted/validator/x86/testing/enuminsts/enuminsts.h"
21 24
22 #include <ctype.h> 25 #include <ctype.h>
23 #include <stdio.h> 26 #include <stdio.h>
24 #include <string.h> 27 #include <string.h>
25 #include <stdlib.h> 28 #include <stdlib.h>
26 #include <stdarg.h> 29 #include <stdarg.h>
30 #include <time.h>
27 31
28 #include "native_client/src/include/portability_io.h" 32 #include "native_client/src/include/portability_io.h"
29 #include "native_client/src/shared/platform/nacl_log.h" 33 #include "native_client/src/shared/platform/nacl_log.h"
30 #include "native_client/src/shared/utils/flags.h" 34 #include "native_client/src/shared/utils/flags.h"
31 #include "native_client/src/trusted/validator/x86/testing/enuminsts/str_utils.h" 35 #include "native_client/src/trusted/validator/x86/testing/enuminsts/str_utils.h"
32 #include "native_client/src/trusted/validator/x86/testing/enuminsts/text2hex.h" 36 #include "native_client/src/trusted/validator/x86/testing/enuminsts/text2hex.h"
33 37
34 /* Defines the maximum buffer size used to hold text generated for the 38 /* Defines the maximum buffer size used to hold text generated for the
35 * disassembly of instructions, and corresponding error messages. 39 * disassembly of instructions, and corresponding error messages.
36 */ 40 */
37 #define kBufferSize 1024 41 #define kBufferSize 1024
38 42
39 /* When true, print more messages (i.e. verbosely). */ 43 /* When true, print more messages (i.e. verbosely). */
40 static Bool gVerbose = FALSE; 44 static Bool gVerbose = FALSE;
41 45
42 /* When true, don't print out messages. That is, only print instructions 46 /* When true, don't print out messages. That is, only print instructions
43 * defined by --print directives. 47 * defined by --print directives.
44 */ 48 */
45 static Bool gSilent = FALSE; 49 static Bool gSilent = FALSE;
46 50
47 /* When true, don't report consecutive errors for consecutive instructions 51 /* When true, don't report consecutive errors for consecutive instructions
48 * with the same instruction mnemonic. 52 * with the same instruction mnemonic.
49 */ 53 */
50 static Bool gSkipRepeatReports = FALSE; 54 static Bool gSkipRepeatReports = FALSE;
51 55
56 /* Set to true to enable checking of mnemonics (opcode names).
57 */
58 static Bool gCheckMnemonics = TRUE;
59
52 /* Count of errors that have a high certainty of being exploitable. */ 60 /* Count of errors that have a high certainty of being exploitable. */
53 static int gSawLethalError = 0; 61 static int gSawLethalError = 0;
54 62
55 /* Defines the assumed text address for the test instruction */ 63 /* Defines the assumed text address for the test instruction */
56 const int kTextAddress = 0x1000; 64 const int kTextAddress = 0x1000;
57 65
58 /* If non-negative, defines the prefix to test. */ 66 /* If non-negative, defines the prefix to test. */
59 static unsigned int gPrefix = 0; 67 static unsigned int gPrefix = 0;
60 68
61 /* If non-negative, defines the opcode to test. */ 69 /* If non-negative, defines the opcode to test. */
62 static int gOpcode = -1; 70 static int gOpcode = -1;
63 71
72 /* This option triggers a set of behaviors that help produce repeatable
73 * output, for easier diffs on the buildbots.
74 */
75 static Bool gEasyDiffMode;
76
64 /* The production and new R-DFA validators */ 77 /* The production and new R-DFA validators */
65 NaClEnumeratorDecoder* vProd; 78 NaClEnumeratorDecoder* vProd;
66 NaClEnumeratorDecoder* vDFA; 79 NaClEnumeratorDecoder* vDFA;
67 80
68 /* The name of the executable (i.e. argv[0] from the command line). */ 81 /* The name of the executable (i.e. argv[0] from the command line). */
69 static char *gArgv0 = "argv0"; 82 static const char *gArgv0 = "argv0";
83 #define FLAG_EasyDiff "--easydiff"
70 84
71 /* Records that unexpected internal error occurred. */ 85 /* Records that unexpected internal error occurred. */
72 void InternalError(const char *why) { 86 void InternalError(const char *why) {
73 fprintf(stderr, "%s: Internal Error: %s\n", gArgv0, why); 87 fprintf(stderr, "%s: Internal Error: %s\n", gArgv0, why);
74 gSawLethalError = 1; 88 gSawLethalError = 1;
75 } 89 }
76 90
77 /* Records that a fatal (i.e. non-recoverable) error occurred. */ 91 /* Records that a fatal (i.e. non-recoverable) error occurred. */
78 void ReportFatalError(const char* why) { 92 void ReportFatalError(const char* why) {
79 char buffer[kBufferSize]; 93 char buffer[kBufferSize];
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 } 152 }
139 153
140 static void CheckMnemonics(NaClEnumerator* pinst, NaClEnumerator* dinst) { 154 static void CheckMnemonics(NaClEnumerator* pinst, NaClEnumerator* dinst) {
141 const char* prod_opcode = vProd->_get_inst_mnemonic_fn(pinst); 155 const char* prod_opcode = vProd->_get_inst_mnemonic_fn(pinst);
142 const char* dfa_opcode = vDFA->_get_inst_mnemonic_fn(dinst); 156 const char* dfa_opcode = vDFA->_get_inst_mnemonic_fn(dinst);
143 157
144 if (0 != strcmp(prod_opcode, dfa_opcode)) { 158 if (0 != strcmp(prod_opcode, dfa_opcode)) {
145 /* avoid redundant messages... */ 159 /* avoid redundant messages... */
146 if (NotOpcodeRepeat(prod_opcode)) { 160 if (NotOpcodeRepeat(prod_opcode)) {
147 printf("Warning: OPCODE MISMATCH: %s != %s\n", prod_opcode, dfa_opcode); 161 printf("Warning: OPCODE MISMATCH: %s != %s\n", prod_opcode, dfa_opcode);
148 /* PrintDisassembledInstructionVariants(pinst, dinst); */
149 } 162 }
150 } 163 }
151 } 164 }
152 165
153 struct vdiff_stats { 166 struct vdiff_stats {
154 int64_t tried; 167 int64_t tried;
155 int64_t valid; 168 int64_t valid;
156 int64_t invalid; 169 int64_t invalid;
157 int64_t errors; 170 int64_t errors;
158 } gVDiffStats = {0, 0, 0, 0}; 171 } gVDiffStats = {0, 0, 0, 0};
159 172
160 static void IncrTried() { 173 static void IncrTried() {
161 gVDiffStats.tried += 1; 174 gVDiffStats.tried += 1;
162 } 175 }
163 176
164 static void IncrValid() { 177 static void IncrValid() {
165 gVDiffStats.valid += 1; 178 gVDiffStats.valid += 1;
166 } 179 }
167 180
168 static void IncrInvalid() { 181 static void IncrInvalid() {
169 gVDiffStats.invalid += 1; 182 gVDiffStats.invalid += 1;
170 } 183 }
171 184
172 static void IncrErrors() { 185 static void IncrErrors() {
173 gVDiffStats.errors += 1; 186 gVDiffStats.errors += 1;
174 } 187 }
175 188
176 static void PrintStats() { 189 static void PrintStats() {
177 printf("valid: %" NACL_PRIu64 "\n", gVDiffStats.valid); 190 if (!gEasyDiffMode) {
178 printf("invalid: %" NACL_PRIu64 "\n", gVDiffStats.invalid); 191 printf("valid: %" NACL_PRIu64 "\n", gVDiffStats.valid);
192 printf("invalid: %" NACL_PRIu64 "\n", gVDiffStats.invalid);
193 }
179 printf("errors: %" NACL_PRIu64 "\n", gVDiffStats.errors); 194 printf("errors: %" NACL_PRIu64 "\n", gVDiffStats.errors);
180 printf("tried: %" NACL_PRIu64 "\n", gVDiffStats.tried); 195 printf("tried: %" NACL_PRIu64 "\n", gVDiffStats.tried);
181 printf(" =? %" NACL_PRIu64 " valid + invalid + errors\n", 196 printf(" =? %" NACL_PRIu64 " valid + invalid + errors\n",
182 gVDiffStats.valid + gVDiffStats.invalid + gVDiffStats.errors); 197 gVDiffStats.valid + gVDiffStats.invalid + gVDiffStats.errors);
183 } 198 }
184 199
185 static void InitInst(NaClEnumerator *nacle, 200 static void InitInst(NaClEnumerator *nacle,
186 uint8_t *itext, size_t nbytes) 201 uint8_t *itext, size_t nbytes)
187 { 202 {
188 memcpy(nacle->_itext, itext, nbytes); 203 memcpy(nacle->_itext, itext, nbytes);
(...skipping 24 matching lines...) Expand all
213 rdfa_okay = vDFA->_maybe_inst_validates_fn(&dinst); 228 rdfa_okay = vDFA->_maybe_inst_validates_fn(&dinst);
214 229
215 if (prod_okay) { 230 if (prod_okay) {
216 if (rdfa_okay) { 231 if (rdfa_okay) {
217 if (vProd->_inst_length_fn(&pinst) == 232 if (vProd->_inst_length_fn(&pinst) ==
218 vDFA->_inst_length_fn(&dinst)) { 233 vDFA->_inst_length_fn(&dinst)) {
219 /* Both validators see a legal instruction, */ 234 /* Both validators see a legal instruction, */
220 /* and they agree on critical details. */ 235 /* and they agree on critical details. */
221 IncrValid(); 236 IncrValid();
222 /* Warn if decoders disagree opcode name. */ 237 /* Warn if decoders disagree opcode name. */
223 CheckMnemonics(&pinst, &dinst); 238 if (gCheckMnemonics) CheckMnemonics(&pinst, &dinst);
224 } else { 239 } else {
225 DecoderError("LENGTH MISMATCH", &pinst, &dinst, ""); 240 DecoderError("LENGTH MISMATCH", &pinst, &dinst, "");
226 IncrErrors(); 241 IncrErrors();
227 } 242 }
228 } else { 243 } else {
229 /* Validators disagree on instruction legality */ 244 /* Validators disagree on instruction legality */
230 DecoderError("VALIDATORS DISAGREE", &pinst, &dinst, ""); 245 DecoderError("VALIDATORS DISAGREE", &pinst, &dinst, "");
231 IncrErrors(); 246 IncrErrors();
232 } 247 }
233 } else if (rdfa_okay) { 248 } else if (rdfa_okay) {
234 /* Validators disagree on instruction legality */ 249 /* Validators disagree on instruction legality */
235 DecoderError("VALIDATORS DISAGREE", &pinst, &dinst, ""); 250 DecoderError("VALIDATORS DISAGREE", &pinst, &dinst, "");
236 IncrErrors(); 251 IncrErrors();
237 } else { 252 } else {
238 /* Both validators see an illegal instruction */ 253 /* Both validators see an illegal instruction */
239 IncrInvalid(); 254 IncrInvalid();
240 } 255 }
241 256
242 /* no error */
243 if (gVerbose) { 257 if (gVerbose) {
244 PrintDisassembledInstructionVariants(&pinst, &dinst); 258 PrintDisassembledInstructionVariants(&pinst, &dinst);
245 } 259 }
246 } while (0); 260 } while (0);
247 } 261 }
248 262
263 /* A function type for instruction "TestAll" functions.
264 * Parameters:
265 * prefix: up to four bytes of prefix.
266 * prefix_length: size_t on [0..4] specifying length of prefix.
267 * print_prefix: For easy diff of test output, avoid printing
268 * the value of a randomly selected REX prefix.
269 */
270 typedef void (*TestAllFunction)(const unsigned int prefix,
271 const size_t prefix_length,
272 const char* print_prefix);
273
274 /* Create a char* rendition of a prefix string, appending bytes
275 * in ps. This is used to create output that is easy to diff when
276 * a random REX byte is used.
277 */
278 static char* StrPrefix(const unsigned int prefix, char* ps, char* str) {
Karl 2012/08/28 21:23:52 It is not clear to me what the arguments here are.
Brad Chen 2012/08/28 22:09:42 Done.
279 sprintf(str, "%x%s", prefix, (ps == NULL) ? "" : ps);
280 return str;
281 }
282
249 /* Enumerate and test all 24-bit opcode+modrm+sib patterns for a 283 /* Enumerate and test all 24-bit opcode+modrm+sib patterns for a
250 * particular prefix. 284 * particular prefix.
251 */ 285 */
252 static void TestAllWithPrefix(unsigned int prefix, size_t prefix_length) { 286 static void TestAllWithPrefix(const unsigned int prefix,
253 const int kInstByteCount = NACL_ENUM_MAX_INSTRUCTION_BYTES; 287 const size_t prefix_length,
254 const int kIterByteCount = 3; 288 const char* print_prefix) {
289 const size_t kInstByteCount = NACL_ENUM_MAX_INSTRUCTION_BYTES;
290 const size_t kIterByteCount = 3;
255 InstByteArray itext; 291 InstByteArray itext;
256 size_t i; 292 size_t i;
257 int op, modrm, sib; 293 int op, modrm, sib;
258 int min_op; 294 int min_op;
259 int max_op; 295 int max_op;
260 296
261 if ((gPrefix > 0) && (gPrefix != prefix)) return; 297 if ((gPrefix > 0) && (gPrefix != prefix)) return;
262 298
263 PrintProgress("TestAllWithPrefix(%x)\n", prefix); 299 PrintProgress("TestAllWithPrefix(%s)\n", print_prefix);
264 /* set up prefix */ 300 /* set up prefix */
265 memcpy(itext, &prefix, prefix_length); 301 memcpy(itext, &prefix, prefix_length);
266 /* set up filler bytes */ 302 /* set up filler bytes */
267 for (i = prefix_length + kIterByteCount; 303 for (i = prefix_length + kIterByteCount;
268 i < NACL_ENUM_MAX_INSTRUCTION_BYTES; i++) { 304 i < NACL_ENUM_MAX_INSTRUCTION_BYTES; i++) {
269 itext[i] = (uint8_t)i; 305 itext[i] = (uint8_t)i;
270 } 306 }
271 if (gOpcode < 0) { 307 if (gOpcode < 0) {
272 min_op = 0; 308 min_op = 0;
273 max_op = 256; 309 max_op = 256;
274 } else { 310 } else {
275 min_op = gOpcode; 311 min_op = gOpcode;
276 max_op = gOpcode + 1; 312 max_op = gOpcode + 1;
277 } 313 }
278 for (op = min_op; op < max_op; op++) { 314 for (op = min_op; op < max_op; op++) {
279 itext[prefix_length] = op; 315 itext[prefix_length] = op;
280 PrintProgress("%02x 00 00\n", op); 316 PrintProgress("%02x 00 00\n", op);
281 for (modrm = 0; modrm < 256; modrm++) { 317 for (modrm = 0; modrm < 256; modrm++) {
282 itext[prefix_length + 1] = modrm; 318 itext[prefix_length + 1] = modrm;
283 for (sib = 0; sib < 256; sib++) { 319 for (sib = 0; sib < 256; sib++) {
284 itext[prefix_length + 2] = sib; 320 itext[prefix_length + 2] = sib;
285 TryOneInstruction(itext, kInstByteCount); 321 TryOneInstruction(itext, kInstByteCount);
286 } 322 }
287 } 323 }
288 } 324 }
289 } 325 }
290 326
327 #if NACL_TARGET_SUBARCH == 64
328 /* REX prefixes range from 0x40 to 0x4f. */
329 const uint32_t kREXBase = 0x40;
330 const uint32_t kREXRange = 0x10;
331 const uint32_t kREXMax = 0x50; /* kREXBase + kREXRange */
Karl 2012/08/28 21:23:52 Add a blank line here?
Brad Chen 2012/08/28 22:09:42 Done.
332 /* Generate a random REX prefix, to use for the entire run. */
333 static uint32_t RandomRexPrefix() {
334 static uint32_t static_rex_prefix = 0;
335
336 if (0 == static_rex_prefix) {
337 #if NACL_LINUX || NACL_OSX
338 static_rex_prefix = kREXBase + (random() % kREXRange);
339 #elif NACL_WINDOWS
340 if (rand_s(&static_rex_prefix) != 0) {
341 ReportFatalError("rand_s() failed\n");
342 } else {
343 static_rex_prefix = kREXBase + (static_rex_prefix % kREXRange);
344 }
345 #else
346 # error "Unknown operating system."
347 #endif
348 }
349 return static_rex_prefix;
350 }
351 #endif
352
291 /* For x86-64, enhance the iteration by looping through REX prefixes. 353 /* For x86-64, enhance the iteration by looping through REX prefixes.
292 */ 354 */
293 static void TestAllWithPrefixREX(unsigned int prefix, size_t prefix_length) { 355 static void WithREX(TestAllFunction testall,
356 const unsigned int prefix,
357 const size_t prefix_length) {
358 char pstr[kBufferSize];
294 #if NACL_TARGET_SUBARCH == 64 359 #if NACL_TARGET_SUBARCH == 64
295 unsigned char REXp; 360 unsigned char irex;
296 unsigned int rprefix; 361 unsigned int rprefix;
297 /* test with REX prefixes */ 362 /* test with REX prefixes */
298 for (REXp = 0x40; REXp < 0x50; REXp++) { 363 printf("WithREX(testall, %x, %d, %d)\n", prefix,
299 rprefix = (prefix << 8 | REXp); 364 (int)prefix_length, gEasyDiffMode);
300 printf("Testing with prefix %x\n", rprefix); 365 if (gEasyDiffMode) {
301 TestAllWithPrefix(rprefix, prefix_length + 1); 366 printf("With random REX prefix.\n");
367 irex = RandomRexPrefix();
368 rprefix = (prefix << 8 | irex);
Karl 2012/08/28 21:23:52 Could this operation be converted to a MACRO. It a
Brad Chen 2012/08/28 22:09:42 Done.
369 testall(rprefix, prefix_length + 1, StrPrefix(prefix, "XX", pstr));
370 } else {
371 for (irex = kREXBase; irex < kREXMax; irex++) {
372 rprefix = (prefix << 8 | irex);
373 printf("With REX prefix %x\n", rprefix);
374 testall(rprefix, prefix_length + 1, StrPrefix(rprefix, "", pstr));
375 }
302 } 376 }
303 #endif 377 #endif
304 /* test with no REX prefix */ 378 /* test with no REX prefix */
305 TestAllWithPrefix(prefix, prefix_length); 379 testall(prefix, prefix_length, StrPrefix(prefix, NULL, pstr));
306 } 380 }
307 381
308 /* For all prefixes, call TestAllWithPrefix() to enumrate and test 382 /* For all prefixes, call TestAllWithPrefix() to enumrate and test
309 * all instructions. 383 * all instructions.
310 */ 384 */
311 static void TestAllInstructions() { 385 static void TestAllInstructions() {
312 gSkipRepeatReports = TRUE; 386 gSkipRepeatReports = TRUE;
313 /* NOTE: Prefix byte order needs to be reversed when written as 387 /* NOTE: Prefix byte order needs to be reversed when written as
314 * an integer. For example, for integer prefix 0x3a0f, 0f will 388 * an integer. For example, for integer prefix 0x3a0f, 0f will
315 * go in instruction byte 0, and 3a in byte 1. 389 * go in instruction byte 0, and 3a in byte 1.
316 */ 390 */
317 /* TODO(bradchen): extend enuminsts-64 to iterate over 64-bit prefixes. */ 391 WithREX(TestAllWithPrefix, 0, 0);
318 TestAllWithPrefixREX(0, 0); 392 WithREX(TestAllWithPrefix, 0x0f, 1); /* two-byte opcode */
319 TestAllWithPrefixREX(0x0f, 1); 393 WithREX(TestAllWithPrefix, 0x0ff2, 2); /* SSE2 */
320 TestAllWithPrefixREX(0x0ff2, 2); 394 WithREX(TestAllWithPrefix, 0x0ff3, 2); /* SSE */
321 TestAllWithPrefixREX(0x0ff3, 2); 395 WithREX(TestAllWithPrefix, 0x0f66, 2); /* SSE2 */
322 TestAllWithPrefixREX(0x0f66, 2); 396 WithREX(TestAllWithPrefix, 0x380f, 2); /* SSSE3 */
323 TestAllWithPrefixREX(0x0f0f, 2); 397 WithREX(TestAllWithPrefix, 0x3a0f, 2); /* SSE4 */
324 TestAllWithPrefixREX(0x380f, 2); 398 WithREX(TestAllWithPrefix, 0x380f66, 3); /* SSE4+ */
325 TestAllWithPrefixREX(0x3a0f, 2); 399 WithREX(TestAllWithPrefix, 0x380ff2, 3); /* SSE4+ */
326 TestAllWithPrefixREX(0x380f66, 3); 400 WithREX(TestAllWithPrefix, 0x3a0f66, 3); /* SSE4+ */
327 TestAllWithPrefixREX(0x380ff2, 3);
328 TestAllWithPrefixREX(0x3a0f66, 3);
329 } 401 }
330 402
331 /* Used to test one instruction at a time, for example, in regression 403 /* Used to test one instruction at a time, for example, in regression
332 * testing, or for instruction arguments from the command line. 404 * testing, or for instruction arguments from the command line.
333 */ 405 */
334 static void TestOneInstruction(char *asciihex) { 406 static void TestOneInstruction(const char *asciihex) {
335 InstByteArray ibytes; 407 InstByteArray ibytes;
336 int nbytes; 408 int nbytes;
337 409
338 nbytes = Text2Bytes(ibytes, asciihex, "Command-line argument", -1); 410 nbytes = Text2Bytes(ibytes, asciihex, "Command-line argument", -1);
339 if (nbytes == 0) return; 411 if (nbytes == 0) return;
340 if (gVerbose) { 412 if (gVerbose) {
341 int i; 413 int i;
342 printf("trying %s (", asciihex); 414 printf("trying %s (", asciihex);
343 for (i = 0; i < nbytes; ++i) { 415 for (i = 0; i < nbytes; ++i) {
344 printf("%02x", ibytes[i]); 416 printf("%02x", ibytes[i]);
(...skipping 28 matching lines...) Expand all
373 */ 445 */
374 TestOneInstruction("262e7e00"); 446 TestOneInstruction("262e7e00");
375 TestOneInstruction("2e3e7900"); 447 TestOneInstruction("2e3e7900");
376 /* From the AMD manual, "An instruction may have only one REX prefix */ 448 /* From the AMD manual, "An instruction may have only one REX prefix */
377 /* which must immediately precede the opcode or first excape byte */ 449 /* which must immediately precede the opcode or first excape byte */
378 /* in the instruction encoding." */ 450 /* in the instruction encoding." */
379 TestOneInstruction("406601d8"); /* illegal; REX before data16 */ 451 TestOneInstruction("406601d8"); /* illegal; REX before data16 */
380 TestOneInstruction("664001d8"); /* legal; REX after data16 */ 452 TestOneInstruction("664001d8"); /* legal; REX after data16 */
381 TestOneInstruction("414001d8"); /* illegal; two REX bytes */ 453 TestOneInstruction("414001d8"); /* illegal; two REX bytes */
382 454
383 /* Reset the opcode repeat test, so as not to silence erros */ 455 /* Reset the opcode repeat test, so as not to silence errors */
384 /* that happened in the regression suite. */ 456 /* that happened in the regression suite. */
385 (void)NotOpcodeRepeat(""); 457 (void)NotOpcodeRepeat("");
386 } 458 }
387 459
388 /* Define decoders that can be registered. */ 460 /* Define decoders that can be registered. */
389 extern NaClEnumeratorDecoder* RegisterNaClDecoder(); 461 extern NaClEnumeratorDecoder* RegisterNaClDecoder();
390 extern NaClEnumeratorDecoder* RegisterRagelDecoder(); 462 extern NaClEnumeratorDecoder* RegisterRagelDecoder();
391 463
392 /* Initialize the set of available decoders. */ 464 /* Initialize the set of available decoders. */
393 static void NaClInitializeAvailableDecoders() { 465 static void VDiffInitializeAvailableDecoders() {
394 vProd = RegisterNaClDecoder(); 466 vProd = RegisterNaClDecoder();
395 vDFA = RegisterRagelDecoder(); 467 vDFA = RegisterRagelDecoder();
396 } 468 }
397 469
398 int main(int argc, char *argv[]) { 470 static int ParseArgv(const int argc, const char* argv[]) {
399 int testargs; 471 int nextarg;
472
473 gArgv0 = argv[0];
474 nextarg = 1;
475 if (nextarg < argc &&
476 0 == strcmp(argv[nextarg], FLAG_EasyDiff)) {
477 gEasyDiffMode = TRUE;
478 gCheckMnemonics = FALSE;
479 nextarg += 1;
480 }
481 return nextarg;
482 }
483
484 int main(const int argc, const char *argv[]) {
485 int nextarg;
400 486
401 NaClLogModuleInit(); 487 NaClLogModuleInit();
402 NaClLogSetVerbosity(LOG_FATAL); 488 NaClLogSetVerbosity(LOG_FATAL);
403 NaClInitializeAvailableDecoders(); 489 #if NACL_LINUX || NACL_OSX
490 srandom(time(NULL));
491 #endif
492 VDiffInitializeAvailableDecoders();
404 493
405 gArgv0 = argv[0]; 494 nextarg = ParseArgv(argc, argv);
406 testargs = 1; 495 if (nextarg == argc) {
407
408 if (testargs == argc) {
409 if (gPrefix == 0) RunRegressionTests(); 496 if (gPrefix == 0) RunRegressionTests();
410 TestAllInstructions(); 497 TestAllInstructions();
411 } else { 498 } else {
412 int i; 499 int i;
413 gVerbose = TRUE; 500 gVerbose = TRUE;
414 for (i = testargs; i < argc; ++i) { 501 for (i = nextarg; i < argc; ++i) {
415 TestOneInstruction(argv[i]); 502 TestOneInstruction(argv[i]);
416 } 503 }
417 } 504 }
418 PrintStats(); 505 PrintStats();
419 } 506 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698