1 /* Defining _XOPEN_SOURCE hides the declaration of madvise() on Solaris <
2 11 and the MADV_DONTNEED definition on IRIX 6.5. */
14 #define MAP_ANON MAP_ANONYMOUS
22 static int dev_zero
= -1;
26 addrspace_free(void *v
__attribute__ ((unused
)), uintptr n
__attribute__ ((unused
)))
29 size_t page_size
= getpagesize();
34 for(off
= 0; off
< n
; off
+= page_size
)
35 if(mincore((char *)v
+ off
, page_size
, (void *)&one_byte
) != -1
43 mmap_fixed(byte
*v
, uintptr n
, int32 prot
, int32 flags
, int32 fd
, uint32 offset
)
47 p
= runtime_mmap((void *)v
, n
, prot
, flags
, fd
, offset
);
48 if(p
!= v
&& addrspace_free(v
, n
)) {
49 // On some systems, mmap ignores v without
50 // MAP_FIXED, so retry if the address space is free.
53 p
= runtime_mmap((void *)v
, n
, prot
, flags
|MAP_FIXED
, fd
, offset
);
59 runtime_SysAlloc(uintptr n
)
68 dev_zero
= open("/dev/zero", O_RDONLY
);
70 runtime_printf("open /dev/zero: errno=%d\n", errno
);
77 p
= runtime_mmap(nil
, n
, PROT_READ
|PROT_WRITE
|PROT_EXEC
, MAP_ANON
|MAP_PRIVATE
, fd
, 0);
78 if (p
== MAP_FAILED
) {
80 runtime_printf("runtime: mmap: access denied\n");
81 runtime_printf("if you're running SELinux, enable execmem for this process.\n");
85 runtime_printf("runtime: mmap: too much locked memory (check 'ulimit -l').\n");
94 runtime_SysUnused(void *v
__attribute__ ((unused
)), uintptr n
__attribute__ ((unused
)))
97 runtime_madvise(v
, n
, MADV_DONTNEED
);
102 runtime_SysFree(void *v
, uintptr n
)
105 runtime_munmap(v
, n
);
109 runtime_SysReserve(void *v
, uintptr n
)
115 if (dev_zero
== -1) {
116 dev_zero
= open("/dev/zero", O_RDONLY
);
118 runtime_printf("open /dev/zero: errno=%d\n", errno
);
125 // On 64-bit, people with ulimit -v set complain if we reserve too
126 // much address space. Instead, assume that the reservation is okay
127 // if we can reserve at least 64K and check the assumption in SysMap.
128 // Only user-mode Linux (UML) rejects these requests.
129 if(sizeof(void*) == 8 && (uintptr
)v
>= 0xffffffffU
) {
130 p
= mmap_fixed(v
, 64<<10, PROT_NONE
, MAP_ANON
|MAP_PRIVATE
, fd
, 0);
133 runtime_munmap(p
, 64<<10);
137 p
= runtime_mmap(v
, n
, PROT_NONE
, MAP_ANON
|MAP_PRIVATE
, fd
, 0);
144 runtime_SysMap(void *v
, uintptr n
)
152 if (dev_zero
== -1) {
153 dev_zero
= open("/dev/zero", O_RDONLY
);
155 runtime_printf("open /dev/zero: errno=%d\n", errno
);
162 // On 64-bit, we don't actually have v reserved, so tread carefully.
163 if(sizeof(void*) == 8 && (uintptr
)v
>= 0xffffffffU
) {
164 p
= mmap_fixed(v
, n
, PROT_READ
|PROT_WRITE
|PROT_EXEC
, MAP_ANON
|MAP_PRIVATE
, fd
, 0);
165 if(p
== MAP_FAILED
&& errno
== ENOMEM
)
166 runtime_throw("runtime: out of memory");
168 runtime_printf("runtime: address space conflict: map(%p) = %p\n", v
, p
);
169 runtime_throw("runtime: address space conflict");
174 p
= runtime_mmap(v
, n
, PROT_READ
|PROT_WRITE
|PROT_EXEC
, MAP_ANON
|MAP_FIXED
|MAP_PRIVATE
, fd
, 0);
176 runtime_throw("runtime: cannot map pages in arena address space");