github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/mmap/darwin_arm64/mmap_nocgo_darwin_arm64.go (about)

     1  //go:build darwin && arm64 && !cgo
     2  // +build darwin,arm64,!cgo
     3  
     4  package darwin_arm64
     5  
     6  import (
     7  	"reflect"
     8  	"runtime"
     9  	"unsafe"
    10  )
    11  
    12  //go:linkname libcCall runtime.libcCall
    13  func libcCall(fn, arg unsafe.Pointer) int32
    14  
    15  func pthread_jit_write_protect_np_trampoline()
    16  
    17  func sys_icache_invalidate_trampoline()
    18  
    19  //go:cgo_import_dynamic libpthread_pthread_jit_write_protect_np pthread_jit_write_protect_np "/usr/lib/libSystem.B.dylib"
    20  
    21  //go:cgo_import_dynamic libkern_sys_icache_invalidate sys_icache_invalidate "/usr/lib/libSystem.B.dylib"
    22  
    23  //go:linkname FuncPCsABI0 github.com/eh-steve/goloader.FuncPCsABI0
    24  func FuncPCsABI0(abiInternalPCs []uintptr) []uintptr
    25  
    26  var jitWriteProtectABI0 uintptr
    27  var sysICacheInvalidateABI0 uintptr
    28  
    29  func init() {
    30  	jitWriteProtectABIInternal := reflect.ValueOf(pthread_jit_write_protect_np_trampoline).Pointer()
    31  	sysICacheInvalidateABIInternal := reflect.ValueOf(sys_icache_invalidate_trampoline).Pointer()
    32  
    33  	abi0PCs := FuncPCsABI0([]uintptr{jitWriteProtectABIInternal, sysICacheInvalidateABIInternal})
    34  	jitWriteProtectABI0 = abi0PCs[0]
    35  	sysICacheInvalidateABI0 = abi0PCs[1]
    36  
    37  	if jitWriteProtectABI0 == 0 {
    38  		panic("could not find ABI0 PC of pthread_jit_write_protect_np_trampoline")
    39  	}
    40  	if sysICacheInvalidateABI0 == 0 {
    41  		panic("could not find ABI0 PC of sys_icache_invalidate_trampoline")
    42  	}
    43  }
    44  
    45  func MakeThreadJITCodeExecutable(ptr uintptr, len int) {
    46  	args := struct {
    47  		writeProtect int32
    48  	}{
    49  		writeProtect: 1,
    50  	}
    51  	libcCall(unsafe.Pointer(jitWriteProtectABI0), unsafe.Pointer(&args))
    52  	runtime.KeepAlive(args)
    53  
    54  	args2 := struct {
    55  		ptr uintptr
    56  		len int
    57  	}{
    58  		ptr: ptr,
    59  		len: len,
    60  	}
    61  	libcCall(unsafe.Pointer(sysICacheInvalidateABI0), unsafe.Pointer(&args2))
    62  	runtime.KeepAlive(args2)
    63  }
    64  
    65  func WriteProtectDisable() {
    66  	args := struct {
    67  		writeProtect int32
    68  	}{
    69  		writeProtect: 0,
    70  	}
    71  	libcCall(unsafe.Pointer(jitWriteProtectABI0), unsafe.Pointer(&args))
    72  	runtime.KeepAlive(args)
    73  }