| 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 |