Annotation of XNU/bsd/dev/i386/unix_signal.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /* 
                     23:  * Copyright (c) 1992 NeXT, Inc.
                     24:  *
                     25:  * HISTORY
                     26:  * 13 May 1992 ? at NeXT
                     27:  *     Created.
                     28:  */
                     29: 
                     30: #include <mach/mach_types.h>
                     31: #include <mach/exception.h>
                     32: 
                     33: #include <kern/thread.h>
                     34: #include <kern/thread_act.h>
                     35: 
                     36: #include <sys/param.h>
                     37: #include <sys/proc.h>
                     38: #include <sys/user.h>
                     39: 
                     40: #include <i386/psl.h>
                     41: 
                     42: #include <mach/i386/thread_status.h>
                     43: #include <dev/i386/sel_inline.h>
                     44: 
                     45: 
                     46: /*
                     47:  * FIXME.. should be included from mach_kernel/i386/seg.h
                     48:  */
                     49: 
                     50: #define        USER_CS 0x17
                     51: #define        USER_DS 0x1f
                     52: 
                     53: #define        UDATA_SEL       USER_DS
                     54: #define        UCODE_SEL       USER_CS
                     55: 
                     56: #define        valid_user_code_selector(x)     (TRUE)
                     57: #define        valid_user_data_selector(x)     (TRUE)
                     58: #define        valid_user_stack_selector(x)    (TRUE)
                     59: 
                     60: 
                     61: #define        NULL_SEG        0
                     62: 
                     63: /*
                     64:  * Send an interrupt to process.
                     65:  *
                     66:  * Stack is set up to allow sigcode stored
                     67:  * in u. to call routine, followed by chmk
                     68:  * to sigreturn routine below.  After sigreturn
                     69:  * resets the signal mask, the stack, the frame 
                     70:  * pointer, and the argument pointer, it returns
                     71:  * to the user specified pc, psl.
                     72:  */
                     73: 
                     74: void
                     75: sendsig(p, catcher, sig, mask, code)
                     76:        struct proc *p;
                     77:        sig_t catcher;
                     78:        int sig, mask;
                     79:        u_long code;
                     80: {
                     81:     struct sigframe {
                     82:        int                     retaddr;
                     83:        int                     sig;
                     84:        int                     code;
                     85:        struct sigcontext *     scp;
                     86:     }                          frame, *fp;
                     87:     struct sigcontext          context, *scp;
                     88:        struct sigacts *ps = p->p_sigacts;
                     89:     int                                oonstack;
                     90:     thread_t                   thread = current_thread();
                     91:     thread_act_t               th_act = current_act();
                     92:     struct i386_saved_state *  saved_state = get_user_regs(th_act);
                     93:     
                     94:        oonstack = ps->ps_sigstk.ss_flags & SA_ONSTACK;
                     95:     if ((ps->ps_flags & SAS_ALTSTACK) && !oonstack &&
                     96:                (ps->ps_sigonstack & sigmask(sig))) {
                     97:                scp = ((struct sigcontext *)ps->ps_sigstk.ss_sp) - 1;
                     98:                        ps->ps_sigstk.ss_flags |= SA_ONSTACK;
                     99:     } else
                    100:            scp = ((struct sigcontext *)saved_state->uesp) - 1;
                    101:     fp = ((struct sigframe *)scp) - 1;
                    102: 
                    103:     /* 
                    104:      * Build the argument list for the signal handler.
                    105:      */
                    106: 
                    107:     frame.retaddr = 0xffffffff;        /* Handler should call sigreturn to get out of it */
                    108:     frame.sig = sig;
                    109: 
                    110:     if (sig == SIGILL || sig == SIGFPE) {
                    111:            frame.code = code;
                    112:     } else
                    113:            frame.code = 0;
                    114:     frame.scp = scp;
                    115:     if (copyout((caddr_t)&frame, (caddr_t)fp, sizeof (frame))) 
                    116:        goto bad;
                    117: 
                    118: #if    PC_SUPPORT
                    119:     {
                    120:        PCcontext_t     context = threadPCContext(thread);
                    121:        
                    122:        if (context && context->running) {
                    123:            oonstack |= 02;
                    124:            context->running = FALSE;
                    125:        }
                    126:     }
                    127: #endif
                    128:     /*
                    129:      * Build the signal context to be used by sigreturn.
                    130:      */
                    131:     context.sc_onstack = oonstack;
                    132:     context.sc_mask = mask;
                    133:     context.sc_eax = saved_state->eax;
                    134:     context.sc_ebx = saved_state->ebx;
                    135:     context.sc_ecx = saved_state->ecx;
                    136:     context.sc_edx = saved_state->edx;
                    137:     context.sc_edi = saved_state->edi;
                    138:     context.sc_esi = saved_state->esi;
                    139:     context.sc_ebp = saved_state->ebp;
                    140:     context.sc_esp = saved_state->uesp;
                    141:     context.sc_ss = saved_state->ss;
                    142:     context.sc_eflags = saved_state->efl;
                    143:     context.sc_eip = saved_state->eip;
                    144:     context.sc_cs = saved_state->cs;
                    145:     if (saved_state->efl & EFL_VM) {
                    146:        context.sc_ds = saved_state->v86_segs.v86_ds;
                    147:        context.sc_es = saved_state->v86_segs.v86_es;
                    148:        context.sc_fs = saved_state->v86_segs.v86_fs;
                    149:        context.sc_gs = saved_state->v86_segs.v86_gs;
                    150: 
                    151:        saved_state->efl &= ~EFL_VM;
                    152:     }
                    153:     else {
                    154:        context.sc_ds = saved_state->ds;
                    155:        context.sc_es = saved_state->es;
                    156:        context.sc_fs = saved_state->fs;
                    157:        context.sc_gs = saved_state->gs;
                    158:     }
                    159:     if (copyout((caddr_t)&context, (caddr_t)scp, sizeof (context))) 
                    160:        goto bad;
                    161: 
                    162:     saved_state->eip = (unsigned int)catcher;
                    163:     saved_state->cs = UCODE_SEL;
                    164: 
                    165:     saved_state->uesp = (unsigned int)fp;
                    166:     saved_state->ss = UDATA_SEL;
                    167: 
                    168:     saved_state->ds = UDATA_SEL;
                    169:     saved_state->es = UDATA_SEL;
                    170:     saved_state->fs = NULL_SEG;
                    171:     saved_state->gs = NULL_SEG;
                    172:     return;
                    173: 
                    174: bad:
                    175:        SIGACTION(p, SIGILL) = SIG_DFL;
                    176:        sig = sigmask(SIGILL);
                    177:        p->p_sigignore &= ~sig;
                    178:        p->p_sigcatch &= ~sig;
                    179:        p->p_sigmask &= ~sig;
                    180:        psignal(p, SIGILL);
                    181:        return;
                    182: }
                    183: 
                    184: /*
                    185:  * System call to cleanup state after a signal
                    186:  * has been taken.  Reset signal mask and
                    187:  * stack state from context left by sendsig (above).
                    188:  * Return to previous pc and psl as specified by
                    189:  * context left by sendsig. Check carefully to
                    190:  * make sure that the user has not modified the
                    191:  * psl to gain improper priviledges or to cause
                    192:  * a machine fault.
                    193:  */
                    194: struct sigreturn_args {
                    195:        struct sigcontext *sigcntxp;
                    196: };
                    197: /* ARGSUSED */
                    198: int
                    199: sigreturn(p, uap, retval)
                    200:        struct proc *p;
                    201:        struct sigreturn_args *uap;
                    202:        int *retval;
                    203: {
                    204:     struct sigcontext          context;
                    205:     thread_t                   thread = current_thread();
                    206:     thread_act_t               th_act = current_act();
                    207:        int error;
                    208:     struct i386_saved_state*   saved_state = get_user_regs(th_act);    
                    209:     
                    210:     if (saved_state == NULL) 
                    211:        return EINVAL;
                    212: 
                    213:     if (error = copyin((caddr_t)uap->sigcntxp, (caddr_t)&context, 
                    214:                                                sizeof (context))) 
                    215:                                        return(error);
                    216: 
                    217: #if 0 /*FIXME*/
                    218:     if ((context.sc_eflags & EFL_VM) == 0 &&
                    219:           (!valid_user_code_selector(context.sc_cs) ||
                    220:            !valid_user_data_selector(context.sc_ds) ||
                    221:            !valid_user_data_selector(context.sc_es) ||
                    222:            !valid_user_data_selector(context.sc_fs) ||
                    223:            !valid_user_data_selector(context.sc_gs) ||
                    224:            !valid_user_stack_selector(context.sc_ss))
                    225:        )
                    226:        return(EINVAL);
                    227: #endif
                    228: 
                    229:     if (context.sc_onstack & 01)
                    230:                        p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
                    231:        else
                    232:                p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
                    233:        p->p_sigmask = context.sc_mask &~ sigcantmask;
                    234:     saved_state->eax = context.sc_eax;
                    235:     saved_state->ebx = context.sc_ebx;
                    236:     saved_state->ecx = context.sc_ecx;
                    237:     saved_state->edx = context.sc_edx;
                    238:     saved_state->edi = context.sc_edi;
                    239:     saved_state->esi = context.sc_esi;
                    240:     saved_state->ebp = context.sc_ebp;
                    241:     saved_state->uesp = context.sc_esp;
                    242:     saved_state->ss = context.sc_ss;
                    243:     saved_state->efl = context.sc_eflags;
                    244:     saved_state->efl &= ~EFL_USERCLR;
                    245:     saved_state->efl |= EFL_USERSET;
                    246:     saved_state->eip = context.sc_eip;
                    247:     saved_state->cs = context.sc_cs;
                    248: 
                    249:     if (context.sc_eflags & EFL_VM) {
                    250:        saved_state->ds = NULL_SEG;
                    251:        saved_state->es = NULL_SEG;
                    252:        saved_state->fs = NULL_SEG;
                    253:        saved_state->gs = NULL_SEG;
                    254:        saved_state->v86_segs.v86_ds = context.sc_ds;
                    255:        saved_state->v86_segs.v86_es = context.sc_es;
                    256:        saved_state->v86_segs.v86_fs = context.sc_fs;
                    257:        saved_state->v86_segs.v86_gs = context.sc_gs;
                    258: 
                    259:        saved_state->efl |= EFL_VM;
                    260:     }
                    261:     else {
                    262:        saved_state->ds = context.sc_ds;
                    263:        saved_state->es = context.sc_es;
                    264:        saved_state->fs = context.sc_fs;
                    265:        saved_state->gs = context.sc_gs;
                    266:     }
                    267: 
                    268: #if    PC_SUPPORT
                    269:     if (context.sc_onstack & 02) {
                    270:        PCcontext_t     context = threadPCContext(thread);
                    271:        
                    272:        if (context)
                    273:            context->running = TRUE;
                    274:     }
                    275: #endif
                    276: 
                    277:        return (EJUSTRETURN);
                    278: }
                    279: 
                    280: /*
                    281:  * machine_exception() performs MD translation
                    282:  * of a mach exception to a unix signal and code.
                    283:  */
                    284: 
                    285: boolean_t
                    286: machine_exception(
                    287:     int                exception,
                    288:     int                code,
                    289:     int                subcode,
                    290:     int                *unix_signal,
                    291:     int                *unix_code
                    292: )
                    293: {
                    294: 
                    295:     switch(exception) {
                    296: 
                    297:     case EXC_BAD_INSTRUCTION:
                    298:        *unix_signal = SIGILL;
                    299:        *unix_code = code;
                    300:        break;
                    301: 
                    302:     case EXC_ARITHMETIC:
                    303:        *unix_signal = SIGFPE;
                    304:        *unix_code = code;
                    305:        break;
                    306: 
                    307:     default:
                    308:        return(FALSE);
                    309:     }
                    310:    
                    311:     return(TRUE);
                    312: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.