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

Side by Side Diff: src/trusted/validator_x86/nc_inst_state_Tests.cc

Issue 6883091: Start unit testing for functions in nc_inst_state.c (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: '' Created 9 years, 8 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 // Unit tests for code in nc_inst_state.cc (and nc_inst_state_statics.c).
8
9 // To turn on debugging of instruction decoding, change value of
10 // DEBUGGING to 1.
11 #define DEBUGGING 0
12
13 #include "native_client/src/trusted/validator_x86/nc_inst_state.h"
14 #include "native_client/src/include/nacl_macros.h"
15 #include "gtest/gtest.h"
16
17 // Include static functions, so that we can test.
18 extern "C" {
19 #include "native_client/src/trusted/validator_x86/nc_inst_state_statics.c"
20 #include "native_client/src/trusted/validator_x86/RexPrefixes.h"
21 };
22
23 namespace {
24
25 // Size of buffer to use to contain bytes of an instruction.
26 static const size_t kBufferSize = 24;
27
28 // Test harness for routines in nc_inst_state.c and nc_inst_state_statics.c.
29 class NcInstStateTests : public ::testing::Test {
30 protected:
31 NcInstStateTests();
32 void SetUp();
33 void TearDown();
34
35 // Plant the given byte as the next input byte in the input buffer.
36 // Uses plant_index to determine the current end of the input buffer.
37 void Plant(uint8_t byte);
38
39 // Reset test state to a cleared input buffer, and (re)initialize
40 // the instruction state.
41 void Reset();
42
43 // Routine to add dummy calls so that compilation errors are not defined
44 // for static routines we have not tested.
45 void dummy();
46
47 // Reinitializes instruction state.
48 void ResetState();
49
50 // Resets the instruction pattern, and its flags to a default initial
51 // state.
52 void ResetInstPattern();
53
54 // Fills the input buffer with unlikely bytes, and initializes
55 // the reader to the beginning of the input buffer.
56 void ResetInput();
57
58 // Fills the input buffer with unlikely bytes, and set the plant
59 // index to the beginning of the input buffer.
60 void ResetInputBuffer();
61
62 // Verify that we have consumed the given number of prefix bytes, with
63 // the given number of rex prefixes, and that the prefix mask is set
64 // to the given mask.
65 //
66 // Parameters are:
67 // num_bytes - Number of prefix bytes read.
68 // num_rex - Number of prefix bytes that were rex prefixes.
69 // mask - prefix mask that should have been generated.
70 void VerifyConsumedPrefixBytes(uint8_t num_bytes, uint8_t num_rex,
71 uint32_t mask);
72
73 // Run tests that verify that the call to NaClConsume0F38XXNaClInstBytes
74 // behaved as expected. Assumes the call was made through a call
75 // to NaClConsumeInstBytes.
76 void VerifyConsume0F38XXInstructions();
77
78 // Run tests that verify that the call to NaClConsume0F3AXXNaClInstBytes
79 // behaved as expected. Assumes the call was made through a call
80 // to NaClConsumeInstBytes.
81 void VerifyConsume0F3AXXInstructions();
82
83 // Run tests that verify that the call to NaClConsume0FXXNaClInstBytes
84 // behaved as expected. Assumes the call was made through a call
85 // to NaClConsumeInstBytes.
86 void VerifyConsume0FXXInstructions();
87
88 // Run tests that verify that the call to NaClConsumeX87NaClInstBytes
89 // behaved as expected. Assumes the call was made through a call
90 // to NaClConsumeInstBytes.
91 void VerifyConsumeX87Instructions();
92
93 // Run tests that verify that the call to NaClConsumeInstBytes consumed
94 // a single byte.
95 void VerifyConsumeOneByteInstructions();
96
97 // The instruction state to test.
98 NaClInstState* _state;
99 // The instruction iterator to use.
100 NaClInstIter* _iter;
101 // The memory segment to test.
102 NaClSegment _segment;
103 // The memory buffer in the memory segment.
104 uint8_t _buffer[kBufferSize];
105 // The instruction pattern to match against.
106 NaClInst _inst_pattern;
107 // The index of where the next planted byte should
108 // be added to the input buffer.
109 size_t _plant_index;
110 };
111
112 NcInstStateTests::NcInstStateTests() {
113 ResetInputBuffer();
114 NaClSegmentInitialize(_buffer, 0, kBufferSize, &_segment);
115 }
116
117 void NcInstStateTests::SetUp() {
118 _iter = NaClInstIterCreate(&_segment);
119 _state = NaClInstIterGetUndecodedState(_iter);
120 ResetInput();
121 ResetState();
122 }
123
124 void NcInstStateTests::TearDown() {
125 NaClInstIterDestroy(_iter);
126 }
127
128 void NcInstStateTests::Reset() {
129 ResetInput();
130 ResetState();
131 }
132
133 void NcInstStateTests::ResetState() {
134 NaClInstStateInit(_iter, _state);
135 ResetInstPattern();
136 }
137
138 void NcInstStateTests::ResetInstPattern() {
139 _inst_pattern.flags = NACL_EMPTY_IFLAGS;
140 _state->inst = &_inst_pattern;
141 }
142
143 void NcInstStateTests::ResetInputBuffer() {
144 // Fill input buffer with unlikely byte codes.
145 for (size_t i = 0; i < kBufferSize; ++i) {
146 _buffer[i] = 'X';
147 }
148 // Mark start point for planting data into
149 // the input buffer.
150 _plant_index = 0;
151 }
152
153 void NcInstStateTests::ResetInput() {
154 ResetInputBuffer();
155 NCInstBytesReset(&_state->bytes);
156 }
157
158 void NcInstStateTests::Plant(uint8_t byte) {
159 // TODO(Karl): Why do we get a compile time error if we use ASSERT.
160 ASSERT_LT(_plant_index, kBufferSize) <<
161 "Planted too many bytes, buffer overflow!";
162 _buffer[_plant_index++] = byte;
163 // Need to reset memory so that peek byte is set.
164 NCRemainingMemoryReset(_state->bytes.memory);
165 }
166
167 void NcInstStateTests::VerifyConsumedPrefixBytes(
168 uint8_t num_bytes, uint8_t num_rex, uint32_t mask) {
169 EXPECT_EQ(num_bytes, _state->bytes.length);
170 EXPECT_EQ(num_bytes, _state->num_prefix_bytes);
171 EXPECT_EQ(mask, _state->prefix_mask);
172 EXPECT_EQ(num_rex, _state->num_rex_prefixes);
173 }
174
175 void NcInstStateTests::VerifyConsume0F38XXInstructions() {
176 NaClInstPrefixDescriptor desc;
177 uint32_t prefix_mask = _state->prefix_mask;
178 // Note: This code assumes that the prefix mask may have
179 // other flags set before this routine is called. Hence,
180 // we must be careful when updating and checking the
181 // mask.
182
183 // Test for all possible XX.
184 for (int i = 0; i < NCDTABLESIZE; ++i) {
185 // Test successfully matching 0f38XX
186 _state->prefix_mask = prefix_mask;
187 Plant(0x0f);
188 Plant(0x38);
189 Plant(i);
190 NaClConsumeInstBytes(_state, &desc);
191 if (NaClHasBit(_state->prefix_mask, kPrefixREP)) {
192 EXPECT_EQ(NaClInstPrefixEnumSize, desc.matched_prefix);
193 } else if (NaClHasBit(_state->prefix_mask, kPrefixREPNE)) {
194 EXPECT_EQ(PrefixF20F38, desc.matched_prefix);
195 } else if (NaClHasBit(_state->prefix_mask, kPrefixDATA16)) {
196 EXPECT_EQ(Prefix660F38, desc.matched_prefix);
197 } else {
198 EXPECT_EQ(Prefix0F38, desc.matched_prefix);
199 }
200 EXPECT_EQ((uint8_t) i, desc.opcode_byte);
201 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
202 ResetInput();
203 ResetState();
204 }
205
206 // Now verify if that there isn't an XX byte, things short curcuit correctly.
207 _state->prefix_mask = prefix_mask;
208 Plant(0x0f);
209 Plant(0x38);
210 _state->length_limit = 2;
211 NaClConsumeInstBytes(_state, &desc);
212 EXPECT_EQ(NaClInstPrefixEnumSize, desc.matched_prefix);
213 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
214 ResetInput();
215 ResetState();
216 }
217
218 void NcInstStateTests::VerifyConsume0F3AXXInstructions() {
219 NaClInstPrefixDescriptor desc;
220 uint32_t prefix_mask = _state->prefix_mask;
221 // Note: This code assumes that the prefix mask may have
222 // other flags set before this routine is called. Hence,
223 // we must be careful when updating and checking the
224 // mask.
225
226 // Test for all possible XX.
227 for (int i = 0; i < NCDTABLESIZE; ++i) {
228 // Test successfully matching 0F3AXX
229 _state->prefix_mask = prefix_mask;
230 Plant(0x0f);
231 Plant(0x3a);
232 Plant(i);
233 NaClConsumeInstBytes(_state, &desc);
234 if (NaClHasBit(_state->prefix_mask, kPrefixREP) ||
235 NaClHasBit(_state->prefix_mask, kPrefixREPNE)) {
236 EXPECT_EQ(NaClInstPrefixEnumSize, desc.matched_prefix);
237 } else if (NaClHasBit(_state->prefix_mask, kPrefixDATA16)) {
238 EXPECT_EQ(Prefix660F3A, desc.matched_prefix);
239 } else {
240 EXPECT_EQ(Prefix0F3A, desc.matched_prefix);
241 }
242 EXPECT_EQ((uint8_t) i, desc.opcode_byte);
243 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
244 ResetInput();
245 ResetState();
246 }
247
248 // Now verify if that there isn't an XX byte, things short curcuit correctly.
249 _state->prefix_mask = prefix_mask;
250 Plant(0x0f);
251 Plant(0x3a);
252 _state->length_limit = 2;
253 NaClConsumeInstBytes(_state, &desc);
254 EXPECT_EQ(NaClInstPrefixEnumSize, desc.matched_prefix);
255 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
256 ResetInput();
257 ResetState();
258 }
259
260 void NcInstStateTests::VerifyConsume0FXXInstructions() {
261 NaClInstPrefixDescriptor desc;
262 uint32_t prefix_mask = _state->prefix_mask;
263 // Note: This code assumes that the prefix mask may have
264 // other flags set before this routine is called. Hence,
265 // we must be careful when updating and checking the
266 // mask.
267
268 // Test for all possible XX.
269 for (int i = 0; i < NCDTABLESIZE; ++i) {
270 if (i == 0x38 || i == 0x3a) continue; // exclude special lookup cases.
271 // Test successfully matching 0fXX
272 _state->prefix_mask = prefix_mask;
273 Plant(0x0f);
274 Plant(i);
275 NaClConsumeInstBytes(_state, &desc);
276 if (NaClHasBit(_state->prefix_mask, kPrefixREP)) {
277 if (NaClHasBit(_state->prefix_mask, kPrefixREPNE)) {
278 EXPECT_EQ(NaClInstPrefixEnumSize, desc.matched_prefix);
279 } else {
280 EXPECT_EQ(PrefixF30F, desc.matched_prefix);
281 }
282 } else if (NaClHasBit(_state->prefix_mask, kPrefixREPNE)) {
283 EXPECT_EQ(PrefixF20F, desc.matched_prefix);
284 } else if (NaClHasBit(_state->prefix_mask, kPrefixDATA16)) {
285 EXPECT_EQ(Prefix660F, desc.matched_prefix);
286 } else {
287 EXPECT_EQ(Prefix0F, desc.matched_prefix);
288 }
289 EXPECT_EQ((uint8_t) i, desc.opcode_byte);
290 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
291 ResetInput();
292 ResetState();
293 }
294
295 // Now verify if that there isn't an XX byte, things short curcuit correctly.
296 _state->prefix_mask = prefix_mask;
297 Plant(0x0f);
298 _state->length_limit = 1;
299 NaClConsumeInstBytes(_state, &desc);
300 EXPECT_EQ(NaClInstPrefixEnumSize, desc.matched_prefix);
301 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
302 ResetInput();
303 ResetState();
304 }
305
306 void NcInstStateTests::VerifyConsumeX87Instructions() {
307 NaClInstPrefixDescriptor desc;
308 uint32_t prefix_mask = _state->prefix_mask;
309 // Note: This code assumes that the prefix mask may have
310 // other flags set before this routine is called. Hence,
311 // we must be careful when updating and checking the
312 // mask.
313
314 // Try for all possible x87 initial bytes.
315 for (uint8_t byte1 = 0xD8; byte1 <= 0xDF; ++byte1) {
316 // Test for all possible XX.
317 for (int i = 0; i < NCDTABLESIZE; ++i) {
318 // Test successfully matching byte1 XX
319 _state->prefix_mask = prefix_mask;
320 Plant(byte1);
321 Plant(i);
322 NaClConsumeInstBytes(_state, &desc);
323 NaClInstPrefix prefix = (NaClInstPrefix) (PrefixD8 + (byte1 - 0xD8));
324 EXPECT_EQ(prefix, desc.matched_prefix);
325 EXPECT_EQ((uint8_t) i, desc.opcode_byte);
326 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
327 ResetInput();
328 ResetState();
329 }
330
331 // Now verify if that there isn't an XX byte, things short curcuit
332 // correctly. For this context, it should return matching a single
333 // byte instruction with no prefix.
334 _state->prefix_mask = prefix_mask;
335 Plant(byte1);
336 _state->length_limit = 1;
337 NaClConsumeInstBytes(_state, &desc);
338 EXPECT_EQ(NoPrefix, desc.matched_prefix);
339 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
340 ResetInput();
341 ResetState();
342 }
343 }
344
345 void NcInstStateTests::VerifyConsumeOneByteInstructions() {
346 NaClInstPrefixDescriptor desc;
347 uint32_t prefix_mask = _state->prefix_mask;
348 // Note: This code assumes that the prefix mask may have
349 // other flags set before this routine is called. Hence,
350 // we must be careful when updating and checking the
351 // mask.
352
353 // Test for all possible XX.
354 for (int i = 0; i < NCDTABLESIZE; ++i) {
355 // exclude special lookup cases.
356 if (i == 0x0f || (i >= 0xD8 && i <= 0xDF)) continue;
357 // Test successfully XX
358 _state->prefix_mask = prefix_mask;
359 Plant(i);
360 NaClConsumeInstBytes(_state, &desc);
361 EXPECT_EQ(NoPrefix, desc.matched_prefix);
362 EXPECT_EQ((uint8_t) i, desc.opcode_byte);
363 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
364 ResetInput();
365 ResetState();
366 }
367
368 // Now verify if that there isn't an XX byte, things short curcuit correctly.
369 _state->prefix_mask = prefix_mask;
370 _state->length_limit = 0;
371 NaClConsumeInstBytes(_state, &desc);
372 EXPECT_EQ(NaClInstPrefixEnumSize, desc.matched_prefix);
373 EXPECT_EQ((uint8_t) 0, desc.next_length_adjustment);
374 ResetInput();
375 ResetState();
376 }
377
378 void NcInstStateTests::dummy() {
379 NaClInstPrefixDescriptor prefix_desc;
380 NaClConsumeAndCheckOperandSize(_state);
381 NaClConsumeAndCheckAddressSize(_state);
382 NaClConsumeModRm(_state);
383 NaClConsumeSib(_state);
384 NaClConsumeDispBytes(_state);
385 NaClConsumeImmediateBytes(_state);
386 NaClValidatePrefixFlags(_state);
387 NaClClearInstState(_state, 0);
388 NaClGetNextInstCandidates(_state, &prefix_desc, NULL);
389 NaClConsumeOpcodeSequence(_state);
390 }
391
392 // Test function NaClExtactOpSize, which returns the expected
393 // number of bytes to represent operands.
394 TEST_F(NcInstStateTests, TestExtractOpSize) {
395 // Test 32 amd 64 bit assumptions.
396
397 // Test explicit size restrictors. Note: Only b should make a difference
398 // in matching the pattern, since v, w, and o are used as excluders rather
399 // than for matching (i.e. don't match unless operand size should be
400 // 1).
401 _inst_pattern.flags = NACL_IFLAG(OperandSize_b);
402 EXPECT_EQ(1, NaClExtractOpSize(_state)) << "bytes are of size 1\n";
403 _inst_pattern.flags = NACL_IFLAG(OperandSize_w);
404 EXPECT_EQ(4, NaClExtractOpSize(_state));
405 _inst_pattern.flags = NACL_IFLAG(OperandSize_v);
406 EXPECT_EQ(4, NaClExtractOpSize(_state));
407 _inst_pattern.flags = NACL_IFLAG(OperandSize_o);
408 EXPECT_EQ(4, NaClExtractOpSize(_state));
409 ResetState();
410
411 // See if we interpret the Data16 prefix correctly.
412 _state->prefix_mask = kPrefixDATA16;
413 EXPECT_EQ(2, NaClExtractOpSize(_state));
414 _inst_pattern.flags = NACL_IFLAG(SizeIgnoresData16);
415 EXPECT_EQ(4, NaClExtractOpSize(_state));
416 ResetState();
417
418 // Test strictly 64-bit assumptions.
419 if (NACL_TARGET_SUBARCH == 64) {
420 // Check that we return a size 64 if the REX.W bit is set.
421 for (uint8_t rex = NaClRexMin; rex <= NaClRexMax; ++rex) {
422 _state->rexprefix = rex;
423 if (NaClRexW(rex)) {
424 EXPECT_EQ(8, NaClExtractOpSize(_state));
425 } else {
426 EXPECT_EQ(4, NaClExtractOpSize(_state));
427 }
428 }
429 ResetState();
430
431 // If we force the size to 64, it returns size 64.
432 _inst_pattern.flags = NACL_IFLAG(OperandSizeForce64);
433 EXPECT_EQ(8, NaClExtractOpSize(_state));
434 ResetState();
435
436 // Now repeat the tests, but with the default size set to 64 bits,
437 // which replaces the default size of 4 with 8.
438
439 // Test explicit size restrictors. Note: Only b should make a difference
440 // in matching the pattern, since v, w, and o are used as excluders rather
441 // than for matching (i.e. don't match unless operand size matches).
442 _inst_pattern.flags =
443 NACL_IFLAG(OperandSize_b) | NACL_IFLAG(OperandSizeDefaultIs64);
444 EXPECT_EQ(1, NaClExtractOpSize(_state)) << "bytes are of size 1\n";
445 _inst_pattern.flags =
446 NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSizeDefaultIs64);
447 EXPECT_EQ(8, NaClExtractOpSize(_state));
448 _inst_pattern.flags =
449 NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSizeDefaultIs64);
450 EXPECT_EQ(8, NaClExtractOpSize(_state));
451 _inst_pattern.flags =
452 NACL_IFLAG(OperandSize_o) | NACL_IFLAG(OperandSizeDefaultIs64);
453 EXPECT_EQ(8, NaClExtractOpSize(_state));
454 ResetState();
455
456 // See if we interpret the Data16 prefix correctly.
457 _state->prefix_mask = kPrefixDATA16;
458 _inst_pattern.flags = NACL_IFLAG(OperandSizeDefaultIs64);
459 EXPECT_EQ(2, NaClExtractOpSize(_state));
460 _inst_pattern.flags =
461 NACL_IFLAG(SizeIgnoresData16) | NACL_IFLAG(OperandSizeDefaultIs64);
462 EXPECT_EQ(8, NaClExtractOpSize(_state));
463 ResetState();
464
465 // Check that we return a size 64 independent of the REX.W bit.
466 _inst_pattern.flags = NACL_IFLAG(OperandSizeDefaultIs64);
467 for (uint8_t rex = NaClRexMin; rex <= NaClRexMax; ++rex) {
468 _state->rexprefix = rex;
469 EXPECT_EQ(8, NaClExtractOpSize(_state));
470 }
471 }
472 }
473
474 // Test function NaClExtractAddressSize, which returns the expected
475 // number of bits in operands corresponding to addresses.
476 TEST_F(NcInstStateTests, TestExtractAddressSize) {
477 // Depending on whether we are in 32/64 bit mode, there are two
478 // different address sizes.
479 int small_address;
480 int large_address;
481 if (NACL_TARGET_SUBARCH == 64) {
482 small_address = 32;
483 large_address = 64;
484 } else {
485 small_address = 16;
486 large_address = 32;
487 }
488 EXPECT_EQ(large_address, NaClExtractAddressSize(_state));
489 _state->prefix_mask = kPrefixADDR16;
490 EXPECT_EQ(small_address, NaClExtractAddressSize(_state));
491 }
492
493 extern "C" {
494 // Define acceptable prefixes, and the corresponding flag that
495 // should be set (except for rex prefixes).
496 static const struct prefix_pairs {
497 uint8_t byte;
498 uint32_t mask;
499 } prefix_values[] = {
500 {kValueSEGCS, kPrefixSEGCS},
501 {kValueSEGSS, kPrefixSEGSS},
502 {kValueSEGFS, kPrefixSEGFS},
503 {kValueSEGGS, kPrefixSEGGS},
504 {kValueDATA16, kPrefixDATA16},
505 {kValueADDR16, kPrefixADDR16},
506 {kValueREPNE, kPrefixREPNE},
507 {kValueREP, kPrefixREP},
508 {kValueLOCK, kPrefixLOCK},
509 {kValueSEGES, kPrefixSEGES},
510 {kValueSEGDS, kPrefixSEGDS}
511 };
512 };
513
514 // Test function NaClConsumePrefixBytes to verify it only recognizes
515 // valid prefix values.
516 TEST_F(NcInstStateTests, ConsumesKnownPrefixBytes) {
517 for (int byte = 0; byte < NCDTABLESIZE; ++byte) {
518 bool byte_categorized = false;
519 Plant(byte);
520 EXPECT_TRUE(NaClConsumePrefixBytes(_state));
521 if (NACL_TARGET_SUBARCH == 64 &&
522 byte >= NaClRexMin && byte <= NaClRexMax) {
523 VerifyConsumedPrefixBytes(1, 1, kPrefixREX);
524 byte_categorized = true;
525 } else {
526 for (size_t j = 0; j < NACL_ARRAY_SIZE(prefix_values); ++j) {
527 if (byte == prefix_values[j].byte) {
528 VerifyConsumedPrefixBytes(1, 0, prefix_values[j].mask);
529 byte_categorized = true;
530 }
531 }
532 }
533 if (!byte_categorized) {
534 VerifyConsumedPrefixBytes(0, 0, 0);
535 }
536 ResetInput();
537 ResetState();
538 }
539 }
540
541 // Test function NaClConsumePrefixBytes to verify it can recognize
542 // pairs of non-rex prefix bytes.
543 TEST_F(NcInstStateTests, ConsumeNonRexPrefixBytePairs) {
544 // First try some pairs within non-rex prefix bytes.
545 for (size_t i = 0; i < NACL_ARRAY_SIZE(prefix_values) - 1; ++i) {
546 Plant(prefix_values[i].byte);
547 Plant(prefix_values[i+1].byte);
548 EXPECT_TRUE(NaClConsumePrefixBytes(_state));
549 VerifyConsumedPrefixBytes(2, 0,
550 prefix_values[i].mask | prefix_values[i+1].mask);
551 ResetInput();
552 ResetState();
553 }
554 }
555
556 // Test Function NaClConsumePrefixBytes to verify it can recognize
557 // a Rex prefix followed by a non-rex prefix.
558 TEST_F(NcInstStateTests, ConsumeRexThenNonRexPrefixPairs) {
559 if (NACL_TARGET_SUBARCH == 64) {
560 // Try some pairs where one is rex.
561 for (size_t i = 0; i < NACL_ARRAY_SIZE(prefix_values); ++i) {
562 for (size_t rex = NaClRexMin; rex <= NaClRexMax; ++rex) {
563 Plant(rex);
564 Plant(prefix_values[i].byte);
565 EXPECT_FALSE(NaClConsumePrefixBytes(_state));
566 VerifyConsumedPrefixBytes(2, 1, prefix_values[i].mask | kPrefixREX);
567 ResetInput();
568 ResetState();
569 }
570 }
571 }
572 }
573
574 // Test Function NaClConsumePrefixBytes to verify it can recognize
575 // a non-rex prefix, followed by a rex prefix.
576 TEST_F(NcInstStateTests, ConsumeNonRexThenRexPrefixPairs) {
577 if (NACL_TARGET_SUBARCH == 64) {
578 // Try some pairs where one is rex.
579 for (size_t i = 0; i < NACL_ARRAY_SIZE(prefix_values); ++i) {
580 for (size_t rex = NaClRexMin; rex <= NaClRexMax; ++rex) {
581 Plant(prefix_values[i].byte);
582 Plant(rex);
583 EXPECT_TRUE(NaClConsumePrefixBytes(_state));
584 VerifyConsumedPrefixBytes(2, 1, prefix_values[i].mask | kPrefixREX);
585 ResetInput();
586 ResetState();
587 }
588 }
589 }
590 }
591
592 // Test function NaClConsumePrefixBytes on multiple rex prefixes.
593 TEST_F(NcInstStateTests, ConsumeMultipleRexPrefixes) {
594 if (NACL_TARGET_SUBARCH == 64) {
595 for (size_t rex1 = NaClRexMin; rex1 <= NaClRexMax; ++rex1) {
596 for (size_t rex2 = NaClRexMin; rex2 <= NaClRexMax; ++rex2) {
597 Plant(rex1);
598 Plant(rex2);
599 EXPECT_TRUE(NaClConsumePrefixBytes(_state));
600 VerifyConsumedPrefixBytes(2, 2, kPrefixREX);
601 ResetInput();
602 ResetState();
603 }
604 }
605 }
606 }
607
608 // Test function NaClConsumePrefixBytes to see if we allow multiple
609 // copies of the same (non-rex) prefix.
610 TEST_F(NcInstStateTests, ConsumeDuplicatePrefixes) {
611 // Try with non rex prefixes.
612 for (size_t i = 0; i < NACL_ARRAY_SIZE(prefix_values); ++i) {
613 Plant(prefix_values[i].byte);
614 Plant(prefix_values[i].byte);
615 EXPECT_TRUE(NaClConsumePrefixBytes(_state));
616 VerifyConsumedPrefixBytes(2, 0, prefix_values[i].mask);
617 ResetInput();
618 ResetState();
619 }
620 }
621
622 // Test if we can recognize 14 prefix bytes.
623 TEST_F(NcInstStateTests, Consume14PrefixBytes) {
624 for (int i = 0; i < 14; ++i) {
625 Plant(kValueDATA16);
626 }
627 EXPECT_TRUE(NaClConsumePrefixBytes(_state));
628 VerifyConsumedPrefixBytes(14, 0, kPrefixDATA16);
629 }
630
631 // Test that we can't accept 15 prefix bytes.
632 TEST_F(NcInstStateTests, Consume15PrefixBytes) {
633 for (int i = 0; i < 15; ++i) {
634 Plant(kValueDATA16);
635 }
636 EXPECT_TRUE(NaClConsumePrefixBytes(_state));
637 EXPECT_EQ((uint8_t) 14, _state->bytes.length);
638 }
639
640 // Defines the set of prefix bytes that effect multibyte instructions
641 // (i.e. REP, REPNE, and DATA16), and all possible combinations of
642 // these prefixes.
643 static const uint32_t kMultibytePrefixes[] = {
644 0,
645 kPrefixREP,
646 kPrefixREP | kPrefixREPNE,
647 kPrefixREP | kPrefixREPNE | kPrefixDATA16,
648 kPrefixREPNE,
649 kPrefixREPNE | kPrefixDATA16,
650 kPrefixDATA16
651 };
652
653 // Test function NaClConsume0F38XXNaClInstBytes, as called through
654 // function NaClConsumeInstBytes.
655 TEST_F(NcInstStateTests, ConsumeOF38XXInstructions) {
656 // First try effects of just multibyte prefixes.
657 for (size_t i = 0; i < NACL_ARRAY_SIZE(kMultibytePrefixes); ++i) {
658 _state->prefix_mask = kMultibytePrefixes[i];
659 VerifyConsume0F38XXInstructions();
660
661 // Verify that adding a rex prefix don't effect anything.
662 _state->prefix_mask = kMultibytePrefixes[i] | kPrefixREX;
663 VerifyConsume0F38XXInstructions();
664
665 // Now try adding other possible prefixes to see if they break anything.
666 for (size_t j = 0; j < NACL_ARRAY_SIZE(prefix_values); ++j) {
667 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask;
668 VerifyConsume0F38XXInstructions();
669
670 // Verify that adding a rex prefix don't effect anything.
671 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask
672 | kPrefixREX;
673 VerifyConsume0F38XXInstructions();
674 }
675 }
676 }
677
678 // Test function NaClConsume0F3AXXNaClInstBytes, as called through
679 // function NaClConsumeInstBytes.
680 TEST_F(NcInstStateTests, ConsumeOF3AXXInstructions) {
681 // First try effects of just multibyte prefixes.
682 for (size_t i = 0; i < NACL_ARRAY_SIZE(kMultibytePrefixes); ++i) {
683 _state->prefix_mask = kMultibytePrefixes[i];
684 VerifyConsume0F3AXXInstructions();
685
686 // Verify that adding a rex prefix don't effect anything.
687 _state->prefix_mask = kMultibytePrefixes[i] | kPrefixREX;
688 VerifyConsume0F3AXXInstructions();
689
690 // Now try adding other possible prefixes to see if they break anything.
691 for (size_t j = 0; j < NACL_ARRAY_SIZE(prefix_values); ++j) {
692 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask;
693 VerifyConsume0F3AXXInstructions();
694
695 // Verify that adding a rex prefix don't effect anything.
696 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask
697 | kPrefixREX;
698 VerifyConsume0F3AXXInstructions();
699 }
700 }
701 }
702
703 // Test function NaClConsume0FXXNaClInstBytes, as called through
704 // function NaClConsumeInstBytes.
705 TEST_F(NcInstStateTests, ConsumeOFXXInstructions) {
706 // First try effects of just multibyte prefixes.
707 for (size_t i = 0; i < NACL_ARRAY_SIZE(kMultibytePrefixes); ++i) {
708 _state->prefix_mask = kMultibytePrefixes[i];
709 VerifyConsume0FXXInstructions();
710
711 // Verify that adding a rex prefix don't effect anything.
712 _state->prefix_mask = kMultibytePrefixes[i] | kPrefixREX;
713 VerifyConsume0FXXInstructions();
714
715 // Now try adding other possible prefixes to see if they break anything.
716 for (size_t j = 0; j < NACL_ARRAY_SIZE(prefix_values); ++j) {
717 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask;
718 VerifyConsume0FXXInstructions();
719
720 // Verify that adding a rex prefix don't effect anything.
721 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask
722 | kPrefixREX;
723 VerifyConsume0FXXInstructions();
724 }
725 }
726 }
727
728 // Test function NaClConsumeX87NaClInstBytes, as called through
729 // function NaClConsumeInstBytes.
730 TEST_F(NcInstStateTests, ConsumeX87Instructions) {
731 // First try effects of just multibyte prefixes.
732 for (size_t i = 0; i < NACL_ARRAY_SIZE(kMultibytePrefixes); ++i) {
733 _state->prefix_mask = kMultibytePrefixes[i];
734 VerifyConsumeX87Instructions();
735
736 // Verify that adding a rex prefix don't effect anything.
737 _state->prefix_mask = kMultibytePrefixes[i] | kPrefixREX;
738 VerifyConsumeX87Instructions();
739
740 // Now try adding other possible prefixes to see if they break anything.
741 for (size_t j = 0; j < NACL_ARRAY_SIZE(prefix_values); ++j) {
742 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask;
743 VerifyConsumeX87Instructions();
744
745 // Verify that adding a rex prefix don't effect anything.
746 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask
747 | kPrefixREX;
748 VerifyConsumeX87Instructions();
749 }
750 }
751 }
752
753 // Test function NaClConsumeInstBytes for one byte instruction values.
754 TEST_F(NcInstStateTests, ConsumeOneByteInstructions) {
755 // First try effects of just multibyte prefixes.
756 for (size_t i = 0; i < NACL_ARRAY_SIZE(kMultibytePrefixes); ++i) {
757 _state->prefix_mask = kMultibytePrefixes[i];
758 VerifyConsumeOneByteInstructions();
759
760 // Verify that adding a rex prefix don't effect anything.
761 _state->prefix_mask = kMultibytePrefixes[i] | kPrefixREX;
762 VerifyConsumeOneByteInstructions();
763
764 // Now try adding other possible prefixes to see if they break anything.
765 for (size_t j = 0; j < NACL_ARRAY_SIZE(prefix_values); ++j) {
766 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask;
767 VerifyConsumeOneByteInstructions();
768
769 // Verify that adding a rex prefix don't effect anything.
770 _state->prefix_mask = kMultibytePrefixes[i] | prefix_values[i].mask
771 | kPrefixREX;
772 VerifyConsumeOneByteInstructions();
773 }
774 }
775 }
776
777 }; // anonymous namespace
778
779 int main(int argc, char *argv[]) {
780 NaClLogModuleInit();
781 testing::InitGoogleTest(&argc, argv);
782 return RUN_ALL_TESTS();
783 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698