Annotation of kernel/machdep/i386/unix_signal.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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