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