OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2012 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can | |
4 * be found in the LICENSE file. | |
5 */ | |
6 | |
7 #include "native_client/src/trusted/service_runtime/nacl_config.h" | |
8 | |
9 .text | |
10 | |
11 | |
12 /* | |
13 * This trusted code is linked into the service runtime. It is executed when a | |
14 * nacl module performs a system call via a service runtime interface. The nacl | |
15 * module jumps to the trampoline corresponding to the syscall and then here. | |
16 * This code switches the execution contexts (registers and stack) from | |
17 * untrusted to trusted. | |
18 * | |
19 * on stack: | |
20 * | |
21 * top | |
22 * ===== | |
23 * a0 - alignment for NaClSyscallCSegHook | |
24 * ra - return address | |
25 * arg 1 | |
26 * arg 2 | |
27 * ..... | |
28 * arg N | |
29 */ | |
30 | |
31 DEFINE_GLOBAL_HIDDEN_IDENTIFIER(NaClSyscallSeg): | |
32 | |
33 .set noreorder | |
34 | |
35 /* | |
36 * The following code (next 6 instructions) does what the trampoline code should | |
37 * do. It places the first 4 parameters of the system call to the stack, and on | |
38 * top of that it places the return address to the user module. On Mips the | |
39 * trampoline is too small for all this, so the code is moved here. | |
40 * | |
41 * Mips passes parameters to a callee in registers a0-a3. If there are more | |
42 * than 4 parameters, the first four args are passed in registers and the rest | |
43 * are placed on the stack. Regardless of the number of arguments passed, Mips | |
44 * o32 ABI requires that the caller should always reserve 16 bytes on stack that | |
45 * correspond to registers a0-a3. | |
46 * | |
47 * This code pushes all parameters from registers into the stack; thus, we keep | |
48 * all parameters on the stack as follows: | |
49 * top - arg0, arg1, arg2, arg3 .... argN | |
50 * | |
51 * On top of that we push the return address, so we will know where to return | |
52 * after the system call. | |
53 * | |
54 * After this code the stack layout must look like: | |
55 * | |
56 * sp+0: retaddr to user module | |
57 * sp+4: arg0 (system call argument) | |
58 * sp+8: arg1 | |
59 * .......... | |
60 * sp+X: argN | |
61 * | |
62 * When service runtime serves a system call, it first creates a structure which | |
63 * utilizes these arguments. The structure is created by Decoder functions in | |
64 * nacl_syscall_handlers.c. (nacl_syscall_handlers.c is an automatically | |
65 * generated file and placed in | |
66 * scons-out//gen/native_client/src/trusted/service_runtime). | |
67 */ | |
68 | |
69 /* Place a0-a3 argument registers in the reserved 16-byte region in caller's | |
70 stack frame (o32 ABI), and place return address on top of that. */ | |
71 | |
72 .cpload $t9 | |
73 | |
74 sw $a3, 12($sp) | |
75 sw $a2, 8($sp) | |
76 sw $a1, 4($sp) | |
77 sw $a0, 0($sp) | |
78 addiu $sp, $sp, -8 | |
79 sw $ra, 4($sp) | |
80 sw $t5, 0($sp) | |
81 | |
82 /* Load the __thread variable's offset into a3. */ | |
83 lui $a3, %tprel_hi(gNaClThreadIdx) | |
84 addiu $a3, $a3, %tprel_lo(gNaClThreadIdx) | |
85 | |
86 /* Fetch the thread-local variable holding the thread index. */ | |
87 rdhwr $v1, $29 | |
88 addu $a3, $v1, $a3 | |
89 lw $a0, 0($a3) | |
90 | |
91 /* Load the nacl_user entry of this thread. | |
92 * a1 = nacl_user[a0*4] */ | |
93 lw $a1,%got(nacl_user)($28) | |
94 sll $a0, $a0, 2 | |
95 addu $a1, $a1, $a0 | |
96 lw $a1, 0($a1) | |
97 | |
98 /* Store thread state to the nacl_user entry. */ | |
99 sw $t6, 0($a1) | |
Mark Seaborn
2012/09/08 02:43:14
Please don't hard code integer NaClThreadContext o
petarj
2012/09/11 16:58:13
Done.
| |
100 sw $t7, 4($a1) | |
101 sw $s0, 8($a1) | |
102 sw $s1, 12($a1) | |
103 sw $s2, 16($a1) | |
104 sw $s3, 20($a1) | |
105 sw $s4, 24($a1) | |
106 sw $s5, 28($a1) | |
107 sw $s6, 32($a1) | |
108 sw $s7, 36($a1) | |
109 sw $t8, 40($a1) | |
110 sw $gp, 44($a1) | |
111 sw $sp, 48($a1) | |
112 sw $fp, 52($a1) | |
113 | |
114 /* Restore the thread index. */ | |
115 srl $a0, $a0, 2 | |
116 | |
117 /* Reserve 16-byte for arguments (o32 ABI) */ | |
118 addiu $sp, $sp, -16 | |
119 lw $t9,%call16(NaClSyscallCSegHook)($gp) | |
120 jr $t9 | |
121 nop | |
122 | |
123 /* NOTREACHED */ | |
124 | |
125 /* | |
126 * If the thread returns, which must not happen, it will be halted | |
127 * by the following instruction | |
128 */ | |
129 | |
130 jr $0 /*NACL_HALT*/ | |
131 | |
OLD | NEW |