Changeset 5007
- Timestamp:
- Aug 22, 2006, 1:03:32 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/ccl/lisp-kernel/x86-exceptions.c (modified) (28 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/lisp-kernel/x86-exceptions.c
r4985 r5007 526 526 pc program_counter = (pc)xpPC(xp); 527 527 LispObj rpc = (LispObj) program_counter, xcf, cmain = nrs_CMAIN.vcell, 528 528 529 save_rbp = xpGPR(xp,Irbp), save_vsp = xpGPR(xp,Isp); 529 530 … … 692 693 return handle_floating_point_exception(tcr, context, info); 693 694 695 case SIGBUS: 696 return handle_fault(tcr, context, info); 697 698 694 699 default: 695 700 return false; … … 769 774 770 775 void 771 signal_handler(int signum, siginfo_t *info, ExceptionInformation *context) 772 { 776 signal_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 773 781 xframe_list xframe_link; 774 782 int old_valence; 775 TCR* tcr = get_tcr(false); 783 #ifndef DARWIN 784 tcr = get_tcr(false); 776 785 777 786 old_valence = prepare_to_wait_for_exception_lock(tcr, context); 787 #endif 778 788 wait_for_exception_lock_in_handler(tcr,context, &xframe_link); 779 789 … … 789 799 } 790 800 unlock_exception_lock_in_handler(tcr); 801 #ifndef DARWIN 791 802 exit_signal_handler(tcr, old_valence); 803 #endif 792 804 /* raise_pending_interrupt(tcr); */ 805 #ifdef DARWIN_GS_HACK 806 if (gs_was_tcr) { 807 set_gs_address(tcr); 808 } 809 #endif 793 810 SIGRETURN(context); 794 811 } … … 846 863 847 864 LispObj * 848 find_foreign_rsp(ExceptionInformation *xp, area *foreign_area, TCR *tcr) 849 { 850 LispObj rsp = xpGPR(xp, Isp); 865 find_foreign_rsp(LispObj rsp, area *foreign_area, TCR *tcr) 866 { 851 867 852 868 if (((BytePtr)rsp < foreign_area->low) || … … 861 877 { 862 878 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); 864 880 #ifdef LINUX 865 881 fpregset_t fpregs = NULL; … … 886 902 interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context) 887 903 { 904 #ifdef DARWIN_GS_HACK 905 Boolean gs_was_tcr = ensure_gs_pthread(); 906 #endif 888 907 TCR *tcr = get_interrupt_tcr(false); 889 908 if (tcr) { … … 924 943 } 925 944 } 945 #ifdef DARWIN_GS_HACK 946 if (gs_was_tcr) { 947 set_gs_address(tcr); 948 } 949 #endif 926 950 SIGRETURN(context); 927 951 } … … 931 955 { 932 956 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); 934 958 #ifdef LINUX 935 959 fpregset_t fpregs = NULL; … … 991 1015 { 992 1016 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); 994 1018 #ifdef LINUX 995 1019 fpregset_t fpregs = NULL; … … 1438 1462 1439 1463 pthread_mutex_t _mach_exception_lock, *mach_exception_lock; 1464 extern void pseudo_sigreturn(ExceptionInformation *); 1440 1465 1441 1466 … … 1548 1573 /* Set the thread's FP state from the pseudosigcontext */ 1549 1574 kret = thread_set_state(thread, 1550 X86_FLOAT_STATE,1575 x86_FLOAT_STATE, 1551 1576 (thread_state_t)&(mc->fs), 1552 X86_FLOAT_STATE_COUNT);1577 x86_FLOAT_STATE_COUNT); 1553 1578 1554 1579 MACH_CHECK_ERROR("setting thread FP state", kret); 1555 1580 1556 1581 /* The thread'll be as good as new ... */ 1557 #if def PPC641582 #if WORD_SIZE == 64 1558 1583 kret = thread_set_state(thread, 1559 X86_THREAD_STATE64,1584 x86_THREAD_STATE64, 1560 1585 (thread_state_t)&(mc->ss), 1561 X86_THREAD_STATE64_COUNT);1586 x86_THREAD_STATE64_COUNT); 1562 1587 #else 1563 1588 kret = thread_set_state(thread, 1564 X86_THREAD_STATE32,1589 x86_THREAD_STATE32, 1565 1590 (thread_state_t)&(mc->ss), 1566 X86_THREAD_STATE32_COUNT);1591 x86_THREAD_STATE32_COUNT); 1567 1592 #endif 1568 1593 MACH_CHECK_ERROR("setting thread state", kret); … … 1604 1629 ExceptionInformation * 1605 1630 create_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, 1608 1634 #ifdef X8664 1609 x86_thread_state64_t ts;1635 x86_thread_state64_t *ts 1610 1636 #else 1611 x86_thread_state_t ts; 1612 #endif 1637 x86_thread_state_t *ts 1638 #endif 1639 ) 1640 { 1613 1641 mach_msg_type_number_t thread_state_count; 1614 1642 kern_return_t result; … … 1622 1650 natural stackp, backlink; 1623 1651 1624 #ifdef X86641625 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 #else1631 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 #endif1637 1652 1638 1653 if (result != KERN_SUCCESS) { … … 1640 1655 Bug(NULL, "Exception thread can't obtain thread state, Mach result = %d", result); 1641 1656 } 1642 stackp = ts.r1; 1643 backlink = stackp; 1657 stackp = (LispObj) find_foreign_rsp(ts->rsp,tcr->cs_area,tcr); 1644 1658 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); 1646 1664 pseudosigcontext = (ExceptionInformation *) ptr_from_lispobj(stackp); 1647 1665 … … 1652 1670 mc = (struct mcontext *) ptr_from_lispobj(stackp); 1653 1671 #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; 1657 1676 thread_get_state(thread, 1658 X86_FLOAT_STATE,1677 x86_FLOAT_STATE, 1659 1678 (thread_state_t)&(mc->fs), 1660 1679 &thread_state_count); … … 1662 1681 1663 1682 #ifdef X8664 1664 thread_state_count = X86_EXCEPTION_STATE64_COUNT;1683 thread_state_count = x86_EXCEPTION_STATE64_COUNT; 1665 1684 #else 1666 thread_state_count = X86_EXCEPTION_STATE_COUNT;1685 thread_state_count = x86_EXCEPTION_STATE_COUNT; 1667 1686 #endif 1668 1687 thread_get_state(thread, 1669 1688 #ifdef X8664 1670 X86_EXCEPTION_STATE64,1689 x86_EXCEPTION_STATE64, 1671 1690 #else 1672 X86_EXCEPTION_STATE,1691 x86_EXCEPTION_STATE, 1673 1692 #endif 1674 1693 (thread_state_t)&(mc->es), … … 1677 1696 1678 1697 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;1682 1698 if (new_stack_top) { 1683 1699 *new_stack_top = stackp; … … 1688 1704 /* 1689 1705 This code sets up the user thread so that it executes a "pseudo-signal 1690 handler" function when it resumes. Create a linux sigcontext struct1706 handler" function when it resumes. Create a fake ucontext struct 1691 1707 on the thread's stack and pass it as an argument to the pseudo-signal 1692 1708 handler. … … 1708 1724 int signum, 1709 1725 int code, 1710 TCR *tcr) 1711 { 1726 TCR *tcr, 1712 1727 #ifdef X8664 1713 x86_thread_state64_t ts;1728 x86_thread_state64_t *ts 1714 1729 #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 1718 1739 ExceptionInformation *pseudosigcontext; 1719 1740 int i, j; 1720 1741 kern_return_t result; 1721 natural stackp; 1742 natural stackp, *stackpp; 1743 siginfo_t *info; 1722 1744 1723 1745 #ifdef DEBUG_MACH_EXCEPTIONS 1724 1746 fprintf(stderr,"Setting up exception handling for 0x%x\n", tcr); 1725 1747 #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; 1727 1753 pseudosigcontext->uc_onstack = 0; 1728 1754 pseudosigcontext->uc_sigmask = (sigset_t) 0; … … 1737 1763 */ 1738 1764 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; 1746 1774 1747 1775 1748 1776 #ifdef X8664 1749 ts.r13 = xpGPR(pseudosigcontext,13);1750 1777 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); 1754 1781 #else 1755 1782 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); 1759 1786 #endif 1760 1787 #ifdef DEBUG_MACH_EXCEPTIONS … … 1764 1791 } 1765 1792 1766 1767 void1768 pseudo_signal_handler(int signum, ExceptionInformation *context, TCR *tcr)1769 {1770 signal_handler(signum, NULL, context, tcr);1771 }1772 1793 1773 1794 … … 1792 1813 Some exceptions could and should be handled here directly. 1793 1814 */ 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 1794 1828 1795 1829 kern_return_t … … 1804 1838 TCR *tcr = TCR_FROM_EXCEPTION_PORT(exception_port); 1805 1839 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 1806 1847 1807 1848 #ifdef DEBUG_MACH_EXCEPTIONS … … 1809 1850 #endif 1810 1851 1852 1811 1853 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 1812 1867 if (tcr->flags & (1<<TCR_FLAG_BIT_PENDING_EXCEPTION)) { 1813 1868 CLR_TCR_FLAG(tcr,TCR_FLAG_BIT_PENDING_EXCEPTION); 1814 1869 } 1815 1870 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); 1822 1873 #if 0 1823 1874 fprintf(stderr, "Exception return in 0x%x\n",tcr); 1824 1875 #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);1829 1876 } else if (tcr->flags & (1<<TCR_FLAG_BIT_PROPAGATE_EXCEPTION)) { 1830 1877 CLR_TCR_FLAG(tcr,TCR_FLAG_BIT_PROPAGATE_EXCEPTION); … … 1833 1880 switch (exception) { 1834 1881 case EXC_BAD_ACCESS: 1835 signum = SIG SEGV;1882 signum = SIGBUS; 1836 1883 break; 1837 1884 1838 1885 case EXC_BAD_INSTRUCTION: 1839 signum = SIGILL; 1886 if (code == EXC_I386_GPFLT) { 1887 signum = SIGSEGV; 1888 } else { 1889 signum = SIGILL; 1890 } 1840 1891 break; 1841 1892 … … 1853 1904 if (signum) { 1854 1905 kret = setup_signal_frame(thread, 1855 (void *) pseudo_signal_handler,1906 (void *)signal_handler, 1856 1907 signum, 1857 1908 code, 1858 tcr); 1909 tcr, 1910 &ts); 1859 1911 #if 0 1860 1912 fprintf(stderr, "Setup pseudosignal handling in 0x%x\n",tcr); … … 2170 2222 result = suspend_mach_thread(mach_thread); 2171 2223 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); 2173 2242 pseudosigcontext->uc_onstack = 0; 2174 2243 pseudosigcontext->uc_sigmask = (sigset_t) 0;
Note:
See TracChangeset
for help on using the changeset viewer.
