| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 regs->r0 = (uintptr_t) test_shm; | 98 regs->r0 = (uintptr_t) test_shm; |
| 99 ASM_WITH_REGS( | 99 ASM_WITH_REGS( |
| 100 regs, | 100 regs, |
| 101 /* Align to ensure no NOPs are inserted in the code that follows. */ | 101 /* Align to ensure no NOPs are inserted in the code that follows. */ |
| 102 ".p2align 4\n" | 102 ".p2align 4\n" |
| 103 /* Set "test_shm->var = test_shm" to indicate that we are ready. */ | 103 /* Set "test_shm->var = test_shm" to indicate that we are ready. */ |
| 104 "bic r0, r0, #0xc0000000\n" | 104 "bic r0, r0, #0xc0000000\n" |
| 105 "str r0, [r0]\n" | 105 "str r0, [r0]\n" |
| 106 "spin_instruction:\n" | 106 "spin_instruction:\n" |
| 107 "b spin_instruction\n"); | 107 "b spin_instruction\n"); |
| 108 #elif defined(__mips__) |
| 109 regs->a0 = (uintptr_t) test_shm; |
| 110 ASM_WITH_REGS( |
| 111 regs, |
| 112 /* Align to ensure no NOPs are inserted in the code that follows. */ |
| 113 ".p2align 4\n" |
| 114 /* Set "test_shm->var = test_shm" to indicate that we are ready. */ |
| 115 "and $a0, $a0, $t7\n" |
| 116 "sw $a0, 0($a0)\n" |
| 117 ".global spin_instruction\n" |
| 118 "spin_instruction:\n" |
| 119 "b spin_instruction\n" |
| 120 "nop\n"); |
| 108 #else | 121 #else |
| 109 # error Unsupported architecture | 122 # error Unsupported architecture |
| 110 #endif | 123 #endif |
| 111 assert(!"Should not reach here"); | 124 assert(!"Should not reach here"); |
| 112 } | 125 } |
| 113 | 126 |
| 114 static void ContinueAfterSyscall(void) { | 127 static void ContinueAfterSyscall(void) { |
| 115 longjmp(return_jmp_buf, 1); | 128 longjmp(return_jmp_buf, 1); |
| 116 } | 129 } |
| 117 | 130 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 "push $ContinueAfterSyscall\n" /* Push return address */ | 167 "push $ContinueAfterSyscall\n" /* Push return address */ |
| 155 "nacljmp %%eax, %%r15\n"); | 168 "nacljmp %%eax, %%r15\n"); |
| 156 #elif defined(__arm__) | 169 #elif defined(__arm__) |
| 157 call_regs.r0 = (uintptr_t) test_shm; /* Set syscall argument */ | 170 call_regs.r0 = (uintptr_t) test_shm; /* Set syscall argument */ |
| 158 call_regs.r1 = syscall_addr; /* Scratch register */ | 171 call_regs.r1 = syscall_addr; /* Scratch register */ |
| 159 call_regs.lr = (uintptr_t) ContinueAfterSyscall; | 172 call_regs.lr = (uintptr_t) ContinueAfterSyscall; |
| 160 ASM_WITH_REGS( | 173 ASM_WITH_REGS( |
| 161 &call_regs, | 174 &call_regs, |
| 162 "bic r1, r1, #0xf000000f\n" | 175 "bic r1, r1, #0xf000000f\n" |
| 163 "bx r1\n"); | 176 "bx r1\n"); |
| 177 #elif defined(__mips__) |
| 178 call_regs.a0 = (uintptr_t) test_shm; /* Set syscall argument */ |
| 179 call_regs.t9 = syscall_addr; /* Scratch register */ |
| 180 call_regs.return_addr = (uintptr_t) ContinueAfterSyscall; |
| 181 ASM_WITH_REGS( |
| 182 &call_regs, |
| 183 "and $t9, $t9, $t6\n" |
| 184 "jr $t9\n" |
| 185 "nop\n"); |
| 164 #else | 186 #else |
| 165 # error Unsupported architecture | 187 # error Unsupported architecture |
| 166 #endif | 188 #endif |
| 167 assert(!"Should not reach here"); | 189 assert(!"Should not reach here"); |
| 168 } | 190 } |
| 169 } | 191 } |
| 170 | 192 |
| 171 void SyscallReturnAddress(void); | 193 void SyscallReturnAddress(void); |
| 172 #if defined(__i386__) | 194 #if defined(__i386__) |
| 173 __asm__(".pushsection .text, \"ax\", @progbits\n" | 195 __asm__(".pushsection .text, \"ax\", @progbits\n" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 186 "jmp SyscallLoop\n" | 208 "jmp SyscallLoop\n" |
| 187 ".popsection\n"); | 209 ".popsection\n"); |
| 188 #elif defined(__arm__) | 210 #elif defined(__arm__) |
| 189 __asm__(".pushsection .text, \"ax\", %progbits\n" | 211 __asm__(".pushsection .text, \"ax\", %progbits\n" |
| 190 ".p2align 4\n" | 212 ".p2align 4\n" |
| 191 "SyscallReturnAddress:\n" | 213 "SyscallReturnAddress:\n" |
| 192 "adr lr, SyscallReturnAddress\n" | 214 "adr lr, SyscallReturnAddress\n" |
| 193 "bic r4, r4, #0xc000000f\n" | 215 "bic r4, r4, #0xc000000f\n" |
| 194 "bx r4\n" | 216 "bx r4\n" |
| 195 ".popsection\n"); | 217 ".popsection\n"); |
| 218 #elif defined(__mips__) |
| 219 __asm__(".pushsection .text, \"ax\", %progbits\n" |
| 220 ".p2align 4\n" |
| 221 ".global SyscallReturnAddress\n" |
| 222 "SyscallReturnAddress:\n" |
| 223 "lui $ra, %hi(SyscallReturnAddress)\n" |
| 224 "addiu $ra, $ra, %lo(SyscallReturnAddress)\n" |
| 225 "and $s0, $s0, $t6\n" |
| 226 "jr $s0\n" |
| 227 "nop\n" |
| 228 ".popsection\n"); |
| 196 #else | 229 #else |
| 197 # error Unsupported architecture | 230 # error Unsupported architecture |
| 198 #endif | 231 #endif |
| 199 | 232 |
| 200 /* | 233 /* |
| 201 * Set registers to known values and call a NaCl syscall in an | 234 * Set registers to known values and call a NaCl syscall in an |
| 202 * infinite loop. This is used for testing that the same register | 235 * infinite loop. This is used for testing that the same register |
| 203 * state is reported while the thread is in untrusted code or inside | 236 * state is reported while the thread is in untrusted code or inside |
| 204 * the syscall. | 237 * the syscall. |
| 205 */ | 238 */ |
| 206 static void SyscallRegisterSetterLoopThread(struct SuspendTestShm *test_shm) { | 239 static void SyscallRegisterSetterLoopThread(struct SuspendTestShm *test_shm) { |
| 207 struct NaClSignalContext *regs = &test_shm->expected_regs; | 240 struct NaClSignalContext *regs = &test_shm->expected_regs; |
| 208 char stack[0x10000]; | 241 char stack[0x10000]; |
| 209 | 242 |
| 210 RegsFillTestValues(regs, /* seed= */ 0); | 243 RegsFillTestValues(regs, /* seed= */ 0); |
| 211 regs->stack_ptr = (uintptr_t) stack + sizeof(stack); | 244 regs->stack_ptr = (uintptr_t) stack + sizeof(stack); |
| 212 regs->prog_ctr = (uintptr_t) SyscallReturnAddress; | 245 regs->prog_ctr = (uintptr_t) SyscallReturnAddress; |
| 213 RegsApplySandboxConstraints(regs); | 246 RegsApplySandboxConstraints(regs); |
| 214 RegsUnsetNonCalleeSavedRegisters(regs); | 247 RegsUnsetNonCalleeSavedRegisters(regs); |
| 215 | 248 |
| 216 uintptr_t syscall_addr = NACL_SYSCALL_ADDR(NACL_sys_test_syscall_2); | 249 uintptr_t syscall_addr = NACL_SYSCALL_ADDR(NACL_sys_test_syscall_2); |
| 217 #if defined(__i386__) | 250 #if defined(__i386__) |
| 218 regs->esi = syscall_addr; | 251 regs->esi = syscall_addr; |
| 219 #elif defined(__x86_64__) | 252 #elif defined(__x86_64__) |
| 220 regs->r12 = syscall_addr; | 253 regs->r12 = syscall_addr; |
| 221 #elif defined(__arm__) | 254 #elif defined(__arm__) |
| 222 regs->r4 = syscall_addr; | 255 regs->r4 = syscall_addr; |
| 256 #elif defined(__mips__) |
| 257 regs->s0 = syscall_addr; |
| 223 #else | 258 #else |
| 224 # error Unsupported architecture | 259 # error Unsupported architecture |
| 225 #endif | 260 #endif |
| 226 JUMP_WITH_REGS(regs, SyscallReturnAddress); | 261 JUMP_WITH_REGS(regs, SyscallReturnAddress); |
| 227 } | 262 } |
| 228 | 263 |
| 229 int main(int argc, char **argv) { | 264 int main(int argc, char **argv) { |
| 230 if (argc != 3) { | 265 if (argc != 3) { |
| 231 fprintf(stderr, "Expected 2 arguments: <test-type> <memory-address>\n"); | 266 fprintf(stderr, "Expected 2 arguments: <test-type> <memory-address>\n"); |
| 232 return 1; | 267 return 1; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 249 } else if (strcmp(test_type, "SyscallRegisterSetterThread") == 0) { | 284 } else if (strcmp(test_type, "SyscallRegisterSetterThread") == 0) { |
| 250 SyscallRegisterSetterThread(test_shm); | 285 SyscallRegisterSetterThread(test_shm); |
| 251 } else if (strcmp(test_type, "SyscallRegisterSetterLoopThread") == 0) { | 286 } else if (strcmp(test_type, "SyscallRegisterSetterLoopThread") == 0) { |
| 252 SyscallRegisterSetterLoopThread(test_shm); | 287 SyscallRegisterSetterLoopThread(test_shm); |
| 253 } else { | 288 } else { |
| 254 fprintf(stderr, "Unknown test type: %s\n", test_type); | 289 fprintf(stderr, "Unknown test type: %s\n", test_type); |
| 255 return 1; | 290 return 1; |
| 256 } | 291 } |
| 257 return 0; | 292 return 0; |
| 258 } | 293 } |
| OLD | NEW |