void NaClAppThreadDelete(struct NaClAppThread *natp) { /* * the thread must not be still running, else this crashes the system */ if (natp->host_thread_is_defined) { NaClThreadDtor(&natp->host_thread); } free(natp->suspended_registers); NaClMutexDtor(&natp->suspend_mu); NaClSignalStackFree(natp->signal_stack); natp->signal_stack = NULL; NaClTlsFree(natp); NaClMutexDtor(&natp->mu); NaClAlignedFree(natp); }
void NaClAppThreadDtor(struct NaClAppThread *natp) { /* * the thread must not be still running, else this crashes the system */ /* * Notify the debug stub that we are done with this thread */ NaClDebugThreadStopDebugging(natp); NaClThreadDtor(&natp->thread); NaClSignalStackUnregister(); NaClSignalStackFree(natp->signal_stack); natp->signal_stack = NULL; NaClClosureResultDtor(&natp->result); (*natp->effp->vtbl->Dtor)(natp->effp); free(natp->effp); natp->effp = NULL; NaClTlsFree(natp); NaClCondVarDtor(&natp->cv); NaClMutexDtor(&natp->mu); }
struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap, uintptr_t usr_entry, uintptr_t usr_stack_ptr, uint32_t user_tls1, uint32_t user_tls2) { struct NaClAppThread *natp; uint32_t tls_idx; natp = NaClAlignedMalloc(sizeof *natp, __alignof(struct NaClAppThread)); if (natp == NULL) { return NULL; } NaClLog(4, " natp = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) natp); NaClLog(4, " nap = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) nap); NaClLog(4, "usr_stack_ptr = 0x%016"NACL_PRIxPTR"\n", usr_stack_ptr); /* * Set these early, in case NaClTlsAllocate() wants to examine them. */ natp->nap = nap; natp->thread_num = -1; /* illegal index */ natp->host_thread_is_defined = 0; memset(&natp->host_thread, 0, sizeof(natp->host_thread)); /* * Even though we don't know what segment base/range should gs/r9/nacl_tls_idx * select, we still need one, since it identifies the thread when we context * switch back. This use of a dummy tls is only needed for the main thread, * which is expected to invoke the tls_init syscall from its crt code (before * main or much of libc can run). Other threads are spawned with the thread * pointer address as a parameter. */ tls_idx = NaClTlsAllocate(natp); if (NACL_TLS_INDEX_INVALID == tls_idx) { NaClLog(LOG_ERROR, "No tls for thread, num_thread %d\n", nap->num_threads); goto cleanup_free; } NaClThreadContextCtor(&natp->user, nap, usr_entry, usr_stack_ptr, tls_idx); NaClTlsSetTlsValue1(natp, user_tls1); NaClTlsSetTlsValue2(natp, user_tls2); natp->signal_stack = NULL; natp->exception_stack = 0; natp->exception_flag = 0; if (!NaClMutexCtor(&natp->mu)) { goto cleanup_free; } if (!NaClSignalStackAllocate(&natp->signal_stack)) { goto cleanup_mu; } if (!NaClMutexCtor(&natp->suspend_mu)) { goto cleanup_mu; } natp->suspend_state = NACL_APP_THREAD_TRUSTED; natp->suspended_registers = NULL; natp->fault_signal = 0; natp->dynamic_delete_generation = 0; return natp; cleanup_mu: NaClMutexDtor(&natp->mu); if (NULL != natp->signal_stack) { NaClSignalStackFree(&natp->signal_stack); natp->signal_stack = NULL; } cleanup_free: NaClAlignedFree(natp); return NULL; }
struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap, uintptr_t usr_entry, uintptr_t usr_stack_ptr, uint32_t user_tls1, uint32_t user_tls2) { struct NaClAppThread *natp; natp = NaClAlignedMalloc(sizeof *natp, __alignof(struct NaClAppThread)); if (natp == NULL) { return NULL; } NaClLog(4, " natp = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) natp); NaClLog(4, " nap = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) nap); NaClLog(4, "usr_stack_ptr = 0x%016"NACL_PRIxPTR"\n", usr_stack_ptr); /* * Set these early, in case NaClTlsAllocate() wants to examine them. */ natp->nap = nap; natp->thread_num = -1; /* illegal index */ natp->host_thread_is_defined = 0; memset(&natp->host_thread, 0, sizeof(natp->host_thread)); if (!NaClAppThreadInitArchSpecific(natp, usr_entry, usr_stack_ptr)) { goto cleanup_free; } NaClTlsSetTlsValue1(natp, user_tls1); NaClTlsSetTlsValue2(natp, user_tls2); natp->signal_stack = NULL; natp->exception_stack = 0; natp->exception_flag = 0; if (!NaClMutexCtor(&natp->mu)) { goto cleanup_free; } if (!NaClSignalStackAllocate(&natp->signal_stack)) { goto cleanup_mu; } if (!NaClMutexCtor(&natp->suspend_mu)) { goto cleanup_mu; } natp->suspend_state = NACL_APP_THREAD_TRUSTED; natp->suspended_registers = NULL; natp->fault_signal = 0; natp->dynamic_delete_generation = 0; if (!NaClCondVarCtor(&natp->futex_condvar)) { goto cleanup_suspend_mu; } return natp; cleanup_suspend_mu: NaClMutexDtor(&natp->suspend_mu); cleanup_mu: NaClMutexDtor(&natp->mu); if (NULL != natp->signal_stack) { NaClSignalStackFree(&natp->signal_stack); natp->signal_stack = NULL; } cleanup_free: NaClAlignedFree(natp); return NULL; }
int NaClAppThreadCtor(struct NaClAppThread *natp, struct NaClApp *nap, int is_privileged, uintptr_t usr_entry, uintptr_t usr_stack_ptr, uint32_t tls_idx, uintptr_t sys_tdb) { int rv; uint64_t thread_idx; struct NaClDescEffectorLdr *effp; NaClLog(4, " natp = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) natp); NaClLog(4, " nap = 0x%016"NACL_PRIxPTR"\n", (uintptr_t) nap); NaClLog(4, "usr_stack_ptr = 0x%016"NACL_PRIxPTR"\n", usr_stack_ptr); NaClThreadContextCtor(&natp->user, nap, usr_entry, usr_stack_ptr, tls_idx); effp = NULL; natp->signal_stack = NULL; if (!NaClMutexCtor(&natp->mu)) { return 0; } if (!NaClCondVarCtor(&natp->cv)) { goto cleanup_mutex; } natp->is_privileged = is_privileged; if (!NaClClosureResultCtor(&natp->result)) { goto cleanup_cv; } natp->sysret = 0; natp->nap = nap; effp = (struct NaClDescEffectorLdr *) malloc(sizeof *effp); if (NULL == effp) { goto cleanup_cv; } if (!NaClDescEffectorLdrCtor(effp, natp)) { goto cleanup_cv; } natp->effp = (struct NaClDescEffector *) effp; effp = NULL; if (!NaClSignalStackAllocate(&natp->signal_stack)) { goto cleanup_cv; } natp->holding_sr_locks = 0; natp->state = NACL_APP_THREAD_ALIVE; natp->thread_num = -1; /* illegal index */ natp->sys_tdb = sys_tdb; natp->dynamic_delete_generation = 0; thread_idx = NaClGetThreadIdx(natp); nacl_thread[thread_idx] = natp; nacl_user[thread_idx] = &natp->user; nacl_sys[thread_idx] = &natp->sys; rv = NaClThreadCtor(&natp->thread, NaClThreadLauncher, (void *) natp, NACL_KERN_STACK_SIZE); if (rv != 0) { return rv; /* Success */ } NaClClosureResultDtor(&natp->result); cleanup_cv: NaClCondVarDtor(&natp->cv); cleanup_mutex: NaClMutexDtor(&natp->mu); free(effp); natp->effp = NULL; if (NULL != natp->signal_stack) { NaClSignalStackFree(&natp->signal_stack); natp->signal_stack = NULL; } return 0; }