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 { | |
53 int blah; | |
54 } __attribute__((aligned(16))); | |
55 | |
56 /* | |
57 * 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 | |
59 * variable. | |
60 * | |
61 * 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. | |
63 */ | |
64 __attribute__((noinline)) | |
65 void check_pointer_is_aligned(void *pointer) { | |
66 assert((uintptr_t) pointer % 16 == 0); | |
67 } | |
68 | |
69 void check_stack_is_aligned(void) { | |
70 struct AlignedType var; | |
71 check_pointer_is_aligned(&var); | |
72 } | |
73 | |
74 | |
75 void crash_at_known_address(void); | 60 void crash_at_known_address(void); |
76 extern char prog_ctr_at_crash[]; | 61 extern char prog_ctr_at_crash[]; |
77 #if defined(__i386__) | 62 #if defined(__i386__) |
78 __asm__(".pushsection .text, \"ax\", @progbits\n" | 63 __asm__(".pushsection .text, \"ax\", @progbits\n" |
79 ".p2align 5\n" | 64 ".p2align 5\n" |
80 "crash_at_known_address:\n" | 65 "crash_at_known_address:\n" |
81 "prog_ctr_at_crash:\n" | 66 "prog_ctr_at_crash:\n" |
82 "movl $0, 0\n" | 67 "movl $0, 0\n" |
83 ".popsection"); | 68 ".popsection"); |
84 #elif defined(__x86_64__) | 69 #elif defined(__x86_64__) |
85 __asm__(".pushsection .text, \"ax\", @progbits\n" | 70 __asm__(".pushsection .text, \"ax\", @progbits\n" |
86 ".p2align 5\n" | 71 ".p2align 5\n" |
87 "crash_at_known_address:\n" | 72 "crash_at_known_address:\n" |
88 "prog_ctr_at_crash:\n" | 73 "prog_ctr_at_crash:\n" |
89 "movl $0, (%r15)\n" | 74 "movl $0, (%r15)\n" |
90 ".popsection"); | 75 ".popsection"); |
91 #elif defined(__arm__) | 76 #elif defined(__arm__) |
92 __asm__(".pushsection .text, \"ax\", %progbits\n" | 77 __asm__(".pushsection .text, \"ax\", %progbits\n" |
93 ".p2align 4\n" | 78 ".p2align 4\n" |
94 "crash_at_known_address:\n" | 79 "crash_at_known_address:\n" |
95 "mov r0, #0\n" | 80 "mov r0, #0\n" |
96 "bic r0, r0, #0xc0000000\n" | 81 "bic r0, r0, #0xc0000000\n" |
97 "prog_ctr_at_crash:\n" | 82 "prog_ctr_at_crash:\n" |
98 "str r0, [r0]\n" | 83 "str r0, [r0]\n" |
99 ".popsection\n"); | 84 ".popsection\n"); |
| 85 #elif defined(__mips__) |
| 86 __asm__(".pushsection .text, \"ax\", %progbits\n" |
| 87 ".p2align 4\n" |
| 88 ".global crash_at_known_address\n" |
| 89 "crash_at_known_address:\n" |
| 90 "and $zero, $zero, $t7\n" |
| 91 ".global prog_ctr_at_crash\n" |
| 92 "prog_ctr_at_crash:\n" |
| 93 "sw $t0, 0($zero)\n" |
| 94 ".popsection\n"); |
100 #else | 95 #else |
101 # error Unsupported architecture | 96 # error Unsupported architecture |
102 #endif | 97 #endif |
103 | 98 |
104 | 99 |
105 void exception_handler(struct NaClExceptionContext *context); | 100 void exception_handler(struct NaClExceptionContext *context); |
106 REGS_SAVER_FUNC_NOPROTO(exception_handler, exception_handler_wrapped); | 101 REGS_SAVER_FUNC_NOPROTO(exception_handler, exception_handler_wrapped); |
107 | 102 |
108 void exception_handler_wrapped(struct NaClSignalContext *entry_regs) { | 103 void exception_handler_wrapped(struct NaClSignalContext *entry_regs) { |
109 struct NaClExceptionContext *context = | 104 struct NaClExceptionContext *context = |
110 (struct NaClExceptionContext *) RegsGetArg1(entry_regs); | 105 (struct NaClExceptionContext *) RegsGetArg1(entry_regs); |
111 | 106 |
112 printf("handler called\n"); | 107 printf("handler called\n"); |
113 | 108 |
114 check_stack_is_aligned(); | |
115 | |
116 assert(context->stack_ptr == (uint32_t) g_regs_at_crash.stack_ptr); | 109 assert(context->stack_ptr == (uint32_t) g_regs_at_crash.stack_ptr); |
117 assert(context->prog_ctr == (uintptr_t) prog_ctr_at_crash); | 110 assert(context->prog_ctr == (uintptr_t) prog_ctr_at_crash); |
118 #if defined(__i386__) | 111 #if defined(__i386__) |
119 assert(context->frame_ptr == g_regs_at_crash.ebp); | 112 assert(context->frame_ptr == g_regs_at_crash.ebp); |
120 #elif defined(__x86_64__) | 113 #elif defined(__x86_64__) |
121 assert(context->frame_ptr == (uint32_t) g_regs_at_crash.rbp); | 114 assert(context->frame_ptr == (uint32_t) g_regs_at_crash.rbp); |
122 #elif defined(__arm__) | 115 #elif defined(__arm__) |
123 assert(context->frame_ptr == g_regs_at_crash.r11); | 116 assert(context->frame_ptr == g_regs_at_crash.r11); |
| 117 #elif defined(__mips__) |
| 118 assert(context->frame_ptr == g_regs_at_crash.frame_ptr); |
124 #else | 119 #else |
125 # error Unsupported architecture | 120 # error Unsupported architecture |
126 #endif | 121 #endif |
127 | 122 |
128 /* | 123 /* |
129 * Convert the NaClUserRegisterState to a NaClSignalContext so that | 124 * Convert the NaClUserRegisterState to a NaClSignalContext so that |
130 * we can reuse RegsAssertEqual() to compare the register state. | 125 * we can reuse RegsAssertEqual() to compare the register state. |
131 */ | 126 */ |
132 struct NaClSignalContext reported_regs; | 127 struct NaClSignalContext reported_regs; |
133 RegsCopyFromUserRegisterState(&reported_regs, &context->regs); | 128 RegsCopyFromUserRegisterState(&reported_regs, &context->regs); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 RUN_TEST(test_unsetting_x86_direction_flag); | 354 RUN_TEST(test_unsetting_x86_direction_flag); |
360 #endif | 355 #endif |
361 | 356 |
362 fprintf(stderr, "** intended_exit_status=0\n"); | 357 fprintf(stderr, "** intended_exit_status=0\n"); |
363 return 0; | 358 return 0; |
364 } | 359 } |
365 | 360 |
366 int main(void) { | 361 int main(void) { |
367 return RunTests(TestMain); | 362 return RunTests(TestMain); |
368 } | 363 } |
OLD | NEW |