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