|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.