Chromium Code Reviews| 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 * NaCl Server Runtime user thread state. | 8 * NaCl Server Runtime user thread state. |
| 9 */ | 9 */ |
| 10 | |
| 11 #include <string.h> | |
| 12 | |
| 10 #include "native_client/src/shared/platform/aligned_malloc.h" | 13 #include "native_client/src/shared/platform/aligned_malloc.h" |
| 11 #include "native_client/src/shared/platform/nacl_check.h" | 14 #include "native_client/src/shared/platform/nacl_check.h" |
| 12 #include "native_client/src/shared/platform/nacl_exit.h" | 15 #include "native_client/src/shared/platform/nacl_exit.h" |
| 13 #include "native_client/src/shared/platform/nacl_sync_checked.h" | 16 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
| 14 | 17 |
| 15 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" | 18 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" |
| 16 #include "native_client/src/trusted/service_runtime/nacl_desc_effector_ldr.h" | 19 #include "native_client/src/trusted/service_runtime/nacl_desc_effector_ldr.h" |
| 17 #include "native_client/src/trusted/service_runtime/nacl_globals.h" | 20 #include "native_client/src/trusted/service_runtime/nacl_globals.h" |
| 18 #include "native_client/src/trusted/service_runtime/nacl_tls.h" | 21 #include "native_client/src/trusted/service_runtime/nacl_tls.h" |
| 19 #include "native_client/src/trusted/service_runtime/nacl_switch_to_app.h" | 22 #include "native_client/src/trusted/service_runtime/nacl_switch_to_app.h" |
| 20 #include "native_client/src/trusted/service_runtime/nacl_stack_safety.h" | 23 #include "native_client/src/trusted/service_runtime/nacl_stack_safety.h" |
| 21 #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h" | 24 #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h" |
| 22 | 25 |
| 23 | 26 |
| 24 void WINAPI NaClThreadLauncher(void *state) { | 27 void WINAPI NaClAppThreadLauncher(void *state) { |
| 25 struct NaClAppThread *natp = (struct NaClAppThread *) state; | 28 struct NaClAppThread *natp = (struct NaClAppThread *) state; |
| 26 uint32_t thread_idx; | 29 uint32_t thread_idx; |
| 27 NaClLog(4, "NaClThreadLauncher: entered\n"); | 30 NaClLog(4, "NaClAppThreadLauncher: entered\n"); |
| 28 | 31 |
| 29 NaClSignalStackRegister(natp->signal_stack); | 32 NaClSignalStackRegister(natp->signal_stack); |
| 30 | 33 |
| 31 NaClLog(4, " natp = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) natp); | 34 NaClLog(4, " natp = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) natp); |
| 32 NaClLog(4, " prog_ctr = 0x%016"NACL_PRIxNACL_REG"\n", natp->user.prog_ctr); | 35 NaClLog(4, " prog_ctr = 0x%016"NACL_PRIxNACL_REG"\n", natp->user.prog_ctr); |
| 33 NaClLog(4, "stack_ptr = 0x%016"NACL_PRIxPTR"\n", | 36 NaClLog(4, "stack_ptr = 0x%016"NACL_PRIxPTR"\n", |
| 34 NaClGetThreadCtxSp(&natp->user)); | 37 NaClGetThreadCtxSp(&natp->user)); |
| 35 | 38 |
| 36 thread_idx = NaClGetThreadIdx(natp); | 39 thread_idx = NaClGetThreadIdx(natp); |
| 37 CHECK(0 < thread_idx); | 40 CHECK(0 < thread_idx); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 /* NOTREACHED */ | 137 /* NOTREACHED */ |
| 135 } | 138 } |
| 136 | 139 |
| 137 | 140 |
| 138 struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap, | 141 struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap, |
| 139 uintptr_t usr_entry, | 142 uintptr_t usr_entry, |
| 140 uintptr_t usr_stack_ptr, | 143 uintptr_t usr_stack_ptr, |
| 141 uint32_t user_tls1, | 144 uint32_t user_tls1, |
| 142 uint32_t user_tls2) { | 145 uint32_t user_tls2) { |
| 143 struct NaClAppThread *natp; | 146 struct NaClAppThread *natp; |
| 144 int rv; | |
| 145 uint32_t tls_idx; | 147 uint32_t tls_idx; |
| 146 | 148 |
| 147 natp = NaClAlignedMalloc(sizeof *natp, __alignof(struct NaClAppThread)); | 149 natp = NaClAlignedMalloc(sizeof *natp, __alignof(struct NaClAppThread)); |
| 148 if (natp == NULL) { | 150 if (natp == NULL) { |
| 149 return NULL; | 151 return NULL; |
| 150 } | 152 } |
| 151 | 153 |
| 152 NaClLog(4, " natp = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) natp); | 154 NaClLog(4, " natp = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) natp); |
| 153 NaClLog(4, " nap = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) nap); | 155 NaClLog(4, " nap = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) nap); |
| 154 NaClLog(4, "usr_stack_ptr = 0x%016"NACL_PRIxPTR"\n", usr_stack_ptr); | 156 NaClLog(4, "usr_stack_ptr = 0x%016"NACL_PRIxPTR"\n", usr_stack_ptr); |
| 155 | 157 |
| 156 /* | 158 /* |
| 157 * Set these early, in case NaClTlsAllocate() wants to examine them. | 159 * Set these early, in case NaClTlsAllocate() wants to examine them. |
| 158 */ | 160 */ |
| 159 natp->nap = nap; | 161 natp->nap = nap; |
| 160 natp->thread_num = -1; /* illegal index */ | 162 natp->thread_num = -1; /* illegal index */ |
| 163 natp->host_thread_is_defined = 0; | |
| 164 memset(&natp->host_thread, 0, sizeof(natp->host_thread)); | |
| 161 | 165 |
| 162 /* | 166 /* |
| 163 * Even though we don't know what segment base/range should gs/r9/nacl_tls_idx | 167 * Even though we don't know what segment base/range should gs/r9/nacl_tls_idx |
| 164 * select, we still need one, since it identifies the thread when we context | 168 * select, we still need one, since it identifies the thread when we context |
| 165 * switch back. This use of a dummy tls is only needed for the main thread, | 169 * switch back. This use of a dummy tls is only needed for the main thread, |
| 166 * which is expected to invoke the tls_init syscall from its crt code (before | 170 * which is expected to invoke the tls_init syscall from its crt code (before |
| 167 * main or much of libc can run). Other threads are spawned with the thread | 171 * main or much of libc can run). Other threads are spawned with the thread |
| 168 * pointer address as a parameter. | 172 * pointer address as a parameter. |
| 169 */ | 173 */ |
| 170 tls_idx = NaClTlsAllocate(natp); | 174 tls_idx = NaClTlsAllocate(natp); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 191 } | 195 } |
| 192 | 196 |
| 193 if (!NaClMutexCtor(&natp->suspend_mu)) { | 197 if (!NaClMutexCtor(&natp->suspend_mu)) { |
| 194 goto cleanup_mu; | 198 goto cleanup_mu; |
| 195 } | 199 } |
| 196 natp->suspend_state = NACL_APP_THREAD_TRUSTED; | 200 natp->suspend_state = NACL_APP_THREAD_TRUSTED; |
| 197 natp->suspended_registers = NULL; | 201 natp->suspended_registers = NULL; |
| 198 natp->fault_signal = 0; | 202 natp->fault_signal = 0; |
| 199 | 203 |
| 200 natp->dynamic_delete_generation = 0; | 204 natp->dynamic_delete_generation = 0; |
| 201 | 205 return natp; |
| 202 rv = NaClThreadCtor(&natp->thread, | |
| 203 NaClThreadLauncher, | |
| 204 (void *) natp, | |
| 205 NACL_KERN_STACK_SIZE); | |
| 206 if (rv != 0) { | |
| 207 return natp; /* Success */ | |
| 208 } | |
| 209 | 206 |
| 210 NaClMutexDtor(&natp->suspend_mu); | 207 NaClMutexDtor(&natp->suspend_mu); |
|
bsy
2012/12/17 21:02:05
this is dead?
Mark Seaborn
2012/12/17 22:30:14
Good point. Removed.
| |
| 211 cleanup_mu: | 208 cleanup_mu: |
| 212 NaClMutexDtor(&natp->mu); | 209 NaClMutexDtor(&natp->mu); |
| 213 if (NULL != natp->signal_stack) { | 210 if (NULL != natp->signal_stack) { |
| 214 NaClSignalStackFree(&natp->signal_stack); | 211 NaClSignalStackFree(&natp->signal_stack); |
| 215 natp->signal_stack = NULL; | 212 natp->signal_stack = NULL; |
| 216 } | 213 } |
| 217 cleanup_free: | 214 cleanup_free: |
| 218 NaClAlignedFree(natp); | 215 NaClAlignedFree(natp); |
| 219 return NULL; | 216 return NULL; |
| 220 } | 217 } |
| 221 | 218 |
| 222 | 219 |
| 220 int NaClAppThreadSpawn(struct NaClApp *nap, | |
| 221 uintptr_t usr_entry, | |
| 222 uintptr_t usr_stack_ptr, | |
| 223 uint32_t user_tls1, | |
| 224 uint32_t user_tls2) { | |
| 225 struct NaClAppThread *natp = NaClAppThreadMake(nap, usr_entry, usr_stack_ptr, | |
| 226 user_tls1, user_tls2); | |
| 227 if (natp == NULL) { | |
| 228 return 0; | |
| 229 } | |
| 230 /* | |
| 231 * We set host_thread_is_defined assuming, for now, that | |
| 232 * NaClThreadCtor() will succeed. | |
| 233 */ | |
| 234 natp->host_thread_is_defined = 1; | |
| 235 if (!NaClThreadCtor(&natp->host_thread, NaClAppThreadLauncher, (void *) natp, | |
| 236 NACL_KERN_STACK_SIZE)) { | |
| 237 /* | |
| 238 * No other thread saw the NaClAppThread, so it is OK that | |
| 239 * host_thread was not initialized despite host_thread_is_defined | |
| 240 * being set. | |
| 241 */ | |
| 242 natp->host_thread_is_defined = 0; | |
| 243 NaClAppThreadDelete(natp); | |
| 244 return 0; | |
| 245 } | |
| 246 return 1; | |
| 247 } | |
| 248 | |
| 249 | |
| 223 void NaClAppThreadDelete(struct NaClAppThread *natp) { | 250 void NaClAppThreadDelete(struct NaClAppThread *natp) { |
| 224 /* | 251 /* |
| 225 * the thread must not be still running, else this crashes the system | 252 * the thread must not be still running, else this crashes the system |
| 226 */ | 253 */ |
| 227 | 254 |
| 255 if (natp->host_thread_is_defined) { | |
| 256 NaClThreadDtor(&natp->host_thread); | |
|
bsy
2012/12/17 21:02:05
if an embedding-supplied thread, there should prob
Mark Seaborn
2012/12/17 22:30:14
Not necessarily. If the embedder implements its o
| |
| 257 } | |
| 228 free(natp->suspended_registers); | 258 free(natp->suspended_registers); |
| 229 NaClMutexDtor(&natp->suspend_mu); | 259 NaClMutexDtor(&natp->suspend_mu); |
| 230 NaClThreadDtor(&natp->thread); | |
| 231 NaClSignalStackFree(natp->signal_stack); | 260 NaClSignalStackFree(natp->signal_stack); |
| 232 natp->signal_stack = NULL; | 261 natp->signal_stack = NULL; |
| 233 NaClTlsFree(natp); | 262 NaClTlsFree(natp); |
| 234 NaClMutexDtor(&natp->mu); | 263 NaClMutexDtor(&natp->mu); |
| 235 NaClAlignedFree(natp); | 264 NaClAlignedFree(natp); |
| 236 } | 265 } |
| OLD | NEW |