this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update darlingserver and libkqueue

We shouldn't use Darwin TLS keys (even direct ones) after the thread is
destroyed, so instead, we store the RPC FD in a Linux thread local
variable and use the new explicit RPC call wrappers added in
this updated darlingserver commit.

This commit also adds `_dup_4libkqueue`, used by libkqueue to duplicate
descriptors without having libsystem_kernel call back into it with
`kqueue_dup`.

+31 -17
-3
src/kernel/emulation/linux/bsdthread/bsdthread_create.c
··· 33 33 static const struct darling_thread_create_callbacks callbacks = { 34 34 .thread_self_trap = &thread_self_trap_impl, 35 35 .thread_set_tsd_base = &sys_thread_set_tsd_base, 36 - .dserver_rpc_checkin = &dserver_rpc_checkin, 37 - .dserver_rpc_checkout = &dserver_rpc_checkout, 38 - .kprintf = &__simple_kprintf, 39 36 }; 40 37 41 38 long sys_bsdthread_create(void* thread_start, void* arg,
-3
src/kernel/emulation/linux/bsdthread/workq_kernreturn.c
··· 94 94 static const struct darling_thread_create_callbacks callbacks = { 95 95 .thread_self_trap = &thread_self_trap_impl, 96 96 .thread_set_tsd_base = &sys_thread_set_tsd_base, 97 - .dserver_rpc_checkin = &dserver_rpc_checkin, 98 - .dserver_rpc_checkout = &dserver_rpc_checkout, 99 - .kprintf = &__simple_kprintf, 100 97 }; 101 98 102 99 static int extract_wq_flags(int priority) {
+12
src/kernel/emulation/linux/ext/for-libkqueue.c
··· 1 1 #include "for-libkqueue.h" 2 2 #include <darlingserver/rpc.h> 3 + #include <linux-syscalls/linux.h> 4 + #include "../errno.h" 3 5 4 6 int _dserver_rpc_kqchan_mach_port_open_4libkqueue(uint32_t port_name, void* receive_buffer, uint64_t receive_buffer_size, uint64_t saved_filter_flags, int* out_socket) { 5 7 return dserver_rpc_kqchan_mach_port_open(port_name, receive_buffer, receive_buffer_size, saved_filter_flags, out_socket); ··· 8 10 int _dserver_rpc_kqchan_proc_open_4libkqueue(int32_t pid, uint32_t flags, int* out_socket) { 9 11 return dserver_rpc_kqchan_proc_open(pid, flags, out_socket); 10 12 }; 13 + 14 + int _dup_4libkqueue(int fd) { 15 + int ret; 16 + 17 + ret = LINUX_SYSCALL1(__NR_dup, fd); 18 + if (ret < 0) 19 + ret = errno_linux_to_bsd(ret); 20 + 21 + return ret; 22 + };
+3
src/kernel/emulation/linux/ext/for-libkqueue.h
··· 11 11 VISIBLE 12 12 int _dserver_rpc_kqchan_proc_open_4libkqueue(int32_t pid, uint32_t flags, int* out_socket); 13 13 14 + VISIBLE 15 + int _dup_4libkqueue(int fd); 16 + 14 17 #endif // _DARLING_EMULATION_FOR_LIBKQUEUE_H_
-3
src/startup/mldr/elfcalls/elfcalls.h
··· 7 7 struct darling_thread_create_callbacks { 8 8 int (*thread_self_trap)(void); 9 9 void (*thread_set_tsd_base)(void*, int); 10 - int (*dserver_rpc_checkin)(bool is_fork); 11 - int (*dserver_rpc_checkout)(int exec_listener_pipe, bool executing_macho); 12 - void (*kprintf)(const char* format, ...); 13 10 }; 14 11 15 12 typedef const struct darling_thread_create_callbacks* darling_thread_create_callbacks_t;
+16 -8
src/startup/mldr/elfcalls/threads.c
··· 43 43 static __thread jmp_buf t_jmpbuf; 44 44 static __thread void* t_freeaddr; 45 45 static __thread size_t t_freesize; 46 - static __thread darling_thread_create_callbacks_t t_callbacks = NULL; 46 + static __thread int t_server_socket = -1; 47 47 48 48 typedef void (*thread_ep)(void**, int, ...); 49 49 struct arg_struct ··· 234 234 // the socket is ready; assign it now 235 235 dthread->tsd[DTHREAD_TSD_SLOT_DSERVER_RPC_FD] = (void*)(intptr_t)new_rpc_fd; 236 236 237 - t_callbacks = args.callbacks; 237 + t_server_socket = new_rpc_fd; 238 238 239 239 // libpthread now expects the kernel to set the TSD 240 240 // so, since we're pretending to be the kernel handling threads... 241 - t_callbacks->thread_set_tsd_base(&dthread->tsd[0], 0); 241 + args.callbacks->thread_set_tsd_base(&dthread->tsd[0], 0); 242 242 *flags |= args.is_workqueue ? DWQ_FLAG_THREAD_TSD_BASE_SET : DTHREAD_START_TSD_BASE_SET; 243 243 244 244 // now that we've set the TSD, darlingserver RPC can now use our per-thread socket; 245 245 // let's check-in with darlingserver on this new thread 246 - if (t_callbacks->dserver_rpc_checkin(false) < 0) { 246 + if (dserver_rpc_explicit_checkin(t_server_socket, false) < 0) { 247 247 // we can't do ANYTHING if darlingserver doesn't acknowledge us successfully 248 248 abort(); 249 249 } 250 250 251 - int thread_self_port = t_callbacks->thread_self_trap(); 251 + int thread_self_port = args.callbacks->thread_self_trap(); 252 252 dthread->tsd[DTHREAD_TSD_SLOT_MACH_THREAD_SELF] = (void*)(intptr_t)thread_self_port; 253 253 args.port = thread_self_port; 254 254 ··· 309 309 int __darling_thread_terminate(void* stackaddr, 310 310 unsigned long freesize, unsigned long pthobj_size) 311 311 { 312 - if ((t_callbacks ? t_callbacks->dserver_rpc_checkout : dserver_rpc_checkout)(-1, false) < 0) { 312 + int checkout_result = 0; 313 + 314 + if (t_server_socket != -1) { 315 + checkout_result = dserver_rpc_explicit_checkout(t_server_socket, -1, false); 316 + } else { 317 + checkout_result = dserver_rpc_checkout(-1, false); 318 + } 319 + 320 + if (checkout_result < 0) { 313 321 // failing to check-out is not fatal. 314 322 // it's not ideal, but it's not fatal. 315 323 #define CHECKOUT_FAILURE_MESSAGE "Failed to checkout" 316 - if (t_callbacks) { 317 - t_callbacks->kprintf(CHECKOUT_FAILURE_MESSAGE); 324 + if (t_server_socket != -1) { 325 + dserver_rpc_explicit_kprintf(t_server_socket, CHECKOUT_FAILURE_MESSAGE, sizeof(CHECKOUT_FAILURE_MESSAGE) - 1); 318 326 } else { 319 327 dserver_rpc_kprintf(CHECKOUT_FAILURE_MESSAGE, sizeof(CHECKOUT_FAILURE_MESSAGE) - 1); 320 328 }