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-2006 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    6  * This file contains Original Code and/or Modifications of Original Code
    7  * as defined in and that are subject to the Apple Public Source License
    8  * Version 2.0 (the 'License'). You may not use this file except in
    9  * compliance with the License. The rights granted to you under the License
   10  * may not be used to create, or enable the creation or redistribution of,
   11  * unlawful or unlicensed copies of an Apple operating system, or to
   12  * circumvent, violate, or enable the circumvention or violation of, any
   13  * terms of an Apple operating system software license agreement.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   18  * The Original Code and all software distributed under the License are
   19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   23  * Please see the License for the specific language governing rights and
   24  * limitations under the License.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   28 /* 
   29  * Copyright (c) 1992 NeXT, Inc.
   30  *
   31  * HISTORY
   32  * 13 May 1992 ? at NeXT
   33  *      Created.
   34  */
   35 
   36 #include <mach/mach_types.h>
   37 #include <mach/exception.h>
   38 
   39 #include <kern/thread.h>
   40 
   41 #include <sys/systm.h>
   42 #include <sys/param.h>
   43 #include <sys/proc_internal.h>
   44 #include <sys/user.h>
   45 #include <sys/sysproto.h>
   46 #include <sys/sysent.h>
   47 #include <sys/ucontext.h>
   48 #include <sys/wait.h>
   49 #include <mach/thread_act.h>    /* for thread_abort_safely */
   50 #include <mach/thread_status.h> 
   51 
   52 #include <i386/eflags.h>
   53 #include <i386/psl.h>
   54 #include <i386/machine_routines.h>
   55 #include <i386/seg.h>
   56 
   57 #include <machine/pal_routines.h>
   58 
   59 #include <sys/kdebug.h>
   60 #include <sys/sdt.h>
   61 
   62 
   63 /* Forward: */
   64 extern boolean_t machine_exception(int, mach_exception_code_t, 
   65                 mach_exception_subcode_t, int *, mach_exception_subcode_t *);
   66 extern kern_return_t thread_getstatus(register thread_t act, int flavor,
   67                         thread_state_t tstate, mach_msg_type_number_t *count);
   68 extern kern_return_t thread_setstatus(thread_t thread, int flavor,
   69                         thread_state_t tstate, mach_msg_type_number_t count);
   70 
   71 /* Signal handler flavors supported */
   72 /* These defns should match the Libc implmn */
   73 #define UC_TRAD                 1
   74 #define UC_FLAVOR               30
   75 #define UC_SET_ALT_STACK        0x40000000
   76 #define UC_RESET_ALT_STACK      0x80000000
   77 
   78 #define C_32_STK_ALIGN          16
   79 #define C_64_STK_ALIGN          16
   80 #define C_64_REDZONE_LEN        128
   81 #define TRUNC_DOWN32(a,c)       ((((uint32_t)a)-(c)) & ((uint32_t)(-(c))))
   82 #define TRUNC_DOWN64(a,c)       ((((uint64_t)a)-(c)) & ((uint64_t)(-(c))))
   83 
   84 /*
   85  * Send an interrupt to process.
   86  *
   87  * Stack is set up to allow sigcode stored
   88  * in u. to call routine, followed by chmk
   89  * to sigreturn routine below.  After sigreturn
   90  * resets the signal mask, the stack, the frame 
   91  * pointer, and the argument pointer, it returns
   92  * to the user specified pc, psl.
   93  */
   94 struct sigframe32 {
   95         int             retaddr;
   96         user32_addr_t   catcher; /* sig_t */
   97         int             sigstyle;
   98         int             sig;
   99         user32_addr_t   sinfo;  /* siginfo32_t* */
  100         user32_addr_t   uctx;   /* struct ucontext32 */
  101 };
  102 
  103 /*
  104  * NOTE: Source and target may *NOT* overlap!
  105  * XXX: Unify with bsd/kern/kern_exit.c
  106  */
  107 static void
  108 siginfo_user_to_user32_x86(user_siginfo_t *in, user32_siginfo_t *out)
  109 {
  110         out->si_signo   = in->si_signo;
  111         out->si_errno   = in->si_errno;
  112         out->si_code    = in->si_code;
  113         out->si_pid     = in->si_pid;
  114         out->si_uid     = in->si_uid;
  115         out->si_status  = in->si_status;
  116         out->si_addr    = CAST_DOWN_EXPLICIT(user32_addr_t,in->si_addr);
  117         /* following cast works for sival_int because of padding */
  118         out->si_value.sival_ptr = CAST_DOWN_EXPLICIT(user32_addr_t,in->si_value.sival_ptr);
  119         out->si_band    = in->si_band;                  /* range reduction */
  120         out->__pad[0]   = in->pad[0];                   /* mcontext.ss.r1 */
  121 }
  122 
  123 static void
  124 siginfo_user_to_user64_x86(user_siginfo_t *in, user64_siginfo_t *out)
  125 {
  126         out->si_signo   = in->si_signo;
  127         out->si_errno   = in->si_errno;
  128         out->si_code    = in->si_code;
  129         out->si_pid     = in->si_pid;
  130         out->si_uid     = in->si_uid;
  131         out->si_status  = in->si_status;
  132         out->si_addr    = in->si_addr;
  133         out->si_value.sival_ptr = in->si_value.sival_ptr;
  134         out->si_band    = in->si_band;                  /* range reduction */
  135         out->__pad[0]   = in->pad[0];                   /* mcontext.ss.r1 */
  136 }
  137 
  138 void
  139 sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused uint32_t code)
  140 {
  141         union {
  142                 struct mcontext_avx32   mctx_avx32;
  143                 struct mcontext_avx64   mctx_avx64;
  144         } mctx_store, *mctxp = &mctx_store;
  145 
  146         user_addr_t     ua_sp;
  147         user_addr_t     ua_fp;
  148         user_addr_t     ua_cr2;
  149         user_addr_t     ua_sip;
  150         user_addr_t     ua_uctxp;
  151         user_addr_t     ua_mctxp;
  152         user_siginfo_t  sinfo64;
  153 
  154         struct sigacts *ps = p->p_sigacts;
  155         int oonstack, flavor; 
  156         user_addr_t trampact;
  157         int sigonstack;
  158         void * state;
  159         mach_msg_type_number_t state_count;
  160 
  161         thread_t thread;
  162         struct uthread * ut;
  163         int stack_size = 0;
  164         int infostyle = UC_TRAD;
  165         boolean_t       sig_avx;
  166 
  167         thread = current_thread();
  168         ut = get_bsdthread_info(thread);
  169 
  170         if (p->p_sigacts->ps_siginfo & sigmask(sig))
  171                 infostyle = UC_FLAVOR;
  172 
  173         oonstack = ut->uu_sigstk.ss_flags & SA_ONSTACK;
  174         trampact = ps->ps_trampact[sig];
  175         sigonstack = (ps->ps_sigonstack & sigmask(sig));
  176 
  177         /*
  178          * init siginfo
  179          */
  180         proc_unlock(p);
  181 
  182         bzero((caddr_t)&sinfo64, sizeof(sinfo64));
  183         sinfo64.si_signo = sig;
  184 
  185         bzero(mctxp, sizeof(*mctxp));
  186         sig_avx = ml_fpu_avx_enabled();
  187 
  188         if (proc_is64bit(p)) {
  189                 x86_thread_state64_t    *tstate64;
  190                 struct user_ucontext64  uctx64;
  191 
  192                 flavor = x86_THREAD_STATE64;
  193                 state_count = x86_THREAD_STATE64_COUNT;
  194                 state = (void *)&mctxp->mctx_avx64.ss;
  195                 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
  196                         goto bad;
  197 
  198                 if (sig_avx) {
  199                         flavor = x86_AVX_STATE64;
  200                         state_count = x86_AVX_STATE64_COUNT;
  201                 }
  202                 else {
  203                         flavor = x86_FLOAT_STATE64;
  204                         state_count = x86_FLOAT_STATE64_COUNT;
  205                 }
  206                 state = (void *)&mctxp->mctx_avx64.fs;
  207                 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
  208                         goto bad;
  209 
  210                 flavor = x86_EXCEPTION_STATE64;
  211                 state_count = x86_EXCEPTION_STATE64_COUNT;
  212                 state = (void *)&mctxp->mctx_avx64.es;
  213                 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
  214                         goto bad;
  215 
  216                 tstate64 = &mctxp->mctx_avx64.ss;
  217 
  218                 /* figure out where our new stack lives */
  219                 if ((ut->uu_flag & UT_ALTSTACK) && !oonstack &&
  220                     (sigonstack)) {
  221                         ua_sp = ut->uu_sigstk.ss_sp;
  222                         stack_size = ut->uu_sigstk.ss_size;
  223                         ua_sp += stack_size;
  224                         ut->uu_sigstk.ss_flags |= SA_ONSTACK;
  225                 } else {
  226                         ua_sp = tstate64->rsp;
  227                 }
  228                 ua_cr2 = mctxp->mctx_avx64.es.faultvaddr;
  229 
  230                 /* The x86_64 ABI defines a 128-byte red zone. */
  231                 ua_sp -= C_64_REDZONE_LEN;
  232 
  233                 ua_sp -= sizeof (struct user_ucontext64);
  234                 ua_uctxp = ua_sp;                        // someone tramples the first word!
  235 
  236                 ua_sp -= sizeof (user64_siginfo_t);
  237                 ua_sip = ua_sp;
  238 
  239                 ua_sp -= sizeof (struct mcontext_avx64);
  240                 ua_mctxp = ua_sp;
  241 
  242                 /*
  243                  * Align the frame and stack pointers to 16 bytes for SSE.
  244                  * (Note that we use 'ua_fp' as the base of the stack going forward)
  245                  */
  246                 ua_fp = TRUNC_DOWN64(ua_sp, C_64_STK_ALIGN);
  247 
  248                 /*
  249                  * But we need to account for the return address so the alignment is
  250                  * truly "correct" at _sigtramp
  251                  */
  252                 ua_fp -= sizeof(user_addr_t);
  253 
  254                 /*
  255                  * Build the signal context to be used by sigreturn.
  256                  */
  257                 bzero(&uctx64, sizeof(uctx64));
  258 
  259                 uctx64.uc_onstack = oonstack;
  260                 uctx64.uc_sigmask = mask;
  261                 uctx64.uc_stack.ss_sp = ua_fp;
  262                 uctx64.uc_stack.ss_size = stack_size;
  263 
  264                 if (oonstack)
  265                         uctx64.uc_stack.ss_flags |= SS_ONSTACK; 
  266                 uctx64.uc_link = 0;
  267 
  268                 uctx64.uc_mcsize = sig_avx ? sizeof(struct mcontext_avx64) : sizeof(struct mcontext64);
  269                 uctx64.uc_mcontext64 = ua_mctxp;
  270                 
  271                 if (copyout((caddr_t)&uctx64, ua_uctxp, sizeof (uctx64))) 
  272                         goto bad;
  273 
  274                 if (copyout((caddr_t)&mctxp->mctx_avx64, ua_mctxp, sizeof (struct mcontext_avx64))) 
  275                         goto bad;
  276 
  277                 sinfo64.pad[0]  = tstate64->rsp;
  278                 sinfo64.si_addr = tstate64->rip;
  279 
  280                 tstate64->rip = trampact;
  281                 tstate64->rsp = ua_fp;
  282                 tstate64->rflags = get_eflags_exportmask();
  283                 /*
  284                  * JOE - might not need to set these
  285                  */
  286                 tstate64->cs = USER64_CS;
  287                 tstate64->fs = NULL_SEG;
  288                 tstate64->gs = USER_CTHREAD;
  289 
  290                 /* 
  291                  * Build the argument list for the signal handler.
  292                  * Handler should call sigreturn to get out of it
  293                  */
  294                 tstate64->rdi = ua_catcher;
  295                 tstate64->rsi = infostyle;
  296                 tstate64->rdx = sig;
  297                 tstate64->rcx = ua_sip;
  298                 tstate64->r8  = ua_uctxp;
  299 
  300         } else {
  301                 x86_thread_state32_t    *tstate32;
  302                 struct user_ucontext32  uctx32;
  303                 struct sigframe32       frame32;
  304 
  305                 flavor = x86_THREAD_STATE32;
  306                 state_count = x86_THREAD_STATE32_COUNT;
  307                 state = (void *)&mctxp->mctx_avx32.ss;
  308                 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
  309                         goto bad;
  310 
  311                 if (sig_avx) {
  312                         flavor = x86_AVX_STATE32;
  313                         state_count = x86_AVX_STATE32_COUNT;
  314                 }
  315                 else {
  316                         flavor = x86_FLOAT_STATE32;
  317                         state_count = x86_FLOAT_STATE32_COUNT;
  318                 }
  319 
  320                 state = (void *)&mctxp->mctx_avx32.fs;
  321                 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
  322                         goto bad;
  323 
  324                 flavor = x86_EXCEPTION_STATE32;
  325                 state_count = x86_EXCEPTION_STATE32_COUNT;
  326                 state = (void *)&mctxp->mctx_avx32.es;
  327                 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
  328                         goto bad;
  329 
  330                 tstate32 = &mctxp->mctx_avx32.ss;
  331 
  332                 /* figure out where our new stack lives */
  333                 if ((ut->uu_flag & UT_ALTSTACK) && !oonstack &&
  334                     (sigonstack)) {
  335                         ua_sp = ut->uu_sigstk.ss_sp;
  336                         stack_size = ut->uu_sigstk.ss_size;
  337                         ua_sp += stack_size;
  338                         ut->uu_sigstk.ss_flags |= SA_ONSTACK;
  339                 } else {
  340                         ua_sp = tstate32->esp;
  341                 }
  342                 ua_cr2 = mctxp->mctx_avx32.es.faultvaddr;
  343 
  344                 ua_sp -= sizeof (struct user_ucontext32);
  345                 ua_uctxp = ua_sp;                        // someone tramples the first word!
  346 
  347                 ua_sp -= sizeof (user32_siginfo_t);
  348                 ua_sip = ua_sp;
  349 
  350                 ua_sp -= sizeof (struct mcontext_avx32);
  351                 ua_mctxp = ua_sp;
  352 
  353                 ua_sp -= sizeof (struct sigframe32);
  354                 ua_fp = ua_sp;
  355 
  356                 /*
  357                  * Align the frame and stack pointers to 16 bytes for SSE.
  358                  * (Note that we use 'fp' as the base of the stack going forward)
  359                  */
  360                 ua_fp = TRUNC_DOWN32(ua_fp, C_32_STK_ALIGN);
  361 
  362                 /*
  363                  * But we need to account for the return address so the alignment is
  364                  * truly "correct" at _sigtramp
  365                  */
  366                 ua_fp -= sizeof(frame32.retaddr);
  367 
  368                 /* 
  369                  * Build the argument list for the signal handler.
  370                  * Handler should call sigreturn to get out of it
  371                  */
  372                 frame32.retaddr = -1;   
  373                 frame32.sigstyle = infostyle;
  374                 frame32.sig = sig;
  375                 frame32.catcher = CAST_DOWN_EXPLICIT(user32_addr_t, ua_catcher);
  376                 frame32.sinfo = CAST_DOWN_EXPLICIT(user32_addr_t, ua_sip);
  377                 frame32.uctx = CAST_DOWN_EXPLICIT(user32_addr_t, ua_uctxp);
  378 
  379                 if (copyout((caddr_t)&frame32, ua_fp, sizeof (frame32))) 
  380                         goto bad;
  381 
  382                 /*
  383                  * Build the signal context to be used by sigreturn.
  384                  */
  385                 bzero(&uctx32, sizeof(uctx32));
  386 
  387                 uctx32.uc_onstack = oonstack;
  388                 uctx32.uc_sigmask = mask;
  389                 uctx32.uc_stack.ss_sp = CAST_DOWN_EXPLICIT(user32_addr_t, ua_fp);
  390                 uctx32.uc_stack.ss_size = stack_size;
  391 
  392                 if (oonstack)
  393                         uctx32.uc_stack.ss_flags |= SS_ONSTACK; 
  394                 uctx32.uc_link = 0;
  395 
  396                 uctx32.uc_mcsize = sig_avx ? sizeof(struct mcontext_avx32) : sizeof(struct mcontext32);
  397 
  398                 uctx32.uc_mcontext = CAST_DOWN_EXPLICIT(user32_addr_t, ua_mctxp);
  399                 
  400                 if (copyout((caddr_t)&uctx32, ua_uctxp, sizeof (uctx32))) 
  401                         goto bad;
  402 
  403                 if (copyout((caddr_t)&mctxp->mctx_avx32, ua_mctxp, sizeof (struct mcontext_avx32))) 
  404                         goto bad;
  405 
  406                 sinfo64.pad[0]  = tstate32->esp;
  407                 sinfo64.si_addr = tstate32->eip;
  408         }
  409 
  410         switch (sig) {
  411                 case SIGILL:
  412                         switch (ut->uu_code) {
  413                                 case EXC_I386_INVOP:
  414                                         sinfo64.si_code = ILL_ILLOPC;
  415                                         break;
  416                                 default:
  417                                         sinfo64.si_code = ILL_NOOP;
  418                         }
  419                         break;
  420                 case SIGFPE:
  421 #define FP_IE 0 /* Invalid operation */
  422 #define FP_DE 1 /* Denormalized operand */
  423 #define FP_ZE 2 /* Zero divide */
  424 #define FP_OE 3 /* overflow */
  425 #define FP_UE 4 /* underflow */
  426 #define FP_PE 5 /* precision */
  427                         if (ut->uu_code == EXC_I386_DIV) {
  428                                 sinfo64.si_code = FPE_INTDIV;
  429                         }
  430                         else if (ut->uu_code == EXC_I386_INTO) {
  431                                 sinfo64.si_code = FPE_INTOVF;
  432                         }
  433                         else if (ut->uu_subcode & (1 << FP_ZE)) {
  434                                 sinfo64.si_code = FPE_FLTDIV;
  435                         } else if (ut->uu_subcode & (1 << FP_OE)) {
  436                                 sinfo64.si_code = FPE_FLTOVF;
  437                         } else if (ut->uu_subcode & (1 << FP_UE)) {
  438                                 sinfo64.si_code = FPE_FLTUND;
  439                         } else if (ut->uu_subcode & (1 << FP_PE)) {
  440                                 sinfo64.si_code = FPE_FLTRES;
  441                         } else if (ut->uu_subcode & (1 << FP_IE)) {
  442                                 sinfo64.si_code = FPE_FLTINV;
  443                         } else {
  444                                 sinfo64.si_code = FPE_NOOP;
  445                         }
  446                         break;
  447                 case SIGBUS:
  448                         sinfo64.si_code = BUS_ADRERR;
  449                         sinfo64.si_addr = ua_cr2;
  450                         break;
  451                 case SIGTRAP:
  452                         sinfo64.si_code = TRAP_BRKPT;
  453                         break;
  454                 case SIGSEGV:
  455                         sinfo64.si_addr = ua_cr2;
  456 
  457                         switch (ut->uu_code) {
  458                                 case EXC_I386_GPFLT:
  459                                         /* CR2 is meaningless after GP fault */
  460                                         /* XXX namespace clash! */
  461                                         sinfo64.si_addr = 0ULL;
  462                                         sinfo64.si_code = 0;
  463                                         break;
  464                                 case KERN_PROTECTION_FAILURE:
  465                                         sinfo64.si_code = SEGV_ACCERR;
  466                                         break;
  467                                 case KERN_INVALID_ADDRESS:
  468                                         sinfo64.si_code = SEGV_MAPERR;
  469                                         break;
  470                                 default:
  471                                         sinfo64.si_code = FPE_NOOP;
  472                         }
  473                                 break;
  474                 default:
  475                 {
  476                         int status_and_exitcode;
  477 
  478                         /*
  479                          * All other signals need to fill out a minimum set of
  480                          * information for the siginfo structure passed into
  481                          * the signal handler, if SA_SIGINFO was specified.
  482                          *
  483                          * p->si_status actually contains both the status and
  484                          * the exit code; we save it off in its own variable
  485                          * for later breakdown.
  486                          */
  487                         proc_lock(p);
  488                         sinfo64.si_pid = p->si_pid;
  489                         p->si_pid =0;
  490                         status_and_exitcode = p->si_status;
  491                         p->si_status = 0;
  492                         sinfo64.si_uid = p->si_uid;
  493                         p->si_uid =0;
  494                         sinfo64.si_code = p->si_code;
  495                         p->si_code = 0;
  496                         proc_unlock(p);
  497                         if (sinfo64.si_code == CLD_EXITED) {
  498                                 if (WIFEXITED(status_and_exitcode)) 
  499                                         sinfo64.si_code = CLD_EXITED;
  500                                 else if (WIFSIGNALED(status_and_exitcode)) {
  501                                         if (WCOREDUMP(status_and_exitcode)) {
  502                                                 sinfo64.si_code = CLD_DUMPED;
  503                                                 status_and_exitcode = W_EXITCODE(status_and_exitcode,status_and_exitcode);
  504                                         } else {
  505                                                 sinfo64.si_code = CLD_KILLED;
  506                                                 status_and_exitcode = W_EXITCODE(status_and_exitcode,status_and_exitcode);
  507                                         }
  508                                 }
  509                         }
  510                         /*
  511                          * The recorded status contains the exit code and the
  512                          * signal information, but the information to be passed
  513                          * in the siginfo to the handler is supposed to only
  514                          * contain the status, so we have to shift it out.
  515                          */
  516                         sinfo64.si_status = WEXITSTATUS(status_and_exitcode);
  517                         break;
  518                 }
  519         }
  520         if (proc_is64bit(p)) {
  521                 user64_siginfo_t sinfo64_user64;
  522                 
  523                 bzero((caddr_t)&sinfo64_user64, sizeof(sinfo64_user64));
  524                           
  525                 siginfo_user_to_user64_x86(&sinfo64,&sinfo64_user64);
  526 
  527 #if CONFIG_DTRACE
  528         bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo));
  529 
  530         ut->t_dtrace_siginfo.si_signo = sinfo64.si_signo;
  531         ut->t_dtrace_siginfo.si_code = sinfo64.si_code;
  532         ut->t_dtrace_siginfo.si_pid = sinfo64.si_pid;
  533         ut->t_dtrace_siginfo.si_uid = sinfo64.si_uid;
  534         ut->t_dtrace_siginfo.si_status = sinfo64.si_status;
  535                 /* XXX truncates faulting address to void * on K32  */
  536         ut->t_dtrace_siginfo.si_addr = CAST_DOWN(void *, sinfo64.si_addr);
  537 
  538                 /* Fire DTrace proc:::fault probe when signal is generated by hardware. */
  539                 switch (sig) {
  540                 case SIGILL: case SIGBUS: case SIGSEGV: case SIGFPE: case SIGTRAP:
  541                         DTRACE_PROC2(fault, int, (int)(ut->uu_code), siginfo_t *, &(ut->t_dtrace_siginfo));
  542                         break;
  543                 default:
  544                         break;
  545                 }
  546 
  547                 /* XXX truncates catcher address to uintptr_t */
  548                 DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &(ut->t_dtrace_siginfo),
  549                         void (*)(void), CAST_DOWN(sig_t, ua_catcher));
  550 #endif /* CONFIG_DTRACE */
  551 
  552                 if (copyout((caddr_t)&sinfo64_user64, ua_sip, sizeof (sinfo64_user64))) 
  553                         goto bad;
  554 
  555                 flavor = x86_THREAD_STATE64;
  556                 state_count = x86_THREAD_STATE64_COUNT;
  557                 state = (void *)&mctxp->mctx_avx64.ss;
  558         } else {
  559                 x86_thread_state32_t    *tstate32;
  560                 user32_siginfo_t sinfo32;
  561 
  562                 bzero((caddr_t)&sinfo32, sizeof(sinfo32));
  563 
  564                 siginfo_user_to_user32_x86(&sinfo64,&sinfo32);
  565 
  566 #if CONFIG_DTRACE
  567         bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo));
  568 
  569         ut->t_dtrace_siginfo.si_signo = sinfo32.si_signo;
  570         ut->t_dtrace_siginfo.si_code = sinfo32.si_code;
  571         ut->t_dtrace_siginfo.si_pid = sinfo32.si_pid;
  572         ut->t_dtrace_siginfo.si_uid = sinfo32.si_uid;
  573         ut->t_dtrace_siginfo.si_status = sinfo32.si_status;
  574         ut->t_dtrace_siginfo.si_addr = CAST_DOWN(void *, sinfo32.si_addr);
  575 
  576                 /* Fire DTrace proc:::fault probe when signal is generated by hardware. */
  577                 switch (sig) {
  578                 case SIGILL: case SIGBUS: case SIGSEGV: case SIGFPE: case SIGTRAP:
  579                         DTRACE_PROC2(fault, int, (int)(ut->uu_code), siginfo_t *, &(ut->t_dtrace_siginfo));
  580                         break;
  581                 default:
  582                         break;
  583                 }
  584 
  585                 DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &(ut->t_dtrace_siginfo),
  586                         void (*)(void), CAST_DOWN(sig_t, ua_catcher));
  587 #endif /* CONFIG_DTRACE */
  588 
  589                 if (copyout((caddr_t)&sinfo32, ua_sip, sizeof (sinfo32))) 
  590                         goto bad;
  591         
  592                 tstate32 = &mctxp->mctx_avx32.ss;
  593 
  594                 tstate32->eip = CAST_DOWN_EXPLICIT(user32_addr_t, trampact);
  595                 tstate32->esp = CAST_DOWN_EXPLICIT(user32_addr_t, ua_fp);
  596 
  597                 tstate32->eflags = get_eflags_exportmask();
  598 
  599                 tstate32->cs = USER_CS;
  600                 tstate32->ss = USER_DS;
  601                 tstate32->ds = USER_DS;
  602                 tstate32->es = USER_DS;
  603                 tstate32->fs = NULL_SEG;
  604                 tstate32->gs = USER_CTHREAD;
  605 
  606                 flavor = x86_THREAD_STATE32;
  607                 state_count = x86_THREAD_STATE32_COUNT;
  608                 state = (void *)tstate32;
  609         }
  610         if (thread_setstatus(thread, flavor, (thread_state_t)state, state_count) != KERN_SUCCESS)
  611                 goto bad;
  612         ml_fp_setvalid(FALSE);
  613 
  614         /* Tell the PAL layer about the signal */
  615         pal_set_signal_delivery( thread );
  616 
  617         proc_lock(p);
  618 
  619         return;
  620 
  621 bad:
  622 
  623         proc_lock(p);
  624         SIGACTION(p, SIGILL) = SIG_DFL;
  625         sig = sigmask(SIGILL);
  626         p->p_sigignore &= ~sig;
  627         p->p_sigcatch &= ~sig;
  628         ut->uu_sigmask &= ~sig;
  629         /* sendsig is called with signal lock held */
  630         proc_unlock(p);
  631         psignal_locked(p, SIGILL);
  632         proc_lock(p);
  633         return;
  634 }
  635 
  636 /*
  637  * System call to cleanup state after a signal
  638  * has been taken.  Reset signal mask and
  639  * stack state from context left by sendsig (above).
  640  * Return to previous pc and psl as specified by
  641  * context left by sendsig. Check carefully to
  642  * make sure that the user has not modified the
  643  * psl to gain improper priviledges or to cause
  644  * a machine fault.
  645  */
  646 
  647 int
  648 sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval)
  649 {
  650         union {
  651                 struct mcontext_avx32   mctx_avx32;
  652                 struct mcontext_avx64   mctx_avx64;
  653         } mctx_store, *mctxp = &mctx_store;
  654 
  655         thread_t thread = current_thread();
  656         struct uthread * ut;
  657         int     error;
  658         int     onstack = 0;
  659 
  660         mach_msg_type_number_t ts_count;
  661         unsigned int           ts_flavor;
  662         void                *  ts;
  663         mach_msg_type_number_t fs_count;
  664         unsigned int           fs_flavor;
  665         void                *  fs;
  666         int     rval = EJUSTRETURN;
  667         boolean_t       sig_avx;
  668 
  669         ut = (struct uthread *)get_bsdthread_info(thread);
  670 
  671         /*
  672          * If we are being asked to change the altstack flag on the thread, we
  673          * just set/reset it and return (the uap->uctx is not used).
  674          */
  675         if ((unsigned int)uap->infostyle == UC_SET_ALT_STACK) {
  676                 ut->uu_sigstk.ss_flags |= SA_ONSTACK;
  677                 return (0);
  678         } else if ((unsigned int)uap->infostyle == UC_RESET_ALT_STACK) {
  679                 ut->uu_sigstk.ss_flags &= ~SA_ONSTACK;
  680                 return (0);
  681         }
  682 
  683         bzero(mctxp, sizeof(*mctxp));
  684         sig_avx = ml_fpu_avx_enabled();
  685 
  686         if (proc_is64bit(p)) {
  687                 struct user_ucontext64  uctx64;
  688 
  689                 if ((error = copyin(uap->uctx, (void *)&uctx64, sizeof (uctx64))))
  690                         return(error);
  691 
  692                 if ((error = copyin(uctx64.uc_mcontext64, (void *)&mctxp->mctx_avx64, sizeof (struct mcontext_avx64))))
  693                         return(error);
  694 
  695                 onstack = uctx64.uc_onstack & 01;
  696                 ut->uu_sigmask = uctx64.uc_sigmask & ~sigcantmask;
  697 
  698                 ts_flavor = x86_THREAD_STATE64;
  699                 ts_count  = x86_THREAD_STATE64_COUNT;
  700                 ts = (void *)&mctxp->mctx_avx64.ss;
  701 
  702                 if (sig_avx) {
  703                         fs_flavor = x86_AVX_STATE64;
  704                         fs_count = x86_AVX_STATE64_COUNT;
  705                 }
  706                 else {
  707                         fs_flavor = x86_FLOAT_STATE64;
  708                         fs_count = x86_FLOAT_STATE64_COUNT;
  709                 }
  710 
  711                 fs = (void *)&mctxp->mctx_avx64.fs;
  712 
  713       } else {
  714                 struct user_ucontext32  uctx32;
  715 
  716                 if ((error = copyin(uap->uctx, (void *)&uctx32, sizeof (uctx32)))) 
  717                         return(error);
  718 
  719                 if ((error = copyin(CAST_USER_ADDR_T(uctx32.uc_mcontext), (void *)&mctxp->mctx_avx32, sizeof (struct mcontext_avx32)))) 
  720                         return(error);
  721 
  722                 onstack = uctx32.uc_onstack & 01;
  723                 ut->uu_sigmask = uctx32.uc_sigmask & ~sigcantmask;
  724 
  725                 ts_flavor = x86_THREAD_STATE32;
  726                 ts_count  = x86_THREAD_STATE32_COUNT;
  727                 ts = (void *)&mctxp->mctx_avx32.ss;
  728 
  729                 if (sig_avx) {
  730                         fs_flavor = x86_AVX_STATE32;
  731                         fs_count = x86_AVX_STATE32_COUNT;
  732                 }
  733                 else {
  734                         fs_flavor = x86_FLOAT_STATE32;
  735                         fs_count = x86_FLOAT_STATE32_COUNT;
  736                 }
  737 
  738                 fs = (void *)&mctxp->mctx_avx32.fs;
  739         }
  740 
  741         if (onstack)
  742                 ut->uu_sigstk.ss_flags |= SA_ONSTACK;
  743         else
  744                 ut->uu_sigstk.ss_flags &= ~SA_ONSTACK;
  745 
  746         if (ut->uu_siglist & ~ut->uu_sigmask)
  747                 signal_setast(thread);
  748         /*
  749          * thread_set_state() does all the needed checks for the passed in
  750          * content
  751          */
  752         if (thread_setstatus(thread, ts_flavor, ts, ts_count) != KERN_SUCCESS) {
  753                 rval = EINVAL;
  754                 goto error_ret;
  755         }
  756         
  757         ml_fp_setvalid(TRUE);
  758 
  759         if (thread_setstatus(thread, fs_flavor, fs, fs_count)  != KERN_SUCCESS) {
  760                 rval = EINVAL;
  761                 goto error_ret;
  762 
  763         }
  764 error_ret:
  765         return rval;
  766 }
  767 
  768 
  769 /*
  770  * machine_exception() performs MD translation
  771  * of a mach exception to a unix signal and code.
  772  */
  773 
  774 boolean_t
  775 machine_exception(
  776         int                             exception,
  777         mach_exception_code_t           code,
  778         __unused mach_exception_subcode_t subcode,
  779         int                             *unix_signal,
  780         mach_exception_code_t           *unix_code)
  781 {
  782 
  783         switch(exception) {
  784 
  785         case EXC_BAD_ACCESS:
  786                 /* Map GP fault to SIGSEGV, otherwise defer to caller */
  787                 if (code == EXC_I386_GPFLT) {
  788                         *unix_signal = SIGSEGV;
  789                         *unix_code = code;
  790                         break;
  791                 }
  792                 return(FALSE);
  793 
  794         case EXC_BAD_INSTRUCTION:
  795                 *unix_signal = SIGILL;
  796                 *unix_code = code;
  797                 break;
  798 
  799         case EXC_ARITHMETIC:
  800                 *unix_signal = SIGFPE;
  801                 *unix_code = code;
  802                 break;
  803 
  804         case EXC_SOFTWARE:
  805                 if (code == EXC_I386_BOUND) {
  806                         /*
  807                          * Map #BR, the Bound Range Exceeded exception, to
  808                          * SIGTRAP.
  809                          */
  810                         *unix_signal = SIGTRAP;
  811                         *unix_code = code;
  812                         break;
  813                 }
  814 
  815         default:
  816                 return(FALSE);
  817         }
  818    
  819         return(TRUE);
  820 }
  821 

Cache object: df8b30a499cf331c5d847ff96ad7ea65


[ 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.