github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/mmap/mmap_darwin_arm64.go (about) 1 //go:build darwin && arm64 2 // +build darwin,arm64 3 4 package mmap 5 6 import ( 7 "github.com/eh-steve/goloader/mmap/darwin_arm64" 8 "github.com/eh-steve/goloader/mprotect" 9 10 "fmt" 11 "os" 12 "reflect" 13 "syscall" 14 "unsafe" 15 ) 16 17 func MakeThreadJITCodeExecutable(ptr uintptr, len int) { 18 var pages []byte 19 pageSlice := (*reflect.SliceHeader)(unsafe.Pointer(&pages)) 20 pageSlice.Data = ptr 21 pageSlice.Len = len 22 pageSlice.Cap = len 23 err := mprotect.MprotectMakeExecutable(pages) 24 if err != nil { 25 panic(err) 26 } 27 darwin_arm64.MakeThreadJITCodeExecutable(ptr, len) 28 } 29 30 func Mmap(size int) ([]byte, error) { 31 return AcquireMapping(size, mmapCode) 32 } 33 34 func MmapData(size int) ([]byte, error) { 35 return AcquireMapping(size, mmapData) 36 } 37 38 func mmapCode(size int, addr uintptr) ([]byte, error) { 39 // darwin arm64 won't accept MAP_FIXED, but seems to take addr as a hint... 40 data, err := mapper.Mmap( 41 addr, 42 -1, 43 0, 44 size, 45 syscall.PROT_READ|syscall.PROT_WRITE, // this is not yet executable, we will mprotect it after we're finished writing to it 46 syscall.MAP_PRIVATE|syscall.MAP_ANON|syscall.MAP_JIT) 47 if err != nil { 48 return nil, err 49 } 50 if uintptr(unsafe.Pointer(&data[0]))-addr > 1<<24 { 51 defer mapper.Munmap(data) 52 return nil, fmt.Errorf("failed to acquire code mapping within 24 bit address of 0x%x, got %p", addr, &data[0]) 53 } 54 darwin_arm64.WriteProtectDisable() 55 return data, err 56 } 57 58 func mmapData(size int, addr uintptr) ([]byte, error) { 59 // darwin arm64 won't accept MAP_FIXED, but seems to take addr as a hint... 60 data, err := mapper.Mmap( 61 addr, 62 -1, 63 0, 64 size, 65 syscall.PROT_READ|syscall.PROT_WRITE, 66 syscall.MAP_PRIVATE|syscall.MAP_ANON) 67 if err != nil { 68 return nil, err 69 } 70 if uintptr(unsafe.Pointer(&data[0]))-addr > 1<<24 { 71 defer mapper.Munmap(data) 72 return nil, fmt.Errorf("failed to acquire data mapping within 24 bit address of 0x%x, got %p", addr, &data[0]) 73 } 74 return data, err 75 } 76 77 func Munmap(b []byte) (err error) { 78 err = mapper.Munmap(b) 79 if err != nil { 80 err = os.NewSyscallError("syscall.Munmap", err) 81 } 82 return 83 }