| 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 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 char stack[4096]; | 25 char stack[4096]; |
| 26 | 26 |
| 27 struct NaClSignalContext g_regs_at_crash; | 27 struct NaClSignalContext g_regs_at_crash; |
| 28 jmp_buf g_jmp_buf; | 28 jmp_buf g_jmp_buf; |
| 29 | 29 |
| 30 char *g_registered_stack; | 30 char *g_registered_stack; |
| 31 size_t g_registered_stack_size; | 31 size_t g_registered_stack_size; |
| 32 | 32 |
| 33 | 33 |
| 34 #if defined(__mips__) |
| 35 #define STACK_ALIGNMENT 8 |
| 36 #else |
| 34 #define STACK_ALIGNMENT 16 | 37 #define STACK_ALIGNMENT 16 |
| 38 #endif |
| 35 | 39 |
| 36 #if defined(__i386__) | 40 #if defined(__i386__) |
| 37 const int kReturnAddrSize = 4; | 41 const int kReturnAddrSize = 4; |
| 38 const int kArgSizeOnStack = 4; | 42 const int kArgSizeOnStack = 4; |
| 39 const int kRedZoneSize = 0; | 43 const int kRedZoneSize = 0; |
| 40 #elif defined(__x86_64__) | 44 #elif defined(__x86_64__) |
| 41 const int kReturnAddrSize = 8; | 45 const int kReturnAddrSize = 8; |
| 42 const int kArgSizeOnStack = 0; | 46 const int kArgSizeOnStack = 0; |
| 43 const int kRedZoneSize = 128; | 47 const int kRedZoneSize = 128; |
| 44 #elif defined(__arm__) | 48 #elif defined(__arm__) |
| 45 const int kReturnAddrSize = 0; | 49 const int kReturnAddrSize = 0; |
| 46 const int kArgSizeOnStack = 0; | 50 const int kArgSizeOnStack = 0; |
| 47 const int kRedZoneSize = 0; | 51 const int kRedZoneSize = 0; |
| 52 #elif defined(__mips__) |
| 53 const int kReturnAddrSize = 0; |
| 54 const int kArgSizeOnStack = 16; |
| 55 const int kRedZoneSize = 0; |
| 48 #else | 56 #else |
| 49 # error Unsupported architecture | 57 # error Unsupported architecture |
| 50 #endif | 58 #endif |
| 51 | 59 |
| 52 struct AlignedType { | 60 struct AlignedType { |
| 53 int blah; | 61 int blah; |
| 54 } __attribute__((aligned(16))); | 62 } __attribute__((aligned(16))); |
| 55 | 63 |
| 56 /* | 64 /* |
| 57 * We do this check in a separate function in an attempt to prevent | 65 * We do this check in a separate function in an attempt to prevent |
| 58 * the compiler from optimising away the check for a stack-allocated | 66 * the compiler from optimising away the check for a stack-allocated |
| 59 * variable. | 67 * variable. |
| 60 * | 68 * |
| 61 * We test for an alignment that is small enough for the compiler to | 69 * We test for an alignment that is small enough for the compiler to |
| 62 * assume on x86-32, even if sel_ldr sets up a larger alignment. | 70 * assume on x86-32, even if sel_ldr sets up a larger alignment. |
| 63 */ | 71 */ |
| 64 __attribute__((noinline)) | 72 __attribute__((noinline)) |
| 65 void check_pointer_is_aligned(void *pointer) { | 73 void check_pointer_is_aligned(void *pointer) { |
| 74 #if defined(__mips__) |
| 75 assert((uintptr_t) pointer % 8 == 0); |
| 76 #else |
| 66 assert((uintptr_t) pointer % 16 == 0); | 77 assert((uintptr_t) pointer % 16 == 0); |
| 78 #endif |
| 67 } | 79 } |
| 68 | 80 |
| 69 void check_stack_is_aligned(void) { | 81 void check_stack_is_aligned(void) { |
| 70 struct AlignedType var; | 82 struct AlignedType var; |
| 71 check_pointer_is_aligned(&var); | 83 check_pointer_is_aligned(&var); |
| 72 } | 84 } |
| 73 | 85 |
| 74 | 86 |
| 75 void crash_at_known_address(void); | 87 void crash_at_known_address(void); |
| 76 extern char prog_ctr_at_crash[]; | 88 extern char prog_ctr_at_crash[]; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 90 ".popsection"); | 102 ".popsection"); |
| 91 #elif defined(__arm__) | 103 #elif defined(__arm__) |
| 92 __asm__(".pushsection .text, \"ax\", %progbits\n" | 104 __asm__(".pushsection .text, \"ax\", %progbits\n" |
| 93 ".p2align 4\n" | 105 ".p2align 4\n" |
| 94 "crash_at_known_address:\n" | 106 "crash_at_known_address:\n" |
| 95 "mov r0, #0\n" | 107 "mov r0, #0\n" |
| 96 "bic r0, r0, #0xc0000000\n" | 108 "bic r0, r0, #0xc0000000\n" |
| 97 "prog_ctr_at_crash:\n" | 109 "prog_ctr_at_crash:\n" |
| 98 "str r0, [r0]\n" | 110 "str r0, [r0]\n" |
| 99 ".popsection\n"); | 111 ".popsection\n"); |
| 112 #elif defined(__mips__) |
| 113 __asm__(".pushsection .text, \"ax\", %progbits\n" |
| 114 ".p2align 4\n" |
| 115 "crash_at_known_address:\n" |
| 116 "ori $t0, $zero, 0\n" |
| 117 "and $t0, $t0, $t7\n" |
| 118 "prog_ctr_at_crash:\n" |
| 119 "sw $t0, 0($t0)\n" |
| 120 ".popsection\n"); |
| 100 #else | 121 #else |
| 101 # error Unsupported architecture | 122 # error Unsupported architecture |
| 102 #endif | 123 #endif |
| 103 | 124 |
| 104 | 125 |
| 105 void exception_handler(struct NaClExceptionContext *context); | 126 void exception_handler(struct NaClExceptionContext *context); |
| 106 REGS_SAVER_FUNC_NOPROTO(exception_handler, exception_handler_wrapped); | 127 REGS_SAVER_FUNC_NOPROTO(exception_handler, exception_handler_wrapped); |
| 107 | 128 |
| 108 void exception_handler_wrapped(struct NaClSignalContext *entry_regs) { | 129 void exception_handler_wrapped(struct NaClSignalContext *entry_regs) { |
| 109 struct NaClExceptionContext *context = | 130 struct NaClExceptionContext *context = |
| 110 (struct NaClExceptionContext *) RegsGetArg1(entry_regs); | 131 (struct NaClExceptionContext *) RegsGetArg1(entry_regs); |
| 111 | 132 |
| 112 printf("handler called\n"); | 133 printf("handler called\n"); |
| 113 | 134 |
| 114 check_stack_is_aligned(); | 135 check_stack_is_aligned(); |
| 115 | 136 |
| 116 assert(context->stack_ptr == (uint32_t) g_regs_at_crash.stack_ptr); | 137 assert(context->stack_ptr == (uint32_t) g_regs_at_crash.stack_ptr); |
| 117 assert(context->prog_ctr == (uintptr_t) prog_ctr_at_crash); | 138 assert(context->prog_ctr == (uintptr_t) prog_ctr_at_crash); |
| 118 #if defined(__i386__) | 139 #if defined(__i386__) |
| 119 assert(context->frame_ptr == g_regs_at_crash.ebp); | 140 assert(context->frame_ptr == g_regs_at_crash.ebp); |
| 120 #elif defined(__x86_64__) | 141 #elif defined(__x86_64__) |
| 121 assert(context->frame_ptr == (uint32_t) g_regs_at_crash.rbp); | 142 assert(context->frame_ptr == (uint32_t) g_regs_at_crash.rbp); |
| 122 #elif defined(__arm__) | 143 #elif defined(__arm__) |
| 123 assert(context->frame_ptr == g_regs_at_crash.r11); | 144 assert(context->frame_ptr == g_regs_at_crash.r11); |
| 145 #elif defined(__mips__) |
| 146 assert(context->frame_ptr == g_regs_at_crash.frame_ptr); |
| 124 #else | 147 #else |
| 125 # error Unsupported architecture | 148 # error Unsupported architecture |
| 126 #endif | 149 #endif |
| 127 | 150 |
| 128 /* | 151 /* |
| 129 * Convert the NaClUserRegisterState to a NaClSignalContext so that | 152 * Convert the NaClUserRegisterState to a NaClSignalContext so that |
| 130 * we can reuse RegsAssertEqual() to compare the register state. | 153 * we can reuse RegsAssertEqual() to compare the register state. |
| 131 */ | 154 */ |
| 132 struct NaClSignalContext reported_regs; | 155 struct NaClSignalContext reported_regs; |
| 133 RegsCopyFromUserRegisterState(&reported_regs, &context->regs); | 156 RegsCopyFromUserRegisterState(&reported_regs, &context->regs); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 g_registered_stack_size = stack_size; | 210 g_registered_stack_size = stack_size; |
| 188 | 211 |
| 189 char crash_stack[0x1000]; | 212 char crash_stack[0x1000]; |
| 190 RegsFillTestValues(&g_regs_at_crash, /* seed= */ 0); | 213 RegsFillTestValues(&g_regs_at_crash, /* seed= */ 0); |
| 191 g_regs_at_crash.stack_ptr = (uintptr_t) crash_stack + sizeof(crash_stack); | 214 g_regs_at_crash.stack_ptr = (uintptr_t) crash_stack + sizeof(crash_stack); |
| 192 g_regs_at_crash.prog_ctr = (uintptr_t) prog_ctr_at_crash; | 215 g_regs_at_crash.prog_ctr = (uintptr_t) prog_ctr_at_crash; |
| 193 RegsApplySandboxConstraints(&g_regs_at_crash); | 216 RegsApplySandboxConstraints(&g_regs_at_crash); |
| 194 #if defined(__arm__) | 217 #if defined(__arm__) |
| 195 /* crash_at_known_address clobbers r0. */ | 218 /* crash_at_known_address clobbers r0. */ |
| 196 g_regs_at_crash.r0 = 0; | 219 g_regs_at_crash.r0 = 0; |
| 220 #elif defined(__mips__) |
| 221 /* crash_at_known_address clobbers t0. */ |
| 222 g_regs_at_crash.t0 = 0; |
| 197 #endif | 223 #endif |
| 198 | 224 |
| 199 if (!setjmp(g_jmp_buf)) { | 225 if (!setjmp(g_jmp_buf)) { |
| 200 JUMP_WITH_REGS(&g_regs_at_crash, crash_at_known_address); | 226 JUMP_WITH_REGS(&g_regs_at_crash, crash_at_known_address); |
| 201 } | 227 } |
| 202 /* Clear the jmp_buf to prevent it from being reused accidentally. */ | 228 /* Clear the jmp_buf to prevent it from being reused accidentally. */ |
| 203 memset(g_jmp_buf, 0, sizeof(g_jmp_buf)); | 229 memset(g_jmp_buf, 0, sizeof(g_jmp_buf)); |
| 204 } | 230 } |
| 205 | 231 |
| 206 void test_exceptions_minimally(void) { | 232 void test_exceptions_minimally(void) { |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 RUN_TEST(test_unsetting_x86_direction_flag); | 385 RUN_TEST(test_unsetting_x86_direction_flag); |
| 360 #endif | 386 #endif |
| 361 | 387 |
| 362 fprintf(stderr, "** intended_exit_status=0\n"); | 388 fprintf(stderr, "** intended_exit_status=0\n"); |
| 363 return 0; | 389 return 0; |
| 364 } | 390 } |
| 365 | 391 |
| 366 int main(void) { | 392 int main(void) { |
| 367 return RunTests(TestMain); | 393 return RunTests(TestMain); |
| 368 } | 394 } |
| OLD | NEW |