github.com/wfusion/gofusion@v1.1.14/common/utils/gomonkey/jmp_arm64.go (about) 1 //go:build arm64 2 // +build arm64 3 4 package gomonkey 5 6 import "unsafe" 7 8 func buildJmpDirective(double uintptr) []byte { 9 res := make([]byte, 0, 24) 10 d0d1 := double & 0xFFFF 11 d2d3 := double >> 16 & 0xFFFF 12 d4d5 := double >> 32 & 0xFFFF 13 d6d7 := double >> 48 & 0xFFFF 14 15 res = append(res, movImm(0b10, 0, d0d1)...) // MOVZ x26, double[16:0] 16 res = append(res, movImm(0b11, 1, d2d3)...) // MOVK x26, double[32:16] 17 res = append(res, movImm(0b11, 2, d4d5)...) // MOVK x26, double[48:32] 18 res = append(res, movImm(0b11, 3, d6d7)...) // MOVK x26, double[64:48] 19 res = append(res, []byte{0x4A, 0x03, 0x40, 0xF9}...) // LDR x10, [x26] 20 res = append(res, []byte{0x40, 0x01, 0x1F, 0xD6}...) // BR x10 21 22 return res 23 } 24 25 func movImm(opc, shift int, val uintptr) []byte { 26 var m uint32 = 26 // rd 27 m |= uint32(val) << 5 // imm16 28 m |= uint32(shift&3) << 21 // hw 29 m |= 0b100101 << 23 // const 30 m |= uint32(opc&0x3) << 29 // opc 31 m |= 0b1 << 31 // sf 32 33 res := make([]byte, 4) 34 *(*uint32)(unsafe.Pointer(&res[0])) = m 35 36 return res 37 }