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 |
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) |
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) |
1509 |
|
|
1510 |
|
return false; |
1511 |
|
} |
1484 |
– |
#endif |
1512 |
|
|
1513 |
|
|
1514 |
|
/* |
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) |
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 |
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 |
|
|
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; |
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 |
|
|