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  }