Ticket #2695: siginfo_2010-01-25.diff

File siginfo_2010-01-25.diff, 5.7 KB (added by andreasf, 14 years ago)

rebased branch

  • 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);  
    2828/* TODO: Support this structure, or more precisely the SA_SIGINFO flag. To do
    2929 * this properly we need real-time signal support. Both are commented out for
    3030 * the time being to not make "configure" scripts think we do support them. */
    31 #if 0
    3231typedef struct {
    3332    int     si_signo;   /* signal number */
    3433    int     si_code;    /* signal code */
    typedef struct {  
    3938    int     si_status;  /* exit value or signal */
    4039    long    si_band;    /* band event for SIGPOLL */
    4140} siginfo_t;
    42 #endif  /* 0 */
    4341
    4442/*
    4543 * structure used by sigaction()
    typedef struct {  
    4846 * See the documentation for more info on this.
    4947 */
    5048struct sigaction {
    51     sighandler_t sa_handler;
     49    union {
     50        sighandler_t    sa_handler;
     51        void            (*sa_sigaction)(int, siginfo_t *, void *);
     52    };
    5253    sigset_t    sa_mask;
    5354    int         sa_flags;
    5455    void        *sa_userdata;  /* will be passed to the signal handler */
    struct sigaction {  
    6162#define SA_NODEFER      0x08
    6263#define SA_RESTART      0x10
    6364#define SA_ONSTACK      0x20
    64 /* #define SA_SIGINFO       0x40 */
     65#define SA_SIGINFO      0x40
    6566#define SA_NOMASK       SA_NODEFER
    6667#define SA_STACK        SA_ONSTACK
    6768#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
     11typedef struct vregs mcontext_t;
     12
     13
     14typedef 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  
    2222#include <thread.h>
    2323#include <tls.h>
    2424#include <tracing.h>
     25#include <ucontext.h>
    2526#include <vm/vm_types.h>
    2627#include <vm/VMAddressSpace.h>
    2728
    arch_setup_signal_frame(struct thread *thread, struct sigaction *action,  
    480481    }
    481482
    482483    uint32 *signalCode;
    483     uint32 *userRegs;
    484     struct vregs regs;
     484    uint32 *userRegs, *userSiginfo, *userContext;
     485    siginfo_t siginfo;
     486    ucontext_t ucontext;
    485487    uint32 buffer[6];
    486488    status_t status;
    487489
    arch_setup_signal_frame(struct thread *thread, struct sigaction *action,  
    501503    if (status < B_OK)
    502504        return status;
    503505
     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
    504519    // 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 *)(&regs.xregs));
    517 
    518     userStack -= (sizeof(struct vregs) + 3) / 4;
    519     userRegs = userStack;
    520     status = user_memcpy(userRegs, &regs, 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    }
    521543    if (status < B_OK)
    522544        return status;
    523545
    arch_setup_signal_frame(struct thread *thread, struct sigaction *action,  
    534556    // now set up the final part
    535557    buffer[0] = (uint32)signalCode; // return address when sa_handler done
    536558    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    }
    539566
    540567    buffer[4] = signalMask;         // Old signal mask to restore
    541568    buffer[5] = (uint32)userRegs;   // Int frame + extra regs to restore
    arch_setup_signal_frame(struct thread *thread, struct sigaction *action,  
    547574        return status;
    548575
    549576    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;
    551578
    552579    return B_OK;
    553580}