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 }