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 setting k0 and k1 registers, they are changed by kernel. */ \ | |
Mark Seaborn
2013/03/12 23:07:28
'setting' -> 'saving'
petarj
2013/03/12 23:44:04
Done.
| |
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" \ | |
Mark Seaborn
2013/03/12 23:07:28
Nit: remove space before \n for consistency
petarj
2013/03/12 23:44:04
Done.
| |
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 |