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 |