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 #ifndef NATIVE_CLIENT_TESTS_COMMON_REGISTER_SET_H_ | 7 #ifndef NATIVE_CLIENT_TESTS_COMMON_REGISTER_SET_H_ |
8 #define NATIVE_CLIENT_TESTS_COMMON_REGISTER_SET_H_ | 8 #define NATIVE_CLIENT_TESTS_COMMON_REGISTER_SET_H_ |
9 | 9 |
10 #include "native_client/src/include/nacl_macros.h" | 10 #include "native_client/src/include/nacl_macros.h" |
| 11 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
11 #include "native_client/src/trusted/service_runtime/nacl_signal.h" | 12 #include "native_client/src/trusted/service_runtime/nacl_signal.h" |
12 #include "native_client/src/trusted/service_runtime/include/sys/nacl_exception.h
" | 13 #include "native_client/src/trusted/service_runtime/include/sys/nacl_exception.h
" |
13 | 14 |
14 /* | 15 /* |
15 * ASM_WITH_REGS(regs, asm_code) executes asm_code with most registers | 16 * ASM_WITH_REGS(regs, asm_code) executes asm_code with most registers |
16 * restored from regs, a pointer of type "struct NaClSignalContext *". | 17 * restored from regs, a pointer of type "struct NaClSignalContext *". |
17 */ | 18 */ |
18 | 19 |
19 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 | 20 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 |
20 | 21 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 REGS_MASK_R0 "ldr r10, [r0, #0x28]\n" \ | 98 REGS_MASK_R0 "ldr r10, [r0, #0x28]\n" \ |
98 REGS_MASK_R0 "ldr r11, [r0, #0x2c]\n" \ | 99 REGS_MASK_R0 "ldr r11, [r0, #0x2c]\n" \ |
99 REGS_MASK_R0 "ldr r12, [r0, #0x30]\n" \ | 100 REGS_MASK_R0 "ldr r12, [r0, #0x30]\n" \ |
100 REGS_MASK_R0 "ldr lr, [r0, #0x38]\n" \ | 101 REGS_MASK_R0 "ldr lr, [r0, #0x38]\n" \ |
101 /* Lastly, restore r0 */ \ | 102 /* Lastly, restore r0 */ \ |
102 REGS_MASK_R0 "ldr r0, [r0, #0x00]\n" \ | 103 REGS_MASK_R0 "ldr r0, [r0, #0x00]\n" \ |
103 ".p2align 4\n" /* Align for whatever comes after */ \ | 104 ".p2align 4\n" /* Align for whatever comes after */ \ |
104 asm_code \ | 105 asm_code \ |
105 : : "r"(regs) : "memory") | 106 : : "r"(regs) : "memory") |
106 | 107 |
| 108 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips |
| 109 |
| 110 # define REGS_MASK_A0 "and $a0, $a0, $t7\n" |
| 111 # define ASM_WITH_REGS(regs, asm_code) \ |
| 112 __asm__( \ |
| 113 ".p2align 4\n" \ |
| 114 "move $a0, %0\n" \ |
| 115 "nop\n" \ |
| 116 /* We skip setting zero register because it's unsettable. */ \ |
| 117 REGS_MASK_A0 "lw $at, 4($a0)\n" \ |
| 118 REGS_MASK_A0 "lw $v0, 8($a0)\n" \ |
| 119 REGS_MASK_A0 "lw $v1, 12($a0)\n" \ |
| 120 REGS_MASK_A0 "lw $a1, 20($a0)\n" \ |
| 121 REGS_MASK_A0 "lw $a2, 24($a0)\n" \ |
| 122 REGS_MASK_A0 "lw $a3, 28($a0)\n" \ |
| 123 REGS_MASK_A0 "lw $t0, 32($a0)\n" \ |
| 124 REGS_MASK_A0 "lw $t1, 36($a0)\n" \ |
| 125 REGS_MASK_A0 "lw $t2, 40($a0)\n" \ |
| 126 REGS_MASK_A0 "lw $t3, 44($a0)\n" \ |
| 127 REGS_MASK_A0 "lw $t4, 48($a0)\n" \ |
| 128 REGS_MASK_A0 "lw $t5, 52($a0)\n" \ |
| 129 /* We skip setting t6 and t7 because those are mask registers. */ \ |
| 130 REGS_MASK_A0 "lw $s0, 64($a0)\n" \ |
| 131 REGS_MASK_A0 "lw $s1, 68($a0)\n" \ |
| 132 REGS_MASK_A0 "lw $s2, 72($a0)\n" \ |
| 133 REGS_MASK_A0 "lw $s3, 76($a0)\n" \ |
| 134 REGS_MASK_A0 "lw $s4, 80($a0)\n" \ |
| 135 REGS_MASK_A0 "lw $s5, 84($a0)\n" \ |
| 136 REGS_MASK_A0 "lw $s6, 88($a0)\n" \ |
| 137 REGS_MASK_A0 "lw $s7, 92($a0)\n" \ |
| 138 /* We skip setting t8 because that register hold TLS index. */ \ |
| 139 REGS_MASK_A0 "lw $t9, 100($a0)\n" \ |
| 140 /* We skip setting k0 and k1 registers, they are changed by kernel. */ \ |
| 141 REGS_MASK_A0 "lw $gp, 112($a0)\n" \ |
| 142 REGS_MASK_A0 "lw $sp, 116($a0)\n" \ |
| 143 /* Value change of sp requires masking instruction. */ \ |
| 144 "and $sp, $sp, $t7\n" \ |
| 145 "nop\n" \ |
| 146 REGS_MASK_A0 "lw $fp, 120($a0)\n" \ |
| 147 REGS_MASK_A0 "lw $ra, 124($a0)\n" \ |
| 148 REGS_MASK_A0 "lw $a0, 16($a0)\n" \ |
| 149 ".p2align 4\n" /* Align for whatever comes after. */ \ |
| 150 asm_code \ |
| 151 : : "r"(regs) : "memory") |
| 152 |
107 #else | 153 #else |
108 # error Unsupported architecture | 154 # error Unsupported architecture |
109 #endif | 155 #endif |
110 | 156 |
111 /* | 157 /* |
112 * JUMP_WITH_REGS(regs, dest) jumps to symbol |dest| with most | 158 * JUMP_WITH_REGS(regs, dest) jumps to symbol |dest| with most |
113 * registers restored from |regs|, a pointer of type "struct | 159 * registers restored from |regs|, a pointer of type "struct |
114 * NaClSignalContext *". | 160 * NaClSignalContext *". |
115 */ | 161 */ |
116 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 | 162 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 |
117 # define JUMP_WITH_REGS(regs, dest) ASM_WITH_REGS(regs, "jmp " #dest) | 163 # define JUMP_WITH_REGS(regs, dest) ASM_WITH_REGS(regs, "jmp " #dest) |
118 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm | 164 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm |
119 # define JUMP_WITH_REGS(regs, dest) ASM_WITH_REGS(regs, "b " #dest) | 165 # define JUMP_WITH_REGS(regs, dest) ASM_WITH_REGS(regs, "b " #dest) |
| 166 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips |
| 167 # define JUMP_WITH_REGS(regs, dest) ASM_WITH_REGS(regs, \ |
| 168 "b " #dest "\n" \ |
| 169 "nop\n") |
120 #else | 170 #else |
121 # error Unsupported architecture | 171 # error Unsupported architecture |
122 #endif | 172 #endif |
123 | 173 |
124 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 | 174 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 |
125 | 175 |
126 /* | 176 /* |
127 * Normally it is possible to save x86 flags using the 'pushf' | 177 * Normally it is possible to save x86 flags using the 'pushf' |
128 * instruction. However, 'pushf' is disallowed under NaCl. Instead, | 178 * instruction. However, 'pushf' is disallowed under NaCl. Instead, |
129 * we can read a subset of the flags indirectly using conditional | 179 * we can read a subset of the flags indirectly using conditional |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 /* Save CPSR (flags) register, a.k.a. APSR for user mode */ \ | 337 /* Save CPSR (flags) register, a.k.a. APSR for user mode */ \ |
288 "mrs r0, apsr\n" \ | 338 "mrs r0, apsr\n" \ |
289 "str r0, [sp, #0x40]\n" \ | 339 "str r0, [sp, #0x40]\n" \ |
290 /* Set argument to callee_func() */ \ | 340 /* Set argument to callee_func() */ \ |
291 "mov r0, sp\n" \ | 341 "mov r0, sp\n" \ |
292 /* Align the stack pointer */ \ | 342 /* Align the stack pointer */ \ |
293 "bic sp, sp, #0xc000000f\n" \ | 343 "bic sp, sp, #0xc000000f\n" \ |
294 "b " #callee_func "\n" \ | 344 "b " #callee_func "\n" \ |
295 ".popsection\n") | 345 ".popsection\n") |
296 | 346 |
| 347 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips |
| 348 |
| 349 # define REGS_SAVER_FUNC_NOPROTO(def_func, callee_func) \ |
| 350 void callee_func(struct NaClSignalContext *regs); \ |
| 351 __asm__( \ |
| 352 ".pushsection .text, \"ax\", %progbits\n" \ |
| 353 ".p2align 4\n" \ |
| 354 #def_func ":\n" \ |
| 355 /* Make space on stack for all registers. */ \ |
| 356 "add $sp, $sp, -132\n" \ |
| 357 "and $sp, $sp, $t7\n"\ |
| 358 "sw $zero, 0($sp)\n" \ |
| 359 "sw $at, 4($sp)\n" \ |
| 360 "sw $v0, 8($sp)\n" \ |
| 361 "sw $v1, 12($sp)\n" \ |
| 362 "sw $a0, 16($sp)\n" \ |
| 363 "sw $a1, 20($sp)\n" \ |
| 364 "sw $a2, 24($sp)\n" \ |
| 365 "sw $a3, 28($sp)\n" \ |
| 366 "sw $t0, 32($sp)\n" \ |
| 367 "sw $t1, 36($sp)\n" \ |
| 368 "sw $t2, 40($sp)\n" \ |
| 369 "sw $t3, 44($sp)\n" \ |
| 370 "sw $t4, 48($sp)\n" \ |
| 371 "sw $t5, 52($sp)\n" \ |
| 372 "sw $t6, 56($sp)\n" \ |
| 373 "sw $t7, 60($sp)\n" \ |
| 374 "sw $s0, 64($sp)\n" \ |
| 375 "sw $s1, 68($sp)\n" \ |
| 376 "sw $s2, 72($sp)\n" \ |
| 377 "sw $s3, 76($sp)\n" \ |
| 378 "sw $s4, 80($sp)\n" \ |
| 379 "sw $s5, 84($sp)\n" \ |
| 380 "sw $s6, 88($sp)\n" \ |
| 381 "sw $s7, 92($sp)\n" \ |
| 382 "sw $t8, 96($sp)\n" \ |
| 383 "sw $t9, 100($sp)\n" \ |
| 384 /* We skip saving k0 and k1 registers, they are changed by kernel. */ \ |
| 385 "sw $gp, 112($sp)\n" \ |
| 386 /* Store the value stack_ptr had on entry of this function. */ \ |
| 387 "add $t1, $sp, 132\n" \ |
| 388 "sw $t1, 116($sp)\n" \ |
| 389 "sw $fp, 120($sp)\n" \ |
| 390 "sw $ra, 124($sp)\n" \ |
| 391 /* Save a correct prog_ctr value. */ \ |
| 392 "lui $t1, %hi(" #def_func ")\n" \ |
| 393 "addiu $t1, $t1, %lo(" #def_func ")\n" \ |
| 394 "sw $t1, 128($sp)\n" \ |
| 395 /* Prepare argument for callee_func. */ \ |
| 396 "move $a0, $sp\n" \ |
| 397 /* Align the stack pointer. */ \ |
| 398 "sll $t1, $t7, 3\n" \ |
| 399 "and $sp, $sp, $t1\n" \ |
| 400 "and $sp, $sp, $t7\n" \ |
| 401 /* Make space on stack for convention calling registers. */ \ |
| 402 "add $sp, $sp, -16\n" \ |
| 403 "and $sp, $sp, $t7\n" \ |
| 404 "b " #callee_func "\n" \ |
| 405 "nop \n" \ |
| 406 ".popsection\n") |
| 407 |
297 #else | 408 #else |
298 # error Unsupported architecture | 409 # error Unsupported architecture |
299 #endif | 410 #endif |
300 | 411 |
301 /* Initialize the register set with arbitrary test data. */ | 412 /* Initialize the register set with arbitrary test data. */ |
302 void RegsFillTestValues(struct NaClSignalContext *regs, int seed); | 413 void RegsFillTestValues(struct NaClSignalContext *regs, int seed); |
303 | 414 |
304 /* Adjust registers to follow the sandbox's constraints. */ | 415 /* Adjust registers to follow the sandbox's constraints. */ |
305 void RegsApplySandboxConstraints(struct NaClSignalContext *regs); | 416 void RegsApplySandboxConstraints(struct NaClSignalContext *regs); |
306 | 417 |
(...skipping 12 matching lines...) Expand all Loading... |
319 void RegsUnsetNonCalleeSavedRegisters(struct NaClSignalContext *regs); | 430 void RegsUnsetNonCalleeSavedRegisters(struct NaClSignalContext *regs); |
320 | 431 |
321 /* | 432 /* |
322 * For a function called with register state |regs|, extract the first | 433 * For a function called with register state |regs|, extract the first |
323 * argument. This is useful for a function entry point defined by | 434 * argument. This is useful for a function entry point defined by |
324 * REGS_SAVER_FUNC. | 435 * REGS_SAVER_FUNC. |
325 */ | 436 */ |
326 uintptr_t RegsGetArg1(const struct NaClSignalContext *regs); | 437 uintptr_t RegsGetArg1(const struct NaClSignalContext *regs); |
327 | 438 |
328 #endif | 439 #endif |
OLD | NEW |