this repo has no description
1
fork

Configure Feed

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

Hook up signal reprocessing

+60 -653
+7 -1
src/kernel/emulation/linux/signal/duct_signals.c
··· 62 62 return SIGUSR1; 63 63 case LINUX_SIGUSR2: 64 64 return SIGUSR2; 65 + // Hack! This is what we send instead of SIGSTOP to allow the target process to receive the signal 66 + // and pass it through the LKM. 67 + case LINUX_SIGSTKFLT: 68 + return SIGSTOP; 65 69 default: 66 70 return 0; 67 71 } ··· 102 106 case SIGURG: 103 107 return LINUX_SIGURG; 104 108 case SIGSTOP: 105 - return LINUX_SIGSTOP; 109 + // Hack! See above. 110 + //return LINUX_SIGSTOP; 111 + return LINUX_SIGSTKFLT; 106 112 case SIGTSTP: 107 113 return LINUX_SIGTSTP; 108 114 case SIGCONT:
+2 -2
src/kernel/emulation/linux/signal/kill.c
··· 16 16 17 17 // If we're stopping a process we're debugging, do an emulated SIGSTOP 18 18 // so that the tracee has a chance to talk to us before stopping. 19 - if (signum == SIGSTOP && pid > 0) 19 + /*if (signum == SIGSTOP && pid > 0) 20 20 { 21 21 int tracer = lkm_call(NR_get_tracer, (void*)(long)pid); 22 22 if (tracer == getpid()) ··· 24 24 linux_sigqueue(pid, SIGNAL_SIGEXC_THUPDATE, -LINUX_SIGSTOP); 25 25 return 0; 26 26 } 27 - } 27 + }*/ 28 28 29 29 linux_signum = signum_bsd_to_linux(signum); 30 30 if (!linux_signum)
+9 -28
src/kernel/emulation/linux/signal/sigaction.c
··· 41 41 return 0; 42 42 } 43 43 44 - if (nsa != NULL) 45 - { 46 - sa_tramp = nsa->sa_tramp; 47 - if (darling_am_i_ptraced()) 48 - { 49 - sa.sa_sigaction = &sigexc_handler; 50 - } 51 - else 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 - 64 - ret = LINUX_SYSCALL(__NR_rt_sigaction, linux_signum, 65 - (nsa != NULL) ? &sa : NULL, &olsa, 66 - sizeof(sa.sa_mask)); 67 - if (ret < 0) 68 - return errno_linux_to_bsd(ret); 44 + ret = 0; 69 45 70 46 if (osa != NULL) 71 47 { 48 + /* 72 49 if (olsa.sa_sigaction == handler_linux_to_bsd) 73 50 osa->sa_sigaction = sig_handlers[linux_signum]; 74 51 else // values such as SIG_DFL 75 52 osa->sa_sigaction = (bsd_sig_handler*) olsa.sa_sigaction; 76 53 sigset_linux_to_bsd(&olsa.sa_mask, &osa->sa_mask); 77 54 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]; 78 59 } 79 60 80 61 if (nsa != NULL && ret >= 0) 81 62 { 82 - // __simple_printf("Saving handler for signal %d: %d\n", linux_signum, nsa->sa_sigaction); 63 + // __simple_printf("Saving handler for signal %d: %p\n", linux_signum, nsa->sa_sigaction); 83 64 sig_handlers[linux_signum] = nsa->sa_sigaction; 84 - sig_flags[linux_signum] = sa.sa_flags; 85 - sig_masks[linux_signum] = sa.sa_mask; 65 + sig_flags[linux_signum] = nsa->sa_flags; 66 + sig_masks[linux_signum] = nsa->sa_mask; 86 67 } 87 68 88 69 return 0;
+42 -622
src/kernel/emulation/linux/signal/sigexc.c
··· 1 + #include "sigaction.h" 1 2 #include "sigexc.h" 2 3 #include "../base.h" 3 4 #include "../unistd/exit.h" ··· 31 32 32 33 #define SIGEXC_TSD_KEY 102 33 34 #define SIGEXC_CONTEXT_TSD_KEY 103 34 - static char sigexc_altstack[8192]; 35 + static char sigexc_altstack[16*1024]; 35 36 static struct bsd_stack orig_stack; 36 37 37 38 #if defined(__x86_64__) ··· 57 58 58 59 void sigexc_setup1(void) 59 60 { 60 - kern_printf("sigexc_setup1()"); 61 - // Setup handler for SIGNAL_SIGEXC_TOGGLE and SIGNAL_SIGEXC_THUPDATE 62 - handle_rt_signal(SIGNAL_SIGEXC_TOGGLE); 63 - handle_rt_signal(SIGNAL_SIGEXC_THUPDATE); 61 + 64 62 } 65 63 66 64 void sigexc_setup2(void) 67 65 { 68 - kern_printf("sigexc_setup2()\n"); 69 - 70 - linux_sigset_t set; 71 - set = (1ull << (SIGNAL_SIGEXC_TOGGLE-1)); 72 - set |= (1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 73 - 74 - LINUX_SYSCALL(__NR_rt_sigprocmask, 1 /* LINUX_SIG_UNBLOCK */, 75 - &set, NULL, sizeof(linux_sigset_t)); 76 - 77 - // If we have a tracer (i.e. we are a new process after execve), 78 - // enable sigexc handling and send SIGTRAP to self to allow 79 - // the debugger to handle this situation. 80 - if (!am_i_ptraced && lkm_call(NR_get_tracer, NULL) != 0) 81 - { 82 - kern_printf("sigexc: the parent is traced\n"); 83 - darling_sigexc_self(); 84 - sigexc_handler(LINUX_SIGTRAP, NULL, NULL); 85 - } 66 + 86 67 } 87 68 88 69 void sigexc_setup(void) 89 70 { 71 + darling_sigexc_self(); 90 72 #ifdef VARIANT_DYLD 91 - sigexc_setup1(); 92 - if (lkm_call(NR_started_suspended, 0)) 93 - { 94 - kern_printf("sigexc: waiting for signal\n"); 95 73 96 - // sigsuspend until resumed or debugger attached 97 - linux_sigset_t set = -1ll; 98 - set &= ~(1ull << (LINUX_SIGCONT-1)); 99 - set &= ~(1ull << (SIGNAL_SIGEXC_TOGGLE-1)); 100 - set &= ~(1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 101 - 102 - LINUX_SYSCALL(__NR_rt_sigsuspend, &set, 8); 103 - 104 - kern_printf("sigexc: done waiting for signal\n"); 105 - } 106 - sigexc_setup2(); 107 74 #else 108 - sigexc_setup1(); 109 - 110 - // get am_i_ptraced value from dyld 111 - bool (*is_traced)(void); 112 - _libkernel_functions->dyld_func_lookup("__dyld_am_i_ptraced", (void**) &is_traced); 113 - am_i_ptraced = is_traced(); 114 - 115 - if (am_i_ptraced) 116 - { 117 - // We have to take over from dyld's build of this file, because 118 - // we rely on having accurate signal handler information of the running application. 119 - kern_printf("sigexc: taking over sigexc handling\n"); 120 - darling_sigexc_self(); 121 - } 75 + 122 76 #endif 123 77 } 124 78 125 - static void handle_rt_signal(int signum) 126 - { 127 - int rv; 128 - struct linux_sigaction sa; 129 - 130 - sa.sa_sigaction = sigrt_handler; 131 - sa.sa_mask = 0; 132 - sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART; 133 - sa.sa_restorer = sig_restorer; 134 - 135 - rv = LINUX_SYSCALL(__NR_rt_sigaction, signum, 136 - &sa, NULL, 137 - sizeof(sa.sa_mask)); 138 - 139 - //char buf[128]; 140 - //__simple_sprintf(xyzbuf, "Setting handler for RT signal %d: %d", signum, rv); 141 - //external/lkm_call(0x1028, buf); 142 - } 143 79 144 80 bool darling_am_i_ptraced(void) 145 81 { 146 82 return am_i_ptraced; 147 83 } 148 84 149 - void sigrt_handler(int signum, struct linux_siginfo* info, void* ctxt) 150 - { 151 - kern_printf("sigexc: sigrt_handler signum=%d, si_value=%x\n", signum, info->si_value); 152 - 153 - if (signum == SIGNAL_SIGEXC_TOGGLE) 154 - { 155 - if (((uint32_t) info->si_value) == SIGRT_MAGIC_ENABLE_SIGEXC) 156 - { 157 - darling_sigexc_self(); 158 - 159 - // Stop on attach 160 - sigexc_handler(LINUX_SIGSTOP, NULL, (struct linux_ucontext*) ctxt); 161 - } 162 - else if (((uint32_t) info->si_value) == SIGRT_MAGIC_DISABLE_SIGEXC) 163 - { 164 - darling_sigexc_uninstall(); 165 - } 166 - } 167 - else if (signum == SIGNAL_SIGEXC_THUPDATE) 168 - { 169 - if (!am_i_ptraced) 170 - return; 171 - 172 - // Examine info->si_value 173 - // If 0, drop the signal 174 - // If >0, process the signal 175 - // If <0, introduce a new signal 176 - int sig = info->si_value; 177 - if (sig == SIGNAL_THREAD_SUSPEND) 178 - { 179 - kern_printf("sigexc: SIGNAL_THREAD_SUSPEND\n"); 180 - if (_pthread_getspecific_direct(SIGEXC_TSD_KEY) == 0) 181 - sigexc_fake_suspend(ctxt); 182 - else 183 - { 184 - kern_printf("sigexc: already suspended\n"); 185 - void* ctxt = _pthread_getspecific_direct(SIGEXC_CONTEXT_TSD_KEY); 186 - 187 - if (ctxt) 188 - { 189 - thread_t thread = mach_thread_self(); 190 - state_to_kernel(ctxt, thread); 191 - kern_printf("sigexc: state_to_kernel complete\n"); 192 - } 193 - } 194 - } 195 - else if (sig == SIGNAL_THREAD_RESUME) 196 - { 197 - kern_printf("sigexc: SIGNAL_THREAD_RESUME\n"); 198 - } 199 - else if (sig < 0) 200 - { 201 - // This is only used to pass a SIGSTOP to the traced process (from the debugger) 202 - // and have it passed back through the sigexc mechanism. 203 - // See sys_kill(). 204 - sigexc_handler(-sig, NULL, (struct linux_ucontext*) ctxt); 205 - } 206 - else 207 - { 208 - // This is the debugger telling us how to deal with the signal. 209 - _pthread_setspecific_direct(SIGEXC_TSD_KEY, sig); 210 - } 211 - } 212 - } 213 85 214 86 void darling_sigexc_self(void) 215 87 { ··· 240 112 }; 241 113 sys_sigaltstack(&newstack, &orig_stack); 242 114 } 243 - void darling_sigexc_uninstall(void) 244 - { 245 - am_i_ptraced = false; 246 - 247 - // __simple_printf("darling_sigexc_uninstall()\n"); 248 - for (int i = 1; i <= 31; i++) 249 - { 250 - if (i == LINUX_SIGSTOP || i == LINUX_SIGKILL) 251 - continue; 252 - 253 - struct linux_sigaction sa; 254 - 255 - if (sig_handlers[i] == SIG_DFL || sig_handlers[i] != SIG_IGN 256 - || sig_handlers[i] != SIG_ERR) 257 - { 258 - sa.sa_sigaction = (linux_sig_handler*) sig_handlers[i]; 259 - } 260 - else 261 - sa.sa_sigaction = &handler_linux_to_bsd; 262 - 263 - sa.sa_mask = sig_masks[i]; 264 - sa.sa_flags = sig_flags[i]; 265 - sa.sa_restorer = sig_restorer; 266 - 267 - LINUX_SYSCALL(__NR_rt_sigaction, i, 268 - &sa, NULL, 269 - sizeof(sa.sa_mask)); 270 - } 271 - 272 - sys_sigaltstack(&orig_stack, NULL); 273 - } 274 - 275 - static mach_port_t get_exc_port(int type, int* behavior) 276 - { 277 - mach_msg_type_number_t count = 0; 278 - exception_mask_t masks[EXC_TYPES_COUNT]; 279 - mach_port_t ports[EXC_TYPES_COUNT]; 280 - exception_behavior_t behaviors[EXC_TYPES_COUNT]; 281 - thread_state_flavor_t flavors[EXC_TYPES_COUNT]; 282 - 283 - kern_return_t result = task_get_exception_ports(mach_task_self(), 1 << type, 284 - masks, &count, ports, behaviors, flavors); 285 - 286 - if (result != KERN_SUCCESS) 287 - return 0; 288 - 289 - for (int i = 0; i < count; i++) 290 - { 291 - if (masks[i] & (1 << type)) 292 - { 293 - if (behavior != NULL) 294 - *behavior = behaviors[i]; 295 - return ports[i]; 296 - } 297 - } 298 - 299 - return 0; 300 - } 301 - 302 - static void state_to_kernel(struct linux_ucontext* ctxt, thread_t thread) 303 - { 304 - #if defined(__x86_64__) 305 - x86_thread_state64_t tstate; 306 - x86_float_state64_t fstate; 307 - 308 - if (ctxt != NULL) 309 - { 310 - mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, &tstate); 311 - mcontext_to_float_state(ctxt->uc_mcontext.fpregs, &fstate); 312 - /* 313 - #ifdef __x86_64__ 314 - if (bsd_signum == SIGTRAP) 315 - { 316 - uint8_t* rip = (uint8_t*) ctxt->uc_mcontext.gregs.rip; 317 - kern_printf("rip is %p\n", rip); 318 - kern_printf("Value at rip-1 on suspend: 0x%x\n", *(rip-1)); 319 - } 320 - #endif 321 - */ 322 - } 323 - else 324 - { 325 - memset(&tstate, 0, sizeof(tstate)); 326 - memset(&fstate, 0, sizeof(fstate)); 327 - } 328 - 329 - __simple_kprintf("sigexc: Telling kernel our RIP is %p\n", tstate.__rip); 330 - 331 - thread_set_state(thread, x86_THREAD_STATE64, (thread_state_t) &tstate, x86_THREAD_STATE64_COUNT); 332 - thread_set_state(thread, x86_FLOAT_STATE64, (thread_state_t) &fstate, x86_FLOAT_STATE64_COUNT); 333 - #elif defined(__i386__) 334 - x86_thread_state32_t tstate; 335 - x86_float_state32_t fstate; 336 - 337 - if (ctxt != NULL) 338 - { 339 - mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, &tstate); 340 - mcontext_to_float_state(ctxt->uc_mcontext.fpregs, &fstate); 341 - } 342 - else 343 - { 344 - memset(&tstate, 0, sizeof(tstate)); 345 - memset(&fstate, 0, sizeof(fstate)); 346 - } 347 - 348 - thread_set_state(thread, x86_THREAD_STATE32, (thread_state_t) &tstate, x86_THREAD_STATE32_COUNT); 349 - thread_set_state(thread, x86_FLOAT_STATE32, (thread_state_t) &fstate, x86_FLOAT_STATE32_COUNT); 350 - #endif 351 - 352 - } 353 - 354 - static void state_from_kernel(struct linux_ucontext* ctxt, thread_t thread) 355 - { 356 - #if defined(__x86_64__) 357 - x86_thread_state64_t tstate; 358 - x86_float_state64_t fstate; 359 - mach_msg_type_number_t count; 360 - 361 - count = x86_THREAD_STATE64_COUNT; 362 - thread_get_state(thread, x86_THREAD_STATE64, (thread_state_t) &tstate, &count); 363 - count = x86_FLOAT_STATE64_COUNT; 364 - thread_get_state(thread, x86_FLOAT_STATE64, (thread_state_t) &fstate, &count); 365 - 366 - thread_state_to_mcontext(&tstate, &ctxt->uc_mcontext.gregs); 367 - float_state_to_mcontext(&fstate, ctxt->uc_mcontext.fpregs); 368 - 369 - #elif defined(__i386__) 370 - x86_thread_state32_t tstate; 371 - x86_float_state32_t fstate; 372 - mach_msg_type_number_t count; 373 - 374 - count = x86_THREAD_STATE32_COUNT; 375 - thread_get_state(thread, x86_THREAD_STATE32, (thread_state_t) &tstate, &count); 376 - count = x86_FLOAT_STATE32_COUNT; 377 - thread_get_state(thread, x86_FLOAT_STATE32, (thread_state_t) &fstate, &count); 378 - 379 - thread_state_to_mcontext(&tstate, &ctxt->uc_mcontext.gregs); 380 - float_state_to_mcontext(&fstate, ctxt->uc_mcontext.fpregs); 381 - #endif 382 - } 383 - 384 - void sigexc_fake_suspend(struct linux_ucontext* ctxt) 385 - { 386 - if (_pthread_getspecific_direct(SIGEXC_TSD_KEY) != 0) 387 - return; 388 - thread_t thread = mach_thread_self(); 389 - 390 - kern_printf("sigexc_fake_suspend -> state_to_kernel\n"); 391 - state_to_kernel(ctxt, thread); 392 - 393 - linux_sigset_t set = -1ll; 394 - set &= ~(1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 395 - 396 - LINUX_SYSCALL(__NR_rt_sigsuspend, &set, 8); 397 - 398 - kern_printf("sigexc_fake_suspend -> state_from_kernel\n"); 399 - state_from_kernel(ctxt, thread); 400 - } 401 115 402 116 // syscall tracking 403 117 #define LINUX_TRAP_BRKPT 1 ··· 414 128 { 415 129 kern_printf("sigexc_handler(%d, %p, %p)\n", linux_signum, info, ctxt); 416 130 417 - if (!darling_am_i_ptraced()) 418 - { 419 - kern_printf("sigexc: NOT TRACED!\n"); 420 - return; 421 - } 422 - 131 + 423 132 if (linux_signum == LINUX_SIGCONT) 424 133 return; 425 134 426 - // Send a Mach message to the debugger. 427 - // The debugger may use ptrace(PT_THUPDATE) to change how the signal is processed. 428 - 429 - int mach_exception, behavior; 430 - long long codes[EXCEPTION_CODE_MAX] = { 0 }; 431 - mach_port_t port; 432 - thread_t thread = mach_thread_self(); 433 - 434 135 int bsd_signum = signum_linux_to_bsd(linux_signum); 435 136 if (bsd_signum <= 0) 436 137 { ··· 438 139 return; 439 140 } 440 141 441 - if (linux_signum == 11) 442 - { 443 - kern_printf("sigexc: faulting address: %p, code: %d\n", info->si_addr, info->si_code); 444 - } 142 + struct sigprocess_args sigprocess; 143 + sigprocess.signum = bsd_signum; 445 144 446 - // SIGSEGV + SIGBUS -> EXC_BAD_ACCESS 447 - // SIGTRAP -> EXC_BREAKPOINT 448 - // SIGILL -> EXC_BAD_INSTRUCTION 449 - // SIGFPE -> EXC_ARITHMETIC 450 - // * -> EXC_SOFTWARE with EXC_SOFT_SIGNAL (e.g. SIGSTOP) 145 + memcpy(&sigprocess.linux_siginfo, info, sizeof(*info)); 146 + memcpy(&sigprocess.linux_ucontext, ctxt, sizeof(*ctxt)); 451 147 452 - // Only real exceptions produced by the CPU get translated to these 453 - // Mach exceptions. The rest comes as EXC_SOFTWARE. 454 - if (info != NULL && info->si_code != 0) 455 - { 456 - switch (bsd_signum) 457 - { 458 - case SIGSEGV: 459 - mach_exception = EXC_BAD_ACCESS; 460 - codes[0] = EXC_I386_GPFLT; 461 - break; 462 - case SIGBUS: 463 - mach_exception = EXC_BAD_ACCESS; 464 - codes[0] = EXC_I386_ALIGNFLT; 465 - break; 466 - case SIGILL: 467 - mach_exception = EXC_BAD_INSTRUCTION; 468 - codes[0] = EXC_I386_INVOP; 469 - break; 470 - case SIGFPE: 471 - mach_exception = EXC_ARITHMETIC; 472 - codes[0] = info->si_code; 473 - break; 474 - case SIGTRAP: 475 - mach_exception = EXC_BREAKPOINT; 476 - codes[0] = (info->si_code == LINUX_SI_KERNEL) ? EXC_I386_BPT : EXC_I386_SGL; 148 + lkm_call(NR_sigprocess, &sigprocess); 477 149 478 - if (info->si_code == LINUX_TRAP_HWBKPT) 479 - { 480 - // Memory watchpoint triggered 481 - struct last_triggered_watchpoint_args args; 482 - if (lkm_call(NR_last_triggered_watchpoint, &args) == 0) 483 - { 484 - codes[1] = args.address; 485 - // codes[2] = args.flags; 486 - } 487 - } 488 - break; 489 - default: 490 - mach_exception = EXC_SOFTWARE; 491 - codes[0] = EXC_SOFT_SIGNAL; 492 - codes[1] = bsd_signum; 493 - } 494 - } 495 - else 150 + if (!sigprocess.signum) 496 151 { 497 - mach_exception = EXC_SOFTWARE; 498 - codes[0] = EXC_SOFT_SIGNAL; 499 - codes[1] = bsd_signum; 152 + kern_printf("sigexc: drop signal\n"); 153 + return; 500 154 } 501 155 502 - port = get_exc_port(mach_exception, &behavior); 156 + memcpy(info, &sigprocess.linux_siginfo, sizeof(*info)); 157 + memcpy(ctxt, &sigprocess.linux_ucontext, sizeof(*ctxt)); 503 158 504 - // Pass register states to LKM 505 - state_to_kernel(ctxt, thread); 159 + linux_signum = signum_bsd_to_linux(sigprocess.signum); 506 160 507 - // __simple_printf("Passing Mach exception to port %d\n", port); 508 - if (port != 0) 161 + if (sig_handlers[linux_signum] != SIG_IGN) 509 162 { 510 - _pthread_setspecific_direct(SIGEXC_TSD_KEY, bsd_signum); 511 - _pthread_setspecific_direct(SIGEXC_CONTEXT_TSD_KEY, ctxt); 512 - 513 - kern_return_t ret; 514 - 515 - if (behavior & MACH_EXCEPTION_CODES) 163 + if (sig_handlers[linux_signum]) 516 164 { 517 - ret = mach_exception_raise(port, thread, mach_task_self(), mach_exception, codes, sizeof(codes) / sizeof(codes[0])); 165 + kern_printf("sigexc: will forward signal to app handler (%p)\n", sig_handlers[linux_signum]); 166 + handler_linux_to_bsd(linux_signum, info, ctxt); 518 167 } 519 168 else 520 169 { 521 - exception_data_type_t small_codes[2] = { (exception_data_type_t) codes[0], (exception_data_type_t) codes[1] }; 522 - ret = exception_raise(port, thread, mach_task_self(), mach_exception, small_codes, sizeof(small_codes) / sizeof(small_codes[0])); 523 - } 524 - 525 - if (ret == MACH_RCV_PORT_DIED || ret == MACH_SEND_INVALID_DEST) 526 - { 527 - kern_printf("Exception handler death? ret is 0x%x\n", ret); 528 - darling_sigexc_uninstall(); 529 - } 530 - 531 - bsd_signum = _pthread_getspecific_direct(SIGEXC_TSD_KEY); 532 - _pthread_setspecific_direct(SIGEXC_TSD_KEY, 0); 533 - } 534 - 535 - // Get (possibly updated by GDB) register states from LKM 536 - if (ctxt != NULL) 537 - state_from_kernel(ctxt, thread); 538 - 539 - // Pass the signal to the application handler or emulate the effects of the signal if SIG_DFL is set. 540 - if (bsd_signum) 541 - { 542 - const int linux_signum = signum_bsd_to_linux(bsd_signum); 543 - 544 - bsd_sig_handler* handler = sig_handlers[linux_signum]; 545 - if (handler == SIG_DFL || handler == SIG_ERR) 546 - { 547 - /* 548 - switch (bsd_signum) 170 + if (sigprocess.signum == SIGTSTP || sigprocess.signum == SIGSTOP) 171 + { 172 + kern_printf("sigexc: emulating SIGTSTP/SIGSTOP\n"); 173 + LINUX_SYSCALL(__NR_kill, 0, LINUX_SIGSTOP); 174 + } 175 + else 549 176 { 550 - // We have to stop the process manually 551 - case SIGSTOP: 552 - case SIGTSTP: 553 - task_suspend(mach_task_self()); 554 - break; 177 + kern_printf("sigexc: emulating default signal effects\n"); 178 + // Set handler to SIG_DFL 179 + struct linux_sigaction sa; 180 + sa.sa_sigaction = (linux_sig_handler*) NULL; // SIG_DFL 181 + sa.sa_mask = 0x7fffffff; // all other standard Unix signals should be blocked while the handler is run 182 + sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK; 183 + sa.sa_restorer = sig_restorer; 555 184 556 - // These signals do nothing by default 557 - case SIGCHLD: 558 - case SIGWINCH: 559 - case SIGURG: 560 - break; 561 - case SIGTRAP: 562 - if (ctxt == NULL) 563 - break; // This trap wasn't caused by int3, carry on 564 - 565 - // Other signals cause termination or core dump. 566 - default: 567 - { 568 - int linux_signum = signum_bsd_to_linux(bsd_signum); 569 - sys_exit(linux_signum); 570 - } 185 + LINUX_SYSCALL(__NR_rt_sigaction, linux_signum, 186 + &sa, NULL, 187 + sizeof(sa.sa_mask)); 188 + 189 + // Resend signal to self 190 + LINUX_SYSCALL(__NR_kill, 0, linux_signum); 571 191 } 572 - */ 573 - } 574 - else if (handler != SIG_IGN) 575 - { 576 - handler_linux_to_bsd(linux_signum, info, ctxt); 577 192 } 578 193 } 579 - 194 + 580 195 kern_printf("sigexc: handler (%d) returning\n", linux_signum); 581 196 } 582 197 583 - #if defined(__x86_64__) 584 - void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state64_t* s) 585 - { 586 - s->__rax = regs->rax; 587 - s->__rbx = regs->rbx; 588 - s->__rcx = regs->rcx; 589 - s->__rdx = regs->rdx; 590 - s->__rdi = regs->rdi; 591 - s->__rsi = regs->rsi; 592 - s->__rbp = regs->rbp; 593 - s->__rsp = regs->rsp; 594 - s->__r8 = regs->r8; 595 - s->__r9 = regs->r9; 596 - s->__r10 = regs->r10; 597 - s->__r11 = regs->r11; 598 - s->__r12 = regs->r12; 599 - s->__r13 = regs->r13; 600 - s->__r14 = regs->r14; 601 - s->__r15 = regs->r15; 602 - s->__rip = regs->rip; 603 - s->__rflags = regs->efl; 604 - s->__cs = regs->cs; 605 - s->__fs = regs->fs; 606 - s->__gs = regs->gs; 607 - 608 - kern_printf("sigexc: saving to kernel: RIP %p, eflags 0x%x\n", regs->rip, regs->efl); 609 - } 610 - 611 - void mcontext_to_float_state(const linux_fpregset_t fx, x86_float_state64_t* s) 612 - { 613 - kern_printf("sigexc: fcw out: 0x%x", fx->cwd); 614 - kern_printf("sigexc: xmm0 out: 0x%x", fx->_xmm[0].element[0]); 615 - *((uint16_t*)&s->__fpu_fcw) = fx->cwd; 616 - *((uint16_t*)&s->__fpu_fsw) = fx->swd; 617 - s->__fpu_ftw = fx->ftw; 618 - s->__fpu_fop = fx->fop; 619 - s->__fpu_ip = fx->rip; 620 - s->__fpu_cs = 0; 621 - s->__fpu_dp = fx->rdp; 622 - s->__fpu_ds = 0; 623 - s->__fpu_mxcsr = fx->mxcsr; 624 - s->__fpu_mxcsrmask = fx->mxcr_mask; 625 - 626 - memcpy(&s->__fpu_stmm0, fx->_st, 128); 627 - memcpy(&s->__fpu_xmm0, fx->_xmm, 256); 628 - } 629 - 630 - void thread_state_to_mcontext(const x86_thread_state64_t* s, struct linux_gregset* regs) 631 - { 632 - regs->rax = s->__rax; 633 - regs->rbx = s->__rbx; 634 - regs->rcx = s->__rcx; 635 - regs->rdx = s->__rdx; 636 - regs->rdi = s->__rdi; 637 - regs->rsi = s->__rsi; 638 - regs->rbp = s->__rbp; 639 - regs->rsp = s->__rsp; 640 - regs->r8 = s->__r8; 641 - regs->r9 = s->__r9; 642 - regs->r10 = s->__r10; 643 - regs->r11 = s->__r11; 644 - regs->r12 = s->__r12; 645 - regs->r13 = s->__r13; 646 - regs->r14 = s->__r14; 647 - regs->r15 = s->__r15; 648 - regs->rip = s->__rip; 649 - regs->efl = s->__rflags; 650 - regs->cs = s->__cs; 651 - regs->fs = s->__fs; 652 - regs->gs = s->__gs; 653 - 654 - kern_printf("sigexc: Next RIP will be %p, eflags: 0x%x\n", regs->rip, regs->efl); // single step trace bit is 0x100 655 - } 656 - 657 - void float_state_to_mcontext(const x86_float_state64_t* s, linux_fpregset_t fx) 658 - { 659 - fx->cwd = *((uint16_t*)&s->__fpu_fcw); 660 - fx->swd = *((uint16_t*)&s->__fpu_fsw); 661 - fx->ftw = s->__fpu_ftw; 662 - fx->fop = s->__fpu_fop; 663 - fx->rip = s->__fpu_ip; 664 - fx->rdp = s->__fpu_dp; 665 - fx->mxcsr = s->__fpu_mxcsr; 666 - fx->mxcr_mask = s->__fpu_mxcsrmask; 667 - 668 - memcpy(fx->_st, &s->__fpu_stmm0, 128); 669 - memcpy(fx->_xmm, &s->__fpu_xmm0, 256); 670 - kern_printf("sigexc: fcw in: 0x%x", fx->cwd); 671 - kern_printf("sigexc: xmm0 in: 0x%x", fx->_xmm[0].element[0]); 672 - } 673 - 674 - #elif defined(__i386__) 675 - void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state32_t* s) 676 - { 677 - s->__eax = regs->eax; 678 - s->__ebx = regs->ebx; 679 - s->__ecx = regs->ecx; 680 - s->__edx = regs->edx; 681 - s->__edi = regs->edi; 682 - s->__esi = regs->esi; 683 - s->__ebp = regs->ebp; 684 - s->__esp = regs->esp; 685 - s->__ss = regs->ss; 686 - s->__eflags = regs->efl; 687 - s->__eip = regs->eip; 688 - s->__cs = regs->cs; 689 - s->__ds = regs->ds; 690 - s->__es = regs->es; 691 - s->__fs = regs->fs; 692 - s->__gs = regs->gs; 693 - } 694 - 695 - void mcontext_to_float_state(const linux_fpregset_t fx, x86_float_state32_t* s) 696 - { 697 - *((uint16_t*)&s->__fpu_fcw) = fx->cw; 698 - *((uint16_t*)&s->__fpu_fsw) = fx->sw; 699 - s->__fpu_ftw = fx->tag; 700 - s->__fpu_fop = 0; 701 - s->__fpu_ip = fx->ipoff; 702 - s->__fpu_cs = fx->cssel; 703 - s->__fpu_dp = fx->dataoff; 704 - s->__fpu_ds = fx->datasel; 705 - s->__fpu_mxcsr = fx->mxcsr; 706 - s->__fpu_mxcsrmask = 0; 707 - 708 - memcpy(&s->__fpu_stmm0, fx->_st, 128); 709 - memcpy(&s->__fpu_xmm0, fx->_xmm, 128); 710 - memset(((char*) &s->__fpu_xmm0) + 128, 0, 128); 711 - } 712 - 713 - void thread_state_to_mcontext(const x86_thread_state32_t* s, struct linux_gregset* regs) 714 - { 715 - regs->eax = s->__eax; 716 - regs->ebx = s->__ebx; 717 - regs->ecx = s->__ecx; 718 - regs->edx = s->__edx; 719 - regs->edi = s->__edi; 720 - regs->esi = s->__esi; 721 - regs->ebp = s->__ebp; 722 - regs->esp = s->__esp; 723 - regs->ss = s->__ss; 724 - regs->efl = s->__eflags; 725 - regs->eip = s->__eip; 726 - regs->cs = s->__cs; 727 - regs->ds = s->__ds; 728 - regs->es = s->__es; 729 - regs->fs = s->__fs; 730 - regs->gs = s->__gs; 731 - } 732 - 733 - void float_state_to_mcontext(const x86_float_state32_t* s, linux_fpregset_t fx) 734 - { 735 - fx->cw = *((uint16_t*)&s->__fpu_fcw); 736 - fx->sw = *((uint16_t*)&s->__fpu_fsw); 737 - fx->tag = s->__fpu_ftw; 738 - fx->ipoff = s->__fpu_ip; 739 - fx->cssel = s->__fpu_cs; 740 - fx->dataoff = s->__fpu_dp; 741 - fx->datasel = s->__fpu_ds; 742 - fx->mxcsr = s->__fpu_mxcsr; 743 - 744 - memcpy(fx->_st, &s->__fpu_stmm0, 128); 745 - memcpy(fx->_xmm, &s->__fpu_xmm0, 128); 746 - } 747 - #endif 748 - 749 - #define LINUX_SI_QUEUE (-1) 750 - int linux_sigqueue(int pid, int rtsig, int value) 751 - { 752 - struct linux_siginfo si; 753 - 754 - memset(&si, 0, sizeof(si)); 755 - si.si_signo = rtsig; 756 - si.si_code = LINUX_SI_QUEUE; 757 - si.si_pid = getpid(); 758 - si.si_uid = LINUX_SYSCALL(__NR_getuid); 759 - si.si_value = value; 760 - 761 - return LINUX_SYSCALL(__NR_rt_sigqueueinfo, pid, rtsig, &si); 762 - } 763 - 764 - int linux_sigqueue_thread(int pid, int tid, int rtsig, int value) 765 - { 766 - struct linux_siginfo si; 767 - 768 - memset(&si, 0, sizeof(si)); 769 - si.si_signo = rtsig; 770 - si.si_code = LINUX_SI_QUEUE; 771 - si.si_pid = getpid(); 772 - si.si_uid = LINUX_SYSCALL(__NR_getuid); 773 - si.si_value = value; 774 - 775 - return LINUX_SYSCALL(__NR_rt_tgsigqueueinfo, pid, tid, rtsig, &si); 776 - } 777 -