github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/ifuzz/arm64/pseudo.go (about) 1 // Copyright 2024 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 // Pseudo instructions for arm64 architecture. 5 6 package arm64 7 8 import ( 9 "math/rand" 10 11 "github.com/google/syzkaller/pkg/ifuzz/iset" 12 ) 13 14 var pseudo = []*Insn{ 15 { 16 Name: "PSEUDO_HCALL", 17 Pseudo: true, 18 Priv: true, 19 Generator: func(cfg *iset.Config, r *rand.Rand) []byte { 20 gen := makeGen(cfg, r) 21 gen.smcccHvc() 22 return gen.text 23 }, 24 }, 25 } 26 27 type generator struct { 28 r *rand.Rand 29 text []byte 30 } 31 32 func makeGen(cfg *iset.Config, r *rand.Rand) *generator { 33 return &generator{ 34 r: r, 35 } 36 } 37 38 func (gen *generator) smcccHvc() { 39 cmd := (uint32(1) << 31) | (uint32(gen.r.Intn(2)) << 30) | 40 (uint32(gen.r.Intn(8)&0x3F) << 24) | (uint32(gen.r.Intn(0x10000)) & 0xFFFF) 41 gen.movRegImm32(0, cmd) 42 gen.movRegImm16(1, uint32(gen.r.Intn(16))) 43 gen.movRegImm16(2, uint32(gen.r.Intn(16))) 44 gen.movRegImm16(3, uint32(gen.r.Intn(16))) 45 gen.movRegImm16(4, uint32(gen.r.Intn(16))) 46 gen.byte(0x02, 0x00, 0x00, 0xd4) 47 } 48 49 func (gen *generator) movRegImm32(reg, imm uint32) { 50 gen.movRegImm16(reg, imm) 51 // Encoding `movk reg, imm16, LSL #16`. 52 upper := (imm >> 16) & 0xffff 53 opcode := uint32(0xf2a00000) 54 opcode |= upper << 5 55 opcode |= reg & 0xf 56 gen.imm32(opcode) 57 } 58 59 func (gen *generator) movRegImm16(reg, imm uint32) { 60 // Encoding `mov reg, imm16`. 61 imm = imm & 0xffff 62 opcode := uint32(0xd2800000) 63 opcode |= imm << 5 64 opcode |= reg & 0xf 65 gen.imm32(opcode) 66 } 67 68 func (gen *generator) imm32(v uint32) { 69 gen.byte(byte(v>>0), byte(v>>8), byte(v>>16), byte(v>>24)) 70 } 71 72 func (gen *generator) byte(v ...uint8) { 73 gen.text = append(gen.text, v...) 74 }