Files
wazero/internal/platform/mmap.go
Crypt Keeper e0e9e27326 Extracts platform-specific runtime code into its own package (#608)
This moves the platform-specific runtime code (currently only used by
the compiler) into its own package. Specifically, this moves the mmap
logic, and in doing so makes it easier to test, for example new
operating systems.

This also backfills missing RATIONALE about x/sys and hints at a future
possibility to allow a plugin. However, the next step is to get FreeBSD
working natively on the compiler without any additional dependencies.

See #607

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-06-01 09:24:02 +08:00

58 lines
1.6 KiB
Go

//go:build !windows
package platform
import (
"syscall"
)
func munmapCodeSegment(code []byte) error {
return syscall.Munmap(code)
}
// mmapCodeSegmentAMD64 gives all read-write-exec permission to the mmap region
// to enter the function. Otherwise, segmentation fault exception is raised.
func mmapCodeSegmentAMD64(code []byte) ([]byte, error) {
mmapFunc, err := syscall.Mmap(
-1,
0,
len(code),
// The region must be RWX: RW for writing native codes, X for executing the region.
syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC,
// Anonymous as this is not an actual file, but a memory,
// Private as this is in-process memory region.
syscall.MAP_ANON|syscall.MAP_PRIVATE,
)
if err != nil {
return nil, err
}
copy(mmapFunc, code)
return mmapFunc, nil
}
// mmapCodeSegmentARM64 cannot give all read-write-exec permission to the mmap region.
// Otherwise, the mmap systemcall would raise an error. Here we give read-write
// to the region at first, write the native code and then change the perm to
// read-exec so we can execute the native code.
func mmapCodeSegmentARM64(code []byte) ([]byte, error) {
mmapFunc, err := syscall.Mmap(
-1,
0,
len(code),
// The region must be RW: RW for writing native codes.
syscall.PROT_READ|syscall.PROT_WRITE,
// Anonymous as this is not an actual file, but a memory,
// Private as this is in-process memory region.
syscall.MAP_ANON|syscall.MAP_PRIVATE,
)
if err != nil {
return nil, err
}
copy(mmapFunc, code)
// Then we're done with writing code, change the permission to RX.
err = syscall.Mprotect(mmapFunc, syscall.PROT_READ|syscall.PROT_EXEC)
return mmapFunc, err
}