this repo has no description
1
fork

Configure Feed

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

At least the basic stuff in LLDB works again

+494 -80
-2
src/dyld/src/dyldAPIs.cpp
··· 125 125 126 126 #ifdef DARLING 127 127 extern "C" int mach_driver_get_fd(void); 128 - extern "C" bool darling_am_i_ptraced(void); 129 128 #endif 130 129 131 130 // In 10.3.x and earlier all the NSObjectFileImage API's were implemeneted in libSystem.dylib ··· 261 260 #endif 262 261 #ifdef DARLING 263 262 {"__dyld_get_mach_driver_fd", (void*)mach_driver_get_fd }, 264 - {"__dyld_am_i_ptraced", (void*)darling_am_i_ptraced }, 265 263 #endif 266 264 #pragma clang diagnostic pop 267 265 #endif //DEPRECATED_APIS_SUPPORTED
+2 -2
src/kernel/emulation/linux/bsdthread/bsdthread_create.c
··· 42 42 pthread = stack = thread_stack_allocate(stacksize); 43 43 } 44 44 45 - ret = darling_thread_create((void**) stack, pthread_entry_point, thread_start, 45 + ret = darling_thread_create((void**) stack, pthread_entry_point_wrapper, thread_start, 46 46 arg, stacksize, flags); 47 47 #else 48 48 // Implemented in libdyld 49 49 extern int thread_self_trap(void); 50 50 51 51 return __darling_thread_create(((uintptr_t)stack), pthread_obj_size, 52 - pthread_entry_point, thread_start, arg, (uintptr_t) stack, flags, 52 + pthread_entry_point_wrapper, thread_start, arg, (uintptr_t) stack, flags, 53 53 thread_self_trap); 54 54 #endif 55 55
+14
src/kernel/emulation/linux/bsdthread/bsdthread_register.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include "../../../../../platform-include/sys/errno.h" 5 + #include "../signal/sigexc.h" 5 6 #include <linux-syscalls/linux.h> 6 7 7 8 int pthread_obj_size; ··· 24 25 | PTHREAD_FEATURE_DISPATCHFUNC | PTHREAD_FEATURE_QOS_DEFAULT */ 0; 25 26 } 26 27 28 + void pthread_entry_point_wrapper(void* self, int thread_port, void* funptr, 29 + void* funarg, unsigned long stacksize, unsigned int flags) 30 + { 31 + sigexc_thread_setup(); 32 + pthread_entry_point(self, thread_port, funptr, funarg, stacksize, flags); 33 + } 34 + 35 + void wqueue_entry_point_wrapper(void* self, int thread_port, void* stackaddr, 36 + void* item, int reuse, int nevents) 37 + { 38 + sigexc_thread_setup(); 39 + wqueue_entry_point(self, thread_port, stackaddr, item, reuse, nevents); 40 + }
+4
src/kernel/emulation/linux/bsdthread/bsdthread_register.h
··· 11 11 12 12 long sys_bsdthread_register(void* thread_start, void* wqthread, int pthsize, 13 13 void* dummy, void* targetconc, unsigned long long dpq_offset); 14 + void pthread_entry_point_wrapper(void* self, int thread_port, void* funptr, 15 + void* funarg, unsigned long stacksize, unsigned int flags); 16 + void wqueue_entry_point_wrapper(void* self, int thread_port, void* stackaddr, 17 + void* item, int reuse, int nevents); 14 18 15 19 #endif 16 20
+1 -1
src/kernel/emulation/linux/bsdthread/workq_kernreturn.c
··· 246 246 // __simple_printf("Spawning a new thread, nevents=%d\n", (wq_event != NULL) ? wq_event->nevents : -1); 247 247 wq_event_pending = wq_event; 248 248 249 - __darling_thread_create(512*1024, pthread_obj_size, wqueue_entry_point, 0, 249 + __darling_thread_create(512*1024, pthread_obj_size, wqueue_entry_point_wrapper, 0, 250 250 (wq_event != NULL) ? wq_event->events : NULL, flags, 251 251 (wq_event != NULL) ? wq_event->nevents : 0, 252 252 thread_self_trap);
+24 -21
src/kernel/emulation/linux/misc/ptrace.c
··· 63 63 ret = lkm_call(NR_set_tracer, &args); 64 64 if (ret < 0) 65 65 ret = errno_linux_to_bsd(ret); 66 - else 67 - { 68 - // This triggers darling_sigexc_self() in the remote process. 69 - ret = linux_sigqueue(pid, SIGNAL_SIGEXC_TOGGLE, SIGRT_MAGIC_ENABLE_SIGEXC); 70 66 71 - if (ret < 0) 72 - ret = errno_linux_to_bsd(ret); 73 - // This doesn't work if the process is stopped, e.g. when spawning a stopped 74 - // process via posix_spawn(). So now we have to resume the process so that 75 - // it gets the RT signal above and triggers a fake SIGSTOP on its own. 76 - // int pstate = lkm_call(NR_pid_get_state, (void*)(long) pid); 77 - // if (pstate & 4 /* __TASK_STOPPED */) 78 - // sys_kill(pid, SIGCONT, 1); 79 - } 67 + sys_kill(pid, SIGSTOP, 1); 68 + 69 + struct ptrace_sigexc_args args2; 70 + args2.pid = pid; 71 + args2.sigexc = 1; 72 + 73 + ret = lkm_call(NR_ptrace_sigexc, &args2); 80 74 81 75 cmd = "PT_ATTACHEXC"; 82 76 break; ··· 105 99 case PT_DETACH: 106 100 { 107 101 // Tell the tracee to restore original application signal handlers. 108 - linux_sigqueue(pid, SIGNAL_SIGEXC_TOGGLE, SIGRT_MAGIC_DISABLE_SIGEXC); 102 + //linux_sigqueue(pid, SIGNAL_SIGEXC_TOGGLE, SIGRT_MAGIC_DISABLE_SIGEXC); 103 + 104 + //ret = 0; //LINUX_SYSCALL(__NR_ptrace, LINUX_PTRACE_DETACH, pid, addr, data); 105 + struct ptrace_sigexc_args args; 106 + args.pid = pid; 107 + args.sigexc = 0; 109 108 110 - ret = 0; //LINUX_SYSCALL(__NR_ptrace, LINUX_PTRACE_DETACH, pid, addr, data); 109 + ret = lkm_call(NR_ptrace_sigexc, &args); 111 110 112 111 // if (ret < 0) 113 112 // ret = errno_linux_to_bsd(ret); ··· 118 117 case PT_SIGEXC: 119 118 { 120 119 lkm_call(0x1028, "sigexc: self via ptrace\n"); 121 - darling_sigexc_self(); 122 - ret = 0; 120 + 121 + struct ptrace_sigexc_args args; 122 + args.pid = getpid(); 123 + args.sigexc = 1; 124 + 125 + ret = lkm_call(NR_ptrace_sigexc, &args); 123 126 124 127 // return ret; 125 128 cmd = "PT_SIGEXC"; break; ··· 148 151 if (tid < 0) 149 152 return -ESRCH; 150 153 151 - int signal = 0; 152 - if (data != -1) 153 - signal = signum_bsd_to_linux(data); 154 + struct ptrace_thupdate_args args; 155 + args.tid = tid; 156 + args.signum = data; 154 157 155 - ret = linux_sigqueue_thread(pid, tid, SIGNAL_SIGEXC_THUPDATE, signal); 158 + ret = lkm_call(NR_ptrace_thupdate, &args); 156 159 if (ret < 0) 157 160 ret = errno_linux_to_bsd(ret); 158 161
+2 -2
src/kernel/emulation/linux/process/execve.c
··· 119 119 } 120 120 121 121 linux_sigset_t set; 122 - set = (1ull << (SIGNAL_SIGEXC_TOGGLE-1)); 123 - set |= (1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 122 + set = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)); 123 + //set |= (1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 124 124 125 125 LINUX_SYSCALL(__NR_rt_sigprocmask, 0 /* LINUX_SIG_BLOCK */, 126 126 &set, NULL, sizeof(linux_sigset_t));
+110 -10
src/kernel/emulation/linux/signal/sigaction.c
··· 17 17 18 18 // Libc uses only one trampoline 19 19 void (*sa_tramp)(void*, int, int, struct bsd_siginfo*, void*) = 0; 20 - bsd_sig_handler* sig_handlers[32]; 20 + bsd_sig_handler* sig_handlers[32] = { 21 + [LINUX_SIGWINCH] = (bsd_sig_handler*) SIG_IGN, 22 + [LINUX_SIGCHLD] = (bsd_sig_handler*) SIG_IGN, 23 + [LINUX_SIGURG] = (bsd_sig_handler*) SIG_IGN, 24 + }; 21 25 int sig_flags[32]; 22 26 unsigned int sig_masks[32]; 23 27 ··· 41 45 return 0; 42 46 } 43 47 44 - ret = 0; 48 + if (nsa != NULL && linux_signum == LINUX_SIGCHLD) 49 + { 50 + sa_tramp = nsa->sa_tramp; 51 + if (nsa->sa_sigaction != SIG_DFL && nsa->sa_sigaction != SIG_IGN 52 + && nsa->sa_sigaction != SIG_ERR) 53 + { 54 + sa.sa_sigaction = &handler_linux_to_bsd; 55 + } 56 + else 57 + sa.sa_sigaction = (linux_sig_handler*) nsa->sa_sigaction; 58 + 59 + sigset_bsd_to_linux(&nsa->sa_mask, &sa.sa_mask); 60 + sa.sa_flags = sigflags_bsd_to_linux(nsa->sa_flags) | LINUX_SA_RESTORER; 61 + sa.sa_restorer = sig_restorer; 62 + 63 + ret = LINUX_SYSCALL(__NR_rt_sigaction, linux_signum, 64 + (nsa != NULL) ? &sa : NULL, &olsa, 65 + sizeof(sa.sa_mask)); 66 + 67 + if (ret < 0) 68 + return errno_linux_to_bsd(ret); 69 + 70 + if (osa != NULL) 71 + { 72 + if (olsa.sa_sigaction == handler_linux_to_bsd) 73 + osa->sa_sigaction = sig_handlers[linux_signum]; 74 + else // values such as SIG_DFL 75 + osa->sa_sigaction = (bsd_sig_handler*) olsa.sa_sigaction; 76 + sigset_linux_to_bsd(&olsa.sa_mask, &osa->sa_mask); 77 + osa->sa_flags = sigflags_linux_to_bsd(olsa.sa_flags); 78 + } 79 + } 80 + else 81 + { 82 + ret = 0; 83 + 84 + if (osa != NULL) 85 + { 86 + osa->sa_sigaction = sig_handlers[linux_signum]; 87 + osa->sa_flags = sig_flags[linux_signum]; 88 + osa->sa_mask = sig_masks[linux_signum]; 89 + } 90 + } 91 + 92 + if (nsa != NULL && ret >= 0) 93 + { 94 + // __simple_printf("Saving handler for signal %d: %p\n", linux_signum, nsa->sa_sigaction); 95 + sig_handlers[linux_signum] = nsa->sa_sigaction; 96 + sig_flags[linux_signum] = nsa->sa_flags; 97 + sig_masks[linux_signum] = nsa->sa_mask; 98 + } 99 + 100 + return 0; 101 + } 102 + 103 + #if 0 104 + long sys_sigaction(int signum, const struct bsd___sigaction* nsa, struct bsd_sigaction* osa) 105 + { 106 + int ret, linux_signum; 107 + struct linux_sigaction sa, olsa; 108 + 109 + linux_signum = signum_bsd_to_linux(signum); 110 + if (linux_signum == 0) 111 + { 112 + // Some software (e.g. Node.js) tries to set up handlers for all signals by 113 + // walking through all signal numbers incrementally. They end up hitting 114 + // signals that don't exist on Linux and then bail out if they receive 115 + // an error. 116 + // Fake that everyting is all right. 117 + 118 + if (osa != NULL) 119 + memset(osa, 0, sizeof(*osa)); 120 + 121 + return 0; 122 + } 123 + 124 + if (nsa != NULL) 125 + { 126 + sa_tramp = nsa->sa_tramp; 127 + /*if (darling_am_i_ptraced()) 128 + { 129 + sa.sa_sigaction = &sigexc_handler; 130 + } 131 + else*/ if (nsa->sa_sigaction != SIG_DFL && nsa->sa_sigaction != SIG_IGN 132 + && nsa->sa_sigaction != SIG_ERR) 133 + { 134 + sa.sa_sigaction = &handler_linux_to_bsd; 135 + } 136 + else 137 + sa.sa_sigaction = (linux_sig_handler*) nsa->sa_sigaction; 138 + 139 + sigset_bsd_to_linux(&nsa->sa_mask, &sa.sa_mask); 140 + sa.sa_flags = sigflags_bsd_to_linux(nsa->sa_flags) | LINUX_SA_RESTORER; 141 + sa.sa_restorer = sig_restorer; 142 + } 143 + 144 + ret = LINUX_SYSCALL(__NR_rt_sigaction, linux_signum, 145 + (nsa != NULL) ? &sa : NULL, &olsa, 146 + sizeof(sa.sa_mask)); 147 + if (ret < 0) 148 + return errno_linux_to_bsd(ret); 45 149 46 150 if (osa != NULL) 47 151 { 48 - /* 49 152 if (olsa.sa_sigaction == handler_linux_to_bsd) 50 153 osa->sa_sigaction = sig_handlers[linux_signum]; 51 154 else // values such as SIG_DFL 52 155 osa->sa_sigaction = (bsd_sig_handler*) olsa.sa_sigaction; 53 156 sigset_linux_to_bsd(&olsa.sa_mask, &osa->sa_mask); 54 157 osa->sa_flags = sigflags_linux_to_bsd(olsa.sa_flags); 55 - */ 56 - osa->sa_sigaction = sig_handlers[linux_signum]; 57 - osa->sa_flags = sig_flags[linux_signum]; 58 - osa->sa_mask = sig_masks[linux_signum]; 59 158 } 60 159 61 160 if (nsa != NULL && ret >= 0) 62 161 { 63 - // __simple_printf("Saving handler for signal %d: %p\n", linux_signum, nsa->sa_sigaction); 162 + // __simple_printf("Saving handler for signal %d: %d\n", linux_signum, nsa->sa_sigaction); 64 163 sig_handlers[linux_signum] = nsa->sa_sigaction; 65 - sig_flags[linux_signum] = nsa->sa_flags; 66 - sig_masks[linux_signum] = nsa->sa_mask; 164 + sig_flags[linux_signum] = sa.sa_flags; 165 + sig_masks[linux_signum] = sa.sa_mask; 67 166 } 68 167 69 168 return 0; 70 169 } 170 + #endif 71 171 72 172 static void ucontext_linux_to_bsd(const struct linux_ucontext* lc, struct bsd_ucontext* bc, struct bsd_mcontext* bm) 73 173 {
+334 -27
src/kernel/emulation/linux/signal/sigexc.c
··· 6 6 #include <sys/signal.h> 7 7 #include <linux-syscalls/linux.h> 8 8 #include <pthread/tsd_private.h> 9 - #include "signal/mach_exc.h" 10 - #include "signal/exc.h" 11 9 #include "sigaltstack.h" 12 10 #include "../mach/lkm.h" 13 11 #include "../../../../external/lkm/api.h" 14 12 #include "../../../libsyscall/wrappers/_libkernel_init.h" 13 + #include "../../../../../platform-include/sys/mman.h" 14 + #include "../mman/mman.h" 15 15 #include "kill.h" 16 16 #include "../simple.h" 17 17 ··· 32 32 33 33 #define SIGEXC_TSD_KEY 102 34 34 #define SIGEXC_CONTEXT_TSD_KEY 103 35 - static char sigexc_altstack[16*1024]; 36 - static struct bsd_stack orig_stack; 35 + static char sigexc_altstack[8*1024]; 37 36 38 37 #if defined(__x86_64__) 39 38 static void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state64_t* s); ··· 47 46 static void float_state_to_mcontext(const x86_float_state32_t* s, linux_fpregset_t fx); 48 47 #endif 49 48 50 - static void state_to_kernel(struct linux_ucontext* ctxt, thread_t thread); 49 + static void state_from_kernel(struct linux_ucontext* ctxt, const struct thread_state* kernel_state); 50 + static void state_to_kernel(struct linux_ucontext* ctxt, struct thread_state* kernel_state); 51 51 52 52 #define DEBUG_SIGEXC 53 53 #ifdef DEBUG_SIGEXC ··· 58 58 59 59 void sigexc_setup1(void) 60 60 { 61 - 61 + handle_rt_signal(SIGNAL_SIGEXC_SUSPEND); 62 62 } 63 63 64 64 void sigexc_setup2(void) 65 65 { 66 - 66 + linux_sigset_t set; 67 + set = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)); 68 + //set |= (1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 69 + 70 + LINUX_SYSCALL(__NR_rt_sigprocmask, 1 /* LINUX_SIG_UNBLOCK */, 71 + &set, NULL, sizeof(linux_sigset_t)); 72 + } 73 + 74 + static void dump_gregs(const struct linux_gregset* regs) 75 + { 76 + unsigned long long* p = (unsigned long long*) regs; 77 + for (int i = 0; i < 23; i++) 78 + { 79 + kern_printf("sigexc: gregs 0x%x\n", p[i]); 80 + } 81 + } 82 + 83 + static void handle_rt_signal(int signum) 84 + { 85 + int rv; 86 + struct linux_sigaction sa; 87 + 88 + sa.sa_sigaction = sigrt_handler; 89 + sa.sa_mask = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)); 90 + sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK; 91 + sa.sa_restorer = sig_restorer; 92 + 93 + rv = LINUX_SYSCALL(__NR_rt_sigaction, signum, 94 + &sa, NULL, 95 + sizeof(sa.sa_mask)); 96 + 97 + //char buf[128]; 98 + //__simple_sprintf(xyzbuf, "Setting handler for RT signal %d: %d", signum, rv); 99 + //external/lkm_call(0x1028, buf); 67 100 } 68 101 69 102 void sigexc_setup(void) 70 103 { 71 104 darling_sigexc_self(); 105 + sigexc_setup1(); 106 + sigexc_setup2(); 72 107 #ifdef VARIANT_DYLD 73 - 108 + if (lkm_call(NR_started_suspended, 0)) 109 + { 110 + kern_printf("sigexc: start_suspended -> suspending (ret to %p)\n", __builtin_return_address(0)); 111 + task_suspend(mach_task_self()); 112 + kern_printf("sigexc: start_suspended -> wokenup (ret to %p)\n", __builtin_return_address(0)); 113 + } 114 + else if (lkm_call(NR_get_tracer, NULL) != 0) 115 + { 116 + kern_printf("sigexc: already traced -> SIGTRAP\n"); 117 + sys_kill(0, SIGTRAP, 0); 118 + } 74 119 #else 75 120 76 121 #endif 77 122 } 78 123 124 + void sigrt_handler(int signum, struct linux_siginfo* info, void* ctxt) 125 + { 126 + #if defined(__x86_64__) 127 + x86_thread_state64_t tstate; 128 + x86_float_state64_t fstate; 129 + #elif defined(__i386__) 130 + x86_thread_state32_t tstate; 131 + x86_float_state32_t fstate; 132 + #endif 79 133 80 - bool darling_am_i_ptraced(void) 81 - { 82 - return am_i_ptraced; 134 + struct thread_suspended_args args; 135 + args.state.tstate = &tstate; 136 + args.state.fstate = &fstate; 137 + 138 + kern_printf("sigexc: sigrt_handler SUSPEND\n"); 139 + 140 + thread_t thread = mach_thread_self(); 141 + state_to_kernel(ctxt, &args.state); 142 + 143 + lkm_call(NR_thread_suspended, &args); 144 + 145 + state_from_kernel(ctxt, &args.state); 83 146 } 84 147 85 148 ··· 91 154 // Make sigexc_handler the handler for all signals in the process 92 155 for (int i = 1; i <= 31; i++) 93 156 { 94 - if (i == LINUX_SIGSTOP || i == LINUX_SIGKILL) 157 + if (i == LINUX_SIGSTOP || i == LINUX_SIGKILL || i == LINUX_SIGCHLD) 95 158 continue; 96 159 97 160 struct linux_sigaction sa; 98 161 sa.sa_sigaction = (linux_sig_handler*) sigexc_handler; 99 162 sa.sa_mask = 0x7fffffff; // all other standard Unix signals should be blocked while the handler is run 163 + sa.sa_mask |= (1ull << (SIGNAL_SIGEXC_SUSPEND-1)); 100 164 sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK; 101 165 sa.sa_restorer = sig_restorer; 102 166 ··· 110 174 .ss_size = sizeof(sigexc_altstack), 111 175 .ss_flags = 0 112 176 }; 113 - sys_sigaltstack(&newstack, &orig_stack); 177 + sys_sigaltstack(&newstack, NULL); 178 + } 179 + 180 + 181 + static void state_to_kernel(struct linux_ucontext* ctxt, struct thread_state* kernel_state) 182 + { 183 + #if defined(__x86_64__) 184 + 185 + dump_gregs(&ctxt->uc_mcontext.gregs); 186 + mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, (x86_thread_state64_t*) kernel_state->tstate); 187 + mcontext_to_float_state(ctxt->uc_mcontext.fpregs, (x86_float_state64_t*) kernel_state->fstate); 188 + 189 + #elif defined(__i386__) 190 + mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, (x86_thread_state32_t*) kernel_state->tstate); 191 + mcontext_to_float_state(ctxt->uc_mcontext.fpregs, (x86_float_state32_t*) kernel_state->fstate); 192 + #endif 193 + 114 194 } 115 195 116 - // syscall tracking 117 - #define LINUX_TRAP_BRKPT 1 118 - // single-stepping 119 - #define LINUX_TRAP_TRACE 2 120 - // ??? 121 - #define LINUX_TRAP_BRANCH 3 122 - // memory watchpoint 123 - #define LINUX_TRAP_HWBKPT 4 124 - // int3 (on x86, other platforms probably use TRAP_BRKPT) 125 - #define LINUX_SI_KERNEL 0x80 196 + static void state_from_kernel(struct linux_ucontext* ctxt, const struct thread_state* kernel_state) 197 + { 198 + #if defined(__x86_64__) 199 + 200 + thread_state_to_mcontext((x86_thread_state64_t*) kernel_state->tstate, &ctxt->uc_mcontext.gregs); 201 + float_state_to_mcontext((x86_float_state64_t*) kernel_state->fstate, ctxt->uc_mcontext.fpregs); 202 + 203 + dump_gregs(&ctxt->uc_mcontext.gregs); 204 + 205 + #elif defined(__i386__) 206 + thread_state_to_mcontext((x86_thread_state32_t*) kernel_state->tstate, &ctxt->uc_mcontext.gregs); 207 + float_state_to_mcontext((x86_float_state32_t*) kernel_state->fstate, ctxt->uc_mcontext.fpregs); 208 + #endif 209 + } 126 210 127 211 void sigexc_handler(int linux_signum, struct linux_siginfo* info, struct linux_ucontext* ctxt) 128 212 { ··· 143 227 sigprocess.signum = bsd_signum; 144 228 145 229 memcpy(&sigprocess.linux_siginfo, info, sizeof(*info)); 146 - memcpy(&sigprocess.linux_ucontext, ctxt, sizeof(*ctxt)); 147 230 231 + #ifdef __x86_64__ 232 + kern_printf("sigexc: have RIP 0x%x\n", ctxt->uc_mcontext.gregs.rip); 233 + #endif 234 + 235 + thread_t thread = mach_thread_self(); 236 + 237 + #if defined(__x86_64__) 238 + x86_thread_state64_t tstate; 239 + x86_float_state64_t fstate; 240 + #elif defined(__i386__) 241 + x86_thread_state32_t tstate; 242 + x86_float_state32_t fstate; 243 + #endif 244 + 245 + sigprocess.state.tstate = &tstate; 246 + sigprocess.state.fstate = &fstate; 247 + 248 + state_to_kernel(ctxt, &sigprocess.state); 148 249 lkm_call(NR_sigprocess, &sigprocess); 250 + state_from_kernel(ctxt, &sigprocess.state); 149 251 150 252 if (!sigprocess.signum) 151 253 { 152 254 kern_printf("sigexc: drop signal\n"); 153 255 return; 154 256 } 155 - 156 - memcpy(info, &sigprocess.linux_siginfo, sizeof(*info)); 157 - memcpy(ctxt, &sigprocess.linux_ucontext, sizeof(*ctxt)); 158 257 159 258 linux_signum = signum_bsd_to_linux(sigprocess.signum); 160 259 ··· 195 294 kern_printf("sigexc: handler (%d) returning\n", linux_signum); 196 295 } 197 296 297 + #define DUMPREG(regname) kern_printf("sigexc: " #regname ": 0x%x\n", regs->regname); 298 + 299 + #if defined(__x86_64__) 300 + void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state64_t* s) 301 + { 302 + s->__rax = regs->rax; 303 + s->__rbx = regs->rbx; 304 + s->__rcx = regs->rcx; 305 + s->__rdx = regs->rdx; 306 + s->__rdi = regs->rdi; 307 + s->__rsi = regs->rsi; 308 + s->__rbp = regs->rbp; 309 + s->__rsp = regs->rsp; 310 + s->__r8 = regs->r8; 311 + s->__r9 = regs->r9; 312 + s->__r10 = regs->r10; 313 + s->__r11 = regs->r11; 314 + s->__r12 = regs->r12; 315 + s->__r13 = regs->r13; 316 + s->__r14 = regs->r14; 317 + s->__r15 = regs->r15; 318 + s->__rip = regs->rip; 319 + s->__rflags = regs->efl; 320 + s->__cs = regs->cs; 321 + s->__fs = regs->fs; 322 + s->__gs = regs->gs; 323 + 324 + kern_printf("sigexc: saving to kernel:\n"); 325 + DUMPREG(rip); 326 + DUMPREG(efl); 327 + DUMPREG(rax); 328 + DUMPREG(rbx); 329 + DUMPREG(rcx); 330 + DUMPREG(rdx); 331 + DUMPREG(rdi); 332 + DUMPREG(rsi); 333 + DUMPREG(rbp); 334 + DUMPREG(rsp); 335 + } 336 + 337 + void mcontext_to_float_state(const linux_fpregset_t fx, x86_float_state64_t* s) 338 + { 339 + kern_printf("sigexc: fcw out: 0x%x", fx->cwd); 340 + kern_printf("sigexc: xmm0 out: 0x%x", fx->_xmm[0].element[0]); 341 + *((uint16_t*)&s->__fpu_fcw) = fx->cwd; 342 + *((uint16_t*)&s->__fpu_fsw) = fx->swd; 343 + s->__fpu_ftw = fx->ftw; 344 + s->__fpu_fop = fx->fop; 345 + s->__fpu_ip = fx->rip; 346 + s->__fpu_cs = 0; 347 + s->__fpu_dp = fx->rdp; 348 + s->__fpu_ds = 0; 349 + s->__fpu_mxcsr = fx->mxcsr; 350 + s->__fpu_mxcsrmask = fx->mxcr_mask; 351 + 352 + memcpy(&s->__fpu_stmm0, fx->_st, 128); 353 + memcpy(&s->__fpu_xmm0, fx->_xmm, 256); 354 + } 355 + 356 + void thread_state_to_mcontext(const x86_thread_state64_t* s, struct linux_gregset* regs) 357 + { 358 + regs->rax = s->__rax; 359 + regs->rbx = s->__rbx; 360 + regs->rcx = s->__rcx; 361 + regs->rdx = s->__rdx; 362 + regs->rdi = s->__rdi; 363 + regs->rsi = s->__rsi; 364 + regs->rbp = s->__rbp; 365 + regs->rsp = s->__rsp; 366 + regs->r8 = s->__r8; 367 + regs->r9 = s->__r9; 368 + regs->r10 = s->__r10; 369 + regs->r11 = s->__r11; 370 + regs->r12 = s->__r12; 371 + regs->r13 = s->__r13; 372 + regs->r14 = s->__r14; 373 + regs->r15 = s->__r15; 374 + regs->rip = s->__rip; 375 + regs->efl = s->__rflags; 376 + regs->cs = s->__cs; 377 + regs->fs = s->__fs; 378 + regs->gs = s->__gs; 379 + 380 + kern_printf("sigexc: restored from kernel:\n"); 381 + DUMPREG(rip); 382 + DUMPREG(efl); 383 + DUMPREG(rax); 384 + DUMPREG(rbx); 385 + DUMPREG(rcx); 386 + DUMPREG(rdx); 387 + DUMPREG(rdi); 388 + DUMPREG(rsi); 389 + DUMPREG(rbp); 390 + DUMPREG(rsp); 391 + } 392 + 393 + void float_state_to_mcontext(const x86_float_state64_t* s, linux_fpregset_t fx) 394 + { 395 + fx->cwd = *((uint16_t*)&s->__fpu_fcw); 396 + fx->swd = *((uint16_t*)&s->__fpu_fsw); 397 + fx->ftw = s->__fpu_ftw; 398 + fx->fop = s->__fpu_fop; 399 + fx->rip = s->__fpu_ip; 400 + fx->rdp = s->__fpu_dp; 401 + fx->mxcsr = s->__fpu_mxcsr; 402 + fx->mxcr_mask = s->__fpu_mxcsrmask; 403 + 404 + memcpy(fx->_st, &s->__fpu_stmm0, 128); 405 + memcpy(fx->_xmm, &s->__fpu_xmm0, 256); 406 + kern_printf("sigexc: fcw in: 0x%x", fx->cwd); 407 + kern_printf("sigexc: xmm0 in: 0x%x", fx->_xmm[0].element[0]); 408 + } 409 + 410 + #elif defined(__i386__) 411 + void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state32_t* s) 412 + { 413 + s->__eax = regs->eax; 414 + s->__ebx = regs->ebx; 415 + s->__ecx = regs->ecx; 416 + s->__edx = regs->edx; 417 + s->__edi = regs->edi; 418 + s->__esi = regs->esi; 419 + s->__ebp = regs->ebp; 420 + s->__esp = regs->esp; 421 + s->__ss = regs->ss; 422 + s->__eflags = regs->efl; 423 + s->__eip = regs->eip; 424 + s->__cs = regs->cs; 425 + s->__ds = regs->ds; 426 + s->__es = regs->es; 427 + s->__fs = regs->fs; 428 + s->__gs = regs->gs; 429 + } 430 + 431 + void mcontext_to_float_state(const linux_fpregset_t fx, x86_float_state32_t* s) 432 + { 433 + *((uint16_t*)&s->__fpu_fcw) = fx->cw; 434 + *((uint16_t*)&s->__fpu_fsw) = fx->sw; 435 + s->__fpu_ftw = fx->tag; 436 + s->__fpu_fop = 0; 437 + s->__fpu_ip = fx->ipoff; 438 + s->__fpu_cs = fx->cssel; 439 + s->__fpu_dp = fx->dataoff; 440 + s->__fpu_ds = fx->datasel; 441 + s->__fpu_mxcsr = fx->mxcsr; 442 + s->__fpu_mxcsrmask = 0; 443 + 444 + memcpy(&s->__fpu_stmm0, fx->_st, 128); 445 + memcpy(&s->__fpu_xmm0, fx->_xmm, 128); 446 + memset(((char*) &s->__fpu_xmm0) + 128, 0, 128); 447 + } 448 + 449 + void thread_state_to_mcontext(const x86_thread_state32_t* s, struct linux_gregset* regs) 450 + { 451 + regs->eax = s->__eax; 452 + regs->ebx = s->__ebx; 453 + regs->ecx = s->__ecx; 454 + regs->edx = s->__edx; 455 + regs->edi = s->__edi; 456 + regs->esi = s->__esi; 457 + regs->ebp = s->__ebp; 458 + regs->esp = s->__esp; 459 + regs->ss = s->__ss; 460 + regs->efl = s->__eflags; 461 + regs->eip = s->__eip; 462 + regs->cs = s->__cs; 463 + regs->ds = s->__ds; 464 + regs->es = s->__es; 465 + regs->fs = s->__fs; 466 + regs->gs = s->__gs; 467 + } 468 + 469 + void float_state_to_mcontext(const x86_float_state32_t* s, linux_fpregset_t fx) 470 + { 471 + fx->cw = *((uint16_t*)&s->__fpu_fcw); 472 + fx->sw = *((uint16_t*)&s->__fpu_fsw); 473 + fx->tag = s->__fpu_ftw; 474 + fx->ipoff = s->__fpu_ip; 475 + fx->cssel = s->__fpu_cs; 476 + fx->dataoff = s->__fpu_dp; 477 + fx->datasel = s->__fpu_ds; 478 + fx->mxcsr = s->__fpu_mxcsr; 479 + 480 + memcpy(fx->_st, &s->__fpu_stmm0, 128); 481 + memcpy(fx->_xmm, &s->__fpu_xmm0, 128); 482 + } 483 + #endif 484 + 485 + void sigexc_thread_setup(void) 486 + { 487 + struct bsd_stack newstack = { 488 + .ss_size = sizeof(sigexc_altstack), 489 + .ss_flags = 0 490 + }; 491 + 492 + newstack.ss_sp = (void*) sys_mmap(NULL, sizeof(sigexc_altstack), PROT_READ | PROT_WRITE, 493 + MAP_ANON | MAP_PRIVATE, -1, 0); 494 + sys_sigaltstack(&newstack, NULL); 495 + } 496 + 497 + void sigexc_thread_exit(void) 498 + { 499 + struct bsd_stack oldstack; 500 + sys_sigaltstack(NULL, &oldstack); 501 + 502 + sys_munmap(oldstack.ss_sp, oldstack.ss_flags); 503 + } 504 +
+3 -15
src/kernel/emulation/linux/signal/sigexc.h
··· 6 6 7 7 // NOTE: Keep these definitions up to date with lkm/darling/binfmt.c! 8 8 // Uses one of the below magic values to toggle the debugging state 9 - #define SIGNAL_SIGEXC_TOGGLE LINUX_SIGRTMIN 10 - 11 - // A BSD signal number is passed as value 12 - #define SIGNAL_SIGEXC_THUPDATE (LINUX_SIGRTMIN + 1) 13 - 14 - #define SIGNAL_THREAD_SUSPEND -100 15 - #define SIGNAL_THREAD_RESUME -101 16 - 17 - #define SIGRT_MAGIC_ENABLE_SIGEXC 0xdebdeb01 18 - #define SIGRT_MAGIC_DISABLE_SIGEXC 0xdebdeb00 9 + #define SIGNAL_SIGEXC_SUSPEND LINUX_SIGRTMIN 19 10 20 11 void sigexc_setup(void); 21 - 22 - // Is this process currently traced by a debugger? 23 - bool darling_am_i_ptraced(void); 24 12 25 13 // for PT_SIGEXC to handle this operation synchronously 26 14 void darling_sigexc_self(void); 27 15 void sigexc_handler(int linux_signum, struct linux_siginfo* info, struct linux_ucontext* ctxt); 28 16 29 - int linux_sigqueue(int pid, int rtsig, int value); 30 - int linux_sigqueue_thread(int pid, int tid, int rtsig, int value); 17 + void sigexc_thread_setup(void); 18 + void sigexc_thread_exit(void); 31 19 32 20 #endif 33 21