1 : /*
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
4 : * found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * ncval_tests.c - simple unit tests for NaCl validator
9 : */
10 :
11 : #ifndef NACL_TRUSTED_BUT_NOT_TCB
12 : #error("This file is not meant for use in the TCB")
13 : #endif
14 :
15 : #include <assert.h>
16 : #include <stdarg.h>
17 : #include <stdio.h>
18 : #include <stdlib.h>
19 : #include <string.h>
20 : #include "native_client/src/include/nacl_macros.h"
21 : #include "native_client/src/include/portability.h"
22 : #include "native_client/src/shared/gio/gio.h"
23 : #include "native_client/src/shared/platform/nacl_log.h"
24 : #include "native_client/src/trusted/validator/x86/ncval_seg_sfi/ncdecode_verbose.h"
25 : #include "native_client/src/trusted/validator/x86/ncval_seg_sfi/ncvalidate.h"
26 : #include "native_client/src/trusted/validator/x86/ncval_seg_sfi/ncvalidate_internaltypes.h"
27 :
28 : /* Define the set of CPU features to use while validating. */
29 : static NaClCPUFeaturesX86 g_ncval_cpu_features;
30 :
31 : void Info(const char *fmt, ...)
32 98 : {
33 : va_list ap;
34 98 : fprintf(stdout, "I: ");
35 98 : va_start(ap, fmt);
36 98 : vfprintf(stdout, fmt, ap);
37 98 : va_end(ap);
38 98 : }
39 :
40 : struct NCValTestCase {
41 : char *name;
42 : char *description;
43 :
44 : /* Expected results: */
45 : int sawfailure; /* Whether code is expected to fail validation */
46 : uint32_t illegalinst; /* Expected number of disallowed instructions */
47 : uint32_t instructions; /* Expected number of instructions (excluding final HLT) */
48 :
49 : /* Input to validator: */
50 : uint32_t vaddr; /* Load address (shouldn't matter) */
51 : const char *data_as_hex;
52 : };
53 :
54 : struct NCValTestCase NCValTests[] = {
55 : /* NOTE: Many of these tests are now in the textual testing structure in
56 : * native_client/src/trusted/validator_x86/testdata/32 using
57 : * files "test-n.hex", "test-n.ndis", "test-n.nvals", and
58 : * "test-n.nvals16".
59 : */
60 : {
61 : "test 1",
62 : "a first very simple test with an illegal inst.",
63 : /* sawfailure= */ 1, /* illegalinst= */ 1,
64 : /* instructions= */ 9,
65 : /* vaddr= */ 0x80000000,
66 : "55 \n" /* push %ebp */
67 : "89 e5 \n" /* mov %esp,%ebp */
68 : "83 ec 08 \n" /* sub $0x8,%esp */
69 : "e8 81 00 00 00 \n" /* call 0x86 */
70 : "e8 d3 00 00 00 \n" /* call 0xd8 */
71 : "e8 f3 04 00 00 \n" /* call 0x4f8 */
72 : "c9 \n" /* leave */
73 : "c3 \n" /* ret */
74 : "00 00 f4 \n"
75 : },
76 : {
77 : "test 4",
78 : "a big chunk of code whose origin is not clear",
79 : /* sawfailure= */ 0, /* illegalinst= */ 0,
80 : /* instructions= */ 90,
81 : /* vaddr= */ 0x8054600,
82 : "8d 4c 24 04 \n" /* lea 0x4(%esp),%ecx */
83 : "83 e4 f0 \n" /* and $0xfffffff0,%esp */
84 : "ff 71 fc \n" /* pushl -0x4(%ecx) */
85 : "55 \n" /* push %ebp */
86 : "89 e5 \n" /* mov %esp,%ebp */
87 : "51 \n" /* push %ecx */
88 : "66 90 \n" /* xchg %ax,%ax */
89 : "83 ec 24 \n" /* sub $0x24,%esp */
90 : "89 4d e8 \n" /* mov %ecx,-0x18(%ebp) */
91 : "c7 45 f4 0a 00 00 00 \n" /* movl $0xa,-0xc(%ebp) */
92 : "8b 45 e8 \n" /* mov -0x18(%ebp),%eax */
93 : "83 38 01 \n" /* cmpl $0x1,(%eax) */
94 : "7f 2b \n" /* jg 0x2d */
95 : "8b 55 e8 \n" /* mov -0x18(%ebp),%edx */
96 : "8b 42 04 \n" /* mov 0x4(%edx),%eax */
97 : "8b 00 \n" /* mov (%eax),%eax */
98 : "8d 76 00 \n" /* lea 0x0(%esi),%esi */
99 : "89 44 24 04 \n" /* mov %eax,0x4(%esp) */
100 : "c7 04 24 54 14 00 08 \n" /* movl $0x8001454,(%esp) */
101 : "e8 c0 02 00 00 \n" /* call 0x2c5 */
102 : "c7 04 24 01 00 00 00 \n" /* movl $0x1,(%esp) */
103 : "8d 74 26 00 \n" /* lea 0x0(%esi),%esi */
104 : "e8 c0 01 00 00 \n" /* call 0x1c5 */
105 : "8b 55 e8 \n" /* mov -0x18(%ebp),%edx */
106 : "8b 42 04 \n" /* mov 0x4(%edx),%eax */
107 : "83 c0 04 \n" /* add $0x4,%eax */
108 : "8b 00 \n" /* mov (%eax),%eax */
109 : "89 04 24 \n" /* mov %eax,(%esp) */
110 : "66 90 \n" /* xchg %ax,%ax */
111 : "8d 74 26 00 \n" /* lea 0x0(%esi),%esi */
112 : "8d bc 27 00 00 00 00 \n" /* lea 0x0(%edi),%edi */
113 : "e8 90 09 00 00 \n" /* call 0x995 */
114 : "89 45 f8 \n" /* mov %eax,-0x8(%ebp) */
115 : "8b 45 e8 \n" /* mov -0x18(%ebp),%eax */
116 : "83 38 02 \n" /* cmpl $0x2,(%eax) */
117 : "7e 25 \n" /* jle 0x27 */
118 : "8b 55 e8 \n" /* mov -0x18(%ebp),%edx */
119 : "66 90 \n" /* xchg %ax,%ax */
120 : "8b 42 04 \n" /* mov 0x4(%edx),%eax */
121 : "83 c0 08 \n" /* add $0x8,%eax */
122 : "8b 00 \n" /* mov (%eax),%eax */
123 : "89 04 24 \n" /* mov %eax,(%esp) */
124 : "e8 70 09 00 00 \n" /* call 0x975 */
125 : "89 45 f4 \n" /* mov %eax,-0xc(%ebp) */
126 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
127 : "8d bc 27 00 00 00 00 \n" /* lea 0x0(%edi),%edi */
128 : "8b 45 f4 \n" /* mov -0xc(%ebp),%eax */
129 : "a3 28 2f 00 08 \n" /* mov %eax,0x8002f28 */
130 : "eb 26 \n" /* jmp 0x28 */
131 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
132 : "c7 44 24 08 03 00 00 00 \n" /* movl $0x3,0x8(%esp) */
133 : "c7 44 24 04 01 00 00 00 \n" /* movl $0x1,0x4(%esp) */
134 : "8b 45 f4 \n" /* mov -0xc(%ebp),%eax */
135 : "89 04 24 \n" /* mov %eax,(%esp) */
136 : "90 \n" /* nop */
137 : "8d 74 26 00 \n" /* lea 0x0(%esi),%esi */
138 : "e8 20 00 00 00 \n" /* call 0x25 */
139 : "83 7d f8 00 \n" /* cmpl $0x0,-0x8(%ebp) */
140 : "0f 9f c0 \n" /* setg %al */
141 : "83 6d f8 01 \n" /* subl $0x1,-0x8(%ebp) */
142 : "84 c0 \n" /* test %al,%al */
143 : "8d 76 00 \n" /* lea 0x0(%esi),%esi */
144 : "75 ce \n" /* jne 0xffffffd0 */
145 : "c7 04 24 00 00 00 00 \n" /* movl $0x0,(%esp) */
146 : "66 90 \n" /* xchg %ax,%ax */
147 : "e8 20 01 00 00 \n" /* call 0x125 */
148 : "55 \n" /* push %ebp */
149 : "89 e5 \n" /* mov %esp,%ebp */
150 : "83 ec 1c \n" /* sub $0x1c,%esp */
151 : "83 7d 08 01 \n" /* cmpl $0x1,0x8(%ebp) */
152 : "75 44 \n" /* jne 0x46 */
153 : "8b 55 0c \n" /* mov 0xc(%ebp),%edx */
154 : "90 \n" /* nop */
155 : "8b 04 95 24 2f 00 08 \n" /* mov 0x8002f24(,%edx,4),%eax */
156 : "83 e8 01 \n" /* sub $0x1,%eax */
157 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
158 : "89 04 95 24 2f 00 08 \n" /* mov %eax,0x8002f24(,%edx,4) */
159 : "8b 55 10 \n" /* mov 0x10(%ebp),%edx */
160 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
161 : "8b 04 95 24 2f 00 08 \n" /* mov 0x8002f24(,%edx,4),%eax */
162 : "83 c0 01 \n" /* add $0x1,%eax */
163 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
164 : "89 04 95 24 2f 00 08 \n" /* mov %eax,0x8002f24(,%edx,4) */
165 : "eb 77 \n" /* jmp 0x79 */
166 : "8d b4 26 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
167 : "8b 45 10 \n" /* mov 0x10(%ebp),%eax */
168 : "8b 55 0c \n" /* mov 0xc(%ebp),%edx */
169 : "01 c2 \n" /* add %eax,%edx */
170 : "b8 06 00 00 00 \n" /* mov $0x6,%eax */
171 : "29 d0 \n" /* sub %edx,%eax */
172 : "f4 \n" /* hlt */
173 : },
174 : {
175 : "test 5",
176 : "a big chunk of code whose origin is not clear",
177 : /* sawfailure= */ 0, /* illegalinst= */ 0,
178 : /* instructions= */ 90,
179 : /* vaddr= */ 0x8054600,
180 : "8d 4c 24 04 \n" /* lea 0x4(%esp),%ecx */
181 : "83 e4 f0 \n" /* and $0xfffffff0,%esp */
182 : "ff 71 fc \n" /* pushl -0x4(%ecx) */
183 : "55 \n" /* push %ebp */
184 : "89 e5 \n" /* mov %esp,%ebp */
185 : "51 \n" /* push %ecx */
186 : "66 90 \n" /* xchg %ax,%ax */
187 : "83 ec 24 \n" /* sub $0x24,%esp */
188 : "89 4d e8 \n" /* mov %ecx,-0x18(%ebp) */
189 : "c7 45 f4 0a 00 00 00 \n" /* movl $0xa,-0xc(%ebp) */
190 : "8b 45 e8 \n" /* mov -0x18(%ebp),%eax */
191 : "83 38 01 \n" /* cmpl $0x1,(%eax) */
192 : "7f 2b \n" /* jg 0x2d */
193 : "8b 55 e8 \n" /* mov -0x18(%ebp),%edx */
194 : "8b 42 04 \n" /* mov 0x4(%edx),%eax */
195 : "8b 00 \n" /* mov (%eax),%eax */
196 : "8d 76 00 \n" /* lea 0x0(%esi),%esi */
197 : "89 44 24 04 \n" /* mov %eax,0x4(%esp) */
198 : "c7 04 24 54 14 00 08 \n" /* movl $0x8001454,(%esp) */
199 : "e8 c0 02 00 00 \n" /* call 0x2c5 */
200 : "c7 04 24 01 00 00 00 \n" /* movl $0x1,(%esp) */
201 : "8d 74 26 00 \n" /* lea 0x0(%esi),%esi */
202 : "e8 c0 01 00 00 \n" /* call 0x1c5 */
203 : "8b 55 e8 \n" /* mov -0x18(%ebp),%edx */
204 : "8b 42 04 \n" /* mov 0x4(%edx),%eax */
205 : "83 c0 04 \n" /* add $0x4,%eax */
206 : "8b 00 \n" /* mov (%eax),%eax */
207 : "89 04 24 \n" /* mov %eax,(%esp) */
208 : "66 90 \n" /* xchg %ax,%ax */
209 : "8d 74 26 00 \n" /* lea 0x0(%esi),%esi */
210 : "8d bc 27 00 00 00 00 \n" /* lea 0x0(%edi),%edi */
211 : "e8 90 09 00 00 \n" /* call 0x995 */
212 : "89 45 f8 \n" /* mov %eax,-0x8(%ebp) */
213 : "8b 45 e8 \n" /* mov -0x18(%ebp),%eax */
214 : "83 38 02 \n" /* cmpl $0x2,(%eax) */
215 : "7e 25 \n" /* jle 0x27 */
216 : "8b 55 e8 \n" /* mov -0x18(%ebp),%edx */
217 : "66 90 \n" /* xchg %ax,%ax */
218 : "8b 42 04 \n" /* mov 0x4(%edx),%eax */
219 : "83 c0 08 \n" /* add $0x8,%eax */
220 : "8b 00 \n" /* mov (%eax),%eax */
221 : "89 04 24 \n" /* mov %eax,(%esp) */
222 : "e8 70 09 00 00 \n" /* call 0x975 */
223 : "89 45 f4 \n" /* mov %eax,-0xc(%ebp) */
224 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
225 : "8d bc 27 00 00 00 00 \n" /* lea 0x0(%edi),%edi */
226 : "8b 45 f4 \n" /* mov -0xc(%ebp),%eax */
227 : "a3 28 2f 00 08 \n" /* mov %eax,0x8002f28 */
228 : "eb 26 \n" /* jmp 0x28 */
229 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
230 : "c7 44 24 08 03 00 00 00 \n" /* movl $0x3,0x8(%esp) */
231 : "c7 44 24 04 01 00 00 00 \n" /* movl $0x1,0x4(%esp) */
232 : "8b 45 f4 \n" /* mov -0xc(%ebp),%eax */
233 : "89 04 24 \n" /* mov %eax,(%esp) */
234 : "90 \n" /* nop */
235 : "8d 74 26 00 \n" /* lea 0x0(%esi),%esi */
236 : "e8 20 00 00 00 \n" /* call 0x25 */
237 : "83 7d f8 00 \n" /* cmpl $0x0,-0x8(%ebp) */
238 : "0f 9f c0 \n" /* setg %al */
239 : "83 6d f8 01 \n" /* subl $0x1,-0x8(%ebp) */
240 : "84 c0 \n" /* test %al,%al */
241 : "8d 76 00 \n" /* lea 0x0(%esi),%esi */
242 : "75 ce \n" /* jne 0xffffffd0 */
243 : "c7 04 24 00 00 00 00 \n" /* movl $0x0,(%esp) */
244 : "66 90 \n" /* xchg %ax,%ax */
245 : "e8 20 01 00 00 \n" /* call 0x125 */
246 : "55 \n" /* push %ebp */
247 : "89 e5 \n" /* mov %esp,%ebp */
248 : "83 ec 1c \n" /* sub $0x1c,%esp */
249 : "83 7d 08 01 \n" /* cmpl $0x1,0x8(%ebp) */
250 : "75 44 \n" /* jne 0x46 */
251 : "8b 55 0c \n" /* mov 0xc(%ebp),%edx */
252 : "90 \n" /* nop */
253 : "8b 04 95 24 2f 00 08 \n" /* mov 0x8002f24(,%edx,4),%eax */
254 : "83 e8 01 \n" /* sub $0x1,%eax */
255 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
256 : "89 04 95 24 2f 00 08 \n" /* mov %eax,0x8002f24(,%edx,4) */
257 : "8b 55 10 \n" /* mov 0x10(%ebp),%edx */
258 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
259 : "8b 04 95 24 2f 00 08 \n" /* mov 0x8002f24(,%edx,4),%eax */
260 : "83 c0 01 \n" /* add $0x1,%eax */
261 : "8d b6 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
262 : "89 04 95 24 2f 00 08 \n" /* mov %eax,0x8002f24(,%edx,4) */
263 : "00 00 \n" /* add %al,(%eax) */
264 : "8d b4 26 00 00 00 00 \n" /* lea 0x0(%esi),%esi */
265 : "8b 45 10 \n" /* mov 0x10(%ebp),%eax */
266 : "8b 55 0c \n" /* mov 0xc(%ebp),%edx */
267 : "01 c2 \n" /* add %eax,%edx */
268 : "b8 06 00 00 00 \n" /* mov $0x6,%eax */
269 : "29 d0 \n" /* sub %edx,%eax */
270 : "f4 \n" /* hlt */
271 : },
272 : {
273 : "test 6",
274 : "test 6: 3c 25 cmp %al, $I",
275 : /* sawfailure= */ 0, /* illegalinst= */ 0,
276 : /* instructions= */ 7,
277 : /* vaddr= */ 0x80000000,
278 : "3c 25 \n" /* cmp $0x25,%al */
279 : "90 90 90 90 90 90 f4 \n"
280 : },
281 : {
282 : "test 7",
283 : "test 7: group2, three byte move",
284 : /* sawfailure= */ 0, /* illegalinst= */ 0,
285 : /* instructions= */ 8,
286 : /* vaddr= */ 0x80000000,
287 : "c1 f9 1f 89 4d e4 \n"
288 : "90 90 90 90 90 90 f4 \n"
289 : },
290 : {
291 : "test 8",
292 : "test 8: five byte move",
293 : /* sawfailure= */ 0, /* illegalinst= */ 0,
294 : /* instructions= */ 7,
295 : /* vaddr= */ 0x80000000,
296 : "c6 44 05 d6 00 \n" /* movb $0x0,-0x2a(%ebp,%eax,1) */
297 : "90 90 90 90 90 90 f4 \n"
298 : },
299 : {
300 : "test 9",
301 : "test 9: seven byte control transfer, unprotected",
302 : /* sawfailure= */ 1, /* illegalinst= */ 0,
303 : /* instructions= */ 7,
304 : /* vaddr= */ 0x80000000,
305 : "ff 24 95 c8 6e 05 08 \n" /* jmp *0x8056ec8(,%edx,4) */
306 : "90 90 90 90 90 90 f4 \n"
307 : },
308 : {
309 : "test 10",
310 : "test 10: eight byte bts instruction",
311 : /* sawfailure= */ 1, /* illegalinst= */ 1,
312 : /* instructions= */ 7,
313 : /* vaddr= */ 0x80000000,
314 : "0f ab 14 85 40 fb 27 08 \n" /* bts %edx,0x827fb40(,%eax,4) */
315 : "90 90 90 90 90 90 f4 \n"
316 : },
317 : {
318 : "test 11",
319 : "test 11: four byte move",
320 : /* sawfailure= */ 0, /* illegalinst= */ 0,
321 : /* instructions= */ 7,
322 : /* vaddr= */ 0x80000000,
323 : "66 bf 08 00 \n" /* mov $0x8,%di */
324 : "90 90 90 90 90 90 f4 \n"
325 : },
326 : {
327 : "test 12",
328 : "test 12: five byte movsx",
329 : /* sawfailure= */ 0, /* illegalinst= */ 0,
330 : /* instructions= */ 7,
331 : /* vaddr= */ 0x80000000,
332 : "66 0f be 04 10 \n" /* movsbw (%eax,%edx,1),%ax */
333 : "90 90 90 90 90 90 f4 \n"
334 : },
335 : /* ldmxcsr, stmxcsr */
336 : {
337 : "test 14",
338 : "test 14: ldmxcsr, stmxcsr",
339 : /* sawfailure= */ 0, /* illegalinst= */ 0,
340 : /* instructions= */ 10,
341 : /* vaddr= */ 0x80000000,
342 : "90 0f ae 10 90 0f ae 18 \n"
343 : "90 90 90 90 90 90 f4 \n"
344 : },
345 : /* invalid */
346 : {
347 : "test 15",
348 : "test 15: invalid instruction",
349 : /* sawfailure= */ 1, /* illegalinst= */ 1,
350 : /* instructions= */ 8,
351 : /* vaddr= */ 0x80000000,
352 : "90 0f ae 21 \n"
353 : "90 90 90 90 90 90 f4 \n"
354 : },
355 : /* lfence */
356 : {
357 : "test 16",
358 : "test 16: lfence",
359 : /* sawfailure= */ 0, /* illegalinst= */ 0,
360 : /* instructions= */ 8,
361 : /* vaddr= */ 0x80000000,
362 : "90 0f ae ef \n"
363 : "90 90 90 90 90 90 f4 \n"
364 : },
365 : {
366 : "test 17",
367 : "test 17: lock cmpxchg",
368 : /* sawfailure= */ 0, /* illegalinst= */ 0,
369 : /* instructions= */ 4,
370 : /* vaddr= */ 0x80000000,
371 : "f0 0f b1 8f a8 01 00 00 \n" /* lock cmpxchg %ecx,0x1a8(%edi) */
372 : "90 90 90 f4 \n"
373 : },
374 : {
375 : "test 18",
376 : "test 18: loop branch into overlapping instruction",
377 : /* sawfailure= */ 1, /* illegalinst= */ 1,
378 : /* instructions= */ 3,
379 : /* vaddr= */ 0x80000000,
380 : "bb 90 40 cd 80 85 c0 e1 f8 f4 \n"
381 : },
382 : {
383 : "test 19",
384 : "test 19: aad test",
385 : /* sawfailure= */ 1, /* illegalinst= */ 2,
386 : /* instructions= */ 5,
387 : /* vaddr= */ 0x80000000,
388 : "68 8a 80 04 08 d5 b0 c3 90 bb 90 40 cd 80 f4 \n"
389 : },
390 : {
391 : "test 20",
392 : "test 20: addr16 lea",
393 : /* sawfailure= */ 1, /* illegalinst= */ 2,
394 : /* instructions= */ 5,
395 : /* vaddr= */ 0x80000000,
396 : "68 8e 80 04 08 66 67 8d 98 ff ff c3 90 bb 90 40 cd 80 f4 \n"
397 : },
398 : {
399 : "test 21",
400 : "test 21: aam",
401 : /* sawfailure= */ 1, /* illegalinst= */ 2,
402 : /* instructions= */ 4,
403 : /* vaddr= */ 0x80000000,
404 : "68 89 80 04 08 \n" /* push $0x8048089 */
405 : "d4 b0 \n" /* aam $0xffffffb0 */
406 : "c3 \n" /* ret */
407 : "bb 90 40 cd f4 \n" /* mov $0xf4cd4090,%ebx */
408 : "f4 \n" /* hlt */
409 : },
410 : {
411 : "test 22",
412 : "test 22: pshufw",
413 : /* sawfailure= */ 1, /* illegalinst= */ 1,
414 : /* instructions= */ 4,
415 : /* vaddr= */ 0x80000000,
416 : "68 8b 80 04 08 0f 70 ca b3 c3 bb 90 40 cd 80 f4 \n"
417 : },
418 : {
419 : "test 23",
420 : "test 23: 14-byte nacljmp using eax",
421 : /* sawfailure= */ 1, /* illegalinst= */ 0,
422 : /* instructions= */ 3,
423 : /* vaddr= */ 0x80000000,
424 : "81 e0 ff ff ff ff 81 c8 00 00 00 00 ff d0 f4 \n"
425 : },
426 : {
427 : "test 24",
428 : "test 24: 5-byte nacljmp",
429 : /* sawfailure= */ 0, /* illegalinst= */ 0,
430 : /* instructions= */ 2,
431 : /* vaddr= */ 0x80000000,
432 : "83 e0 f0 ff e0 f4 \n"
433 : },
434 : {
435 : "test 25",
436 : "test 25: 0xe3 jmp",
437 : /* sawfailure= */ 1, /* illegalinst= */ 1,
438 : /* instructions= */ 1,
439 : /* vaddr= */ 0x80000000,
440 : "e3 00 f4 \n"
441 : },
442 : {
443 : "test 26",
444 : "test 26: 0xe9 jmp, nop",
445 : /* sawfailure= */ 0, /* illegalinst= */ 0,
446 : /* instructions= */ 2,
447 : /* vaddr= */ 0x80000000,
448 : "e9 00 00 00 00 90 f4 \n"
449 : },
450 : {
451 : "test 27",
452 : "test 27: 0xf0 0x80 jmp, nop",
453 : /* sawfailure= */ 0, /* illegalinst= */ 0,
454 : /* instructions= */ 2,
455 : /* vaddr= */ 0x80000000,
456 : "0f 80 00 00 00 00 90 f4 \n"
457 : },
458 : {
459 : "test 28",
460 : "test 28: 0xe9 jmp",
461 : /* sawfailure= */ 1, /* illegalinst= */ 0,
462 : /* instructions= */ 1,
463 : /* vaddr= */ 0x80000000,
464 : "e9 00 00 00 00 f4 \n"
465 : },
466 : {
467 : "test 30",
468 : "test 30: addr16 lea ret",
469 : /* sawfailure= */ 1, /* illegalinst= */ 2,
470 : /* instructions= */ 3,
471 : /* vaddr= */ 0x80000000,
472 : "67 8d b4 9a 40 c3 90 f4 \n"
473 : },
474 : {
475 : "test 31",
476 : "test 31: repz movsbl",
477 : /* sawfailure= */ 1, /* illegalinst= */ 2,
478 : /* instructions= */ 3,
479 : /* vaddr= */ 0x80000000,
480 : "f3 0f be 40 d0 c3 90 f4 \n"
481 : },
482 : {
483 : "test 32",
484 : "test 32: infinite loop",
485 : /* sawfailure= */ 0, /* illegalinst= */ 0,
486 : /* instructions= */ 1,
487 : /* vaddr= */ 0x80000000,
488 : "7f fe f4 \n"
489 : },
490 : {
491 : "test 33",
492 : "test 33: bad branch",
493 : /* sawfailure= */ 1, /* illegalinst= */ 0,
494 : /* instructions= */ 1,
495 : /* vaddr= */ 0x80000000,
496 : "7f fd f4 \n"
497 : },
498 : {
499 : "test 34",
500 : "test 34: bad branch",
501 : /* sawfailure= */ 1, /* illegalinst= */ 0,
502 : /* instructions= */ 1,
503 : /* vaddr= */ 0x80000000,
504 : "7f ff f4 \n"
505 : },
506 : {
507 : "test 35",
508 : "test 35: bad branch",
509 : /* sawfailure= */ 1, /* illegalinst= */ 0,
510 : /* instructions= */ 1,
511 : /* vaddr= */ 0x80000000,
512 : "7f 00 f4 \n"
513 : },
514 : {
515 : "test 36",
516 : "test 36: bad branch",
517 : /* sawfailure= */ 1, /* illegalinst= */ 0,
518 : /* instructions= */ 1,
519 : /* vaddr= */ 0x80000000,
520 : "7f 01 f4 \n"
521 : },
522 : {
523 : "test 37",
524 : "test 37: bad branch",
525 : /* sawfailure= */ 1, /* illegalinst= */ 0,
526 : /* instructions= */ 1,
527 : /* vaddr= */ 0x80000000,
528 : "7f 02 f4 \n"
529 : },
530 : {
531 : "test 38",
532 : "test 38: intc",
533 : /* sawfailure= */ 1, /* illegalinst= */ 8,
534 : /* instructions= */ 10,
535 : /* vaddr= */ 0x80000000,
536 : "66 eb 1b 31 51 3d ef cc 2f 36 48 6e 44 2e cc 14 f4 f4 \n"
537 : },
538 : {
539 : "test 39",
540 : "test 39: bad branch",
541 : /* sawfailure= */ 1, /* illegalinst= */ 2,
542 : /* instructions= */ 7,
543 : /* vaddr= */ 0x80000000,
544 : "67 8d 1d 22 a0 05 e3 7b 9c db 08 04 b1 90 ed 12 f4 f4 \n"
545 : },
546 : {
547 : "test 40",
548 : "test 40: more addr16 problems",
549 : /* sawfailure= */ 1, /* illegalinst= */ 2,
550 : /* instructions= */ 4,
551 : /* vaddr= */ 0x80000000,
552 : "67 a0 00 00 cd 80 90 90 f4 \n"
553 : },
554 : {
555 : "test 41",
556 : "test 41: the latest non-bug from hcf",
557 : /* sawfailure= */ 1, /* illegalinst= */ 1,
558 : /* instructions= */ 5,
559 : /* vaddr= */ 0x80000000,
560 : "84 d4 04 53 a0 04 6a 5a 20 cc b8 48 03 2b 96 11 f4 \n"
561 : },
562 : {
563 : "test 42",
564 : "test 42: another case from hcf",
565 : /* sawfailure= */ 1, /* illegalinst= */ 1,
566 : /* instructions= */ 7,
567 : /* vaddr= */ 0x80000000,
568 : "45 7f 89 58 94 04 24 1b c3 e2 6f 1a 94 87 8f 0b f4 \n"
569 : },
570 : {
571 : "test 43",
572 : "test 43: too many prefix bytes",
573 : /* sawfailure= */ 1, /* illegalinst= */ 1,
574 : /* instructions= */ 2,
575 : /* vaddr= */ 0x80000000,
576 : "66 66 66 66 00 00 90 f4 \n"
577 : },
578 : {
579 : "test 44",
580 : "test 44: palignr (SSSE3)",
581 : /* sawfailure= */ 0, /* illegalinst= */ 0,
582 : /* instructions= */ 2,
583 : /* vaddr= */ 0x80000000,
584 : "66 0f 3a 0f d0 c0 90 f4 \n"
585 : },
586 : {
587 : "test 45",
588 : "test 45: undefined inst in 3-byte opcode space",
589 : /* sawfailure= */ 1, /* illegalinst= */ 2,
590 : /* instructions= */ 2,
591 : /* vaddr= */ 0x80000000,
592 : "66 0f 39 0f d0 c0 90 f4 \n"
593 : },
594 : {
595 : "test 46",
596 : "test 46: SSE2x near miss",
597 : /* sawfailure= */ 1, /* illegalinst= */ 1,
598 : /* instructions= */ 2,
599 : /* vaddr= */ 0x80000000,
600 : "66 0f 73 00 00 90 f4 \n"
601 : },
602 : {
603 : "test 47",
604 : "test 47: SSE2x",
605 : /* sawfailure= */ 0, /* illegalinst= */ 0,
606 : /* instructions= */ 2,
607 : /* vaddr= */ 0x80000000,
608 : "66 0f 73 ff 00 90 f4 \n"
609 : },
610 : {
611 : "test 48",
612 : "test 48: SSE2x, missing required prefix byte",
613 : /* sawfailure= */ 1, /* illegalinst= */ 1,
614 : /* instructions= */ 2,
615 : /* vaddr= */ 0x80000000,
616 : "0f 73 ff 00 90 f4 \n"
617 : },
618 : {
619 : "test 49",
620 : "test 49: 3DNow example",
621 : /* sawfailure= */ 0, /* illegalinst= */ 0,
622 : /* instructions= */ 2,
623 : /* vaddr= */ 0x80000000,
624 : "0f 0f 46 01 bf 90 f4 \n"
625 : },
626 : {
627 : "test 50",
628 : "test 50: 3DNow error example 1",
629 : /* sawfailure= */ 1, /* illegalinst= */ 1,
630 : /* instructions= */ 2,
631 : /* vaddr= */ 0x80000000,
632 : "0f 0f 46 01 00 90 f4 \n"
633 : },
634 : {
635 : "test 51",
636 : "test 51: 3DNow error example 2",
637 : /* sawfailure= */ 1, /* illegalinst= */ 0,
638 : /* instructions= */ 0,
639 : /* vaddr= */ 0x80000000,
640 : "0f 0f 46 01 f4 \n"
641 : },
642 : {
643 : "test 52",
644 : "test 52: 3DNow error example 3",
645 : /* sawfailure= */ 1, /* illegalinst= */ 1,
646 : /* instructions= */ 2,
647 : /* vaddr= */ 0x80000000,
648 : "0f 0f 46 01 be 90 f4 \n"
649 : },
650 : {
651 : "test 53",
652 : "test 53: 3DNow error example 4",
653 : /* sawfailure= */ 1, /* illegalinst= */ 1,
654 : /* instructions= */ 2,
655 : /* vaddr= */ 0x80000000,
656 : "0f 0f 46 01 af 90 f4 \n"
657 : },
658 : {
659 : "test 54",
660 : "test 54: SSE4",
661 : /* sawfailure= */ 0, /* illegalinst= */ 0,
662 : /* instructions= */ 2,
663 : /* vaddr= */ 0x80000000,
664 : "66 0f 3a 0e d0 c0 90 f4 \n"
665 : },
666 : {
667 : "test 55",
668 : "test 55: SSE4",
669 : /* sawfailure= */ 0, /* illegalinst= */ 0,
670 : /* instructions= */ 3,
671 : /* vaddr= */ 0x80000000,
672 : "66 0f 38 0a d0 90 90 f4 \n"
673 : },
674 : {
675 : "test 56",
676 : "test 56: incb decb",
677 : /* sawfailure= */ 0, /* illegalinst= */ 0,
678 : /* instructions= */ 3,
679 : /* vaddr= */ 0x80000000,
680 : "fe 85 4f fd ff ff fe 8d 73 fd ff ff 90 f4 \n"
681 : },
682 : {
683 : "test 57",
684 : "test 57: lzcnt",
685 : /* sawfailure= */ 0, /* illegalinst= */ 0,
686 : /* instructions= */ 2,
687 : /* vaddr= */ 0x80000000,
688 : "f3 0f bd 00 90 f4 \n"
689 : },
690 : {
691 : "test 58",
692 : "test 58: fldz",
693 : /* sawfailure= */ 0, /* illegalinst= */ 0,
694 : /* instructions= */ 2,
695 : /* vaddr= */ 0x80000000,
696 : "d9 ee 90 f4 \n"
697 : },
698 : {
699 : "test 59",
700 : "test 59: x87",
701 : /* sawfailure= */ 0, /* illegalinst= */ 0,
702 : /* instructions= */ 7,
703 : /* vaddr= */ 0x80000000,
704 : "dd 9c fd b0 fe ff ff \n" /* fstpl -0x150(%ebp,%edi,8) */
705 : "dd 9d 40 ff ff ff \n" /* fstpl -0xc0(%ebp) */
706 : "db 04 24 \n" /* fildl (%esp) */
707 : "dd 5d a0 \n" /* fstpl -0x60(%ebp) */
708 : "da e9 \n" /* fucompp */
709 : "df e0 \n" /* fnstsw %ax */
710 : "90 f4 \n"
711 : },
712 : {
713 : "test 60",
714 : "test 60: x87 bad instructions",
715 : /* sawfailure= */ 1, /* illegalinst= */ 9,
716 : /* instructions= */ 19,
717 : /* vaddr= */ 0x80000000,
718 : "dd cc \n" /* (bad) */
719 : "dd c0 \n" /* ffree %st(0) */
720 : "dd c7 \n" /* ffree %st(7) */
721 : "dd c8 \n" /* (bad) */
722 : "dd cf \n" /* (bad) */
723 : "dd f0 \n" /* (bad) */
724 : "dd ff \n" /* (bad) */
725 : "dd fd \n" /* (bad) */
726 : "de d1 \n" /* (bad) */
727 : "de d9 \n" /* fcompp */
728 : "db 04 24 \n" /* fildl (%esp) */
729 : "dd 5d a0 \n" /* fstpl -0x60(%ebp) */
730 : "db e0 \n" /* feni(287 only) */
731 : "db ff \n" /* (bad) */
732 : "db e8 \n" /* fucomi %st(0),%st */
733 : "db f7 \n" /* fcomi %st(7),%st */
734 : "da e9 \n" /* fucompp */
735 : "df e0 \n" /* fnstsw %ax */
736 : "90 f4 \n"
737 : },
738 : {
739 : "test 61",
740 : "test 61: 3DNow prefetch",
741 : /* sawfailure= */ 0, /* illegalinst= */ 0,
742 : /* instructions= */ 2,
743 : /* vaddr= */ 0x80000000,
744 : "0f 0d 00 \n" /* prefetch (%eax) */
745 : "90 f4 \n"
746 : },
747 : {
748 : "test 61.1",
749 : "test 61.1: F2 0F ...",
750 : /* sawfailure= */ 1, /* illegalinst= */ 1,
751 : /* instructions= */ 3,
752 : /* vaddr= */ 0x80000000,
753 : "f2 0f 48 0f 48 a4 52 \n"
754 : "f2 0f 10 c8 \n" /* movsd %xmm0,%xmm1 */
755 : "90 f4 \n"
756 : },
757 : {
758 : "test 62",
759 : "test 62: f6/f7 test Ib/Iv ...",
760 : /* sawfailure= */ 0, /* illegalinst= */ 0,
761 : /* instructions= */ 10,
762 : /* vaddr= */ 0x80000000,
763 : "f6 c1 ff \n" /* test $0xff,%cl */
764 : "f6 44 43 01 02 \n" /* testb $0x2,0x1(%ebx,%eax,2) */
765 : "f7 c6 03 00 00 00 \n" /* test $0x3,%esi */
766 : "90 90 90 90 90 \n"
767 : "f7 45 18 00 00 00 20 \n" /* testl $0x20000000,0x18(%ebp) */
768 : "90 f4 \n"
769 : },
770 : {
771 : "test 63",
772 : "test 63: addr16 corner cases ...",
773 : /* sawfailure= */ 1, /* illegalinst= */ 4,
774 : /* instructions= */ 5,
775 : /* vaddr= */ 0x80000000,
776 : "67 01 00 \n" /* addr16 add %eax,(%bx,%si) */
777 : "67 01 40 00 \n" /* addr16 add %eax,0x0(%bx,%si) */
778 : "67 01 80 00 90 \n" /* addr16 add %eax,-0x7000(%bx,%si) */
779 : "67 01 c0 \n" /* addr16 add %eax,%eax */
780 : "90 f4 \n"
781 : },
782 : {
783 : "test 64",
784 : "test 64: text starts with indirect jmp ...",
785 : /* sawfailure= */ 1, /* illegalinst= */ 0,
786 : /* instructions= */ 2,
787 : /* vaddr= */ 0x80000000,
788 : "ff d0 90 f4 \n"
789 : },
790 : {
791 : "test 65",
792 : "test 65: nacljmp crosses 32-byte boundary ...",
793 : /* sawfailure= */ 1, /* illegalinst= */ 0,
794 : /* instructions= */ 32,
795 : /* vaddr= */ 0x80000000,
796 : "90 90 90 90 90 90 90 90 \n"
797 : "90 90 90 90 90 90 90 90 \n"
798 : "90 90 90 90 90 90 90 90 \n"
799 : "90 90 90 90 90 83 e0 ff \n"
800 : "ff d0 90 f4 \n"
801 : },
802 : {
803 : /* I think this is currently NACLi_ILLEGAL */
804 : "test 65",
805 : "test 65: fxsave",
806 : /* sawfailure= */ 1, /* illegalinst= */ 1,
807 : /* instructions= */ 2,
808 : /* vaddr= */ 0x80000000,
809 : "0f ae 00 00 90 90 90 90 90 f4 \n"
810 : },
811 : {
812 : "test 66",
813 : "test 66: NACLi_CMPXCHG8B",
814 : /* sawfailure= */ 0, /* illegalinst= */ 0,
815 : /* instructions= */ 2,
816 : /* vaddr= */ 0x80000000,
817 : "f0 0f c7 08 90 f4 \n"
818 : },
819 : {
820 : "test 67",
821 : "test 67: NACLi_FCMOV",
822 : /* sawfailure= */ 0, /* illegalinst= */ 0,
823 : /* instructions= */ 7,
824 : /* vaddr= */ 0x80000000,
825 : "da c0 00 00 90 90 90 90 90 f4 \n"
826 : },
827 : {
828 : "test 68",
829 : "test 68: NACLi_MMX",
830 : /* sawfailure= */ 0, /* illegalinst= */ 0,
831 : /* instructions= */ 4,
832 : /* vaddr= */ 0x80000000,
833 : "0f 60 00 \n" /* punpcklbw (%eax),%mm0 */
834 : "90 90 90 f4 \n"
835 : },
836 : {
837 : "test 69",
838 : "test 69: NACLi_SSE",
839 : /* sawfailure= */ 0, /* illegalinst= */ 0,
840 : /* instructions= */ 2,
841 : /* vaddr= */ 0x80000000,
842 : "0f 5e 90 90 90 90 90 90 f4 \n"
843 : },
844 : {
845 : "test 70",
846 : "test 70: NACLi_SSE2",
847 : /* sawfailure= */ 0, /* illegalinst= */ 0,
848 : /* instructions= */ 4,
849 : /* vaddr= */ 0x80000000,
850 : "66 0f 60 00 90 90 90 f4 \n"
851 : },
852 : {
853 : "test 71",
854 : "test 71: NACLi_SSE3",
855 : /* sawfailure= */ 0, /* illegalinst= */ 0,
856 : /* instructions= */ 4,
857 : /* vaddr= */ 0x80000000,
858 : "66 0f 7d 00 90 90 90 f4 \n"
859 : },
860 : {
861 : "test 72",
862 : "test 72: NACLi_SSE4A",
863 : /* sawfailure= */ 0, /* illegalinst= */ 0,
864 : /* instructions= */ 4,
865 : /* vaddr= */ 0x80000000,
866 : "f2 0f 79 00 90 90 90 f4 \n"
867 : },
868 : {
869 : "test 73",
870 : "test 73: NACLi_POPCNT",
871 : /* sawfailure= */ 0, /* illegalinst= */ 0,
872 : /* instructions= */ 2,
873 : /* vaddr= */ 0x80000000,
874 : "f3 0f b8 00 90 f4 \n"
875 : },
876 : {
877 : "test 74",
878 : "test 74: NACLi_E3DNOW",
879 : /* sawfailure= */ 0, /* illegalinst= */ 0,
880 : /* instructions= */ 2,
881 : /* vaddr= */ 0x80000000,
882 : "0f 0f 46 01 bb 90 f4 \n"
883 : },
884 : {
885 : "test 75",
886 : "test 75: NACLi_MMXSSE2",
887 : /* sawfailure= */ 0, /* illegalinst= */ 0,
888 : /* instructions= */ 2,
889 : /* vaddr= */ 0x80000000,
890 : "66 0f 71 f6 00 90 f4 \n"
891 : },
892 : {
893 : "test 76",
894 : "test 76: mov eax, ss",
895 : /* sawfailure= */ 1, /* illegalinst= */ 4,
896 : /* instructions= */ 4,
897 : /* vaddr= */ 0x80000000,
898 : "8e d0 8c d0 66 8c d0 90 f4 \n"
899 : },
900 : {
901 : "test 77",
902 : "test 77: call esp",
903 : /* sawfailure= */ 1, /* illegalinst= */ 0,
904 : /* instructions= */ 3,
905 : /* vaddr= */ 0x80000000,
906 : "83 e4 f0 ff d4 90 f4 \n"
907 : },
908 : /* code.google.com issue 23 reported by defend.the.world on 11 Dec 2008 */
909 : {
910 : "test 78",
911 : "test 78: call (*edx)",
912 : /* sawfailure= */ 1, /* illegalinst= */ 0,
913 : /* instructions= */ 30,
914 : /* vaddr= */ 0x80000000,
915 : "90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 \n"
916 : "90 90 90 90 90 90 90 90 90 90 90 \n"
917 : "83 e2 f0 \n" /* and */
918 : "ff 12 \n" /* call (*edx) */
919 : "90 f4 \n" /* nop halt */
920 : },
921 : {
922 : "test 79",
923 : "test 79: call *edx",
924 : /* sawfailure= */ 0, /* illegalinst= */ 0,
925 : /* instructions= */ 30,
926 : /* vaddr= */ 0x80000000,
927 : "90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 \n"
928 : "90 90 90 90 90 90 90 90 90 90 90 \n"
929 : "83 e2 f0 \n" /* and */
930 : "ff d2 \n" /* call *edx */
931 : "90 f4 \n" /* nop halt */
932 : },
933 : {
934 : "test 80",
935 : "test 80: roundss",
936 : /* sawfailure= */ 0, /* illegalinst= */ 0,
937 : /* instructions= */ 3,
938 : /* vaddr= */ 0x80000000,
939 : "66 0f 3a 0a c0 00 \n" /* roundss $0x0,%xmm0,%xmm0 */
940 : "90 90 \n"
941 : "f4 \n" /* hlt */
942 : },
943 : {
944 : "test 81",
945 : "test 81: crc32",
946 : /* sawfailure= */ 0, /* illegalinst= */ 0,
947 : /* instructions= */ 3,
948 : /* vaddr= */ 0x80000000,
949 : "f2 0f 38 f1 c8 \n" /* crc32l %eax,%ecx */
950 : "90 90 \n"
951 : "f4 \n" /* hlt */
952 : },
953 : {
954 : "test 82",
955 : "test 82: SSE4 error 1",
956 : /* sawfailure= */ 1, /* illegalinst= */ 2,
957 : /* instructions= */ 4,
958 : /* vaddr= */ 0x80000000,
959 : "f3 0f 3a 0e d0 c0 90 f4 \n"
960 : },
961 : {
962 : "test 83",
963 : "test 83: SSE4 error 2",
964 : /* sawfailure= */ 1, /* illegalinst= */ 2,
965 : /* instructions= */ 2,
966 : /* vaddr= */ 0x80000000,
967 : "f3 0f 38 0f d0 c0 90 f4 \n"
968 : },
969 : {
970 : "test 84",
971 : "test 84: SSE4 error 3",
972 : /* sawfailure= */ 1, /* illegalinst= */ 1,
973 : /* instructions= */ 3,
974 : /* vaddr= */ 0x80000000,
975 : "66 0f 38 0f d0 c0 90 f4 \n"
976 : },
977 : {
978 : "test 85",
979 : "test 85: SSE4 error 4",
980 : /* sawfailure= */ 1, /* illegalinst= */ 1,
981 : /* instructions= */ 3,
982 : /* vaddr= */ 0x80000000,
983 : "f2 66 0f 3a 0a c0 00 \n"
984 : "90 90 \n"
985 : "f4 \n" /* hlt */
986 : },
987 : {
988 : "test 86",
989 : "test 86: bad SSE4 crc32",
990 : /* sawfailure= */ 1, /* illegalinst= */ 1,
991 : /* instructions= */ 3,
992 : /* vaddr= */ 0x80000000,
993 : "f2 f3 0f 38 f1 c8 \n"
994 : "90 90 \n"
995 : "f4 \n" /* hlt */
996 : },
997 : {
998 : "test 87",
999 : "test 87: bad NACLi_3BYTE instruction (SEGCS prefix)",
1000 : /* sawfailure= */ 1, /* illegalinst= */ 1,
1001 : /* instructions= */ 3,
1002 : /* vaddr= */ 0x80000000,
1003 : /* Note: Fixed so that this is a legal instruction,
1004 : * except for the prefix! (karl)
1005 : */
1006 : "2e 0f 3a 0f bb ab 00 00 00 00 \n"
1007 : "90 90 \n"
1008 : "f4 \n" /* hlt */
1009 : },
1010 : {
1011 : "test 87a",
1012 : "test 87a: bad NACLi_3BYTE instruction (not really an instruction)",
1013 : /* sawfailure= */ 1, /* illegalinst= */ 2,
1014 : /* instructions= */ 2,
1015 : /* vaddr= */ 0x80000000,
1016 : /* Note: Fixed so that this is a legal instruction,
1017 : * except for the prefix! (karl)
1018 : */
1019 : "2e 0f 3a 7d bb ab 00 00 00 00 \n"
1020 : "90 90 \n"
1021 : "f4 \n" /* hlt */
1022 : },
1023 : {
1024 : "test 88",
1025 : "test 88: two-byte jump with prefix (bug reported by Mark Dowd)",
1026 : /* sawfailure= */ 1, /* illegalinst= */ 1,
1027 : /* instructions= */ 4,
1028 : /* vaddr= */ 0x80000000,
1029 : "66 0f 84 00 00 \n" /* data16 je 0x5 */
1030 : "90 90 \n"
1031 : "f4 \n" /* hlt */
1032 : },
1033 : {
1034 : "test 89",
1035 : "test 89: sfence",
1036 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1037 : /* instructions= */ 8,
1038 : /* vaddr= */ 0x80000000,
1039 : "90 0f ae ff \n"
1040 : "90 90 90 90 90 90 f4 \n"
1041 : },
1042 : {
1043 : "test 90",
1044 : "test 90: clflush",
1045 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1046 : /* instructions= */ 8,
1047 : /* vaddr= */ 0x80000000,
1048 : "90 0f ae 3f \n"
1049 : "90 90 90 90 90 90 f4 \n"
1050 : },
1051 : {
1052 : "test 91",
1053 : "test 91: mfence",
1054 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1055 : /* instructions= */ 8,
1056 : /* vaddr= */ 0x80000000,
1057 : "90 0f ae f7 \n"
1058 : "90 90 90 90 90 90 f4 \n"
1059 : },
1060 : {
1061 : "test 92",
1062 : "test 92: jump to zero should be allowed",
1063 : /* A jump/call to a zero address will be emitted for a jump/call
1064 : to a weak symbol that is undefined. */
1065 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1066 : /* instructions= */ 1,
1067 : /* vaddr= */ 0x08049000,
1068 : "e9 fb 6f fb f7 \n" /* jmp 0 */
1069 : "f4 \n" /* hlt */
1070 : },
1071 : {
1072 : "test 93",
1073 : "test 93: jump to bundle-aligned zero page address is currently allowed",
1074 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1075 : /* instructions= */ 1,
1076 : /* vaddr= */ 0x08049000,
1077 : "e9 fb 70 fb f7 \n" /* jmp 100 */
1078 : "f4 \n" /* hlt */
1079 : },
1080 : {
1081 : "test 94",
1082 : "test 94: jump to syscall trampoline should be allowed",
1083 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1084 : /* instructions= */ 1,
1085 : /* vaddr= */ 0x08049000,
1086 : "e9 fb 6f fc f7 \n" /* jmp 10000 */
1087 : "f4 \n" /* hlt */
1088 : },
1089 : {
1090 : "test 95",
1091 : "test 95: unaligned jump to trampoline area must be disallowed",
1092 : /* sawfailure= */ 1, /* illegalinst= */ 0,
1093 : /* instructions= */ 1,
1094 : /* vaddr= */ 0x08049000,
1095 : "e9 fc 6f fc f7 \n" /* jmp 10001 */
1096 : "f4 \n" /* hlt */
1097 : },
1098 : {
1099 : "test 96",
1100 : "test 96: bundle-aligned jump to before the code chunk is allowed",
1101 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1102 : /* instructions= */ 1,
1103 : /* vaddr= */ 0x08049000,
1104 : "e9 fb 6f fb f8 \n" /* jmp 1000000 */
1105 : "f4 \n" /* hlt */
1106 : },
1107 : {
1108 : "test 97",
1109 : "test 97: bundle-aligned jump to after the code chunk is allowed",
1110 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1111 : /* instructions= */ 1,
1112 : /* vaddr= */ 0x08049000,
1113 : "e9 fb 6f fb 07 \n" /* jmp 10000000 */
1114 : "f4 \n" /* hlt */
1115 : },
1116 : };
1117 :
1118 : static void DecodeHexString(const char *input, uint8_t **result_data,
1119 97 : size_t *result_size) {
1120 97 : size_t buf_size = strlen(input) / 2; /* Over-estimate size */
1121 : uint8_t *output;
1122 97 : uint8_t *buf = malloc(buf_size);
1123 97 : assert(buf != NULL);
1124 :
1125 97 : output = buf;
1126 3940 : while (*input != '\0') {
1127 5805 : if (*input == ' ' || *input == '\n') {
1128 2059 : input++;
1129 : } else {
1130 : char *end;
1131 1687 : assert(output < buf + buf_size);
1132 1687 : *output++ = (uint8_t) strtoul(input, &end, 16);
1133 : /* Expect 2 digits of hex. */
1134 1687 : assert(end == input + 2);
1135 1687 : input = end;
1136 : }
1137 : }
1138 97 : *result_data = buf;
1139 97 : *result_size = output - buf;
1140 97 : }
1141 :
1142 97 : static void TestValidator(struct NCValTestCase *vtest, int didstubout) {
1143 : struct NCValidatorState *vstate;
1144 : uint8_t *byte0;
1145 : size_t data_size;
1146 : int rc;
1147 :
1148 97 : DecodeHexString(vtest->data_as_hex, &byte0, &data_size);
1149 : /*
1150 : * The validator used to require that code chunks end in HLT. We
1151 : * have left the HLTs in, but don't pass them to the validator.
1152 : * TODO(mseaborn): Remove the HLTs.
1153 : */
1154 97 : assert(byte0[data_size - 1] == 0xf4 /* HLT */);
1155 :
1156 97 : vstate = NCValidateInit(vtest->vaddr, data_size - 1, 16,
1157 : &g_ncval_cpu_features);
1158 97 : assert (vstate != NULL);
1159 97 : NCValidateSetErrorReporter(vstate, &kNCVerboseErrorReporter);
1160 97 : NCValidateSegment(byte0, (uint32_t)vtest->vaddr, data_size - 1, vstate);
1161 97 : free(byte0);
1162 97 : rc = NCValidateFinish(vstate);
1163 :
1164 : do {
1165 97 : printf("vtest->sawfailure = %d, vstate->stats.sawfailure = %d\n",
1166 : vtest->sawfailure, vstate->stats.sawfailure);
1167 97 : NCStatsPrint(vstate);
1168 97 : if (vtest->sawfailure != rc) break;
1169 97 : if (vtest->sawfailure ^ vstate->stats.sawfailure) break;
1170 97 : if (didstubout != vstate->stats.didstubout) break;
1171 97 : if (vtest->instructions != vstate->stats.instructions) break;
1172 97 : if (vtest->illegalinst != vstate->stats.illegalinst) break;
1173 97 : Info("*** %s passed (%s)\n", vtest->name, vtest->description);
1174 97 : NCValidateFreeState(&vstate);
1175 : return;
1176 : } while (0);
1177 0 : NCStatsPrint(vstate);
1178 0 : NCValidateFreeState(&vstate);
1179 0 : Info("*** %s failed (%s)\n", vtest->name, vtest->description);
1180 0 : exit(-1);
1181 : }
1182 :
1183 1 : void test_fail_on_bad_alignment() {
1184 : struct NCValidatorState *vstate;
1185 :
1186 1 : vstate = NCValidateInit(0x80000000, 0x1000, 16, &g_ncval_cpu_features);
1187 1 : assert (vstate != NULL);
1188 1 : NCValidateFreeState(&vstate);
1189 :
1190 : /* Unaligned start addresses are not allowed. */
1191 1 : vstate = NCValidateInit(0x80000001, 0x1000, 16, &g_ncval_cpu_features);
1192 1 : assert (vstate == NULL);
1193 :
1194 : /* Only alignments of 32 and 64 bytes are supported. */
1195 1 : vstate = NCValidateInit(0x80000000, 0x1000, 64, &g_ncval_cpu_features);
1196 1 : assert (vstate == NULL);
1197 1 : }
1198 :
1199 1 : void test_stubout() {
1200 : /* Similar to test 68 */
1201 : struct NCValTestCase test = {
1202 : "test stubout",
1203 : "test stubout: NACLi_MMX",
1204 : /* sawfailure= */ 0, /* illegalinst= */ 0,
1205 : /* instructions= */ 1,
1206 : /* vaddr= */ 0x80000000,
1207 : "0f 60 00 f4 \n" /* punpcklbw (%eax),%mm0 */
1208 1 : };
1209 :
1210 : /* If MMX instructions are not allowed, stubout will occur. */
1211 1 : NaClSetCPUFeature(&g_ncval_cpu_features, NaClCPUFeature_MMX, FALSE);
1212 1 : TestValidator(&test, TRUE);
1213 1 : NaClSetCPUFeature(&g_ncval_cpu_features, NaClCPUFeature_MMX, TRUE);
1214 1 : }
1215 :
1216 1 : void ncvalidate_unittests() {
1217 : size_t i;
1218 :
1219 : /* Default to stubbing out nothing. */
1220 1 : NaClSetAllCPUFeatures(&g_ncval_cpu_features);
1221 :
1222 97 : for (i = 0; i < NACL_ARRAY_SIZE(NCValTests); i++) {
1223 96 : TestValidator(&NCValTests[i], FALSE);
1224 : }
1225 :
1226 1 : test_fail_on_bad_alignment();
1227 1 : test_stubout();
1228 :
1229 1 : Info("\nAll tests passed.\n\n");
1230 1 : }
1231 :
1232 :
1233 1 : int main() {
1234 : struct GioFile gio_out_stream;
1235 1 : struct Gio *gout = (struct Gio*) &gio_out_stream;
1236 1 : if (!GioFileRefCtor(&gio_out_stream, stdout)) {
1237 0 : fprintf(stderr, "Unable to create gio file for stdout!\n");
1238 0 : return 1;
1239 : }
1240 :
1241 1 : NaClLogModuleInitExtended(LOG_INFO, gout);
1242 1 : ncvalidate_unittests();
1243 1 : GioFileDtor(gout);
1244 1 : return 0;
1245 : }
|