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