ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/sigsegv.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/sigsegv.cpp (file contents):
Revision 1.47 by gbeauche, 2004-02-16T16:02:48Z vs.
Revision 1.48 by gbeauche, 2004-11-13T23:44:11Z

# Line 481 | Line 481 | static sigsegv_address_t get_fault_addre
481   #endif
482   #endif
483  
484 + #if HAVE_WIN32_EXCEPTIONS
485 + #define WIN32_LEAN_AND_MEAN /* avoid including junk */
486 + #include <windows.h>
487 + #include <winerror.h>
488 +
489 + #define SIGSEGV_FAULT_HANDLER_ARGLIST   EXCEPTION_POINTERS *ExceptionInfo
490 + #define SIGSEGV_FAULT_HANDLER_ARGS              ExceptionInfo
491 + #define SIGSEGV_FAULT_ADDRESS                   ExceptionInfo->ExceptionRecord->ExceptionInformation[1]
492 + #define SIGSEGV_CONTEXT_REGS                    ExceptionInfo->ContextRecord
493 + #define SIGSEGV_FAULT_INSTRUCTION               SIGSEGV_CONTEXT_REGS->Eip
494 + #define SIGSEGV_REGISTER_FILE                   ((unsigned long *)&SIGSEGV_CONTEXT_REGS->Edi)
495 + #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
496 + #endif
497 +
498   #if HAVE_MACH_EXCEPTIONS
499  
500   // This can easily be extended to other Mach systems, but really who
# Line 673 | Line 687 | enum {
687   #endif
688   };
689   #endif
690 + #if defined(_WIN32)
691 + enum {
692 + #if (defined(i386) || defined(__i386__))
693 +        X86_REG_EIP = 7,
694 +        X86_REG_EAX = 5,
695 +        X86_REG_ECX = 4,
696 +        X86_REG_EDX = 3,
697 +        X86_REG_EBX = 2,
698 +        X86_REG_ESP = 10,
699 +        X86_REG_EBP = 6,
700 +        X86_REG_ESI = 1,
701 +        X86_REG_EDI = 0
702 + #endif
703 + };
704 + #endif
705   // FIXME: this is partly redundant with the instruction decoding phase
706   // to discover transfer type and register number
707   static inline int ix86_step_over_modrm(unsigned char * p)
# Line 1437 | Line 1466 | static bool arm_skip_instruction(unsigne
1466   *  SIGSEGV global handler
1467   */
1468  
1440 #if defined(HAVE_SIGSEGV_RECOVERY) || defined(HAVE_MACH_EXCEPTIONS)
1469   // This function handles the badaccess to memory.
1470   // It is called from the signal handler or the exception handler.
1471   static bool handle_badaccess(SIGSEGV_FAULT_HANDLER_ARGLIST_1)
# Line 1481 | Line 1509 | static bool handle_badaccess(SIGSEGV_FAU
1509  
1510          return false;
1511   }
1484 #endif
1512  
1513  
1514   /*
# Line 1775 | Line 1802 | static bool sigsegv_do_install_handler(s
1802   }
1803   #endif
1804  
1805 + #ifdef HAVE_WIN32_EXCEPTIONS
1806 + static LONG WINAPI main_exception_filter(EXCEPTION_POINTERS *ExceptionInfo)
1807 + {
1808 +        if (sigsegv_fault_handler != NULL
1809 +                && ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION
1810 +                && ExceptionInfo->ExceptionRecord->NumberParameters == 2
1811 +                && handle_badaccess(ExceptionInfo))
1812 +                return EXCEPTION_CONTINUE_EXECUTION;
1813 +
1814 +        return EXCEPTION_CONTINUE_SEARCH;
1815 + }
1816 +
1817 + #if defined __CYGWIN__ && defined __i386__
1818 + /* In Cygwin programs, SetUnhandledExceptionFilter has no effect because Cygwin
1819 +   installs a global exception handler.  We have to dig deep in order to install
1820 +   our main_exception_filter.  */
1821 +
1822 + /* Data structures for the current thread's exception handler chain.
1823 +   On the x86 Windows uses register fs, offset 0 to point to the current
1824 +   exception handler; Cygwin mucks with it, so we must do the same... :-/ */
1825 +
1826 + /* Magic taken from winsup/cygwin/include/exceptions.h.  */
1827 +
1828 + struct exception_list {
1829 +    struct exception_list *prev;
1830 +    int (*handler) (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
1831 + };
1832 + typedef struct exception_list exception_list;
1833 +
1834 + /* Magic taken from winsup/cygwin/exceptions.cc.  */
1835 +
1836 + __asm__ (".equ __except_list,0");
1837 +
1838 + extern exception_list *_except_list __asm__ ("%fs:__except_list");
1839 +
1840 + /* For debugging.  _except_list is not otherwise accessible from gdb.  */
1841 + static exception_list *
1842 + debug_get_except_list ()
1843 + {
1844 +  return _except_list;
1845 + }
1846 +
1847 + /* Cygwin's original exception handler.  */
1848 + static int (*cygwin_exception_handler) (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
1849 +
1850 + /* Our exception handler.  */
1851 + static int
1852 + libsigsegv_exception_handler (EXCEPTION_RECORD *exception, void *frame, CONTEXT *context, void *dispatch)
1853 + {
1854 +  EXCEPTION_POINTERS ExceptionInfo;
1855 +  ExceptionInfo.ExceptionRecord = exception;
1856 +  ExceptionInfo.ContextRecord = context;
1857 +  if (main_exception_filter (&ExceptionInfo) == EXCEPTION_CONTINUE_SEARCH)
1858 +    return cygwin_exception_handler (exception, frame, context, dispatch);
1859 +  else
1860 +    return 0;
1861 + }
1862 +
1863 + static void
1864 + do_install_main_exception_filter ()
1865 + {
1866 +  /* We cannot insert any handler into the chain, because such handlers
1867 +     must lie on the stack (?).  Instead, we have to replace(!) Cygwin's
1868 +     global exception handler.  */
1869 +  cygwin_exception_handler = _except_list->handler;
1870 +  _except_list->handler = libsigsegv_exception_handler;
1871 + }
1872 +
1873 + #else
1874 +
1875 + static void
1876 + do_install_main_exception_filter ()
1877 + {
1878 +  SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER) &main_exception_filter);
1879 + }
1880 + #endif
1881 +
1882 + static bool sigsegv_do_install_handler(sigsegv_fault_handler_t handler)
1883 + {
1884 +        static bool main_exception_filter_installed = false;
1885 +        if (!main_exception_filter_installed) {
1886 +                do_install_main_exception_filter();
1887 +                main_exception_filter_installed = true;
1888 +        }
1889 +        sigsegv_fault_handler = handler;
1890 +        return true;
1891 + }
1892 + #endif
1893 +
1894   bool sigsegv_install_handler(sigsegv_fault_handler_t handler)
1895   {
1896   #if defined(HAVE_SIGSEGV_RECOVERY)
# Line 1785 | Line 1901 | bool sigsegv_install_handler(sigsegv_fau
1901          if (success)
1902              sigsegv_fault_handler = handler;
1903          return success;
1904 < #elif defined(HAVE_MACH_EXCEPTIONS)
1904 > #elif defined(HAVE_MACH_EXCEPTIONS) || defined(HAVE_WIN32_EXCEPTIONS)
1905          return sigsegv_do_install_handler(handler);
1906   #else
1907          // FAIL: no siginfo_t nor sigcontext subterfuge is available
# Line 1811 | Line 1927 | void sigsegv_deinstall_handler(void)
1927          SIGSEGV_ALL_SIGNALS
1928   #undef FAULT_HANDLER
1929   #endif
1930 + #ifdef HAVE_WIN32_EXCEPTIONS
1931 +        sigsegv_fault_handler = NULL;
1932 + #endif
1933   }
1934  
1935  
# Line 1832 | Line 1951 | void sigsegv_set_dump_state(sigsegv_stat
1951   #include <stdio.h>
1952   #include <stdlib.h>
1953   #include <fcntl.h>
1954 + #ifdef HAVE_SYS_MMAN_H
1955   #include <sys/mman.h>
1956 + #endif
1957   #include "vm_alloc.h"
1958  
1959   const int REF_INDEX = 123;
# Line 1956 | Line 2077 | int main(void)
2077          if (vm_init() < 0)
2078                  return 1;
2079  
2080 + #ifdef _WIN32
2081 +        page_size = 4096;
2082 + #else
2083          page_size = getpagesize();
2084 + #endif
2085          if ((page = (char *)vm_acquire(page_size)) == VM_MAP_FAILED)
2086                  return 2;
2087          

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines