github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/platform/platform.go (about) 1 // Package platform includes runtime-specific code needed for the compiler or otherwise. 2 // 3 // Note: This is a dependency-free alternative to depending on parts of Go's x/sys. 4 // See /RATIONALE.md for more context. 5 package platform 6 7 import ( 8 "runtime" 9 ) 10 11 // archRequirementsVerified is set by platform-specific init to true if the platform is supported 12 var archRequirementsVerified bool 13 14 // CompilerSupported is exported for tests and includes constraints here and also the assembler. 15 func CompilerSupported() bool { 16 switch runtime.GOOS { 17 case "darwin", "windows", "linux", "freebsd": 18 default: 19 return false 20 } 21 22 return archRequirementsVerified 23 } 24 25 // MmapCodeSegment copies the code into the executable region and returns the byte slice of the region. 26 // 27 // See https://man7.org/linux/man-pages/man2/mmap.2.html for mmap API and flags. 28 func MmapCodeSegment(size int) ([]byte, error) { 29 if size == 0 { 30 panic("BUG: MmapCodeSegment with zero length") 31 } 32 if runtime.GOARCH == "amd64" { 33 return mmapCodeSegmentAMD64(size) 34 } else { 35 return mmapCodeSegmentARM64(size) 36 } 37 } 38 39 // RemapCodeSegment reallocates the memory mapping of an existing code segment 40 // to increase its size. The previous code mapping is unmapped and must not be 41 // reused after the function returns. 42 // 43 // This is similar to mremap(2) on linux, and emulated on platforms which do not 44 // have this syscall. 45 // 46 // See https://man7.org/linux/man-pages/man2/mremap.2.html 47 func RemapCodeSegment(code []byte, size int) ([]byte, error) { 48 if size < len(code) { 49 panic("BUG: RemapCodeSegment with size less than code") 50 } 51 if code == nil { 52 return MmapCodeSegment(size) 53 } 54 if runtime.GOARCH == "amd64" { 55 return remapCodeSegmentAMD64(code, size) 56 } else { 57 return remapCodeSegmentARM64(code, size) 58 } 59 } 60 61 // MunmapCodeSegment unmaps the given memory region. 62 func MunmapCodeSegment(code []byte) error { 63 if len(code) == 0 { 64 panic("BUG: MunmapCodeSegment with zero length") 65 } 66 return munmapCodeSegment(code) 67 } 68 69 // mustMunmapCodeSegment panics instead of returning an error to the 70 // application. 71 // 72 // # Why panic? 73 // 74 // It is less disruptive to the application to leak the previous block if it 75 // could be unmapped than to leak the new block and return an error. 76 // Realistically, either scenarios are pretty hard to debug, so we panic. 77 func mustMunmapCodeSegment(code []byte) { 78 if err := munmapCodeSegment(code); err != nil { 79 panic(err) 80 } 81 }