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