Chromium Code Reviews| 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> |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 longjmp(g_jmp_buf, 1); | 115 longjmp(g_jmp_buf, 1); |
| 116 } | 116 } |
| 117 | 117 |
| 118 void simple_exception_handler(struct NaClExceptionContext *regs) { | 118 void simple_exception_handler(struct NaClExceptionContext *regs) { |
| 119 return_from_exception_handler(); | 119 return_from_exception_handler(); |
| 120 } | 120 } |
| 121 | 121 |
| 122 void exception_handler(struct NaClExceptionContext *context); | 122 void exception_handler(struct NaClExceptionContext *context); |
| 123 REGS_SAVER_FUNC_NOPROTO(exception_handler, exception_handler_wrapped); | 123 REGS_SAVER_FUNC_NOPROTO(exception_handler, exception_handler_wrapped); |
| 124 | 124 |
| 125 __attribute__((__used__)) | |
|
Junichi Uekawa
2014/09/09 12:23:58
inline assembly is something external in pexe, so
| |
| 125 void exception_handler_wrapped(struct NaClSignalContext *entry_regs) { | 126 void exception_handler_wrapped(struct NaClSignalContext *entry_regs) { |
| 126 struct NaClExceptionContext *context = | 127 struct NaClExceptionContext *context = |
| 127 (struct NaClExceptionContext *) RegsGetArg1(entry_regs); | 128 (struct NaClExceptionContext *) RegsGetArg1(entry_regs); |
| 128 struct NaClExceptionPortableContext *portable = | 129 struct NaClExceptionPortableContext *portable = |
| 129 nacl_exception_context_get_portable(context); | 130 nacl_exception_context_get_portable(context); |
| 130 | 131 |
| 131 printf("handler called\n"); | 132 printf("handler called\n"); |
| 132 | 133 |
| 133 assert(context->size == (uintptr_t) (portable + 1) - (uintptr_t) context); | 134 assert(context->size == (uintptr_t) (portable + 1) - (uintptr_t) context); |
| 134 assert(context->portable_context_size == | 135 assert(context->portable_context_size == |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 193 #endif | 194 #endif |
| 194 | 195 |
| 195 return_from_exception_handler(); | 196 return_from_exception_handler(); |
| 196 } | 197 } |
| 197 | 198 |
| 198 void test_exception_stack_with_size(char *stack, size_t stack_size) { | 199 void test_exception_stack_with_size(char *stack, size_t stack_size) { |
| 199 if (0 != nacl_exception_set_handler(exception_handler)) { | 200 if (0 != nacl_exception_set_handler(exception_handler)) { |
| 200 printf("failed to set exception handler\n"); | 201 printf("failed to set exception handler\n"); |
| 201 exit(4); | 202 exit(4); |
| 202 } | 203 } |
| 203 if (0 != nacl_exception_set_stack(stack, stack_size)) { | 204 if (!NONSFI_MODE) { |
| 204 printf("failed to set alt stack\n"); | 205 /* TODO(uekawa): Implement set_stack on Non-SFI NaCl. */ |
| 205 exit(5); | 206 if (0 != nacl_exception_set_stack(stack, stack_size)) { |
| 207 printf("failed to set alt stack\n"); | |
| 208 exit(5); | |
| 209 } | |
| 210 g_registered_stack = stack; | |
| 211 g_registered_stack_size = stack_size; | |
| 206 } | 212 } |
| 207 g_registered_stack = stack; | |
| 208 g_registered_stack_size = stack_size; | |
| 209 | 213 |
| 210 char crash_stack[0x1000]; | 214 char crash_stack[0x1000]; |
| 211 RegsFillTestValues(&g_regs_at_crash, /* seed= */ 0); | 215 RegsFillTestValues(&g_regs_at_crash, /* seed= */ 0); |
| 212 g_regs_at_crash.stack_ptr = (uintptr_t) crash_stack + sizeof(crash_stack); | 216 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; | 217 g_regs_at_crash.prog_ctr = (uintptr_t) prog_ctr_at_crash; |
| 214 RegsApplySandboxConstraints(&g_regs_at_crash); | 218 RegsApplySandboxConstraints(&g_regs_at_crash); |
| 215 #if defined(__arm__) | 219 #if defined(__arm__) |
| 216 /* crash_at_known_address clobbers r0. */ | 220 /* crash_at_known_address clobbers r0. */ |
| 217 g_regs_at_crash.r0 = 0; | 221 g_regs_at_crash.r0 = 0; |
| 218 #endif | 222 #endif |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 if (!setjmp(g_jmp_buf)) { | 323 if (!setjmp(g_jmp_buf)) { |
| 320 __asm__("hlt"); | 324 __asm__("hlt"); |
| 321 exit(1); | 325 exit(1); |
| 322 } | 326 } |
| 323 printf("Testing ud2a (an illegal instruction)...\n"); | 327 printf("Testing ud2a (an illegal instruction)...\n"); |
| 324 if (!setjmp(g_jmp_buf)) { | 328 if (!setjmp(g_jmp_buf)) { |
| 325 __asm__("ud2a"); | 329 __asm__("ud2a"); |
| 326 exit(1); | 330 exit(1); |
| 327 } | 331 } |
| 328 printf("Testing integer division by zero...\n"); | 332 printf("Testing integer division by zero...\n"); |
| 333 #if !NONSFI_MODE | |
| 334 /* TODO(uekawa): Enable on Non-SFI NaCl. */ | |
| 329 if (!setjmp(g_jmp_buf)) { | 335 if (!setjmp(g_jmp_buf)) { |
| 330 uint32_t result; | 336 uint32_t result; |
| 331 __asm__ volatile("idivb %1" | 337 __asm__ volatile("idivb %1" |
| 332 : "=a"(result) | 338 : "=a"(result) |
| 333 : "r"((uint8_t) 0), "a"((uint16_t) 1)); | 339 : "r"((uint8_t) 0), "a"((uint16_t) 1)); |
| 334 exit(1); | 340 exit(1); |
| 335 } | 341 } |
| 336 #endif | 342 #endif |
| 343 #endif | |
| 337 | 344 |
| 338 /* Clear the jmp_buf to prevent it from being reused accidentally. */ | 345 /* Clear the jmp_buf to prevent it from being reused accidentally. */ |
| 339 memset(g_jmp_buf, 0, sizeof(g_jmp_buf)); | 346 memset(g_jmp_buf, 0, sizeof(g_jmp_buf)); |
| 340 } | 347 } |
| 341 | 348 |
| 342 | 349 |
| 343 #if defined(__i386__) || defined(__x86_64__) | 350 #if !NONSFI_MODE && (defined(__i386__) || defined(__x86_64__)) |
| 351 /* TODO(uekawa): Enable on Non-SFI NaCl */ | |
| 344 | 352 |
| 345 int get_x86_direction_flag(void); | 353 int get_x86_direction_flag(void); |
| 346 | 354 |
| 347 void test_get_x86_direction_flag(void) { | 355 void test_get_x86_direction_flag(void) { |
| 348 /* | 356 /* |
| 349 * Sanity check: Ensure that get_x86_direction_flag() works. We | 357 * Sanity check: Ensure that get_x86_direction_flag() works. We |
| 350 * avoid calling assert() with the flag set, because that might not | 358 * avoid calling assert() with the flag set, because that might not |
| 351 * work. | 359 * work. |
| 352 */ | 360 */ |
| 353 assert(get_x86_direction_flag() == 0); | 361 assert(get_x86_direction_flag() == 0); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 389 | 397 |
| 390 void run_test(const char *test_name, void (*test_func)(void)) { | 398 void run_test(const char *test_name, void (*test_func)(void)) { |
| 391 printf("Running %s...\n", test_name); | 399 printf("Running %s...\n", test_name); |
| 392 test_func(); | 400 test_func(); |
| 393 } | 401 } |
| 394 | 402 |
| 395 #define RUN_TEST(test_func) (run_test(#test_func, test_func)) | 403 #define RUN_TEST(test_func) (run_test(#test_func, test_func)) |
| 396 | 404 |
| 397 int TestMain(void) { | 405 int TestMain(void) { |
| 398 RUN_TEST(test_exceptions_minimally); | 406 RUN_TEST(test_exceptions_minimally); |
| 399 RUN_TEST(test_exception_stack_alignments); | 407 if (!NONSFI_MODE) { |
| 400 RUN_TEST(test_getting_previous_handler); | 408 /* |
| 401 RUN_TEST(test_invalid_handlers); | 409 * The following tests are for SFI invariants which do not hold |
| 410 * true for Non-SFI mode. | |
| 411 */ | |
| 412 RUN_TEST(test_exception_stack_alignments); | |
| 413 RUN_TEST(test_getting_previous_handler); | |
| 414 RUN_TEST(test_invalid_handlers); | |
| 415 } | |
| 402 /* pthread_join() is broken under qemu-arm. */ | 416 /* pthread_join() is broken under qemu-arm. */ |
| 403 if (getenv("UNDER_QEMU_ARM") == NULL) | 417 if (getenv("UNDER_QEMU_ARM") == NULL) |
| 404 RUN_TEST(test_exceptions_on_non_main_thread); | 418 RUN_TEST(test_exceptions_on_non_main_thread); |
| 405 RUN_TEST(test_catching_various_exception_types); | 419 RUN_TEST(test_catching_various_exception_types); |
| 406 | 420 |
| 407 #if defined(__i386__) || defined(__x86_64__) | 421 #if !NONSFI_MODE && (defined(__i386__) || defined(__x86_64__)) |
| 422 /* TODO(uekawa): Enable these test for Non-SFI mode too. */ | |
| 408 RUN_TEST(test_get_x86_direction_flag); | 423 RUN_TEST(test_get_x86_direction_flag); |
| 409 RUN_TEST(test_unsetting_x86_direction_flag); | 424 RUN_TEST(test_unsetting_x86_direction_flag); |
| 410 #endif | 425 #endif |
| 411 | 426 |
| 412 fprintf(stderr, "** intended_exit_status=0\n"); | 427 fprintf(stderr, "** intended_exit_status=0\n"); |
| 413 return 0; | 428 return 0; |
| 414 } | 429 } |
| 415 | 430 |
| 416 int main(void) { | 431 int main(void) { |
| 417 return RunTests(TestMain); | 432 return RunTests(TestMain); |
| 418 } | 433 } |
| OLD | NEW |