mremap_nosize.go raw
1 //go:build (arm64 || arm) && linux && !js
2 // +build arm64 arm
3 // +build linux
4 // +build !js
5
6 /*
7 * SPDX-FileCopyrightText: © Hypermode Inc. <hello@hypermode.com>
8 * SPDX-License-Identifier: Apache-2.0
9 */
10
11 package z
12
13 import (
14 "reflect"
15 "unsafe"
16
17 "golang.org/x/sys/unix"
18 )
19
20 // mremap is a Linux-specific system call to remap pages in memory. This can be used in place of munmap + mmap.
21 func mremap(data []byte, size int) ([]byte, error) {
22 //nolint:lll
23 // taken from <https://github.com/torvalds/linux/blob/f8394f232b1eab649ce2df5c5f15b0e528c92091/include/uapi/linux/mman.h#L8>
24 const MREMAP_MAYMOVE = 0x1
25
26 header := (*reflect.SliceHeader)(unsafe.Pointer(&data))
27 // For ARM64, the second return argument for SYS_MREMAP is inconsistent (prior allocated size) with
28 // other architectures, which return the size allocated
29 mmapAddr, _, errno := unix.Syscall6(
30 unix.SYS_MREMAP,
31 header.Data,
32 uintptr(header.Len),
33 uintptr(size),
34 uintptr(MREMAP_MAYMOVE),
35 0,
36 0,
37 )
38 if errno != 0 {
39 return nil, errno
40 }
41
42 header.Data = mmapAddr
43 header.Cap = size
44 header.Len = size
45 return data, nil
46 }
47