| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 The Native Client Authors. All rights reserved. | 2 * Copyright 2014 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 #include <errno.h> | 7 #include <errno.h> |
| 8 | 8 |
| 9 #include "native_client/src/nonsfi/linux/linux_syscall_defines.h" | 9 #include "native_client/src/nonsfi/linux/linux_syscall_defines.h" |
| 10 #include "native_client/src/nonsfi/linux/linux_syscall_structs.h" | 10 #include "native_client/src/nonsfi/linux/linux_syscall_structs.h" |
| 11 #include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h" | 11 #include "native_client/src/nonsfi/linux/linux_syscall_wrappers.h" |
| 12 #include "native_client/src/nonsfi/linux/linux_sys_private.h" | 12 #include "native_client/src/nonsfi/linux/linux_sys_private.h" |
| 13 #include "native_client/src/public/linux_syscalls/sched.h" | 13 #include "native_client/src/public/linux_syscalls/sched.h" |
| 14 #include "native_client/src/public/linux_syscalls/sys/syscall.h" | 14 #include "native_client/src/public/linux_syscalls/sys/syscall.h" |
| 15 #include "native_client/src/untrusted/nacl/nacl_irt.h" | 15 #include "native_client/src/untrusted/nacl/nacl_irt.h" |
| 16 #include "native_client/src/untrusted/nacl/nacl_thread.h" | 16 #include "native_client/src/untrusted/nacl/nacl_thread.h" |
| 17 #include "native_client/src/untrusted/pthread/pthread_internal.h" | 17 #include "native_client/src/untrusted/pthread/pthread_internal.h" |
| 18 | 18 |
| 19 /* Convert a return value of a Linux syscall to the one of an IRT call. */ | 19 /* Convert a return value of a Linux syscall to the one of an IRT call. */ |
| 20 static uint32_t irt_return_call(uintptr_t result) { | 20 static uint32_t irt_return_call(uintptr_t result) { |
| 21 if (linux_is_error_result(result)) | 21 if (linux_is_error_result(result)) |
| 22 return -result; | 22 return -result; |
| 23 return 0; | 23 return 0; |
| 24 } | 24 } |
| 25 | 25 |
| 26 static int nacl_irt_thread_create(void (*start_func)(void), void *stack, | 26 static int nacl_irt_thread_create(void (*start_func)(void), void *stack, |
| 27 void *thread_ptr) { | 27 void *thread_ptr, |
| 28 nacl_irt_tid_t *child_tid) { |
| 28 /* | 29 /* |
| 29 * We do not use CLONE_CHILD_CLEARTID as we do not want any | 30 * We do not use CLONE_CHILD_CLEARTID as we do not want any |
| 30 * non-private futex signaling. Also, NaCl ABI does not require us | 31 * non-private futex signaling. Also, NaCl ABI does not require us |
| 31 * to signal the futex on stack_flag. | 32 * to signal the futex on stack_flag. |
| 32 */ | 33 */ |
| 33 int flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | | 34 int flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | |
| 34 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS); | 35 CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | |
| 36 CLONE_PARENT_SETTID); |
| 35 /* | 37 /* |
| 36 * linux_clone_wrapper expects start_func's type is "int (*)(void *)". | 38 * linux_clone_wrapper expects start_func's type is "int (*)(void *)". |
| 37 * Although |start_func| has type "void (*)(void)", the type mismatching | 39 * Although |start_func| has type "void (*)(void)", the type mismatching |
| 38 * will not cause a problem. Passing a dummy |arg| (= 0) does nothing there. | 40 * will not cause a problem. Passing a dummy |arg| (= 0) does nothing there. |
| 39 * Also, start_func will never return. | 41 * Also, start_func will never return. |
| 40 */ | 42 */ |
| 41 return irt_return_call(linux_clone_wrapper( | 43 return irt_return_call(linux_clone_wrapper( |
| 42 (uintptr_t) start_func, /* arg */ 0, flags, stack, | 44 (uintptr_t) start_func, /* arg */ 0, flags, stack, |
| 43 /* ptid */ NULL, thread_ptr, /* ctid */ NULL)); | 45 child_tid, thread_ptr, /* ctid */ NULL)); |
| 44 } | 46 } |
| 45 | 47 |
| 46 static void nacl_irt_thread_exit(int32_t *stack_flag) { | 48 static void nacl_irt_thread_exit(int32_t *stack_flag) { |
| 47 /* | 49 /* |
| 48 * We fill zero to stack_flag by ourselves instead of relying | 50 * We fill zero to stack_flag by ourselves instead of relying |
| 49 * on CLONE_CHILD_CLEARTID. We do everything in the following inline | 51 * on CLONE_CHILD_CLEARTID. We do everything in the following inline |
| 50 * assembly because we need to make sure we will never touch stack. | 52 * assembly because we need to make sure we will never touch stack. |
| 51 * | 53 * |
| 52 * We will set the stack pointer to zero at the beginning of the | 54 * We will set the stack pointer to zero at the beginning of the |
| 53 * assembly code just in case an async signal arrives after setting | 55 * assembly code just in case an async signal arrives after setting |
| (...skipping 19 matching lines...) Expand all Loading... |
| 73 #else | 75 #else |
| 74 # error Unsupported architecture | 76 # error Unsupported architecture |
| 75 #endif | 77 #endif |
| 76 } | 78 } |
| 77 | 79 |
| 78 static int nacl_irt_thread_nice(const int nice) { | 80 static int nacl_irt_thread_nice(const int nice) { |
| 79 return 0; | 81 return 0; |
| 80 } | 82 } |
| 81 | 83 |
| 82 void __nc_initialize_interfaces(void) { | 84 void __nc_initialize_interfaces(void) { |
| 83 const struct nacl_irt_thread init = { | 85 const struct nacl_irt_thread_v0_2 init = { |
| 84 nacl_irt_thread_create, | 86 nacl_irt_thread_create, |
| 85 nacl_irt_thread_exit, | 87 nacl_irt_thread_exit, |
| 86 nacl_irt_thread_nice, | 88 nacl_irt_thread_nice, |
| 87 }; | 89 }; |
| 88 __libnacl_irt_thread = init; | 90 __libnacl_irt_thread = init; |
| 89 } | 91 } |
| OLD | NEW |