| 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 "native_client/tests/thread_suspension/suspend_test.h" | 7 #include "native_client/tests/thread_suspension/suspend_test.h" |
| 8 | 8 |
| 9 #include <assert.h> | 9 #include <assert.h> |
| 10 #include <setjmp.h> | 10 #include <setjmp.h> |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 #else | 102 #else |
| 103 # error Unsupported architecture | 103 # error Unsupported architecture |
| 104 #endif | 104 #endif |
| 105 assert(!"Should not reach here"); | 105 assert(!"Should not reach here"); |
| 106 } | 106 } |
| 107 | 107 |
| 108 static void ContinueAfterSyscall(void) { | 108 static void ContinueAfterSyscall(void) { |
| 109 longjmp(return_jmp_buf, 1); | 109 longjmp(return_jmp_buf, 1); |
| 110 } | 110 } |
| 111 | 111 |
| 112 static void UnsetNonCalleeSavedRegisters(struct NaClSignalContext *regs) { | |
| 113 #if defined(__i386__) | |
| 114 regs->eax = 0; | |
| 115 regs->ecx = 0; | |
| 116 regs->edx = 0; | |
| 117 #elif defined(__x86_64__) | |
| 118 regs->rax = 0; | |
| 119 regs->rcx = 0; | |
| 120 regs->rdx = 0; | |
| 121 regs->rsi = 0; | |
| 122 regs->rdi = 0; | |
| 123 regs->r8 = 0; | |
| 124 regs->r9 = 0; | |
| 125 regs->r10 = 0; | |
| 126 regs->r11 = 0; | |
| 127 #elif defined(__arm__) | |
| 128 regs->r0 = 0; | |
| 129 regs->r1 = 0; | |
| 130 regs->r2 = 0; | |
| 131 regs->r3 = 0; | |
| 132 regs->r12 = 0; | |
| 133 regs->lr = 0; | |
| 134 #else | |
| 135 # error Unsupported architecture | |
| 136 #endif | |
| 137 } | |
| 138 | |
| 139 /* Set registers to known values and enter a NaCl syscall. */ | 112 /* Set registers to known values and enter a NaCl syscall. */ |
| 140 static void SyscallRegisterSetterThread(struct SuspendTestShm *test_shm) { | 113 static void SyscallRegisterSetterThread(struct SuspendTestShm *test_shm) { |
| 141 struct NaClSignalContext call_regs; | 114 struct NaClSignalContext call_regs; |
| 142 char stack[0x10000]; | 115 char stack[0x10000]; |
| 143 | 116 |
| 144 RegsFillTestValues(&call_regs); | 117 RegsFillTestValues(&call_regs); |
| 145 call_regs.stack_ptr = (uintptr_t) stack + sizeof(stack); | 118 call_regs.stack_ptr = (uintptr_t) stack + sizeof(stack); |
| 146 call_regs.prog_ctr = (uintptr_t) ContinueAfterSyscall; | 119 call_regs.prog_ctr = (uintptr_t) ContinueAfterSyscall; |
| 147 RegsApplySandboxConstraints(&call_regs); | 120 RegsApplySandboxConstraints(&call_regs); |
| 148 | 121 |
| 149 /* | 122 /* |
| 150 * call_regs are the registers we set on entry to the syscall. | 123 * call_regs are the registers we set on entry to the syscall. |
| 151 * expected_regs are the registers that should be reported by | 124 * expected_regs are the registers that should be reported by |
| 152 * NaClAppThreadGetSuspendedRegisters(). Since not all registers | 125 * NaClAppThreadGetSuspendedRegisters(). Since not all registers |
| 153 * are saved when entering a syscall, expected_regs will be the same | 126 * are saved when entering a syscall, expected_regs will be the same |
| 154 * as call_regs but with various registers zeroed out. | 127 * as call_regs but with various registers zeroed out. |
| 155 */ | 128 */ |
| 156 test_shm->expected_regs = call_regs; | 129 test_shm->expected_regs = call_regs; |
| 157 UnsetNonCalleeSavedRegisters(&test_shm->expected_regs); | 130 RegsUnsetNonCalleeSavedRegisters(&test_shm->expected_regs); |
| 158 | 131 |
| 159 uintptr_t syscall_addr = (uintptr_t) NACL_SYSCALL(test_syscall_1); | 132 uintptr_t syscall_addr = (uintptr_t) NACL_SYSCALL(test_syscall_1); |
| 160 if (!setjmp(return_jmp_buf)) { | 133 if (!setjmp(return_jmp_buf)) { |
| 161 #if defined(__i386__) | 134 #if defined(__i386__) |
| 162 test_shm->expected_regs.stack_ptr -= 4; /* Account for argument */ | 135 test_shm->expected_regs.stack_ptr -= 4; /* Account for argument */ |
| 163 call_regs.eax = syscall_addr; | 136 call_regs.eax = syscall_addr; |
| 164 call_regs.ecx = (uintptr_t) test_shm; /* Scratch register */ | 137 call_regs.ecx = (uintptr_t) test_shm; /* Scratch register */ |
| 165 ASM_WITH_REGS( | 138 ASM_WITH_REGS( |
| 166 &call_regs, | 139 &call_regs, |
| 167 "push %%ecx\n" /* Push syscall argument */ | 140 "push %%ecx\n" /* Push syscall argument */ |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 } else if (strcmp(test_type, "RegisterSetterThread") == 0) { | 183 } else if (strcmp(test_type, "RegisterSetterThread") == 0) { |
| 211 RegisterSetterThread(test_shm); | 184 RegisterSetterThread(test_shm); |
| 212 } else if (strcmp(test_type, "SyscallRegisterSetterThread") == 0) { | 185 } else if (strcmp(test_type, "SyscallRegisterSetterThread") == 0) { |
| 213 SyscallRegisterSetterThread(test_shm); | 186 SyscallRegisterSetterThread(test_shm); |
| 214 } else { | 187 } else { |
| 215 fprintf(stderr, "Unknown test type: %s\n", test_type); | 188 fprintf(stderr, "Unknown test type: %s\n", test_type); |
| 216 return 1; | 189 return 1; |
| 217 } | 190 } |
| 218 return 0; | 191 return 0; |
| 219 } | 192 } |
| OLD | NEW |