#include <unistd.h>
#include <errno.h>
#include <sys/param.h>
+#include <sys/utsname.h>
#include "os.h"
#include "arch.h"
static os_vm_size_t real_page_size_difference=0;
-void
-os_init(void)
+/* So, this sucks. Versions of Solaris prior to 8 (SunOS releases
+ earlier than 5.8) do not support MAP_ANON passed as a flag to
+ mmap(). However, we would like SBCL compiled on SunOS 5.7 but
+ running on 5.8 to use MAP_ANON, but because of C's lack of
+ introspection at runtime, we can't grab the right value because
+ it's stuffed in a header file somewhere. We can, however, hardcode
+ it, and test at runtime for whether to use it... -- CSR, 2002-05-06
+
+ And, in fact, it sucks slightly more, as if you don't use MAP_ANON
+ you need to have /dev/zero open and pass the file descriptor to
+ mmap(). So overall, this counts as a KLUDGE. -- CSR, 2002-05-20 */
+int KLUDGE_MAYBE_MAP_ANON = 0x0;
+int kludge_mmap_fd = -1; /* default for MAP_ANON */
+
+void os_init(void)
{
+ struct utsname name;
+ int major_version;
+ int minor_version;
+
+ uname(&name);
+ major_version = atoi(name.release);
+ if (major_version != 5) {
+ lose("sunos major version=%d (which isn't 5!)", major_version);
+ }
+ minor_version = atoi(name.release+2);
+ if ((minor_version == 8) || (minor_version == 9)) {
+ KLUDGE_MAYBE_MAP_ANON = 0x100;
+ } else if (minor_version > 9) {
+ FSHOW((stderr, "os_init: Solaris version greater than 9?\nUnknown MAP_ANON behaviour.\n"));
+ lose("Unknown mmap() interaction with MAP_ANON");
+ } else { /* minor_version < 8 */
+ kludge_mmap_fd = open("/dev/zero",O_RDONLY);
+ if (kludge_mmap_fd < 0) {
+ perror("open");
+ lose("Error in open(..)");
+ }
+ }
+
/* I do not understand this at all. FIXME. */
os_vm_page_size = os_real_page_size = sysconf(_SC_PAGESIZE);
fprintf(stderr,"os_init: Pagesize too large (%d > %d)\n",
os_vm_page_size,OS_VM_DEFAULT_PAGESIZE);
exit(1);
- }else{
+ } else {
/*
* we do this because there are apparently dependencies on
* the pagesize being OS_VM_DEFAULT_PAGESIZE somewhere...
}
}
-os_vm_address_t
-os_validate(os_vm_address_t addr, os_vm_size_t len)
+os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
{
- int flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANON;
-
+ int flags = MAP_PRIVATE | MAP_NORESERVE | KLUDGE_MAYBE_MAP_ANON;
if (addr)
flags |= MAP_FIXED;
-
+
addr = mmap(addr, len,
OS_VM_PROT_ALL,
flags,
- -1, 0);
+ kludge_mmap_fd, 0);
+
if (addr == MAP_FAILED) {
perror("mmap");
lose ("Error in mmap(..)");
return addr;
}
-void
-os_invalidate(os_vm_address_t addr, os_vm_size_t len)
+void os_invalidate(os_vm_address_t addr, os_vm_size_t len)
{
if(munmap((void*) addr, len) == -1)
perror("munmap");
\f
-os_vm_address_t
+os_vm_address_t
os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
{
}
}
-static boolean
-in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
+static boolean in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
{
char* beg = (char*) sbeg;
char* end = (char*) sbeg + slen;
return (adr >= beg && adr < end);
}
-boolean
-is_valid_lisp_addr(os_vm_address_t addr)
+boolean is_valid_lisp_addr(os_vm_address_t addr)
{
- /* Just assume address is valid if it lies within one of the known
+ /* Old CMUCL comment:
+
+ Just assume address is valid if it lies within one of the known
spaces. (Unlike sunos-os which keeps track of every valid page.) */
return ( in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
|| in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE )
\f
-#if defined GENCGC
-
-#error "GENCGC is not yet supported (presumably on x86 solaris?)"
-
-#else
static void
sigsegv_handler(int signal, siginfo_t *info, void* void_context)
os_vm_address_t addr;
addr = arch_get_bad_addr(signal, info, context);
- /* There's some complicated recovery code in linux-os.c here
- that I'm currently too confused to understand. Fixme. */
if(!interrupt_maybe_gc(signal, info, context)) {
- interrupt_handle_now(signal, info, context);
+ if(!handle_control_stack_guard_triggered(context,addr))
+ interrupt_handle_now(signal, info, context);
}
}
-#endif
-
void
os_install_interrupt_handlers()
{
- undoably_install_low_level_interrupt_handler(SIGSEGV,sigsegv_handler);
+ undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT,
+ sigsegv_handler);
}