Annotation of kernel/machdep/ppc/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) 1993 NeXT, Inc.
                     27:  *
                     28:  * HISTORY
                     29:  * 23 Aug 93 Mac Gillon 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 <ppc/signal.h>
                     41: #import <sys/signalvar.h>
                     42: #import <kern/thread.h>
                     43: #import <mach/ppc/thread_status.h>
                     44: #import <machdep/ppc/proc_reg.h>
                     45: #import <machdep/ppc/fpu.h>
                     46: 
                     47: #define        C_REDZONE_LEN           224
                     48: #define        C_STK_ALIGN                     16
                     49: #define C_PARAMSAVE_LEN                64
                     50: #define        C_LINKAGE_LEN           48
                     51: #define TRUNC_DOWN(a,b,c)  (((((unsigned)a)-(b))/(c)) * (c))
                     52: #define NBITS (MASK(MSR_POW)|MASK(MSR_ILE)|MASK(MSR_IP)|MASK(MSR_LE))
                     53: #define RBITS (MASK(MSR_PR)|MASK(MSR_ME)|MASK(MSR_IR)|MASK(MSR_DR)|MASK(MSR_EE))
                     54: 
                     55: 
                     56: /*
                     57:  * Arrange for this process to run a signal handler
                     58:  */
                     59: 
                     60: 
                     61: struct sigregs {
                     62:        struct ppc_saved_state ss;
                     63:        struct ppc_float_state fs;
                     64: };
                     65: 
                     66: void
                     67: sendsig(p, catcher, sig, mask, code)
                     68:        struct proc *p;
                     69:        sig_t catcher;
                     70:        int sig, mask;
                     71:        u_long code;
                     72: {
                     73:        struct sigregs *p_regs;
                     74:        struct sigcontext context, *p_context;
                     75:        struct sigacts *ps = p->p_sigacts;
                     76:        int framesize;
                     77:        int oonstack;
                     78:        unsigned long sp;
                     79:        struct ppc_saved_state *statep;
                     80:        struct thread *thread;
                     81:        unsigned long paramp,linkp;
                     82: 
                     83:        thread = current_thread();
                     84: 
                     85:        statep = &(thread->pcb->ss);
                     86: 
                     87:        oonstack = ps->ps_sigstk.ss_flags & SA_ONSTACK;
                     88: 
                     89:        /* figure out where our new stack lives */
                     90:        if ((ps->ps_flags & SAS_ALTSTACK) && !oonstack &&
                     91:                (ps->ps_sigonstack & sigmask(sig))) {
                     92:                sp = (unsigned long)(ps->ps_sigstk.ss_sp);
                     93:                ps->ps_sigstk.ss_flags |= SA_ONSTACK;
                     94:        }
                     95:        else
                     96:                sp = statep->r1;
                     97: 
                     98:        // preserve RED ZONE area
                     99:        sp = TRUNC_DOWN(sp, C_REDZONE_LEN, C_STK_ALIGN);
                    100: 
                    101:        // context goes first on stack
                    102:        sp -= sizeof(*p_context);
                    103:        p_context = (struct sigcontext *) sp;
                    104: 
                    105:        // next are the saved registers
                    106:        sp -= sizeof(*p_regs);
                    107:        p_regs = (struct sigregs *)sp;
                    108: 
                    109:        // C calling conventions, create param save and linkage
                    110:        // areas
                    111: 
                    112:        sp = TRUNC_DOWN(sp, C_PARAMSAVE_LEN, C_STK_ALIGN);
                    113:        paramp = sp;
                    114:        sp -= C_LINKAGE_LEN;
                    115:        linkp = sp;
                    116: 
                    117:        /* flush fpu registers to pcb */
                    118:        fp_state_save(thread);
                    119: 
                    120:        /* fill out sigcontext */
                    121:        context.sc_onstack = oonstack;
                    122:        context.sc_mask = mask;
                    123:        context.sc_ir = statep->srr0;
                    124:        context.sc_psw = statep->srr1;
                    125:        context.sc_regs = p_regs;
                    126: 
                    127:        /* copy info out to user space */
                    128:        if (copyout((caddr_t)&context, (caddr_t)p_context, sizeof(context)))
                    129:                goto bad;
                    130:        if (copyout((caddr_t)statep, (caddr_t)&p_regs->ss, 
                    131:                        sizeof(struct ppc_saved_state)))
                    132:                goto bad;
                    133:        if (copyout((caddr_t)&thread->pcb->fs, (caddr_t)&p_regs->fs,
                    134:                        sizeof(struct ppc_float_state)))
                    135:                goto bad;
                    136: 
                    137:        /* Place our arguments in arg registers: rtm dependent */
                    138: 
                    139:        statep->r3 = (unsigned long)sig;
                    140:        statep->r4 = (unsigned long)code;
                    141:        statep->r5 = (unsigned long)p_context;
                    142: 
                    143:        statep->srr0 = (unsigned long)catcher;
                    144:        statep->srr1 = MSR_EXPORT_MASK_SET;
                    145:        statep->r1 = sp;
                    146: 
                    147:        return;
                    148: 
                    149: bad:
                    150:        SIGACTION(p, SIGILL) = SIG_DFL;
                    151:        sig = sigmask(SIGILL);
                    152:        p->p_sigignore &= ~sig;
                    153:        p->p_sigcatch &= ~sig;
                    154:        p->p_sigmask &= ~sig;
                    155:        psignal(p, SIGILL);
                    156:        return;
                    157: }
                    158: 
                    159: /*
                    160:  * System call to cleanup state after a signal
                    161:  * has been taken.  Reset signal mask and
                    162:  * stack state from context left by sendsig (above).
                    163:  * Return to previous pc and psl as specified by
                    164:  * context left by sendsig. Check carefully to
                    165:  * make sure that the user has not modified the
                    166:  * psl to gain improper priviledges or to cause
                    167:  * a machine fault.
                    168:  */
                    169: struct sigreturn_args {
                    170:        struct sigcontext *sigcntxp;
                    171: };
                    172: 
                    173: /* ARGSUSED */
                    174: int
                    175: sigreturn(p, uap, retval)
                    176:        struct proc *p;
                    177:        struct sigreturn_args *uap;
                    178:        int *retval;
                    179: {
                    180:        struct sigcontext context;
                    181:        struct sigregs *p_regs;
                    182:        int error;
                    183:        struct thread *thread;
                    184: 
                    185:        thread = current_thread();
                    186: 
                    187:        if (error = copyin(uap->sigcntxp, &context, sizeof(context))) {
                    188:                return(error);
                    189:        }
                    190:        
                    191:        /* adjust the critical fields */
                    192:        /* make sure naughty bits are off */
                    193:        context.sc_psw &= ~(NBITS);
                    194:        /* make sure necessary bits are on */
                    195:        context.sc_psw |= (RBITS);
                    196: 
                    197: //     /* we return from sigreturns as if we faulted in */
                    198: //     entry->es_flags = (entry->es_flags & ~ES_GATEWAY) | ES_TRAP;
                    199: 
                    200:        if (context.sc_regs) {
                    201:                p_regs = (struct sigregs *)context.sc_regs;
                    202:                if (error = copyin(&p_regs->ss, &thread->pcb->ss,
                    203:                                sizeof(struct ppc_saved_state)))
                    204:                        return(error);
                    205: 
                    206:                if (error = copyin(&p_regs->fs, &thread->pcb->fs,
                    207:                                sizeof(struct ppc_float_state)))
                    208:                        return(error);
                    209: 
                    210:                }
                    211:        else {
                    212:                thread->pcb->ss.r1 = context.sc_sp;
                    213:        }
                    214: //             entry->es_general.saved.stack_pointer = context.sc_sp;
                    215: 
                    216:        if (context.sc_onstack & 01)
                    217:                        p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
                    218:        else
                    219:                p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
                    220:        p->p_sigmask = context.sc_mask &~ sigcantmask;
                    221:        thread->pcb->ss.srr0 = context.sc_ir;
                    222:        thread->pcb->ss.srr1 = context.sc_psw;
                    223: 
                    224:        return (EJUSTRETURN);
                    225: }
                    226: 
                    227: /*
                    228:  * machine_exception() performs MD translation
                    229:  * of a mach exception to a unix signal and code.
                    230:  */
                    231: 
                    232: boolean_t
                    233: machine_exception(
                    234:     int                exception,
                    235:     int                code,
                    236:     int                subcode,
                    237:     int                *unix_signal,
                    238:     int                *unix_code
                    239: )
                    240: {
                    241:     switch(exception) {
                    242: 
                    243:     case EXC_BAD_INSTRUCTION:
                    244:        *unix_signal = SIGILL;
                    245:        *unix_code = code;
                    246:        break;
                    247: 
                    248:     case EXC_ARITHMETIC:
                    249:        *unix_signal = SIGFPE;
                    250:        *unix_code = code;
                    251:        break;
                    252: 
                    253:     default:
                    254:        return(FALSE);
                    255:     }
                    256:    
                    257:     return(TRUE);
                    258: }
                    259: 

unix.superglobalmegacorp.com

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