this repo has no description
1
fork

Configure Feed

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

Work on better working thread support in LLDB

+115 -72
+112 -72
src/kernel/emulation/linux/signal/sigexc.c
··· 20 20 21 21 static volatile bool am_i_ptraced = false; 22 22 static void handle_rt_signal(int signum); 23 + static void sigexc_fake_suspend(struct linux_ucontext* ctxt); 23 24 extern void sig_restorer(void); 24 25 extern int getpid(void); 25 26 ··· 170 171 // If >0, process the signal 171 172 // If <0, introduce a new signal 172 173 int sig = info->si_value; 173 - if (sig < 0) 174 + if (sig == SIGNAL_THREAD_SUSPEND) 175 + { 176 + kern_printf("sigexc: SIGNAL_THREAD_SUSPEND"); 177 + sigexc_fake_suspend(ctxt); 178 + } 179 + else if (sig == SIGNAL_THREAD_RESUME) 180 + { 181 + kern_printf("sigexc: SIGNAL_THREAD_RESUME"); 182 + } 183 + else if (sig < 0) 174 184 { 175 185 // This is only used to pass a SIGSTOP to the traced process (from the debugger) 176 186 // and have it passed back through the sigexc mechanism. 177 - // See sys_wait4(). 187 + // See sys_kill(). 178 188 sigexc_handler(-sig, NULL, (struct linux_ucontext*) ctxt); 179 189 } 180 190 else ··· 273 283 return 0; 274 284 } 275 285 286 + static void state_to_kernel(struct linux_ucontext* ctxt, thread_t thread) 287 + { 288 + #if defined(__x86_64__) 289 + x86_thread_state64_t tstate; 290 + x86_float_state64_t fstate; 291 + 292 + if (ctxt != NULL) 293 + { 294 + mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, &tstate); 295 + mcontext_to_float_state(ctxt->uc_mcontext.fpregs, &fstate); 296 + /* 297 + #ifdef __x86_64__ 298 + if (bsd_signum == SIGTRAP) 299 + { 300 + uint8_t* rip = (uint8_t*) ctxt->uc_mcontext.gregs.rip; 301 + kern_printf("rip is %p\n", rip); 302 + kern_printf("Value at rip-1 on suspend: 0x%x\n", *(rip-1)); 303 + } 304 + #endif 305 + */ 306 + } 307 + else 308 + { 309 + memset(&tstate, 0, sizeof(tstate)); 310 + memset(&fstate, 0, sizeof(fstate)); 311 + } 312 + 313 + thread_set_state(thread, x86_THREAD_STATE64, (thread_state_t) &tstate, x86_THREAD_STATE64_COUNT); 314 + thread_set_state(thread, x86_FLOAT_STATE64, (thread_state_t) &fstate, x86_FLOAT_STATE64_COUNT); 315 + #elif defined(__i386__) 316 + x86_thread_state32_t tstate; 317 + x86_float_state32_t fstate; 318 + 319 + if (ctxt != NULL) 320 + { 321 + mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, &tstate); 322 + mcontext_to_float_state(ctxt->uc_mcontext.fpregs, &fstate); 323 + } 324 + else 325 + { 326 + memset(&tstate, 0, sizeof(tstate)); 327 + memset(&fstate, 0, sizeof(fstate)); 328 + } 329 + 330 + thread_set_state(thread, x86_THREAD_STATE32, (thread_state_t) &tstate, x86_THREAD_STATE32_COUNT); 331 + thread_set_state(thread, x86_FLOAT_STATE32, (thread_state_t) &fstate, x86_FLOAT_STATE32_COUNT); 332 + #endif 333 + 334 + } 335 + 336 + static void state_from_kernel(struct linux_ucontext* ctxt, thread_t thread) 337 + { 338 + #if defined(__x86_64__) 339 + x86_thread_state64_t tstate; 340 + x86_float_state64_t fstate; 341 + mach_msg_type_number_t count; 342 + 343 + count = x86_THREAD_STATE64_COUNT; 344 + thread_get_state(thread, x86_THREAD_STATE64, (thread_state_t) &tstate, &count); 345 + count = x86_FLOAT_STATE64_COUNT; 346 + thread_get_state(thread, x86_FLOAT_STATE64, (thread_state_t) &fstate, &count); 347 + 348 + thread_state_to_mcontext(&tstate, &ctxt->uc_mcontext.gregs); 349 + float_state_to_mcontext(&fstate, ctxt->uc_mcontext.fpregs); 350 + 351 + #elif defined(__i386__) 352 + x86_thread_state32_t tstate; 353 + x86_float_state32_t fstate; 354 + mach_msg_type_number_t count; 355 + 356 + count = x86_THREAD_STATE32_COUNT; 357 + thread_get_state(thread, x86_THREAD_STATE32, (thread_state_t) &tstate, &count); 358 + count = x86_FLOAT_STATE32_COUNT; 359 + thread_get_state(thread, x86_FLOAT_STATE32, (thread_state_t) &fstate, &count); 360 + 361 + thread_state_to_mcontext(&tstate, &ctxt->uc_mcontext.gregs); 362 + float_state_to_mcontext(&fstate, ctxt->uc_mcontext.fpregs); 363 + #endif 364 + } 365 + 366 + void sigexc_fake_suspend(struct linux_ucontext* ctxt) 367 + { 368 + if (_pthread_getspecific_direct(SIGEXC_TSD_KEY) != 0) 369 + return; 370 + thread_t thread = mach_thread_self(); 371 + 372 + kern_printf("sigexc_fake_suspend -> state_to_kernel\n"); 373 + state_to_kernel(ctxt, thread); 374 + 375 + linux_sigset_t set = -1ll; 376 + set &= ~(1ull << (SIGNAL_SIGEXC_THUPDATE-1)); 377 + 378 + LINUX_SYSCALL(__NR_rt_sigsuspend, &set, 8); 379 + 380 + kern_printf("sigexc_fake_suspend -> state_from_kernel\n"); 381 + state_from_kernel(ctxt, thread); 382 + } 276 383 277 384 // syscall tracking 278 385 #define LINUX_TRAP_BRKPT 1 ··· 318 425 // SIGILL -> EXC_BAD_INSTRUCTION 319 426 // SIGFPE -> EXC_ARITHMETIC 320 427 // * -> EXC_SOFTWARE with EXC_SOFT_SIGNAL (e.g. SIGSTOP) 321 - kern_printf("sigexc_handler #2\n"); 322 428 323 429 // Only real exceptions produced by the CPU get translated to these 324 430 // Mach exceptions. The rest comes as EXC_SOFTWARE. ··· 373 479 port = get_exc_port(mach_exception, &behavior); 374 480 375 481 // Pass register states to LKM 376 - #if defined(__x86_64__) 377 - x86_thread_state64_t tstate; 378 - x86_float_state64_t fstate; 379 - 380 - if (ctxt != NULL) 381 - { 382 - mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, &tstate); 383 - mcontext_to_float_state(ctxt->uc_mcontext.fpregs, &fstate); 384 - /* 385 - #ifdef __x86_64__ 386 - if (bsd_signum == SIGTRAP) 387 - { 388 - uint8_t* rip = (uint8_t*) ctxt->uc_mcontext.gregs.rip; 389 - kern_printf("rip is %p\n", rip); 390 - kern_printf("Value at rip-1 on suspend: 0x%x\n", *(rip-1)); 391 - } 392 - #endif 393 - */ 394 - } 395 - else 396 - { 397 - memset(&tstate, 0, sizeof(tstate)); 398 - memset(&fstate, 0, sizeof(fstate)); 399 - } 400 - 401 - thread_set_state(thread, x86_THREAD_STATE64, (thread_state_t) &tstate, x86_THREAD_STATE64_COUNT); 402 - thread_set_state(thread, x86_FLOAT_STATE64, (thread_state_t) &fstate, x86_FLOAT_STATE64_COUNT); 403 - #elif defined(__i386__) 404 - x86_thread_state32_t tstate; 405 - x86_float_state32_t fstate; 406 - 407 - if (ctxt != NULL) 408 - { 409 - mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, &tstate); 410 - mcontext_to_float_state(ctxt->uc_mcontext.fpregs, &fstate); 411 - } 412 - else 413 - { 414 - memset(&tstate, 0, sizeof(tstate)); 415 - memset(&fstate, 0, sizeof(fstate)); 416 - } 417 - 418 - thread_set_state(thread, x86_THREAD_STATE32, (thread_state_t) &tstate, x86_THREAD_STATE32_COUNT); 419 - thread_set_state(thread, x86_FLOAT_STATE32, (thread_state_t) &fstate, x86_FLOAT_STATE32_COUNT); 420 - #endif 482 + state_to_kernel(ctxt, thread); 421 483 422 484 // __simple_printf("Passing Mach exception to port %d\n", port); 423 485 if (port != 0) ··· 443 505 } 444 506 445 507 bsd_signum = _pthread_getspecific_direct(SIGEXC_TSD_KEY); 508 + _pthread_setspecific_direct(SIGEXC_TSD_KEY, 0); 446 509 } 447 510 448 511 // Get (possibly updated by GDB) register states from LKM 449 512 if (ctxt != NULL) 450 - { 451 - #if defined(__x86_64__) 452 - mach_msg_type_number_t count; 453 - 454 - count = x86_THREAD_STATE64_COUNT; 455 - thread_get_state(thread, x86_THREAD_STATE64, (thread_state_t) &tstate, &count); 456 - count = x86_FLOAT_STATE64_COUNT; 457 - thread_get_state(thread, x86_FLOAT_STATE64, (thread_state_t) &fstate, &count); 458 - 459 - thread_state_to_mcontext(&tstate, &ctxt->uc_mcontext.gregs); 460 - float_state_to_mcontext(&fstate, ctxt->uc_mcontext.fpregs); 461 - 462 - #elif defined(__i386__) 463 - mach_msg_type_number_t count; 464 - 465 - count = x86_THREAD_STATE32_COUNT; 466 - thread_get_state(thread, x86_THREAD_STATE32, (thread_state_t) &tstate, &count); 467 - count = x86_FLOAT_STATE32_COUNT; 468 - thread_get_state(thread, x86_FLOAT_STATE32, (thread_state_t) &fstate, &count); 469 - 470 - thread_state_to_mcontext(&tstate, &ctxt->uc_mcontext.gregs); 471 - float_state_to_mcontext(&fstate, ctxt->uc_mcontext.fpregs); 472 - #endif 473 - } 513 + state_from_kernel(ctxt, thread); 474 514 475 515 // Pass the signal to the application handler or emulate the effects of the signal if SIG_DFL is set. 476 516 if (bsd_signum)
+3
src/kernel/emulation/linux/signal/sigexc.h
··· 11 11 // A BSD signal number is passed as value 12 12 #define SIGNAL_SIGEXC_THUPDATE (LINUX_SIGRTMIN + 1) 13 13 14 + #define SIGNAL_THREAD_SUSPEND -100 15 + #define SIGNAL_THREAD_RESUME -101 16 + 14 17 #define SIGRT_MAGIC_ENABLE_SIGEXC 0xdebdeb01 15 18 #define SIGRT_MAGIC_DISABLE_SIGEXC 0xdebdeb00 16 19