github.com/tencent/goom@v1.0.1/internal/iface/jmp_arm64.go (about)

     1  package iface
     2  
     3  import "unsafe"
     4  
     5  const (
     6  	_0b1      = 1  // _0b1
     7  	_0b10     = 2  // 0b10
     8  	_0b11     = 3  // 0b11
     9  	_0b100101 = 37 // 0b100101
    10  )
    11  
    12  // jmpWithRdx Assembles a jump to a clourse function value
    13  // dx DX 寄存器
    14  func jmpWithRdx(dx uintptr) (value []byte) {
    15  	res := make([]byte, 0, 24)
    16  	d0d1 := dx & 0xFFFF
    17  	d2d3 := dx >> 16 & 0xFFFF
    18  	d4d5 := dx >> 32 & 0xFFFF
    19  	d6d7 := dx >> 48 & 0xFFFF
    20  
    21  	res = append(res, movImm(_0b10, 0, d0d1)...)         // MOVZ x26, double[16:0]
    22  	res = append(res, movImm(_0b11, 1, d2d3)...)         // MOVK x26, double[32:16]
    23  	res = append(res, movImm(_0b11, 2, d4d5)...)         // MOVK x26, double[48:32]
    24  	res = append(res, movImm(_0b11, 3, d6d7)...)         // MOVK x26, double[64:48]
    25  	res = append(res, []byte{0x5B, 0x03, 0x40, 0xF9}...) // LDR x27, [x26]
    26  	res = append(res, []byte{0x60, 0x03, 0x1F, 0xD6}...) // BR x27
    27  	return res
    28  }
    29  
    30  func movImm(opc, shift int, val uintptr) []byte {
    31  	var m uint32 = 26          // rd
    32  	m |= uint32(val) << 5      // imm16
    33  	m |= uint32(shift&3) << 21 // hw
    34  	m |= _0b100101 << 23       // const
    35  	m |= uint32(opc&0x3) << 29 // opc
    36  	m |= _0b1 << 31            // sf
    37  
    38  	res := make([]byte, 4)
    39  	*(*uint32)(unsafe.Pointer(&res[0])) = m
    40  
    41  	return res
    42  }
    43  
    44  // jmpWithRdxAndCtx Assembles a jump to a function value
    45  // ctx context 地址
    46  // to 跳转目标地址
    47  // from 跳转来源地址
    48  func jmpWithRdxAndCtx(ctx, _, _ uintptr) (value []byte) {
    49  	res := make([]byte, 0, 40)
    50  	d0d1 := ctx & 0xFFFF
    51  	d2d3 := ctx >> 16 & 0xFFFF
    52  	d4d5 := ctx >> 32 & 0xFFFF
    53  	d6d7 := ctx >> 48 & 0xFFFF
    54  
    55  	res = append(res, movImm(_0b10, 0, d0d1)...)         // MOVZ x26, double[16:0]
    56  	res = append(res, movImm(_0b11, 1, d2d3)...)         // MOVK x26, double[32:16]
    57  	res = append(res, movImm(_0b11, 2, d4d5)...)         // MOVK x26, double[48:32]
    58  	res = append(res, movImm(_0b11, 3, d6d7)...)         // MOVK x26, double[64:48]
    59  	res = append(res, []byte{0x5B, 0x03, 0x40, 0xF9}...) // LDR x27, [x26]
    60  	res = append(res, []byte{0x60, 0x03, 0x1F, 0xD6}...) // BR x27
    61  	return res
    62  }