Ticket #2695: siginfo_2009-11-17.diff

File siginfo_2009-11-17.diff, 5.5 KB (added by andreasf, 9 years ago)

Git branch from 2008-08-11, rebased

  • headers/posix/signal.h

    diff --git a/headers/posix/signal.h b/headers/posix/signal.h
    index 97703c8..bd002e4 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 60e0a57..9265ebc 100644
    a b  
    2323#include <tracing.h>
    2424#include <vm_address_space.h>
    2525#include <vm_types.h>
     26#include <ucontext.h>
    2627
    2728#include "x86_paging.h"
    2829
    arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 
    485486    }
    486487
    487488    uint32 *signalCode;
    488     uint32 *userRegs;
    489     struct vregs regs;
     489    uint32 *userRegs, *userSiginfo, *userContext;
     490    siginfo_t siginfo;
     491    ucontext_t ucontext;
    490492    uint32 buffer[6];
    491493    status_t status;
    492494
    arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 
    506508    if (status < B_OK)
    507509        return status;
    508510
     511    if (action->sa_flags & SA_SIGINFO) {
     512        // store the signal info
     513        memset(&siginfo, 0, sizeof(siginfo));
     514        siginfo.si_signo = signal;
     515        //TODO fill in other members
     516       
     517        userStack -= (sizeof(siginfo_t) + 3) / 4;
     518        userSiginfo = userStack;
     519        status = user_memcpy(userSiginfo, &siginfo, sizeof(siginfo));
     520        if (status < B_OK)
     521            return status;
     522    }
     523
    509524    // store the saved regs onto the user stack
    510     regs.eip = frame->eip;
    511     regs.eflags = frame->flags;
    512     regs.eax = frame->eax;
    513     regs.ecx = frame->ecx;
    514     regs.edx = frame->edx;
    515     regs.ebp = frame->ebp;
    516     regs.esp = frame->esp;
    517     regs._reserved_1 = frame->user_esp;
    518     regs._reserved_2[0] = frame->edi;
    519     regs._reserved_2[1] = frame->esi;
    520     regs._reserved_2[2] = frame->ebx;
    521     i386_fnsave((void *)(&regs.xregs));
    522 
    523     userStack -= (sizeof(struct vregs) + 3) / 4;
    524     userRegs = userStack;
    525     status = user_memcpy(userRegs, &regs, sizeof(regs));
     525    ucontext.uc_mcontext.eip = frame->eip;
     526    ucontext.uc_mcontext.eflags = frame->flags;
     527    ucontext.uc_mcontext.eax = frame->eax;
     528    ucontext.uc_mcontext.ecx = frame->ecx;
     529    ucontext.uc_mcontext.edx = frame->edx;
     530    ucontext.uc_mcontext.ebp = frame->ebp;
     531    ucontext.uc_mcontext.esp = frame->esp;
     532    ucontext.uc_mcontext._reserved_1 = frame->user_esp;
     533    ucontext.uc_mcontext._reserved_2[0] = frame->edi;
     534    ucontext.uc_mcontext._reserved_2[1] = frame->esi;
     535    ucontext.uc_mcontext._reserved_2[2] = frame->ebx;
     536    i386_fnsave((void *)(&ucontext.uc_mcontext.xregs));
     537
     538    if (action->sa_flags & SA_SIGINFO) {
     539        userStack -= (sizeof(ucontext_t) + 3) / 4;
     540        userContext = userStack;
     541        userRegs = userContext + offsetof(ucontext_t, uc_mcontext);
     542        status = user_memcpy(userContext, &ucontext, sizeof(ucontext));
     543    } else {
     544        userStack -= (sizeof(struct vregs) + 3) / 4;
     545        userRegs = userStack;
     546        status = user_memcpy(userRegs, &ucontext.uc_mcontext, sizeof(struct vregs));
     547    }
    526548    if (status < B_OK)
    527549        return status;
    528550
    arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 
    539561    // now set up the final part
    540562    buffer[0] = (uint32)signalCode; // return address when sa_handler done
    541563    buffer[1] = signal;             // arguments to sa_handler
    542     buffer[2] = (uint32)action->sa_userdata;
    543     buffer[3] = (uint32)userRegs;
     564    if (action->sa_flags & SA_SIGINFO) {
     565        buffer[2] = (uint32)userSiginfo;
     566        buffer[3] = (uint32)userContext;
     567    } else {
     568        buffer[2] = (uint32)action->sa_userdata;
     569        buffer[3] = (uint32)userRegs;
     570    }
    544571
    545572    buffer[4] = signalMask;         // Old signal mask to restore
    546573    buffer[5] = (uint32)userRegs;   // Int frame + extra regs to restore
    arch_setup_signal_frame(struct thread *thread, struct sigaction *action, 
    552579        return status;
    553580
    554581    frame->user_esp = (uint32)userStack;
    555     frame->eip = (uint32)action->sa_handler;
     582    frame->eip = (action->sa_flags & SA_SIGINFO) ? (uint32)action->sa_sigaction : (uint32)action->sa_handler;
    556583
    557584    return B_OK;
    558585}