this repo has no description
1
fork

Configure Feed

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

Working threading (but psynch is not implemented yet)

+167 -52
+3
src/kernel/emulation/linux/CMakeLists.txt
··· 113 113 time/gettimeofday.c 114 114 time/utimes.c 115 115 time/futimes.c 116 + ioctl/ioctl.c 117 + # ioctl/termios.c 116 118 ext/uname.c 117 119 ext/epoll_create.c 118 120 ext/epoll_create1.c ··· 135 137 bsdthread/bsdthread_register.c 136 138 bsdthread/bsdthread_create.c 137 139 bsdthread/bsdthread_terminate.c 140 + bsdthread/disable_threadsignal.c 138 141 syscalls-amd64.asm 139 142 ) 140 143
+11 -9
src/kernel/emulation/linux/bsdthread/bsdthread_create.c
··· 7 7 #include <stdint.h> 8 8 #include "../../../../../platform-include/sys/mman.h" 9 9 #include "../mman/mman.h" 10 + #include "../simple.h" 10 11 11 12 extern void *memset(void *s, int c, size_t n); 12 13 ··· 35 36 stacksize = (unsigned long) stack; 36 37 37 38 // The pthread object is placed above stack area 38 - allocsize = stacksize + pthread_obj_size; 39 + allocsize = stacksize + pthread_obj_size + STACK_GUARD_SIZE; 39 40 allocsize = (allocsize + 4095) & ~4095; // round up to page size 40 41 41 42 stack = (void**) sys_mmap(NULL, allocsize, PROT_READ | PROT_WRITE, 42 43 MAP_ANON | MAP_PRIVATE, -1, 0); 43 44 45 + // Protect the stack guard 46 + sys_mprotect(stack, STACK_GUARD_SIZE, PROT_NONE); 47 + 44 48 if (((intptr_t)stack) < 0 && ((intptr_t)stack) >= -4095) 45 49 ret = errno_linux_to_bsd((int) stack); 46 50 47 - pthread = (void*) (((uintptr_t)stack) + stacksize); 48 - stack = (void**) (((uintptr_t)stack) + stacksize); 51 + pthread = (void*) (((uintptr_t)stack) + stacksize + STACK_GUARD_SIZE); 52 + stack = (void**) (((uintptr_t)stack) + stacksize + STACK_GUARD_SIZE); 49 53 } 50 54 51 55 #if defined(__x86_64__) ··· 66 70 "movl %%eax, %%esi\n" // thread_self is 2nd arg to pthread_entry_point 67 71 "movq %%rsp, %%rdi\n" // pthread_self as 1st arg 68 72 "movq -24(%%rsp), %%rdx\n" // thread_start as 3rd arg 69 - "movq -8(%%rsp), %%rcx\n" // stack_size as 4th arg 70 - "movq -32(%%rsp), %%r8\n" // thread arg as 5th arg 73 + "movq -8(%%rsp), %%r8\n" // stack_size as 5th arg 74 + "movq -32(%%rsp), %%rcx\n" // thread arg as 4th arg 71 75 "movq -16(%%rsp), %%r9\n" // flags as 6th arg 72 76 "movq -40(%%rsp), %%rbx\n" 73 - "addq $-0x10, %%rsp\n" // align the stack 74 - "call *%%rbx\n" 75 - "int3\n" 77 + "jmp *%%rbx\n" 76 78 "1:\n" 77 79 : "=a"(ret) 78 - : "0" (__NR_clone), "r"(pthread_entry_point), 80 + : "0" (__NR_clone), 79 81 "D"(LINUX_CLONE_THREAD | LINUX_CLONE_VM | LINUX_CLONE_SIGHAND 80 82 | LINUX_CLONE_FILES | LINUX_CLONE_FS | LINUX_CLONE_SYSVSEM), 81 83 "S"(stack));
+8 -11
src/kernel/emulation/linux/bsdthread/bsdthread_terminate.c
··· 5 5 #include <stddef.h> 6 6 #include <stdint.h> 7 7 8 + int bsdthread_terminate_trap( 9 + uintptr_t stackaddr, 10 + unsigned long freesize, 11 + int thread, 12 + int sem); 13 + 8 14 long sys_bsdthread_terminate(void* stackaddr, unsigned long freesize, int port, 9 15 int join_sem) 10 16 { 11 - long ret; 12 - 13 - ret = LINUX_SYSCALL(__NR_exit, 0); 14 - if (ret < 0) 15 - return errno_linux_to_bsd(ret); 16 - else 17 - { 18 - // TODO: signal join_sem 19 - } 20 - 21 - return ret; 17 + return bsdthread_terminate_trap((uintptr_t) stackaddr, freesize, 18 + port, join_sem); 22 19 } 23 20 24 21
+24
src/kernel/emulation/linux/bsdthread/disable_threadsignal.c
··· 1 + #include "disable_threadsignal.h" 2 + #include "../base.h" 3 + #include "../errno.h" 4 + #include "../signal/duct_signals.h" 5 + #include "../signal/sigprocmask.h" 6 + #include "../../../../../platform-include/sys/errno.h" 7 + #include <asm/unistd.h> 8 + #include <stddef.h> 9 + 10 + #ifndef SIG_BLOCK 11 + # define SIG_BLOCK 1 12 + #endif 13 + 14 + long sys_disable_threadsignal(int disable) 15 + { 16 + if (!disable) 17 + return -ENOTSUP; 18 + 19 + sigset_t set = ~0; 20 + 21 + // Signal config is per-thread on Linux 22 + return sys_sigprocmask(SIG_BLOCK, &set, NULL); 23 + } 24 +
+7
src/kernel/emulation/linux/bsdthread/disable_threadsignal.h
··· 1 + #ifndef DISABLE_THREADSIGNAL_H 2 + #define DISABLE_THREADSIGNAL_H 3 + 4 + long sys_disable_threadsignal(int disable); 5 + 6 + #endif 7 +
+2
src/kernel/emulation/linux/syscalls.c
··· 90 90 #include "bsdthread/bsdthread_register.h" 91 91 #include "bsdthread/bsdthread_create.h" 92 92 #include "bsdthread/bsdthread_terminate.h" 93 + #include "bsdthread/disable_threadsignal.h" 93 94 #include "hfs/stub.h" 94 95 #include "xattr/listxattr.h" 95 96 #include "xattr/flistxattr.h" ··· 208 209 [239] = sys_fremovexattr, 209 210 [240] = sys_listxattr, 210 211 [241] = sys_flistxattr, 212 + [331] = sys_disable_threadsignal, 211 213 [334] = sys_semwait_signal, 212 214 [338] = sys_stat64, 213 215 [339] = sys_fstat64,
-11
src/kernel/mach_server/client/lkm.c
··· 30 30 } 31 31 } 32 32 33 - // Emulated ioctl implementation 34 - int ioctl(int fd, int cmd, void* arg) 35 - { 36 - struct bsd_ioctl_args args = { 37 - .fd = fd, 38 - .request = cmd, 39 - .arg = arg 40 - }; 41 - 42 - return __real_ioctl(driver_fd, NR_bsd_ioctl_trap, &args); 43 - } 44 33
+17
src/kernel/mach_server/client/mach_traps.c
··· 535 535 return KERN_FAILURE; 536 536 } 537 537 538 + kern_return_t bsdthread_terminate_trap( 539 + uintptr_t stackaddr, 540 + unsigned long freesize, 541 + mach_port_name_t thread, 542 + mach_port_name_t sem) 543 + { 544 + struct bsdthread_terminate_args args = { 545 + .stackaddr = stackaddr, 546 + .freesize = freesize, 547 + .thread_right_name = thread, 548 + .signal = sem 549 + }; 550 + 551 + return ioctl(driver_fd, NR_bsdthread_terminate_trap, &args); 552 + } 553 + 554 +
+15 -5
src/lkm/api.h
··· 19 19 20 20 #ifndef LKM_API_H 21 21 #define LKM_API_H 22 + #include <stdint.h> 22 23 23 24 #define DARLING_MACH_API_VERSION 1 24 25 #define DARLING_MACH_API_VERSION_STR "1" ··· 41 42 NR_semaphore_timedwait_signal_trap, 42 43 NR_semaphore_timedwait_trap, 43 44 NR_bsd_ioctl_trap, 44 - NR_thread_self_trap 45 + NR_thread_self_trap, 46 + NR_bsdthread_terminate_trap, 45 47 }; 46 48 47 49 struct mach_port_mod_refs_args ··· 61 63 62 64 struct mach_msg_overwrite_args 63 65 { 64 - union { void* msg; long long pad; }; 66 + union { void* msg; uint64_t pad; }; 65 67 unsigned int option; 66 68 unsigned int send_size; 67 69 unsigned int recv_size; 68 70 unsigned int rcv_name; 69 71 unsigned int timeout; 70 72 unsigned int notify; 71 - union { void* rcv_msg; long long pad2; }; 73 + union { void* rcv_msg; uint64_t pad2; }; 72 74 unsigned int rcv_limit; 73 75 }; 74 76 ··· 123 125 struct bsd_ioctl_args 124 126 { 125 127 int fd; 126 - unsigned long long request; 127 - unsigned long long arg; 128 + uint64_t request; 129 + uint64_t arg; 130 + }; 131 + 132 + struct bsdthread_terminate_args 133 + { 134 + uint64_t stackaddr; 135 + uint32_t freesize; 136 + unsigned int thread_right_name; 137 + unsigned int signal; 128 138 }; 129 139 130 140 #endif
+3 -10
src/lkm/darling_task.c
··· 216 216 217 217 void darling_task_free_threads(mach_task_t* task) 218 218 { 219 - struct rb_node *node, *next; 220 - struct thread_entry* entry; 219 + struct thread_entry *entry, *n; 221 220 221 + debug_msg("darling_task_free_threads(%p)\n", task); 222 222 write_lock(&task->threads_lock); 223 223 224 - node = rb_first(&task->threads); 225 - while (node != NULL) 224 + rbtree_postorder_for_each_entry_safe(entry, n, &task->threads, node) 226 225 { 227 - entry = container_of(node, struct thread_entry, node); 228 - 229 226 ipc_port_put(entry->thread_port); 230 - 231 - next = rb_next(node); 232 - 233 227 kfree(entry); 234 - node = next; 235 228 } 236 229 237 230 task->threads.rb_node = NULL;
+23 -2
src/lkm/primitives/semaphore.c
··· 84 84 { 85 85 struct mach_semaphore* ms; 86 86 87 + debug_msg("mach_semaphore_signal(%p)\n", port); 87 88 if (port->server_port.port_type != PORT_TYPE_SEMAPHORE) 88 89 { 89 90 ipc_port_unlock(port); ··· 106 107 { 107 108 struct mach_semaphore* ms; 108 109 110 + debug_msg("mach_semaphore_signal_all(%p)\n", port); 109 111 if (port->server_port.port_type != PORT_TYPE_SEMAPHORE) 110 112 { 111 113 ipc_port_unlock(port); ··· 130 132 struct mach_semaphore* ms; 131 133 kern_return_t ret; 132 134 135 + debug_msg("mach_semaphore_wait(%p)\n", port); 133 136 if (port->server_port.port_type != PORT_TYPE_SEMAPHORE) 134 137 { 135 138 ipc_port_unlock(port); ··· 143 146 144 147 ret = KERN_SUCCESS; 145 148 146 - if (down_killable(&ms->sem) == -EINTR) 149 + if (down_interruptible(&ms->sem) == -EINTR) 147 150 { 148 151 ret = KERN_ABORTED; 149 152 } ··· 197 200 return -EINTR; 198 201 } 199 202 200 - static int down_timeout_interruptible(struct semaphore *sem, long timeout) 203 + static int __down_timeout_interruptible(struct semaphore *sem, long timeout) 201 204 { 202 205 return __down_common(sem, TASK_INTERRUPTIBLE, timeout); 203 206 } 204 207 208 + int down_timeout_interruptible(struct semaphore *sem, long timeout) 209 + { 210 + unsigned long flags; 211 + int result = 0; 212 + 213 + raw_spin_lock_irqsave(&sem->lock, flags); 214 + if (likely(sem->count > 0)) 215 + sem->count--; 216 + else 217 + result = __down_timeout_interruptible(sem, timeout); 218 + raw_spin_unlock_irqrestore(&sem->lock, flags); 219 + 220 + return result; 221 + } 222 + 223 + 205 224 kern_return_t 206 225 mach_semaphore_timedwait(darling_mach_port_t* port, unsigned int sec, 207 226 unsigned int nsec) ··· 211 230 int err; 212 231 unsigned long jiffies; 213 232 233 + debug_msg("mach_semaphore_timedwait(%p)\n", port); 214 234 if (port->server_port.port_type != PORT_TYPE_SEMAPHORE) 215 235 { 216 236 ipc_port_unlock(port); ··· 231 251 jiffies = nsecs_to_jiffies(((u64) sec) * NSEC_PER_SEC + nsec); 232 252 #endif 233 253 254 + debug_msg("down_timeout(jiffies=%d, pid=%d)\n", jiffies, current->pid); 234 255 err = down_timeout_interruptible(&ms->sem, jiffies); 235 256 if (err == -ETIME) 236 257 ret = KERN_OPERATION_TIMED_OUT;
+51 -4
src/lkm/traps.c
··· 28 28 #include <linux/file.h> 29 29 #include <linux/dcache.h> 30 30 #include <linux/kernel.h> 31 + #include <linux/mm.h> 31 32 #include "darling_task.h" 32 33 #include "traps.h" 33 34 #include "ipc_space.h" ··· 74 75 [sc(NR_semaphore_timedwait_trap)] = (trap_handler) semaphore_timedwait_trap, 75 76 [sc(NR_bsd_ioctl_trap)] = (trap_handler) bsd_ioctl_trap, 76 77 [sc(NR_thread_self_trap)] = (trap_handler) mach_thread_self_trap, 78 + [sc(NR_bsdthread_terminate_trap)] = (trap_handler) bsdthread_terminate_trap, 77 79 }; 78 80 #undef sc 79 81 ··· 294 296 ipc_port_lock(task->task_self); 295 297 296 298 thread_port = darling_task_lookup_thread(task, current->pid); 299 + if (thread_port == NULL) 300 + { 301 + if (ipc_port_new(&thread_port) != KERN_SUCCESS) 302 + { 303 + ipc_port_unlock(task->task_self); 304 + return KERN_RESOURCE_SHORTAGE; 305 + } 306 + 307 + ipc_port_make_thread(thread_port); 308 + darling_task_register_thread(task, thread_port); 309 + } 297 310 298 - if (thread_port != NULL) 299 - ret = ipc_space_make_send(&task->namespace, thread_port, false, &name); 300 - else 301 - ret = KERN_FAILURE; 311 + ret = ipc_space_make_send(&task->namespace, thread_port, false, &name); 302 312 303 313 ipc_port_unlock(task->task_self); 304 314 ··· 745 755 fput(f); 746 756 747 757 return retval; 758 + } 759 + 760 + kern_return_t bsdthread_terminate_trap(mach_task_t* task, 761 + struct bsdthread_terminate_args* in_args) 762 + { 763 + struct bsdthread_terminate_args args; 764 + darling_mach_port_right_t* sem; 765 + darling_mach_port_t* thread_self; 766 + 767 + if (copy_from_user(&args, in_args, sizeof(args))) 768 + return KERN_INVALID_ADDRESS; 769 + 770 + debug_msg("bsdthread_terminate_trap(), pid=%d\n", 771 + current->pid); 772 + ipc_space_lock(&task->namespace); 773 + 774 + sem = ipc_space_lookup(&task->namespace, args.signal); 775 + 776 + ipc_space_unlock(&task->namespace); 777 + 778 + // Signal threads calling pthread_join() 779 + if (PORT_IS_VALID(sem->port)) 780 + mach_semaphore_signal(sem->port); 781 + else 782 + debug_msg("Invalid semaphore %d!\n", args.signal); 783 + 784 + // Deallocate stack 785 + debug_msg("unmap %p, 0x%x bytes\n", args.stackaddr, args.freesize); 786 + vm_munmap(args.stackaddr, args.freesize); 787 + 788 + // Deregister thread 789 + // Here we assume that args.thread_right_name refers 790 + // to the current thread. 791 + thread_self = darling_task_lookup_thread(task, current->pid); 792 + darling_task_deregister_thread(task, thread_self); 793 + 794 + do_exit(0); 748 795 } 749 796 750 797 module_init(mach_init);
+3
src/lkm/traps.h
··· 57 57 struct semaphore_timedwait_signal_args* args); 58 58 long bsd_ioctl_trap(mach_task_t* task, struct bsd_ioctl_args* fd); 59 59 60 + kern_return_t bsdthread_terminate_trap(mach_task_t* task, 61 + struct bsdthread_terminate_args* args); 62 + 60 63 // Internal 61 64 kern_return_t _kernelrpc_mach_port_destroy(mach_task_t* task, 62 65 mach_port_name_t task_name, mach_port_name_t right_name);