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 /* | 7 /* |
8 * The MacOS assembler has a macro facility that is pretty close | 8 * The MacOS assembler has a macro facility that is pretty close |
9 * to GNU as macros, but not quite the same. | 9 * to GNU as macros, but not quite the same. |
10 */ | 10 */ |
(...skipping 23 matching lines...) Expand all Loading... |
34 * syscall trampoline code, and this code is responsible for figuring | 34 * syscall trampoline code, and this code is responsible for figuring |
35 * out the identity of the thread, saving the user registers, finish | 35 * out the identity of the thread, saving the user registers, finish |
36 * restoring the segment registers (and getting out of the sandbox), | 36 * restoring the segment registers (and getting out of the sandbox), |
37 * and actually invoking the C system call handler code. | 37 * and actually invoking the C system call handler code. |
38 */ | 38 */ |
39 | 39 |
40 #include "native_client/src/trusted/service_runtime/arch/x86_64/sel_rt_64.h" | 40 #include "native_client/src/trusted/service_runtime/arch/x86_64/sel_rt_64.h" |
41 #include "native_client/src/trusted/service_runtime/nacl_config.h" | 41 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
42 | 42 |
43 /* | 43 /* |
44 * This macro gets the thread index from the nacl_thread_index TLS variable | 44 * This macro gets the NaClThreadContext from the nacl_current_thread |
45 * in Windows or Linux, or the corresponding pthread_getspecific(...) TSD | 45 * TLS variable in Windows or Linux, or the corresponding |
46 * data in OSX and puts it in %eax. | 46 * pthread_getspecific(...) TSD data in OSX and puts it in %rdx. |
47 * | 47 * |
48 * May clobber two registers %rcx and %rdx (windows only). | 48 * May clobber two registers, %rax and %rcx. |
49 * | 49 * |
50 * If %rax contains 0, then this is an invalid thread. | 50 * If %rdx contains 0, then this is an invalid thread. |
51 */ | 51 */ |
52 MACRO(get_tls) | 52 MACRO(get_tls) |
53 /* | 53 /* |
54 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING | 54 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING |
55 * | 55 * |
56 * Open coded TLS (or TSD) access, for all of our target host | 56 * Open coded TLS (or TSD) access, for all of our target host |
57 * OS/toolchains. If the compiler / runtime conventions for | 57 * OS/toolchains. If the compiler / runtime conventions for |
58 * how to access TLS or TSD changes, this code will break | 58 * how to access TLS or TSD changes, this code will break |
59 * mysteriously. | 59 * mysteriously. |
60 * | 60 * |
61 * Any changes/fixes for this must be mirrored in nacl_test_capture.S | 61 * Any changes/fixes for this must be mirrored in nacl_test_capture.S |
62 * | 62 * |
63 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING | 63 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING |
64 */ | 64 */ |
65 #if NACL_LINUX | 65 #if NACL_LINUX |
66 /* | 66 /* |
67 * Linux uses TLS. | 67 * Linux uses TLS. |
68 * We use "@GOTTPOFF" rather than "@TPOFF" in order to be PIC-friendly. | 68 * We use "@GOTTPOFF" rather than "@TPOFF" in order to be PIC-friendly. |
69 */ | 69 */ |
70 movq nacl_thread_index@GOTTPOFF(%rip), %rax | 70 movq nacl_current_thread@GOTTPOFF(%rip), %rax |
71 movl %fs:(%rax), %eax | 71 movq %fs:(%rax), %rdx |
72 #elif NACL_OSX | 72 #elif NACL_OSX |
73 /* | 73 /* |
74 * This assumes a particular implementation of OS X's | 74 * This assumes a particular implementation of OS X's |
75 * pthread_getspecific(), which we check for in NaClTlsInit(). | 75 * pthread_getspecific(), which we check for in NaClTlsInit(). |
76 */ | 76 */ |
77 movl _nacl_thread_index_tls_offset(%rip), %eax | 77 movl _nacl_current_thread_tls_offset(%rip), %eax |
78 movl %gs:(%rax), %eax | 78 movq %gs:(%rax), %rdx |
79 #elif NACL_WINDOWS | 79 #elif NACL_WINDOWS |
80 /* | 80 /* |
81 * NOTE: This code should match the code in platform/win/test_tls.S! | 81 * NOTE: This code should match the code in platform/win/test_tls.S! |
82 * If you change this code, please update that file as well. | 82 * If you change this code, please update that file as well. |
83 * | 83 * |
84 * The following two lines generate this instruction: | 84 * The following two lines generate this instruction: |
85 * ba XX XX XX XX movl $nacl_thread_index@SECREL, %edx | 85 * ba XX XX XX XX movl $nacl_current_thread@SECREL, %edx |
86 * | 86 * |
87 * SECREL is a relocation type which gives the offset of | 87 * SECREL is a relocation type which gives the offset of |
88 * nacl_thread_index within the TLS template section. GNU | 88 * nacl_current_thread within the TLS template section. GNU |
89 * binutils' assembler does not have a syntax for generating | 89 * binutils' assembler does not have a syntax for generating |
90 * this relocation as part of an instruction. It only has the | 90 * this relocation as part of an instruction. It only has the |
91 * .secrel32 syntax for generating the relocated value as a | 91 * .secrel32 syntax for generating the relocated value as a |
92 * 32-bit literal. We use this here for generating the | 92 * 32-bit literal. We use this here for generating the |
93 * instruction by hand. | 93 * instruction by hand. |
94 * | 94 * |
95 * For background, see: | 95 * For background, see: |
96 * http://code.google.com/p/nativeclient/issues/detail?id=2155 | 96 * http://code.google.com/p/nativeclient/issues/detail?id=2155 |
97 * | 97 * |
98 * because of the need to do .byte, we cannot simply name the | 98 * because of the need to do .byte, we cannot simply name the |
99 * scratch registers via macro arguments. | 99 * scratch registers via macro arguments. |
100 */ | 100 */ |
101 .byte 0xba | 101 .byte 0xba |
102 .secrel32 nacl_thread_index | 102 .secrel32 nacl_current_thread |
103 | 103 |
104 mov _tls_index(%rip), %ecx | 104 mov _tls_index(%rip), %ecx |
105 movq %gs:0x58, %rax | 105 movq %gs:0x58, %rax |
106 /* Get the address of this module (executable/DLL)'s TLS area. */ | 106 /* Get the address of this module (executable/DLL)'s TLS area. */ |
107 movq (%rax,%rcx,8), %rax | 107 movq (%rax,%rcx,8), %rax |
108 /* Get the value of nacl_thread_index from the TLS area. */ | 108 /* Get the value of nacl_current_thread from the TLS area. */ |
109 movl (%rdx,%rax), %eax | 109 movq (%rdx,%rax), %rdx |
110 #else | 110 #else |
111 # error "What OS/compiler is the service runtime being compiled with?" | 111 # error "What OS/compiler is the service runtime being compiled with?" |
112 #endif | 112 #endif |
113 ENDMACRO | 113 ENDMACRO |
114 | 114 |
115 /* | 115 /* |
116 * On untrusted stack: | 116 * On untrusted stack: |
117 * return-addr-to-caller-of-trampoline | 117 * return-addr-to-caller-of-trampoline |
118 * return-addr-to-trampoline (essentially syscall number) | 118 * return-addr-to-trampoline (essentially syscall number) |
119 * | 119 * |
(...skipping 10 matching lines...) Expand all Loading... |
130 movl %r9d, -0x04(%rsp) | 130 movl %r9d, -0x04(%rsp) |
131 movl %r8d, -0x08(%rsp) | 131 movl %r8d, -0x08(%rsp) |
132 movl %ecx, -0x0c(%rsp) | 132 movl %ecx, -0x0c(%rsp) |
133 movl %edx, -0x10(%rsp) | 133 movl %edx, -0x10(%rsp) |
134 movl %esi, -0x14(%rsp) | 134 movl %esi, -0x14(%rsp) |
135 movl %edi, -0x18(%rsp) | 135 movl %edi, -0x18(%rsp) |
136 | 136 |
137 /* rax, rdi, rsi, rdx, rcx, r8, r9 are usable for scratch */ | 137 /* rax, rdi, rsi, rdx, rcx, r8, r9 are usable for scratch */ |
138 | 138 |
139 get_tls | 139 get_tls |
140 | |
141 leaq IDENTIFIER(nacl_user)(%rip), %rdx | |
142 movq (%rdx,%rax,8), %rdx | |
143 /* | 140 /* |
144 * Code below will segfault if %rdx is the NULL pointer, since | 141 * Code below will segfault if %rdx is the NULL pointer, since |
145 * the zero page is unmapped. | 142 * the zero page is unmapped. |
146 */ | 143 */ |
147 | 144 |
148 /* only save the callee saved registers */ | 145 /* only save the callee saved registers */ |
149 DEFINE_GLOBAL_HIDDEN_IDENTIFIER(NaClSyscallThreadCaptureFault): | 146 DEFINE_GLOBAL_HIDDEN_IDENTIFIER(NaClSyscallThreadCaptureFault): |
150 movq %rbx, NACL_THREAD_CONTEXT_OFFSET_RBX(%rdx) | 147 movq %rbx, NACL_THREAD_CONTEXT_OFFSET_RBX(%rdx) |
151 movq %rbp, NACL_THREAD_CONTEXT_OFFSET_RBP(%rdx) | 148 movq %rbp, NACL_THREAD_CONTEXT_OFFSET_RBP(%rdx) |
152 /* | 149 /* |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 * 0x10 -0x08 r8 | 220 * 0x10 -0x08 r8 |
224 * 0x0c -0x0c rcx | 221 * 0x0c -0x0c rcx |
225 * 0x08 -0x10 rdx | 222 * 0x08 -0x10 rdx |
226 * 0x04 -0x14 rsi | 223 * 0x04 -0x14 rsi |
227 * 0x00 -0x18 rdi | 224 * 0x00 -0x18 rdi |
228 */ | 225 */ |
229 | 226 |
230 MACRO(tls_syscall) | 227 MACRO(tls_syscall) |
231 MACROENTRY | 228 MACROENTRY |
232 get_tls | 229 get_tls |
233 leaq IDENTIFIER(nacl_user)(%rip), %rdx | |
234 movq (%rdx,%rax,8), %rdx | |
235 movl MACROARG2(%rdx), %eax | 230 movl MACROARG2(%rdx), %eax |
236 /* sandbox the return, straight off the untrusted stack */ | 231 /* sandbox the return, straight off the untrusted stack */ |
237 movq 0x8(%rsp), %rcx | 232 movq 0x8(%rsp), %rcx |
238 addq DOLLAR 0x10, %rsp | 233 addq DOLLAR 0x10, %rsp |
239 addl DOLLAR 31, %ecx | 234 addl DOLLAR 31, %ecx |
240 andl DOLLAR 0xffffffe0, %ecx | 235 andl DOLLAR 0xffffffe0, %ecx |
241 addq %r15, %rcx | 236 addq %r15, %rcx |
242 /* | 237 /* |
243 * Set %rdx to zero so that we do not leak the address of the | 238 * Set %rdx to zero so that we do not leak the address of the |
244 * NaClThreadContext struct. This also resets flags. | 239 * NaClThreadContext struct. This also resets flags. |
245 * Resetting flags to fixed values by doing this last | 240 * Resetting flags to fixed values by doing this last |
246 * simplifies testing that we do not leak any information via | 241 * simplifies testing that we do not leak any information via |
247 * flags. | 242 * flags. |
248 */ | 243 */ |
249 xorl %edx, %edx | 244 xorl %edx, %edx |
250 jmp *%rcx | 245 jmp *%rcx |
251 ENDMACRO | 246 ENDMACRO |
252 | 247 |
253 tls_syscall NaClGetTlsFastPath1, NACL_THREAD_CONTEXT_OFFSET_TLS_VALUE1 | 248 tls_syscall NaClGetTlsFastPath1, NACL_THREAD_CONTEXT_OFFSET_TLS_VALUE1 |
254 tls_syscall NaClGetTlsFastPath2, NACL_THREAD_CONTEXT_OFFSET_TLS_VALUE2 | 249 tls_syscall NaClGetTlsFastPath2, NACL_THREAD_CONTEXT_OFFSET_TLS_VALUE2 |
OLD | NEW |