1.0.45.8: fix os_vm_page_size on freebsd, openbsd and osf1
[sbcl.git] / src / runtime / hpux-os.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <signal.h>
4 #include <sys/file.h>
5
6 #include <unistd.h>
7 #include <errno.h>
8 #include <sys/param.h>
9 #include <sys/utsname.h>
10
11 #include "sbcl.h"
12 #include "os.h"
13 #include "arch.h"
14 #include "interr.h"
15 #include "interrupt.h"
16 #include "globals.h"
17 #include "validate.h"
18 #include "target-arch-os.h"
19
20 #ifdef LISP_FEATURE_GENCGC
21 #error gencgc not ported to hpux
22 #endif
23
24 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
25 #error C_STACK_IS_CONTROL_STACK isnt supported
26 #endif
27
28 size_t os_vm_page_size;
29
30 void
31 os_init(char *argv[], char *envp[])
32 {
33     os_vm_page_size = BACKEND_PAGE_BYTES;
34 }
35
36 os_vm_address_t
37 os_validate(os_vm_address_t addr, os_vm_size_t len)
38 {
39     os_vm_address_t actual;
40     int flags = MAP_PRIVATE | MAP_ANONYMOUS;
41     if (addr) flags |= MAP_FIXED;
42
43     actual = mmap(addr, len, OS_VM_PROT_ALL, flags, -1, 0);
44
45     if (actual == MAP_FAILED) {
46         perror("mmap");
47         lose("os_validate(): mmap() failure\n");
48     }
49
50     if (addr && (addr!=actual)) {
51         fprintf(stderr, "mmap: wanted %lu bytes at %p, actually mapped at %p\n",
52                 (unsigned long) len, addr, actual);
53         return 0;
54     }
55
56     return actual;
57 }
58
59 void
60 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
61 {
62     if (munmap(addr,len) == -1) {
63         perror("munmap");
64         lose("os_invalidate(): mmap() failure\n");
65     }
66 }
67
68 os_vm_address_t
69 os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
70 {
71     os_vm_address_t actual;
72     actual = mmap(addr, len,
73                 OS_VM_PROT_ALL,
74                 MAP_PRIVATE | MAP_FILE | MAP_FIXED,
75                 fd, (off_t) offset);
76     if (actual == MAP_FAILED || (addr && (addr != actual))) {
77         perror("mmap");
78         lose("os_map(): mmap() failure\n");
79     }
80     return actual;
81 }
82
83 void
84 os_protect(os_vm_address_t addr, os_vm_size_t len, os_vm_prot_t prot)
85 {
86     if (mprotect(addr, len, prot) == -1) {
87         perror("mprotect");
88     }
89 }
90
91 boolean
92 is_valid_lisp_addr(os_vm_address_t addr)
93 {
94     struct thread *th;
95     size_t ad = (size_t) addr;
96
97     if ((READ_ONLY_SPACE_START <= ad && ad < READ_ONLY_SPACE_END)
98         || (STATIC_SPACE_START <= ad && ad < STATIC_SPACE_END)
99         || (DYNAMIC_0_SPACE_START <= ad && ad < DYNAMIC_0_SPACE_END)
100         || (DYNAMIC_1_SPACE_START <= ad && ad < DYNAMIC_1_SPACE_END)
101         )
102         return 1;
103     for_each_thread(th) {
104         if((size_t)(th->control_stack_start) <= ad
105            && ad < (size_t)(th->control_stack_end))
106             return 1;
107         if((size_t)(th->binding_stack_start) <= ad
108            && ad < (size_t)(th->binding_stack_start + BINDING_STACK_SIZE))
109             return 1;
110     }
111     return 0;
112 }
113 \f
114 /*
115  * any OS-dependent special low-level handling for signals
116  */
117
118 static void
119 sigsegv_handler(int signal, siginfo_t *info, os_context_t *context)
120 {
121     os_vm_address_t addr = arch_get_bad_addr(signal, info, context);
122
123     if (!cheneygc_handle_wp_violation(context, addr))
124         if (!handle_guard_page_triggered(context, addr))
125             lisp_memory_fault_error(context, addr);
126     *((os_context_register_t *) &((ucontext_t *) context)->uc_mcontext.ss_flags)
127      |= SS_MODIFIEDWIDE;
128 }
129
130 void
131 os_install_interrupt_handlers(void)
132 {
133     undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT,
134                                                  sigsegv_handler);
135 }
136
137 char *
138 os_get_runtime_executable_path(int external)
139 {
140     return NULL;
141 }
142
143 /* when inside call_into_lisp, we will first jump to the stub
144  * and then the stub will jump into the lisp function. Then
145  * the lisp function will return to the stub function and
146  * the stub will return to the call_into_lisp function.
147  */
148 void *return_from_lisp_stub;
149 void
150 setup_return_from_lisp_stub (void *addr)
151 {
152   return_from_lisp_stub = addr;
153 }