mSysStatInc(sysStat, n)
// AIX does not allow mapping a range that is already mapped.
- // So always unmap first even if it is already unmapped.
- munmap(v, n)
- p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
-
+ // So, call mprotect to change permissions.
+ // Note that sysMap is always called with a non-nil pointer
+ // since it transitions a Reserved memory region to Prepared,
+ // so mprotect is always possible.
+ _, err := mprotect(v, n, _PROT_READ|_PROT_WRITE)
if err == _ENOMEM {
throw("runtime: out of memory")
}
- if p != v || err != 0 {
+ if err != 0 {
throw("runtime: cannot map pages in arena address space")
}
}
//go:cgo_import_dynamic libc_madvise madvise "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_malloc malloc "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_mmap mmap "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_munmap munmap "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_open open "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_pipe pipe "libc.a/shr_64.o"
//go:linkname libc_madvise libc_madvise
//go:linkname libc_malloc libc_malloc
//go:linkname libc_mmap libc_mmap
+//go:linkname libc_mprotect libc_mprotect
//go:linkname libc_munmap libc_munmap
//go:linkname libc_open libc_open
//go:linkname libc_pipe libc_pipe
libc_madvise,
libc_malloc,
libc_mmap,
+ libc_mprotect,
libc_munmap,
libc_open,
libc_pipe,
return unsafe.Pointer(r), int(err0)
}
+//go:nosplit
+func mprotect(addr unsafe.Pointer, n uintptr, prot int32) (unsafe.Pointer, int) {
+ r, err0 := syscall3(&libc_mprotect, uintptr(addr), uintptr(n), uintptr(prot))
+ if r == ^uintptr(0) {
+ return nil, int(err0)
+ }
+ return unsafe.Pointer(r), int(err0)
+}
+
//go:nosplit
func munmap(addr unsafe.Pointer, n uintptr) {
r, err := syscall2(&libc_munmap, uintptr(addr), uintptr(n))