github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/platform/mmap_unix.go (about)

     1  //go:build (darwin || linux || freebsd) && !tinygo
     2  
     3  package platform
     4  
     5  import (
     6  	"syscall"
     7  	"unsafe"
     8  )
     9  
    10  const (
    11  	mmapProtAMD64 = syscall.PROT_READ | syscall.PROT_WRITE | syscall.PROT_EXEC
    12  	mmapProtARM64 = syscall.PROT_READ | syscall.PROT_WRITE
    13  )
    14  
    15  const MmapSupported = true
    16  
    17  func munmapCodeSegment(code []byte) error {
    18  	return syscall.Munmap(code)
    19  }
    20  
    21  // mmapCodeSegmentAMD64 gives all read-write-exec permission to the mmap region
    22  // to enter the function. Otherwise, segmentation fault exception is raised.
    23  func mmapCodeSegmentAMD64(size int) ([]byte, error) {
    24  	// The region must be RWX: RW for writing native codes, X for executing the region.
    25  	return mmapCodeSegment(size, mmapProtAMD64)
    26  }
    27  
    28  // mmapCodeSegmentARM64 cannot give all read-write-exec permission to the mmap region.
    29  // Otherwise, the mmap systemcall would raise an error. Here we give read-write
    30  // to the region so that we can write contents at call-sites. Callers are responsible to
    31  // execute MprotectRX on the returned buffer.
    32  func mmapCodeSegmentARM64(size int) ([]byte, error) {
    33  	// The region must be RW: RW for writing native codes.
    34  	return mmapCodeSegment(size, mmapProtARM64)
    35  }
    36  
    37  // MprotectRX is like syscall.Mprotect with RX permission, defined locally so that freebsd compiles.
    38  func MprotectRX(b []byte) (err error) {
    39  	var _p0 unsafe.Pointer
    40  	if len(b) > 0 {
    41  		_p0 = unsafe.Pointer(&b[0])
    42  	}
    43  	const prot = syscall.PROT_READ | syscall.PROT_EXEC
    44  	_, _, e1 := syscall.Syscall(syscall.SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
    45  	if e1 != 0 {
    46  		err = syscall.Errno(e1)
    47  	}
    48  	return
    49  }