Ticket #2695: siginfo_2010-01-25.diff
File siginfo_2010-01-25.diff, 5.7 KB (added by , 14 years ago) |
---|
-
headers/posix/signal.h
headers/posix/signal.h | 9 ++-- headers/posix/ucontext.h | 22 +++++++++ src/system/kernel/arch/x86/arch_thread.cpp | 69 +++++++++++++++++++-------- 3 files changed, 75 insertions(+), 25 deletions(-) diff --git a/headers/posix/signal.h b/headers/posix/signal.h index e6c702f..37e3669 100644
a b typedef void (*__signal_func_ptr)(int); 28 28 /* TODO: Support this structure, or more precisely the SA_SIGINFO flag. To do 29 29 * this properly we need real-time signal support. Both are commented out for 30 30 * the time being to not make "configure" scripts think we do support them. */ 31 #if 032 31 typedef struct { 33 32 int si_signo; /* signal number */ 34 33 int si_code; /* signal code */ … … typedef struct { 39 38 int si_status; /* exit value or signal */ 40 39 long si_band; /* band event for SIGPOLL */ 41 40 } siginfo_t; 42 #endif /* 0 */43 41 44 42 /* 45 43 * structure used by sigaction() … … typedef struct { 48 46 * See the documentation for more info on this. 49 47 */ 50 48 struct sigaction { 51 sighandler_t sa_handler; 49 union { 50 sighandler_t sa_handler; 51 void (*sa_sigaction)(int, siginfo_t *, void *); 52 }; 52 53 sigset_t sa_mask; 53 54 int sa_flags; 54 55 void *sa_userdata; /* will be passed to the signal handler */ … … struct sigaction { 61 62 #define SA_NODEFER 0x08 62 63 #define SA_RESTART 0x10 63 64 #define SA_ONSTACK 0x20 64 /* #define SA_SIGINFO 0x40 */ 65 #define SA_SIGINFO 0x40 65 66 #define SA_NOMASK SA_NODEFER 66 67 #define SA_STACK SA_ONSTACK 67 68 #define SA_ONESHOT SA_RESETHAND -
new file headers/posix/ucontext.h
diff --git a/headers/posix/ucontext.h b/headers/posix/ucontext.h new file mode 100644 index 0000000..6900401
- + 1 /* 2 * Copyright 2008, Haiku Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT license. 4 */ 5 #ifndef _UCONTEXT_H_ 6 #define _UCONTEXT_H_ 7 8 #include <signal.h> 9 10 11 typedef struct vregs mcontext_t; 12 13 14 typedef struct ucontext_t { 15 ucontext_t *uc_link; 16 sigset_t uc_sigmask; 17 stack_t uc_stack; 18 mcontext_t uc_mcontext; 19 } ucontext_t; 20 21 22 #endif /* _UCONTEXT_H_ */ -
src/system/kernel/arch/x86/arch_thread.cpp
diff --git a/src/system/kernel/arch/x86/arch_thread.cpp b/src/system/kernel/arch/x86/arch_thread.cpp index 6831f7b..81e7267 100644
a b 22 22 #include <thread.h> 23 23 #include <tls.h> 24 24 #include <tracing.h> 25 #include <ucontext.h> 25 26 #include <vm/vm_types.h> 26 27 #include <vm/VMAddressSpace.h> 27 28 … … arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 480 481 } 481 482 482 483 uint32 *signalCode; 483 uint32 *userRegs; 484 struct vregs regs; 484 uint32 *userRegs, *userSiginfo, *userContext; 485 siginfo_t siginfo; 486 ucontext_t ucontext; 485 487 uint32 buffer[6]; 486 488 status_t status; 487 489 … … arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 501 503 if (status < B_OK) 502 504 return status; 503 505 506 if (action->sa_flags & SA_SIGINFO) { 507 // store the signal info 508 memset(&siginfo, 0, sizeof(siginfo)); 509 siginfo.si_signo = signal; 510 //TODO fill in other members 511 512 userStack -= (sizeof(siginfo_t) + 3) / 4; 513 userSiginfo = userStack; 514 status = user_memcpy(userSiginfo, &siginfo, sizeof(siginfo)); 515 if (status < B_OK) 516 return status; 517 } 518 504 519 // store the saved regs onto the user stack 505 regs.eip = frame->eip; 506 regs.eflags = frame->flags; 507 regs.eax = frame->eax; 508 regs.ecx = frame->ecx; 509 regs.edx = frame->edx; 510 regs.ebp = frame->ebp; 511 regs.esp = frame->esp; 512 regs._reserved_1 = frame->user_esp; 513 regs._reserved_2[0] = frame->edi; 514 regs._reserved_2[1] = frame->esi; 515 regs._reserved_2[2] = frame->ebx; 516 i386_fnsave((void *)(®s.xregs)); 517 518 userStack -= (sizeof(struct vregs) + 3) / 4; 519 userRegs = userStack; 520 status = user_memcpy(userRegs, ®s, sizeof(regs)); 520 ucontext.uc_mcontext.eip = frame->eip; 521 ucontext.uc_mcontext.eflags = frame->flags; 522 ucontext.uc_mcontext.eax = frame->eax; 523 ucontext.uc_mcontext.ecx = frame->ecx; 524 ucontext.uc_mcontext.edx = frame->edx; 525 ucontext.uc_mcontext.ebp = frame->ebp; 526 ucontext.uc_mcontext.esp = frame->esp; 527 ucontext.uc_mcontext._reserved_1 = frame->user_esp; 528 ucontext.uc_mcontext._reserved_2[0] = frame->edi; 529 ucontext.uc_mcontext._reserved_2[1] = frame->esi; 530 ucontext.uc_mcontext._reserved_2[2] = frame->ebx; 531 i386_fnsave((void *)(&ucontext.uc_mcontext.xregs)); 532 533 if (action->sa_flags & SA_SIGINFO) { 534 userStack -= (sizeof(ucontext_t) + 3) / 4; 535 userContext = userStack; 536 userRegs = userContext + offsetof(ucontext_t, uc_mcontext); 537 status = user_memcpy(userContext, &ucontext, sizeof(ucontext)); 538 } else { 539 userStack -= (sizeof(struct vregs) + 3) / 4; 540 userRegs = userStack; 541 status = user_memcpy(userRegs, &ucontext.uc_mcontext, sizeof(struct vregs)); 542 } 521 543 if (status < B_OK) 522 544 return status; 523 545 … … arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 534 556 // now set up the final part 535 557 buffer[0] = (uint32)signalCode; // return address when sa_handler done 536 558 buffer[1] = signal; // arguments to sa_handler 537 buffer[2] = (uint32)action->sa_userdata; 538 buffer[3] = (uint32)userRegs; 559 if (action->sa_flags & SA_SIGINFO) { 560 buffer[2] = (uint32)userSiginfo; 561 buffer[3] = (uint32)userContext; 562 } else { 563 buffer[2] = (uint32)action->sa_userdata; 564 buffer[3] = (uint32)userRegs; 565 } 539 566 540 567 buffer[4] = signalMask; // Old signal mask to restore 541 568 buffer[5] = (uint32)userRegs; // Int frame + extra regs to restore … … arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 547 574 return status; 548 575 549 576 frame->user_esp = (uint32)userStack; 550 frame->eip = ( uint32)action->sa_handler;577 frame->eip = (action->sa_flags & SA_SIGINFO) ? (uint32)action->sa_sigaction : (uint32)action->sa_handler; 551 578 552 579 return B_OK; 553 580 }