Ignore:
Timestamp:
Aug 24, 2006, 4:59:35 AM (13 years ago)
Author:
gb
Message:

Darwin needs to decode the mxcsr on SIGFPE.

DARWIN_GS_HACK changes in altstack handlers for interrupt/suspend.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lisp-kernel/x86-exceptions.c

    r5007 r5017  
    571571
    572572
    573 #ifdef FREEBSD
     573#if defined(FREEBSD) || defined(DARWIN)
    574574static
    575575char mxcsr_bit_to_fpe_code[] = {
     
    583583
    584584void
    585 freebsd_decode_vector_fp_exception(siginfo_t *info, ExceptionInformation *xp)
     585decode_vector_fp_exception(siginfo_t *info, uint32_t mxcsr)
    586586{
    587587  /* If the exception appears to be an XMM FP exception, try to
    588588     determine what it was by looking at bits in the mxcsr.
    589589  */
     590  int xbit, maskbit;
     591 
     592  for (xbit = 0, maskbit = MXCSR_IM_BIT; xbit < 6; xbit++, maskbit++) {
     593    if ((mxcsr & (1 << xbit)) &&
     594        !(mxcsr & (1 << maskbit))) {
     595      info->si_code = mxcsr_bit_to_fpe_code[xbit];
     596      return;
     597    }
     598  }
     599}
     600
     601#ifdef FREEBSD
     602void
     603freebsd_decode_vector_fp_exception(siginfo_t *info, ExceptionInformation *xp)
     604{
    590605  if (info->si_code == 0) {
    591606    struct savefpu *fpu = (struct savefpu *) &(xp->uc_mcontext.mc_fpstate);
    592607    uint32_t mxcsr = fpu->sv_env.en_mxcsr;
    593     int xbit, maskbit;
    594    
    595     for (xbit = 0, maskbit = MXCSR_IM_BIT; xbit < 6; xbit++, maskbit++) {
    596       if ((mxcsr & (1 << xbit)) &&
    597           !(mxcsr & (1 << maskbit))) {
    598         info->si_code = mxcsr_bit_to_fpe_code[xbit];
    599         return;
    600       }
    601     }
    602   }
    603 }
     608
     609    decode_vector_fp_exception(info, mxcsr);
     610  }
     611}
     612#endif
     613
     614#ifdef DARWIN
     615void
     616darwin_decode_vector_fp_exception(siginfo_t *info, ExceptionInformation *xp)
     617{
     618  if (info->si_code == EXC_I386_SSEEXTERR) {
     619    uint32_t mxcsr = UC_MCONTEXT(xp)->fs.fpu_mxcsr;
     620
     621    decode_vector_fp_exception(info, mxcsr);
     622  }
     623}
     624
     625#endif
     626
    604627#endif
    605628
     
    691714    freebsd_decode_vector_fp_exception(info,context);
    692715#endif
     716#ifdef DARWIN
     717    /* Same general problem with Darwin as of 8.7.2 */
     718    darwin_decode_vector_fp_exception(info,context);
     719#endif
     720
    693721    return handle_floating_point_exception(tcr, context, info);
    694722
     
    830858#endif
    831859
     860#ifdef DARWIN
     861LispObj *
     862copy_darwin_mcontext(struct mcontext64 *context,
     863                     LispObj *current,
     864                     struct mcontext64 **out)
     865{
     866  struct mcontext64 *dest = ((struct mcontext64 *)current)-1;
     867  dest = (struct mcontext64 *) (((LispObj)dest) & ~15);
     868
     869  *dest = *context;
     870  *out = dest;
     871  return (LispObj *)dest;
     872}
     873#endif
     874
    832875LispObj *
    833876copy_siginfo(siginfo_t *info, LispObj *current)
    834877{
    835878  siginfo_t *dest = ((siginfo_t *)current) - 1;
     879  dest = (siginfo_t *) (((LispObj)dest)&~15);
    836880  *dest = *info;
    837881  return (LispObj *)dest;
     
    954998altstack_interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
    955999{
     1000#ifdef DARWIN_GS_HACK
     1001  Boolean gs_was_tcr = ensure_gs_pthread();
     1002#endif
    9561003  TCR *tcr = get_interrupt_tcr(false);
    9571004  LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
     
    9611008  void *fpregs = NULL;
    9621009#endif
     1010#ifdef DARWIN
     1011  struct mcontext64 *mcontextp = NULL;
     1012#endif
    9631013  siginfo_t *info_copy = NULL;
    9641014  ExceptionInformation *xp = NULL;
     
    9671017#ifdef LINUX
    9681018    foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
     1019#endif
     1020#ifdef DARWIN
     1021    foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    9691022#endif
    9701023    foreign_rsp = copy_siginfo(info, foreign_rsp);
     
    9721025    foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    9731026    xp = (ExceptionInformation *)foreign_rsp;
     1027#ifdef DARWIN
     1028    UC_MCONTEXT(xp) = mcontextp;
     1029#endif
    9741030    *--foreign_rsp = (LispObj)__builtin_return_address(0);
     1031#ifdef DARWIN_GS_HACK
     1032    if (gs_was_tcr) {
     1033      set_gs_address(tcr);
     1034    }
     1035#endif
    9751036    switch_to_foreign_stack(foreign_rsp,interrupt_handler,signum,info_copy,xp);
    9761037  }
     
    9971058install_pmcl_exception_handlers()
    9981059{
    999  
     1060#ifndef DARWIN 
    10001061  install_signal_handler(SIGILL, altstack_signal_handler);
    10011062 
     
    10031064  install_signal_handler(SIGSEGV,altstack_signal_handler);
    10041065  install_signal_handler(SIGFPE, altstack_signal_handler);
    1005 
     1066#endif
    10061067 
    10071068  install_signal_handler(SIGNAL_FOR_PROCESS_INTERRUPT,
     
    10141075altstack_suspend_resume_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
    10151076{
     1077#ifdef DARWIN_GS_HACK
     1078  Boolean gs_was_tcr = ensure_gs_pthread();
     1079#endif
    10161080  TCR* tcr = get_tcr(true);
    10171081  LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
     
    10211085  void *fpregs = NULL;
    10221086#endif
     1087#ifdef DARWIN
     1088  struct mcontext64 *mcontextp = NULL;
     1089#endif
     1090
    10231091  siginfo_t *info_copy = NULL;
    10241092  ExceptionInformation *xp = NULL;
     
    10271095#ifdef LINUX
    10281096    foreign_rsp = copy_fpregs(context, foreign_rsp, &fpregs);
     1097#endif
     1098#ifdef DARWIN
     1099    foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    10291100#endif
    10301101    foreign_rsp = copy_siginfo(info, foreign_rsp);
     
    10321103    foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    10331104    xp = (ExceptionInformation *)foreign_rsp;
     1105#ifdef DARWIN
     1106    UC_MCONTEXT(xp) = mcontextp;
     1107#endif
    10341108    *--foreign_rsp = (LispObj)__builtin_return_address(0);
     1109#ifdef DARWIN_GS_HACK
     1110    if (gs_was_tcr) {
     1111      set_gs_address(tcr);
     1112    }
     1113#endif
    10351114    switch_to_foreign_stack(foreign_rsp,suspend_resume_handler,signum,info_copy,xp);
    10361115  }
     
    15731652  /* Set the thread's FP state from the pseudosigcontext */
    15741653  kret = thread_set_state(thread,
    1575                           x86_FLOAT_STATE,
     1654                          x86_FLOAT_STATE64,
    15761655                          (thread_state_t)&(mc->fs),
    1577                           x86_FLOAT_STATE_COUNT);
     1656                          x86_FLOAT_STATE64_COUNT);
    15781657
    15791658  MACH_CHECK_ERROR("setting thread FP state", kret);
     
    16731752  bcopy(ts,&(mc->ss),sizeof(*ts));
    16741753
    1675   thread_state_count = x86_FLOAT_STATE_COUNT;
     1754  thread_state_count = x86_FLOAT_STATE64_COUNT;
    16761755  thread_get_state(thread,
    1677                    x86_FLOAT_STATE,
     1756                   x86_FLOAT_STATE64,
    16781757                   (thread_state_t)&(mc->fs),
    16791758                   &thread_state_count);
Note: See TracChangeset for help on using the changeset viewer.