2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * ncval_tests.c - simple unit tests for NaCl validator
35 #include "native_client/include/portability.h"
39 #include "native_client/ncv/ncvalidate.h"
40 #include "native_client/ncv/ncvalidate_internaltypes.h"
42 struct NCValTestCase
{
46 uint32_t instructions
;
53 struct NCValTestCase NCValTests
[] = {
56 "a first very simple test with an illegal inst.",
57 1, 9, 1, 26, 0x80000000,
61 "\xe8\x81\x00\x00\x00"
62 "\xe8\xd3\x00\x00\x00"
63 "\xe8\xf3\x04\x00\x00"
70 "like test 1 but no illegal inst",
71 1, 9, 0, 26, 0x80000000,
75 "\xe8\x81\x00\x00\x00"
76 "\xe8\xd3\x00\x00\x00"
77 "\xe8\xf3\x04\x00\x00"
84 "like test 1 but no illegal inst, with bad alignment",
85 1, 9, 0, 26, 0x80000001,
89 "\xe8\x81\x00\x00\x00"
90 "\xe8\xd3\x00\x00\x00"
91 "\xe8\xf3\x04\x00\x00"
98 "a longer simple test with a bad jump target",
99 1, 90, 0, 336, 0x8054600,
100 (uint8_t *)"\x8d\x4c\x24\x04"
109 "\xc7\x45\xf4\x0a\x00\x00\x00"
118 "\xc7\x04\x24\x54\x14\x00\x08"
119 "\xe8\xc0\x02\x00\x00"
120 "\xc7\x04\x24\x01\x00\x00\x00"
122 "\xe8\xc0\x01\x00\x00"
130 "\x8d\xbc\x27\x00\x00\x00\x00"
131 "\xe8\x90\x09\x00\x00"
142 "\xe8\x70\x09\x00\x00"
144 "\x8d\xb6\x00\x00\x00\x00"
145 "\x8d\xbc\x27\x00\x00\x00\x00"
147 "\xa3\x28\x2f\x00\x08"
149 "\x8d\xb6\x00\x00\x00\x00"
150 "\xc7\x44\x24\x08\x03\x00\x00\x00"
151 "\xc7\x44\x24\x04\x01\x00\x00\x00"
156 "\xe8\x20\x00\x00\x00"
163 "\xc7\x04\x24\x00\x00\x00\x00"
165 "\xe8\x20\x01\x00\x00"
173 "\x8b\x04\x95\x24\x2f\x00\x08"
175 "\x8d\xb6\x00\x00\x00\x00"
176 "\x89\x04\x95\x24\x2f\x00\x08"
178 "\x8d\xb6\x00\x00\x00\x00"
179 "\x8b\x04\x95\x24\x2f\x00\x08"
181 "\x8d\xb6\x00\x00\x00\x00"
182 "\x89\x04\x95\x24\x2f\x00\x08"
184 "\x8d\xb4\x26\x00\x00\x00\x00"
188 "\xb8\x06\x00\x00\x00"
194 "like test 4; with bad jump target",
195 1, 90, 0, 336, 0x8054600,
196 (uint8_t *)"\x8d\x4c\x24\x04"
205 "\xc7\x45\xf4\x0a\x00\x00\x00"
214 "\xc7\x04\x24\x54\x14\x00\x08"
215 "\xe8\xc0\x02\x00\x00"
216 "\xc7\x04\x24\x01\x00\x00\x00"
218 "\xe8\xc0\x01\x00\x00"
226 "\x8d\xbc\x27\x00\x00\x00\x00"
227 "\xe8\x90\x09\x00\x00"
238 "\xe8\x70\x09\x00\x00"
240 "\x8d\xb6\x00\x00\x00\x00"
241 "\x8d\xbc\x27\x00\x00\x00\x00"
243 "\xa3\x28\x2f\x00\x08"
245 "\x8d\xb6\x00\x00\x00\x00"
246 "\xc7\x44\x24\x08\x03\x00\x00\x00"
247 "\xc7\x44\x24\x04\x01\x00\x00\x00"
252 "\xe8\x20\x00\x00\x00"
259 "\xc7\x04\x24\x00\x00\x00\x00"
261 "\xe8\x20\x01\x00\x00"
269 "\x8b\x04\x95\x24\x2f\x00\x08"
271 "\x8d\xb6\x00\x00\x00\x00"
272 "\x89\x04\x95\x24\x2f\x00\x08"
274 "\x8d\xb6\x00\x00\x00\x00"
275 "\x8b\x04\x95\x24\x2f\x00\x08"
277 "\x8d\xb6\x00\x00\x00\x00"
278 "\x89\x04\x95\x24\x2f\x00\x08"
280 "\x8d\xb4\x26\x00\x00\x00\x00"
284 "\xb8\x06\x00\x00\x00"
290 "test 6: 3c 25 cmp %al, $I",
291 0, 7, 0, 9, 0x80000000,
292 (uint8_t *)"\x3c\x25"
293 "\x90\x90\x90\x90\x90\x90\xf4"
297 "test 7: group2, three byte move",
298 0, 8, 0, 13, 0x80000000,
299 (uint8_t *)"\xc1\xf9\x1f\x89\x4d\xe4"
300 "\x90\x90\x90\x90\x90\x90\xf4"
304 "test 8: five byte move",
305 0, 7, 0, 12, 0x80000000,
306 (uint8_t *)"\xc6\x44\x05\xd6\x00"
307 "\x90\x90\x90\x90\x90\x90\xf4"
311 "test 9: seven byte control transfer, unprotected",
312 1, 7, 0, 14, 0x80000000,
313 (uint8_t *)"\xff\x24\x95\xc8\x6e\x05\x08"
314 "\x90\x90\x90\x90\x90\x90\xf4"
318 "test 10: eight byte bts instruction",
319 1, 7, 1, 15, 0x80000000,
320 (uint8_t *)"\x0f\xab\x14\x85\x40\xfb\x27\x08"
321 "\x90\x90\x90\x90\x90\x90\xf4",
325 "test 11: four byte move",
326 0, 7, 0, 11, 0x80000000,
327 (uint8_t *)"\x66\xbf\x08\x00"
328 "\x90\x90\x90\x90\x90\x90\xf4",
332 "test 12: five byte movsx",
333 0, 7, 0, 12, 0x80000000,
334 (uint8_t *)"\x66\x0f\xbe\x04\x10"
335 "\x90\x90\x90\x90\x90\x90\xf4"
339 "test 13: eight byte bts instruction, missing full stop",
340 1, 7, 1, 15, 0x80000000,
341 (uint8_t *)"\x0f\xab\x14\x85\x40\xfb\x27\x08"
342 "\x90\x90\x90\x90\x90\x90\x90",
344 /* ldmxcsr, stmxcsr */
347 "test 14: ldmxcsr, stmxcsr",
348 1, 10, 2, 15, 0x80000000,
349 (uint8_t *)"\x90\x0f\xae\x10\x90\x0f\xae\x18"
350 "\x90\x90\x90\x90\x90\x90\xf4",
355 "test 15: invalid instruction",
356 1, 8, 1, 11, 0x80000000,
357 (uint8_t *)"\x90\x0f\xae\x21"
358 "\x90\x90\x90\x90\x90\x90\xf4",
364 1, 8, 1, 11, 0x80000000,
365 (uint8_t *)"\x90\x0f\xae\x28"
366 "\x90\x90\x90\x90\x90\x90\xf4",
370 "test 17: lock cmpxchg",
371 0, 4, 0, 12, 0x80000000,
372 (uint8_t *)"\xf0\x0f\xb1\x8f\xa8\x01\x00\x00"
377 "test 18: loop branch into overlapping instruction",
378 1, 3, 1, 10, 0x80000000,
379 (uint8_t *)"\xbb\x90\x40\xcd\x80\x85\xc0\xe1\xf8\xf4",
384 1, 5, 2, 15, 0x80000000,
385 (uint8_t *)"\x68\x8a\x80\x04\x08\xd5\xb0\xc3\x90\xbb\x90\x40\xcd\x80\xf4"
389 "test 20: addr16 lea",
390 1, 5, 1, 19, 0x80000000,
391 (uint8_t *)"\x68\x8e\x80\x04\x08\x66\x67\x8d\x98\xff\xff\xc3\x90\xbb\x90\x40\xcd\x80\xf4"
396 1, 4, 2, 14, 0x80000000,
397 (uint8_t *)"\x68\x89\x80\x04\x08\xd4\xb0\xc3\xbb\x90\x40\xcd\xf4",
402 1, 4, 1, 16, 0x80000000,
403 (uint8_t *)"\x68\x8b\x80\x04\x08\x0f\x70\xca\xb3\xc3\xbb\x90\x40\xcd\x80\xf4",
407 "test 23: 14-byte nacljmp using eax",
408 1, 3, 0, 15, 0x80000000,
409 (uint8_t *)"\x81\xe0\xff\xff\xff\xff\x81\xc8\x00\x00\x00\x00\xff\xd0\xf4",
413 "test 24: 5-byte nacljmp",
414 0, 2, 0, 6, 0x80000000,
415 (uint8_t *)"\x83\xe0\xf0\xff\xe0\xf4",
420 1, 1, 1, 3, 0x80000000,
421 (uint8_t *)"\xe3\x00\xf4",
425 "test 26: 0xe9 jmp, nop",
426 0, 2, 0, 7, 0x80000000,
427 (uint8_t *)"\xe9\x00\x00\x00\x00\x90\xf4",
431 "test 27: 0xf0 0x80 jmp, nop",
432 0, 2, 0, 8, 0x80000000,
433 (uint8_t *)"\x0f\x80\x00\x00\x00\x00\x90\xf4",
438 1, 1, 0, 6, 0x80000000,
439 (uint8_t *)"\xe9\x00\x00\x00\x00\xf4",
443 "test 30: addr16 lea ret",
444 1, 3, 1, 8, 0x80000000,
445 (uint8_t *)"\x67\x8d\xb4\x9a\x40\xc3\x90\xf4",
449 "test 31: repz movsbl",
450 1, 3, 2, 8, 0x80000000,
451 (uint8_t *)"\xf3\x0f\xbe\x40\xd0\xc3\x90\xf4",
455 "test 32: infinite loop",
456 0, 1, 0, 3, 0x80000000,
457 (uint8_t *)"\x7f\xfe\xf4",
461 "test 33: bad branch",
462 1, 1, 0, 3, 0x80000000,
463 (uint8_t *)"\x7f\xfd\xf4",
467 "test 34: bad branch",
468 1, 1, 0, 3, 0x80000000,
469 (uint8_t *)"\x7f\xff\xf4",
473 "test 35: bad branch",
474 1, 1, 0, 3, 0x80000000,
475 (uint8_t *)"\x7f\x00\xf4",
479 "test 36: bad branch",
480 1, 1, 0, 3, 0x80000000,
481 (uint8_t *)"\x7f\x01\xf4",
485 "test 37: bad branch",
486 1, 1, 0, 3, 0x80000000,
487 (uint8_t *)"\x7f\x02\xf4",
492 1, 10, 5, 18, 0x80000000,
493 (uint8_t *)"\x66\xeb\x1b\x31\x51\x3d\xef\xcc\x2f\x36\x48\x6e\x44\x2e\xcc\x14\xf4\xf4",
497 "test 39: bad branch",
498 1, 7, 1, 18, 0x80000000,
499 (uint8_t *)"\x67\x8d\x1d\x22\xa0\x05\xe3\x7b\x9c\xdb\x08\x04\xb1\x90\xed\x12\xf4\xf4",
503 "test 40: more addr16 problems",
504 1, 4, 1, 9, 0x80000000,
505 (uint8_t *)"\x67\xa0\x00\x00\xcd\x80\x90\x90\xf4",
509 "test 41: the latest non-bug from hcf",
510 1, 5, 1, 17, 0x80000000,
511 (uint8_t *)"\x84\xd4\x04\x53\xa0\x04\x6a\x5a\x20\xcc\xb8\x48\x03\x2b\x96\x11\xf4"
515 "test 42: another case from hcf",
516 1, 7, 1, 17, 0x80000000,
517 (uint8_t *)"\x45\x7f\x89\x58\x94\x04\x24\x1b\xc3\xe2\x6f\x1a\x94\x87\x8f\x0b\xf4",
521 "test 43: too many prefix bytes",
522 1, 2, 0, 8, 0x80000000,
523 (uint8_t *)"\x66\x66\x66\x66\x00\x00\x90\xf4"
527 "test 44: palignr (SSSE3)",
528 0, 2, 0, 8, 0x80000000,
529 (uint8_t *)"\x66\x0f\x3a\x0f\xd0\xc0\x90\xf4"
533 "test 45: undefined inst in 3-byte opcode space",
534 1, 2, 2, 8, 0x80000000,
535 (uint8_t *)"\x66\x0f\x39\x0f\xd0\xc0\x90\xf4"
539 "test 46: SSE2x near miss",
540 1, 2, 1, 7, 0x80000000,
541 (uint8_t *)"\x66\x0f\x73\x00\x00\x90\xf4"
546 0, 2, 0, 7, 0x80000000,
547 (uint8_t *)"\x66\x0f\x73\xff\x00\x90\xf4"
551 "test 48: SSE2x, missing required prefix byte",
552 1, 2, 0, 6, 0x80000000,
553 (uint8_t *)"\x0f\x73\xff\x00\x90\xf4"
557 "test 49: 3DNow example",
558 0, 2, 0, 7, 0x80000000,
559 (uint8_t *)"\x0f\x0f\x46\x01\xbf\x90\xf4"
563 "test 50: 3DNow error example 1",
564 1, 2, 1, 7, 0x80000000,
565 (uint8_t *)"\x0f\x0f\x46\x01\x00\x90\xf4"
569 "test 51: 3DNow error example 2",
570 1, 0, 0, 5, 0x80000000,
571 (uint8_t *)"\x0f\x0f\x46\x01\xf4"
575 "test 52: 3DNow error example 3",
576 1, 2, 1, 7, 0x80000000,
577 (uint8_t *)"\x0f\x0f\x46\x01\xbe\x90\xf4"
581 "test 53: 3DNow error example 4",
582 1, 2, 1, 7, 0x80000000,
583 (uint8_t *)"\x0f\x0f\x46\x01\xaf\x90\xf4"
587 "test 54: SSSE3 error 1",
588 1, 3, 1, 8, 0x80000000,
589 (uint8_t *)"\x66\x0f\x3a\x0e\xd0\xc0\x90\xf4"
593 "test 55: SSSE3 error 2",
594 1, 3, 1, 8, 0x80000000,
595 (uint8_t *)"\x66\x0f\x38\x0f\xd0\xc0\x90\xf4"
599 "test 56: incb decb",
600 0, 3, 0, 14, 0x80000000,
601 (uint8_t *)"\xfe\x85\x4f\xfd\xff\xff\xfe\x8d\x73\xfd\xff\xff\x90\xf4",
606 0, 2, 0, 6, 0x80000000,
607 (uint8_t *)"\xf3\x0f\xbd\x00\x90\xf4",
612 0, 2, 0, 4, 0x80000000,
613 (uint8_t *)"\xd9\xee\x90\xf4",
618 0, 7, 0, 25, 0x80000000,
619 (uint8_t *)"\xdd\x9c\xfd\xb0\xfe\xff\xff"
620 "\xdd\x9d\x40\xff\xff\xff"
629 "test 60: x87 bad instructions",
630 1, 19, 9, 40, 0x80000000,
631 (uint8_t *)"\xdd\xcc"
653 "test 61: 3DNow prefetch",
654 0, 2, 0, 5, 0x80000000,
655 (uint8_t *)"\x0f\x0d\x00"
660 "test 61.1: F2 0F ...",
661 1, 3, 1, 13, 0x80000000,
662 (uint8_t *)"\xf2\x0f\x48\x0f\x48\xa4\x52"
668 "test 62: f6/f7 test Ib/Iv ...",
669 0, 10, 0, 28, 0x80000000,
670 (uint8_t *)"\xf6\xc1\xff"
671 "\xf6\x44\x43\x01\x02"
672 "\xf7\xc6\x03\x00\x00\x00"
673 "\x90\x90\x90\x90\x90"
674 "\xf7\x45\x18\x00\x00\x00\x20"
679 "test 63: addr16 corner cases ...",
680 1, 5, 0, 17, 0x80000000,
681 (uint8_t *)"\x67\x01\x00"
683 "\x67\x01\x80\x00\x90"
689 "test 64: text starts with indirect jmp ...",
690 1, 2, 0, 4, 0x80000000,
691 (uint8_t *)"\xff\xd0\x90\xf4"
695 "test 65: nacljmp crosses 32-byte boundary ...",
696 1, 32, 0, 36, 0x80000000,
697 (uint8_t *)"\x90\x90\x90\x90\x90\x90\x90\x90"
698 "\x90\x90\x90\x90\x90\x90\x90\x90"
699 "\x90\x90\x90\x90\x90\x90\x90\x90"
700 "\x90\x90\x90\x90\x90\x83\xe0\xff"
704 /* I think this is currently NACLi_ILLEGAL */
706 "test 65: NACLi_CFLUSH",
707 1, 2, 1, 10, 0x80000000,
708 (uint8_t *)"\x0f\xae\x00\x00\x90\x90\x90\x90\x90\xf4"
712 "test 66: NACLi_CMPXCHG8B",
713 0, 2, 0, 6, 0x80000000,
714 (uint8_t *)"\xf0\x0f\xc7\010\x90\xf4"
718 "test 67: NACLi_FCMOV",
719 0, 7, 0, 10, 0x80000000,
720 (uint8_t *)"\xda\xc0\x00\x00\x90\x90\x90\x90\x90\xf4"
724 "test 68: NACLi_MMX",
725 0, 4, 0, 7, 0x80000000,
726 (uint8_t *)"\x0f\x60\x00\x90\x90\x90\xf4"
730 "test 69: NACLi_SSE",
731 0, 2, 0, 9, 0x80000000,
732 (uint8_t *)"\x0f\x5e\x90\x90\x90\x90\x90\x90\xf4"
736 "test 70: NACLi_SSE2",
737 0, 4, 0, 8, 0x80000000,
738 (uint8_t *)"\x66\x0f\x60\x00\x90\x90\x90\xf4"
742 "test 71: NACLi_SSE3",
743 0, 4, 0, 8, 0x80000000,
744 (uint8_t *)"\x66\x0f\x7d\x00\x90\x90\x90\xf4"
748 "test 72: NACLi_SSE4A",
749 0, 4, 0, 8, 0x80000000,
750 (uint8_t *)"\xf2\x0f\x79\x00\x90\x90\x90\xf4"
754 "test 73: NACLi_POPCNT",
755 0, 2, 0, 6, 0x80000000,
756 (uint8_t *)"\xf3\x0f\xb8\x00\x90\xf4"
760 "test 74: NACLi_E3DNOW",
761 0, 2, 0, 7, 0x80000000,
762 (uint8_t *)"\x0f\x0f\x46\x01\xbb\x90\xf4"
766 "test 75: NACLi_MMXSSE2",
767 0, 2, 0, 7, 0x80000000,
768 (uint8_t *)"\x66\x0f\x71\xf6\x00\x90\xf4",
772 "test 76: mov eax, ss",
773 1, 4, 3, 9, 0x80000000,
774 (uint8_t *)"\x8e\xd0\x8c\xd0\x66\x8c\xd0\x90\xf4",
779 1, 3, 0, 7, 0x80000000,
780 (uint8_t *)"\x83\xe4\xf0\xff\xd4\x90\xf4",
782 /* code.google.com issue 23 reported by defend.the.world on 11 Dec 2008 */
785 "test 79: call (*edx)",
786 1, 30, 0, 34, 0x80000000,
788 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
789 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
790 "\x83\xe2\xf0" /* and */
791 "\xff\x12" /* call (*edx) */
792 "\x90\xf4", /* nop halt */
796 "test 79: call *edx",
797 0, 30, 0, 34, 0x80000000,
799 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
800 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
801 "\x83\xe2\xf0" /* and */
802 "\xff\xd2" /* call *edx */
803 "\x90\xf4", /* nop halt */
807 static uint8_t *memdup(uint8_t *s
, int len
) {
808 return memcpy(malloc(len
), s
, len
);
811 static void TestValidator(struct NCValTestCase
*vtest
) {
812 struct NCValidatorState
*vstate
;
813 uint8_t *byte0
= memdup(vtest
->testbytes
, vtest
->testsize
);
816 vstate
= NCValidateInit(vtest
->vaddr
,
817 vtest
->vaddr
+ vtest
->testsize
, 16);
818 NCValidateSegment(byte0
, (uint32_t)vtest
->vaddr
, vtest
->testsize
, vstate
);
820 rc
= NCValidateFinish(vstate
);
822 if (vtest
->sawfailure
^ vstate
->stats
.sawfailure
) break;
823 if (vtest
->instructions
!= vstate
->stats
.instructions
) break;
824 if (vtest
->illegalinst
!= vstate
->stats
.illegalinst
) break;
825 fprintf(stderr
, "*** %s passed (%s)\n", vtest
->name
, vtest
->description
);
826 NCValidateFreeState(&vstate
);
829 Stats_Print(stderr
, vstate
);
830 NCValidateFreeState(&vstate
);
831 fprintf(stderr
, "*** %s failed (%s)\n", vtest
->name
, vtest
->description
);
835 #define sizeofA(array) (sizeof(array)/sizeof(array[0]))
836 void ncvalidate_unittests() {
839 for (i
= 0; i
< sizeofA(NCValTests
); i
++) {
840 TestValidator(&NCValTests
[i
]);
842 fprintf(stderr
, "\nAll tests passed.\n\n");