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  }