The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/bsd/dev/i386/unix_signal.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e5b1cc4a718ecc7347b7cdc25e2cc789


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.