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