github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/ifuzz/x86/x86.go (about) 1 // Copyright 2017 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 //go:generate bash -c "go run gen/gen.go gen/all-enc-instructions.txt > generated/insns.go" 5 6 // Package x86 allows to generate and mutate x86 machine code. 7 package x86 8 9 import ( 10 "math/rand" 11 12 "github.com/google/syzkaller/pkg/ifuzz/iset" 13 ) 14 15 type Insn struct { 16 Name string 17 Extension string 18 19 Mode iset.Mode // bitmask of compatible modes 20 Priv bool // CPL=0 21 Pseudo bool // pseudo instructions can consist of several real instructions 22 23 Opcode []byte 24 Prefix []byte 25 Suffix []byte 26 Modrm bool 27 Mod int8 28 Reg int8 // -6 - segment register, -8 - control register 29 Rm int8 30 Srm bool // register is embed in the first byte 31 NoSibDisp bool // no SIB/disp even if modrm says otherwise 32 Imm int8 // immediate size, -1 - immediate size, -2 - address size, -3 - operand size 33 Imm2 int8 34 NoRepPrefix bool 35 No66Prefix bool 36 Rexw int8 // 1 must be set, -1 must not be set 37 Mem32 bool // instruction always references 32-bit memory operand, 0x67 is illegal 38 Mem16 bool // instruction always references 16-bit memory operand 39 40 Vex byte 41 VexMap byte 42 VexL int8 43 VexNoR bool 44 VexP int8 45 Avx2Gather bool 46 47 generator func(cfg *iset.Config, r *rand.Rand) []byte // for pseudo instructions 48 } 49 50 type InsnSet struct { 51 modeInsns iset.ModeInsns 52 Insns []*Insn 53 } 54 55 func Register(insns []*Insn) { 56 if len(insns) == 0 { 57 panic("no instructions") 58 } 59 insnset := &InsnSet{ 60 Insns: append(insns, pseudo...), 61 } 62 for _, insn := range insnset.Insns { 63 insnset.modeInsns.Add(insn) 64 } 65 iset.Arches[iset.ArchX86] = insnset 66 } 67 68 func (insnset *InsnSet) GetInsns(mode iset.Mode, typ iset.Type) []iset.Insn { 69 return insnset.modeInsns[mode][typ] 70 } 71 72 func (insn *Insn) Info() (string, iset.Mode, bool, bool) { 73 return insn.Name, insn.Mode, insn.Pseudo, insn.Priv 74 } 75 76 func generateArg(cfg *iset.Config, r *rand.Rand, size int) []byte { 77 v := iset.GenerateInt(cfg, r, size) 78 arg := make([]byte, size) 79 for i := 0; i < size; i++ { 80 arg[i] = byte(v) 81 v >>= 8 82 } 83 return arg 84 }