OLD | NEW |
---|---|
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 #include <assert.h> | 7 #include <assert.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <pthread.h> | 9 #include <pthread.h> |
10 #include <setjmp.h> | 10 #include <setjmp.h> |
11 #include <stdint.h> | 11 #include <stdint.h> |
12 #include <stdio.h> | 12 #include <stdio.h> |
13 #include <stdlib.h> | 13 #include <stdlib.h> |
14 #include <string.h> | 14 #include <string.h> |
15 | 15 |
16 #if !TESTS_USE_IRT && NONSFI_MODE | |
17 #include "native_client/src/nonsfi/linux/irt_exception_handling.h" | |
18 #endif | |
19 | |
16 #include "native_client/src/include/elf_constants.h" | 20 #include "native_client/src/include/elf_constants.h" |
17 #include "native_client/src/include/nacl/nacl_exception.h" | 21 #include "native_client/src/include/nacl/nacl_exception.h" |
18 #include "native_client/src/trusted/service_runtime/include/sys/nacl_syscalls.h" | 22 #include "native_client/src/trusted/service_runtime/include/sys/nacl_syscalls.h" |
19 #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h" | 23 #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h" |
20 #include "native_client/tests/common/register_set.h" | 24 #include "native_client/tests/common/register_set.h" |
21 #include "native_client/tests/inbrowser_test_runner/test_runner.h" | 25 #include "native_client/tests/inbrowser_test_runner/test_runner.h" |
22 | 26 |
23 | 27 |
24 /* | 28 /* |
25 * This is used for calculating the size of the exception stack frame | 29 * This is used for calculating the size of the exception stack frame |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 stack_top = g_registered_stack + g_registered_stack_size; | 179 stack_top = g_registered_stack + g_registered_stack_size; |
176 assert(g_registered_stack <= &local_var); | 180 assert(g_registered_stack <= &local_var); |
177 assert(&local_var < stack_top); | 181 assert(&local_var < stack_top); |
178 } | 182 } |
179 | 183 |
180 /* Check the exception handler's initial stack pointer more exactly. */ | 184 /* Check the exception handler's initial stack pointer more exactly. */ |
181 uintptr_t frame_base = entry_regs->stack_ptr + kReturnAddrSize; | 185 uintptr_t frame_base = entry_regs->stack_ptr + kReturnAddrSize; |
182 assert(frame_base % STACK_ALIGNMENT == 0); | 186 assert(frame_base % STACK_ALIGNMENT == 0); |
183 char *frame_top = (char *) (frame_base + kArgSizeOnStack + | 187 char *frame_top = (char *) (frame_base + kArgSizeOnStack + |
184 sizeof(struct CombinedContext)); | 188 sizeof(struct CombinedContext)); |
185 /* Check that no more than the stack alignment size is wasted. */ | 189 if (NONSFI_MODE) { |
186 assert(stack_top - STACK_ALIGNMENT < frame_top); | 190 /* |
191 * Non-SFI mode exception stack will have ucontext_t and | |
192 * siginfo_t, which would be anywhere from 400 bytes to 1.5k | |
193 */ | |
194 assert(stack_top - 1500 < frame_top); | |
195 } else { | |
196 /* Check that no more than the stack alignment size is wasted. */ | |
197 assert(stack_top - STACK_ALIGNMENT < frame_top); | |
198 } | |
187 assert(frame_top <= stack_top); | 199 assert(frame_top <= stack_top); |
188 | 200 |
189 #if defined(__x86_64__) | 201 #if defined(__x86_64__) |
190 /* Check that %rsp and %rbp have safe, %r15-extended values. */ | 202 /* Check that %rsp and %rbp have safe, %r15-extended values. */ |
191 assert(entry_regs->stack_ptr >> 32 == entry_regs->r15 >> 32); | 203 assert(entry_regs->stack_ptr >> 32 == entry_regs->r15 >> 32); |
192 assert(entry_regs->rbp >> 32 == entry_regs->r15 >> 32); | 204 assert(entry_regs->rbp >> 32 == entry_regs->r15 >> 32); |
193 #endif | 205 #endif |
194 | 206 |
195 return_from_exception_handler(); | 207 return_from_exception_handler(); |
196 } | 208 } |
197 | 209 |
198 void test_exception_stack_with_size(char *stack, size_t stack_size) { | 210 void test_exception_stack_with_size(char *stack, size_t stack_size) { |
199 if (0 != nacl_exception_set_handler(exception_handler)) { | 211 if (0 != nacl_exception_set_handler(exception_handler)) { |
200 printf("failed to set exception handler\n"); | 212 printf("failed to set exception handler\n"); |
201 exit(4); | 213 exit(4); |
202 } | 214 } |
215 #if !NONSFI_MODE | |
216 /* TODO(uekawa): Implement set_stack for Non-SFI mode. */ | |
203 if (0 != nacl_exception_set_stack(stack, stack_size)) { | 217 if (0 != nacl_exception_set_stack(stack, stack_size)) { |
204 printf("failed to set alt stack\n"); | 218 printf("failed to set alt stack\n"); |
205 exit(5); | 219 exit(5); |
206 } | 220 } |
207 g_registered_stack = stack; | 221 g_registered_stack = stack; |
208 g_registered_stack_size = stack_size; | 222 g_registered_stack_size = stack_size; |
223 #endif | |
209 | 224 |
210 char crash_stack[0x1000]; | 225 char crash_stack[0x1000]; |
211 RegsFillTestValues(&g_regs_at_crash, /* seed= */ 0); | 226 RegsFillTestValues(&g_regs_at_crash, /* seed= */ 0); |
212 g_regs_at_crash.stack_ptr = (uintptr_t) crash_stack + sizeof(crash_stack); | 227 g_regs_at_crash.stack_ptr = (uintptr_t) crash_stack + sizeof(crash_stack); |
213 g_regs_at_crash.prog_ctr = (uintptr_t) prog_ctr_at_crash; | 228 g_regs_at_crash.prog_ctr = (uintptr_t) prog_ctr_at_crash; |
214 RegsApplySandboxConstraints(&g_regs_at_crash); | 229 RegsApplySandboxConstraints(&g_regs_at_crash); |
215 #if defined(__arm__) | 230 #if defined(__arm__) |
216 /* crash_at_known_address clobbers r0. */ | 231 /* crash_at_known_address clobbers r0. */ |
217 g_regs_at_crash.r0 = 0; | 232 g_regs_at_crash.r0 = 0; |
218 #endif | 233 #endif |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
307 void test_catching_various_exception_types(void) { | 322 void test_catching_various_exception_types(void) { |
308 int rc = nacl_exception_set_handler(simple_exception_handler); | 323 int rc = nacl_exception_set_handler(simple_exception_handler); |
309 assert(rc == 0); | 324 assert(rc == 0); |
310 | 325 |
311 printf("Testing __builtin_trap()...\n"); | 326 printf("Testing __builtin_trap()...\n"); |
312 if (!setjmp(g_jmp_buf)) { | 327 if (!setjmp(g_jmp_buf)) { |
313 __builtin_trap(); | 328 __builtin_trap(); |
314 exit(1); | 329 exit(1); |
315 } | 330 } |
316 | 331 |
317 #if defined(__i386__) || defined(__x86_64__) | 332 #if !NONSFI_MODE && (defined(__i386__) || defined(__x86_64__)) |
318 printf("Testing hlt...\n"); | 333 printf("Testing hlt...\n"); |
319 if (!setjmp(g_jmp_buf)) { | 334 if (!setjmp(g_jmp_buf)) { |
320 __asm__("hlt"); | 335 __asm__("hlt"); |
321 exit(1); | 336 exit(1); |
322 } | 337 } |
323 printf("Testing ud2a (an illegal instruction)...\n"); | 338 printf("Testing ud2a (an illegal instruction)...\n"); |
324 if (!setjmp(g_jmp_buf)) { | 339 if (!setjmp(g_jmp_buf)) { |
325 __asm__("ud2a"); | 340 __asm__("ud2a"); |
326 exit(1); | 341 exit(1); |
327 } | 342 } |
328 printf("Testing integer division by zero...\n"); | 343 printf("Testing integer division by zero...\n"); |
329 if (!setjmp(g_jmp_buf)) { | 344 if (!setjmp(g_jmp_buf)) { |
330 uint32_t result; | 345 uint32_t result; |
331 __asm__ volatile("idivb %1" | 346 __asm__ volatile("idivb %1" |
332 : "=a"(result) | 347 : "=a"(result) |
333 : "r"((uint8_t) 0), "a"((uint16_t) 1)); | 348 : "r"((uint8_t) 0), "a"((uint16_t) 1)); |
334 exit(1); | 349 exit(1); |
335 } | 350 } |
336 #endif | 351 #endif |
337 | 352 |
338 /* Clear the jmp_buf to prevent it from being reused accidentally. */ | 353 /* Clear the jmp_buf to prevent it from being reused accidentally. */ |
339 memset(g_jmp_buf, 0, sizeof(g_jmp_buf)); | 354 memset(g_jmp_buf, 0, sizeof(g_jmp_buf)); |
340 } | 355 } |
341 | 356 |
342 | 357 |
343 #if defined(__i386__) || defined(__x86_64__) | 358 #if !NONSFI_MODE && (defined(__i386__) || defined(__x86_64__)) |
344 | 359 |
345 int get_x86_direction_flag(void); | 360 int get_x86_direction_flag(void); |
346 | 361 |
347 void test_get_x86_direction_flag(void) { | 362 void test_get_x86_direction_flag(void) { |
348 /* | 363 /* |
349 * Sanity check: Ensure that get_x86_direction_flag() works. We | 364 * Sanity check: Ensure that get_x86_direction_flag() works. We |
350 * avoid calling assert() with the flag set, because that might not | 365 * avoid calling assert() with the flag set, because that might not |
351 * work. | 366 * work. |
352 */ | 367 */ |
353 assert(get_x86_direction_flag() == 0); | 368 assert(get_x86_direction_flag() == 0); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 | 404 |
390 void run_test(const char *test_name, void (*test_func)(void)) { | 405 void run_test(const char *test_name, void (*test_func)(void)) { |
391 printf("Running %s...\n", test_name); | 406 printf("Running %s...\n", test_name); |
392 test_func(); | 407 test_func(); |
393 } | 408 } |
394 | 409 |
395 #define RUN_TEST(test_func) (run_test(#test_func, test_func)) | 410 #define RUN_TEST(test_func) (run_test(#test_func, test_func)) |
396 | 411 |
397 int TestMain(void) { | 412 int TestMain(void) { |
398 RUN_TEST(test_exceptions_minimally); | 413 RUN_TEST(test_exceptions_minimally); |
399 RUN_TEST(test_exception_stack_alignments); | 414 if (!NONSFI_MODE) { |
400 RUN_TEST(test_getting_previous_handler); | 415 /* TODO(uekawa): Implement set_stack for Non-SFI mode. */ |
401 RUN_TEST(test_invalid_handlers); | 416 RUN_TEST(test_exception_stack_alignments); |
417 /* NACL_SYSCALL not supported on nonsfi mode */ | |
418 RUN_TEST(test_getting_previous_handler); | |
419 /* Those handlers are not invalid in NonSFI NaCl. */ | |
420 RUN_TEST(test_invalid_handlers); | |
421 } | |
402 /* pthread_join() is broken under qemu-arm. */ | 422 /* pthread_join() is broken under qemu-arm. */ |
403 if (getenv("UNDER_QEMU_ARM") == NULL) | 423 if (getenv("UNDER_QEMU_ARM") == NULL) |
404 RUN_TEST(test_exceptions_on_non_main_thread); | 424 RUN_TEST(test_exceptions_on_non_main_thread); |
405 RUN_TEST(test_catching_various_exception_types); | 425 RUN_TEST(test_catching_various_exception_types); |
406 | 426 |
407 #if defined(__i386__) || defined(__x86_64__) | 427 #if !NONSFI_MODE && (defined(__i386__) || defined(__x86_64__)) |
428 /* TODO(uekawa): Implement for Non-SFI mode. */ | |
408 RUN_TEST(test_get_x86_direction_flag); | 429 RUN_TEST(test_get_x86_direction_flag); |
409 RUN_TEST(test_unsetting_x86_direction_flag); | 430 RUN_TEST(test_unsetting_x86_direction_flag); |
410 #endif | 431 #endif |
411 | 432 |
412 fprintf(stderr, "** intended_exit_status=0\n"); | 433 fprintf(stderr, "** intended_exit_status=0\n"); |
413 return 0; | 434 return 0; |
414 } | 435 } |
415 | 436 |
416 int main(void) { | 437 int main(void) { |
438 #if !TESTS_USE_IRT && NONSFI_MODE | |
439 /* | |
440 * In Non-SFI mode Non-IRT loading version does not initialize | |
441 * signal handler. | |
442 */ | |
443 nonsfi_initialize_signal_handler(); | |
Junichi Uekawa
2014/09/29 07:32:30
I couldn't find a reasonable place to do initializ
| |
444 #endif | |
417 return RunTests(TestMain); | 445 return RunTests(TestMain); |
418 } | 446 } |
OLD | NEW |