Changeset 5007


Ignore:
Timestamp:
Aug 22, 2006, 1:03:32 AM (18 years ago)
Author:
Gary Byers
Message:

Lots of changes, especially to Mach exception handling code.

Do the DARWIN_GS_HACK things to overload %gs.

File:
1 edited

Legend:

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

    r4985 r5007  
    526526  pc program_counter = (pc)xpPC(xp);
    527527  LispObj rpc = (LispObj) program_counter, xcf, cmain = nrs_CMAIN.vcell,
     528
    528529    save_rbp = xpGPR(xp,Irbp), save_vsp = xpGPR(xp,Isp);
    529530
     
    692693    return handle_floating_point_exception(tcr, context, info);
    693694
     695  case SIGBUS:
     696    return handle_fault(tcr, context, info);
     697   
     698   
    694699  default:
    695700    return false;
     
    769774
    770775void
    771 signal_handler(int signum, siginfo_t *info, ExceptionInformation  *context)
    772 {
     776signal_handler(int signum, siginfo_t *info, ExceptionInformation  *context, TCR *tcr)
     777{
     778#ifdef DARWIN_GS_HACK
     779  Boolean gs_was_tcr = ensure_gs_pthread();
     780#endif
    773781  xframe_list xframe_link;
    774782  int old_valence;
    775   TCR* tcr = get_tcr(false);
     783#ifndef DARWIN
     784  tcr = get_tcr(false);
    776785
    777786  old_valence = prepare_to_wait_for_exception_lock(tcr, context);
     787#endif
    778788  wait_for_exception_lock_in_handler(tcr,context, &xframe_link);
    779789
     
    789799  }
    790800  unlock_exception_lock_in_handler(tcr);
     801#ifndef DARWIN
    791802  exit_signal_handler(tcr, old_valence);
     803#endif
    792804  /* raise_pending_interrupt(tcr); */
     805#ifdef DARWIN_GS_HACK
     806  if (gs_was_tcr) {
     807    set_gs_address(tcr);
     808  }
     809#endif
    793810  SIGRETURN(context);
    794811}
     
    846863
    847864LispObj *
    848 find_foreign_rsp(ExceptionInformation *xp, area *foreign_area, TCR *tcr)
    849 {
    850   LispObj rsp = xpGPR(xp, Isp);
     865find_foreign_rsp(LispObj rsp, area *foreign_area, TCR *tcr)
     866{
    851867
    852868  if (((BytePtr)rsp < foreign_area->low) ||
     
    861877{
    862878  TCR* tcr = get_tcr(true);
    863   LispObj *foreign_rsp = find_foreign_rsp(context, tcr->cs_area, tcr);
     879  LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    864880#ifdef LINUX
    865881  fpregset_t fpregs = NULL;
     
    886902interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
    887903{
     904#ifdef DARWIN_GS_HACK
     905  Boolean gs_was_tcr = ensure_gs_pthread();
     906#endif
    888907  TCR *tcr = get_interrupt_tcr(false);
    889908  if (tcr) {
     
    924943    }
    925944  }
     945#ifdef DARWIN_GS_HACK
     946  if (gs_was_tcr) {
     947    set_gs_address(tcr);
     948  }
     949#endif
    926950  SIGRETURN(context);
    927951}
     
    931955{
    932956  TCR *tcr = get_interrupt_tcr(false);
    933   LispObj *foreign_rsp = find_foreign_rsp(context, tcr->cs_area, tcr);
     957  LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    934958#ifdef LINUX
    935959  fpregset_t fpregs = NULL;
     
    9911015{
    9921016  TCR* tcr = get_tcr(true);
    993   LispObj *foreign_rsp = find_foreign_rsp(context, tcr->cs_area, tcr);
     1017  LispObj *foreign_rsp = find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
    9941018#ifdef LINUX
    9951019  fpregset_t fpregs = NULL;
     
    14381462
    14391463pthread_mutex_t _mach_exception_lock, *mach_exception_lock;
     1464extern void pseudo_sigreturn(ExceptionInformation *);
    14401465
    14411466
     
    15481573  /* Set the thread's FP state from the pseudosigcontext */
    15491574  kret = thread_set_state(thread,
    1550                           X86_FLOAT_STATE,
     1575                          x86_FLOAT_STATE,
    15511576                          (thread_state_t)&(mc->fs),
    1552                           X86_FLOAT_STATE_COUNT);
     1577                          x86_FLOAT_STATE_COUNT);
    15531578
    15541579  MACH_CHECK_ERROR("setting thread FP state", kret);
    15551580
    15561581  /* The thread'll be as good as new ... */
    1557 #ifdef PPC64
     1582#if WORD_SIZE == 64
    15581583  kret = thread_set_state(thread,
    1559                           X86_THREAD_STATE64,
     1584                          x86_THREAD_STATE64,
    15601585                          (thread_state_t)&(mc->ss),
    1561                           X86_THREAD_STATE64_COUNT);
     1586                          x86_THREAD_STATE64_COUNT);
    15621587#else
    15631588  kret = thread_set_state(thread,
    1564                           X86_THREAD_STATE32,
     1589                          x86_THREAD_STATE32,
    15651590                          (thread_state_t)&(mc->ss),
    1566                           X86_THREAD_STATE32_COUNT);
     1591                          x86_THREAD_STATE32_COUNT);
    15671592#endif
    15681593  MACH_CHECK_ERROR("setting thread state", kret);
     
    16041629ExceptionInformation *
    16051630create_thread_context_frame(mach_port_t thread,
    1606                             natural *new_stack_top)
    1607 {
     1631                            natural *new_stack_top,
     1632                            siginfo_t **info_ptr,
     1633                            TCR *tcr,
    16081634#ifdef X8664
    1609   x86_thread_state64_t ts;
     1635                            x86_thread_state64_t *ts
    16101636#else
    1611   x86_thread_state_t ts;
    1612 #endif
     1637                            x86_thread_state_t *ts
     1638#endif
     1639                            )
     1640{
    16131641  mach_msg_type_number_t thread_state_count;
    16141642  kern_return_t result;
     
    16221650  natural stackp, backlink;
    16231651
    1624 #ifdef X8664
    1625   thread_state_count = X86_THREAD_STATE64_COUNT;
    1626   result = thread_get_state(thread,
    1627                             X86_THREAD_STATE64,
    1628                             (thread_state_t)&ts,
    1629                             &thread_state_count);
    1630 #else
    1631   thread_state_count = MACHINE_THREAD_STATE_COUNT;
    1632   result = thread_get_state(thread,
    1633                             X86_THREAD_STATE,   /* GPRs, some SPRs  */
    1634                             (thread_state_t)&ts,
    1635                             &thread_state_count);
    1636 #endif
    16371652 
    16381653  if (result != KERN_SUCCESS) {
     
    16401655    Bug(NULL, "Exception thread can't obtain thread state, Mach result = %d", result);
    16411656  }
    1642   stackp = ts.r1;
    1643   backlink = stackp;
     1657  stackp = (LispObj) find_foreign_rsp(ts->rsp,tcr->cs_area,tcr);
    16441658  stackp = TRUNC_DOWN(stackp, C_REDZONE_LEN, C_STK_ALIGN);
    1645   stackp -= sizeof(*pseudosigcontext);
     1659  stackp = TRUNC_DOWN(stackp, sizeof(siginfo_t), C_STK_ALIGN);
     1660  if (info_ptr) {
     1661    *info_ptr = (siginfo_t *)stackp;
     1662  }
     1663  stackp = TRUNC_DOWN(stackp,sizeof(*pseudosigcontext), C_STK_ALIGN);
    16461664  pseudosigcontext = (ExceptionInformation *) ptr_from_lispobj(stackp);
    16471665
     
    16521670  mc = (struct mcontext *) ptr_from_lispobj(stackp);
    16531671#endif
    1654   bcopy(&ts,&(mc->ss),sizeof(ts));
    1655 
    1656   thread_state_count = X86_FLOAT_STATE_COUNT;
     1672 
     1673  bcopy(ts,&(mc->ss),sizeof(*ts));
     1674
     1675  thread_state_count = x86_FLOAT_STATE_COUNT;
    16571676  thread_get_state(thread,
    1658                    X86_FLOAT_STATE,
     1677                   x86_FLOAT_STATE,
    16591678                   (thread_state_t)&(mc->fs),
    16601679                   &thread_state_count);
     
    16621681
    16631682#ifdef X8664
    1664   thread_state_count = X86_EXCEPTION_STATE64_COUNT;
     1683  thread_state_count = x86_EXCEPTION_STATE64_COUNT;
    16651684#else
    1666   thread_state_count = X86_EXCEPTION_STATE_COUNT;
     1685  thread_state_count = x86_EXCEPTION_STATE_COUNT;
    16671686#endif
    16681687  thread_get_state(thread,
    16691688#ifdef X8664
    1670                    X86_EXCEPTION_STATE64,
     1689                   x86_EXCEPTION_STATE64,
    16711690#else
    1672                    X86_EXCEPTION_STATE,
     1691                   x86_EXCEPTION_STATE,
    16731692#endif
    16741693                   (thread_state_t)&(mc->es),
     
    16771696
    16781697  UC_MCONTEXT(pseudosigcontext) = mc;
    1679   stackp = TRUNC_DOWN(stackp, C_PARAMSAVE_LEN, C_STK_ALIGN);
    1680   stackp -= C_LINKAGE_LEN;
    1681   *(natural *)ptr_from_lispobj(stackp) = backlink;
    16821698  if (new_stack_top) {
    16831699    *new_stack_top = stackp;
     
    16881704/*
    16891705  This code sets up the user thread so that it executes a "pseudo-signal
    1690   handler" function when it resumes.  Create a linux sigcontext struct
     1706  handler" function when it resumes.  Create a fake ucontext struct
    16911707  on the thread's stack and pass it as an argument to the pseudo-signal
    16921708  handler.
     
    17081724                   int signum,
    17091725                   int code,
    1710                    TCR *tcr)
    1711 {
     1726                   TCR *tcr,
    17121727#ifdef X8664
    1713   x86_thread_state64_t ts;
     1728                   x86_thread_state64_t *ts
    17141729#else
    1715   x86_thread_state_t ts;
    1716 #endif
    1717   mach_msg_type_number_t thread_state_count;
     1730                   x86_thread_state_t *ts
     1731#endif
     1732                   )
     1733{
     1734#ifdef X8664
     1735  x86_thread_state64_t new_ts;
     1736#else
     1737  x86_thread_state_t new_ts;
     1738#endif
    17181739  ExceptionInformation *pseudosigcontext;
    17191740  int i, j;
    17201741  kern_return_t result;
    1721   natural stackp;
     1742  natural stackp, *stackpp;
     1743  siginfo_t *info;
    17221744
    17231745#ifdef DEBUG_MACH_EXCEPTIONS
    17241746  fprintf(stderr,"Setting up exception handling for 0x%x\n", tcr);
    17251747#endif
    1726   pseudosigcontext = create_thread_context_frame(thread, &stackp);
     1748  pseudosigcontext = create_thread_context_frame(thread, &stackp, &info, tcr,  ts);
     1749  bzero(info, sizeof(*info));
     1750  info->si_code = code;
     1751  info->si_addr = (void *)(UC_MCONTEXT(pseudosigcontext)->es.faultvaddr);
     1752  info->si_signo = signum;
    17271753  pseudosigcontext->uc_onstack = 0;
    17281754  pseudosigcontext->uc_sigmask = (sigset_t) 0;
     
    17371763  */
    17381764
    1739   ts.srr0 = (natural) handler_address;
    1740   ts.srr1 = (int) xpMSR(pseudosigcontext) & ~MSR_FE0_FE1_MASK;
    1741   ts.r1 = stackp;
    1742   ts.r3 = signum;
    1743   ts.r4 = (natural)pseudosigcontext;
    1744   ts.r5 = (natural)tcr;
    1745   ts.lr = (natural)pseudo_sigreturn;
     1765  new_ts.rip = (natural) handler_address;
     1766  stackpp = (natural *)stackp;
     1767  *--stackpp = (natural)pseudo_sigreturn;
     1768  stackp = (natural)stackpp;
     1769  new_ts.rdi = signum;
     1770  new_ts.rsi = (natural)info;
     1771  new_ts.rdx = (natural)pseudosigcontext;
     1772  new_ts.rcx = (natural)tcr;
     1773  new_ts.rsp = stackp;
    17461774
    17471775
    17481776#ifdef X8664
    1749   ts.r13 = xpGPR(pseudosigcontext,13);
    17501777  thread_set_state(thread,
    1751                    X86_THREAD_STATE64,
    1752                    (thread_state_t)&ts,
    1753                    X86_THREAD_STATE64_COUNT);
     1778                   x86_THREAD_STATE64,
     1779                   (thread_state_t)&new_ts,
     1780                   x86_THREAD_STATE64_COUNT);
    17541781#else
    17551782  thread_set_state(thread,
    1756                    MACHINE_THREAD_STATE,
    1757                    (thread_state_t)&ts,
    1758                    MACHINE_THREAD_STATE_COUNT);
     1783                   x86_THREAD_STATE,
     1784                   (thread_state_t)&new_ts,
     1785                   x86_THREAD_STATE_COUNT);
    17591786#endif
    17601787#ifdef DEBUG_MACH_EXCEPTIONS
     
    17641791}
    17651792
    1766 
    1767 void
    1768 pseudo_signal_handler(int signum, ExceptionInformation *context, TCR *tcr)
    1769 {
    1770   signal_handler(signum, NULL, context, tcr);
    1771 }
    17721793
    17731794
     
    17921813  Some exceptions could and should be handled here directly.
    17931814*/
     1815
     1816/* We need the thread's state earlier on x86_64 than we did on PPC;
     1817   the PC won't fit in code_vector[1].  We shouldn't try to get it
     1818   lazily (via catch_exception_raise_state()); until we own the
     1819   exception lock, we shouldn't have it in userspace (since a GCing
     1820   thread wouldn't know that we had our hands on it.)
     1821*/
     1822
     1823#ifdef X8664
     1824#define ts_pc(t) t.rip
     1825#else
     1826#define ts_pc(t) t.eip
     1827#endif
    17941828
    17951829kern_return_t
     
    18041838  TCR *tcr = TCR_FROM_EXCEPTION_PORT(exception_port);
    18051839  kern_return_t kret;
     1840#ifdef X8664
     1841  x86_thread_state64_t ts;
     1842#else
     1843  x86_thread_state_t ts;
     1844#endif
     1845  mach_msg_type_number_t thread_state_count;
     1846
    18061847
    18071848#ifdef DEBUG_MACH_EXCEPTIONS
     
    18091850#endif
    18101851
     1852
    18111853  if (pthread_mutex_trylock(mach_exception_lock) == 0) {
     1854#ifdef X8664
     1855    thread_state_count = x86_THREAD_STATE64_COUNT;
     1856    thread_get_state(thread,
     1857                     x86_THREAD_STATE64,
     1858                     (thread_state_t)&ts,
     1859                     &thread_state_count);
     1860#else
     1861    thread_state_count = x86_THREAD_STATE_COUNT;
     1862    thread_get_state(thread,
     1863                     x86_THREAD_STATE,
     1864                     (thread_state_t)&ts,
     1865                     &thread_state_count);
     1866#endif
    18121867    if (tcr->flags & (1<<TCR_FLAG_BIT_PENDING_EXCEPTION)) {
    18131868      CLR_TCR_FLAG(tcr,TCR_FLAG_BIT_PENDING_EXCEPTION);
    18141869    }
    18151870    if ((exception == EXC_BAD_INSTRUCTION) &&
    1816         (code_vector[0] == EXC_X86_UNIPL_INST) &&
    1817         (((code1 = code_vector[1]) == (int)pseudo_sigreturn) ||
    1818          (code1 == (int)enable_fp_exceptions) ||
    1819          (code1 == (int)disable_fp_exceptions))) {
    1820       if (code1 == (int)pseudo_sigreturn) {
    1821         kret = do_pseudo_sigreturn(thread, tcr);
     1871        ((natural)(ts_pc(ts)) == (natural)pseudo_sigreturn)) {
     1872      kret = do_pseudo_sigreturn(thread, tcr);
    18221873#if 0
    18231874      fprintf(stderr, "Exception return in 0x%x\n",tcr);
    18241875#endif
    1825        
    1826       } else if (code1 == (int)enable_fp_exceptions) {
    1827         kret = thread_set_fp_exceptions_enabled(thread, true);
    1828       } else kret =  thread_set_fp_exceptions_enabled(thread, false);
    18291876    } else if (tcr->flags & (1<<TCR_FLAG_BIT_PROPAGATE_EXCEPTION)) {
    18301877      CLR_TCR_FLAG(tcr,TCR_FLAG_BIT_PROPAGATE_EXCEPTION);
     
    18331880      switch (exception) {
    18341881      case EXC_BAD_ACCESS:
    1835         signum = SIGSEGV;
     1882        signum = SIGBUS;
    18361883        break;
    18371884       
    18381885      case EXC_BAD_INSTRUCTION:
    1839         signum = SIGILL;
     1886        if (code == EXC_I386_GPFLT) {
     1887          signum = SIGSEGV;
     1888        } else {
     1889          signum = SIGILL;
     1890        }
    18401891        break;
    18411892     
     
    18531904      if (signum) {
    18541905        kret = setup_signal_frame(thread,
    1855                                   (void *)pseudo_signal_handler,
     1906                                  (void *)signal_handler,
    18561907                                  signum,
    18571908                                  code,
    1858                                   tcr);
     1909                                  tcr,
     1910                                  &ts);
    18591911#if 0
    18601912      fprintf(stderr, "Setup pseudosignal handling in 0x%x\n",tcr);
     
    21702222  result = suspend_mach_thread(mach_thread);
    21712223  if (result) {
    2172     pseudosigcontext = create_thread_context_frame(mach_thread, NULL);
     2224    mach_msg_type_number_t thread_state_count;
     2225#ifdef X8664
     2226    x86_thread_state64_t ts;
     2227    thread_state_count = x86_THREAD_STATE64_COUNT;
     2228    thread_get_state(mach_thread,
     2229                     x86_THREAD_STATE64,
     2230                     (thread_state_t)&ts,
     2231                     &thread_state_count);
     2232#else
     2233    x86_thread_state_t ts;
     2234    thread_state_count = x86_THREAD_STATE_COUNT;
     2235    thread_get_state(mach_thread,
     2236                     x86_THREAD_STATE,
     2237                     (thread_state_t)&ts,
     2238                     &thread_state_count);
     2239#endif
     2240
     2241    pseudosigcontext = create_thread_context_frame(mach_thread, NULL, NULL,tcr, &ts);
    21732242    pseudosigcontext->uc_onstack = 0;
    21742243    pseudosigcontext->uc_sigmask = (sigset_t) 0;
Note: See TracChangeset for help on using the changeset viewer.