2 * This file (along with os.h) exports an OS-independent interface to
3 * the operating system VM facilities. Surprise surprise, this
4 * interface looks a lot like the Mach interface (but simpler in some
5 * places). For some operating systems, a subset of these functions
6 * will have to be emulated.
8 * This is the OSF/1 version, based on the Linux version, itself based
9 * on the OSF1 version from CMUCL by Sean Hallgren. Now _there's_
10 * a metacircularity for you ...
14 * This software is part of the SBCL system. See the README file for
17 * This software is derived from the CMU CL system, which was
18 * written at Carnegie Mellon University and released into the
19 * public domain. The software is in the public domain and is
20 * provided with absolutely no warranty. See the COPYING and CREDITS
21 * files for more information.
25 #include <sys/param.h>
31 #include "interrupt.h"
35 #include <sys/socket.h>
36 #include <sys/utsname.h>
38 #include <sys/sysinfo.h>
41 #include <machine/hal_sysinfo.h>
43 #include <sys/types.h>
50 size_t os_vm_page_size;
59 os_vm_page_size = getpagesize();
64 os_validate(os_vm_address_t addr, os_vm_size_t len)
66 int flags = MAP_PRIVATE|MAP_ANONYMOUS;
67 if (addr) flags |= MAP_FIXED;
68 else flags |= MAP_VARIABLE;
70 if((addr=mmap(addr,len,OS_VM_PROT_ALL,flags,-1,0)) == (os_vm_address_t) -1)
77 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
79 if (munmap(addr,len) == -1) {
85 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
87 addr = mmap(addr, len,
89 MAP_PRIVATE | MAP_FILE | MAP_FIXED,
92 if (addr == MAP_FAILED) {
94 lose("unexpected mmap(..) failure");
101 os_protect(os_vm_address_t address, os_vm_size_t length, os_vm_prot_t prot)
103 if (mprotect(address, length, prot) == -1) {
109 is_valid_lisp_addr(os_vm_address_t addr)
112 os_vm_address_t newaddr;
113 newaddr=os_trunc_to_page(addr);
114 if((ret=mvalid(newaddr,newaddr-addr+4,OS_VM_PROT_ALL)) == 0)
116 else if(errno==EINVAL)
122 * any OS-dependent special low-level handling for signals
127 sigsegv_handler(int signal, siginfo_t *info, void* void_context)
129 os_context_t *context = arch_os_get_context(&void_context);
131 os_vm_address_t addr = arch_get_bad_addr(signal,info,context);
134 *os_context_register_addr(context,reg_ALLOC) & (1L<<63)){
135 /* this is lifted from linux-os.c, so violates OOAO */
136 *os_context_register_addr(context,reg_ALLOC) -= (1L<<63);
137 interrupt_handle_pending(context);
138 } else if(((addr>=DYNAMIC_0_SPACE_END) && (addr<DYNAMIC_1_SPACE_START)) ||
139 ((addr>=DYNAMIC_1_SPACE_END) && (addr<CONTROL_STACK_START))){
140 /* there's empty gap between these spaces. This clause needs
141 review if the spaces are ever juggled to make this untrue */
142 fprintf(stderr, "bad address 0x%p\n",addr);
143 lose("ran off end of dynamic space");
144 } else if (!interrupt_maybe_gc(signal, info, context)) {
145 if(!handle_control_stack_guard_triggered(context,addr))
146 interrupt_handle_now(signal, info, context);
152 os_install_interrupt_handlers(void)
154 undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT,