diff options
Diffstat (limited to 'pkg/ifuzz/encode.go')
| -rw-r--r-- | pkg/ifuzz/encode.go | 259 |
1 files changed, 0 insertions, 259 deletions
diff --git a/pkg/ifuzz/encode.go b/pkg/ifuzz/encode.go deleted file mode 100644 index 5d27a29fd..000000000 --- a/pkg/ifuzz/encode.go +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2017 syzkaller project authors. All rights reserved. -// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. - -// See Intel Software Developer’s Manual Volume 2: Instruction Set Reference -// and AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions -// for details of instruction encoding. - -package ifuzz - -import ( - "math/rand" -) - -// nolint: gocyclo, nestif, gocognit, funlen -func (insn *Insn) Encode(cfg *Config, r *rand.Rand) []byte { - if !insn.isCompatible(cfg) { - panic("instruction is not suitable for this mode") - } - if insn.Pseudo { - return insn.generator(cfg, r) - } - - var operSize, immSize, dispSize, addrSize int - switch cfg.Mode { - case ModeLong64: - operSize, immSize, dispSize, addrSize = 4, 4, 4, 8 - case ModeProt32: - operSize, immSize, dispSize, addrSize = 4, 4, 4, 4 - case ModeProt16, ModeReal16: - operSize, immSize, dispSize, addrSize = 2, 2, 2, 2 - default: - panic("bad mode") - } - - var code []byte - - rexR := false - var vvvv, vexR, vexX, vexB byte - - // LEGACY PREFIXES - if insn.Vex == 0 { - for r.Intn(3) == 0 { - // LOCK 0xF0 is always added to insn.Prefix - prefixes := []byte{ - 0x2E, // CS - 0x3E, // DS - 0x26, // ES - 0x64, // FS - 0x65, // GS - 0x36, // SS - } - if !insn.No66Prefix { - prefixes = append(prefixes, 0x66) // operand size - } - if cfg.Mode == ModeLong64 || !insn.Mem32 { - prefixes = append(prefixes, 0x67) // address size - } - if !insn.NoRepPrefix { - prefixes = append(prefixes, - 0xF3, // REP - 0xF2, // REPNE - ) - } - pref := prefixes[r.Intn(len(prefixes))] - code = append(code, pref) - } - - code = append(code, insn.Prefix...) - - // REX - var rex byte - if cfg.Mode == ModeLong64 && r.Intn(2) == 0 { - // bit 0 - B - // bit 1 - X - // bit 2 - R - // bit 3 - W - rex = byte(0x40 | r.Intn(16)) - if insn.Rexw == 1 { - rex |= 1 << 3 - } else { - rex &^= 1 << 3 - } - rexR = rex&0x4 != 0 - code = append(code, rex) - } - - operSize1, immSize1, dispSize1, addrSize1 := operSize, immSize, dispSize, addrSize - for _, pref := range code { - switch pref { - case 0x66: - if immSize == 4 { - immSize1 = 2 - operSize1 = 2 - } else if immSize == 2 { - immSize1 = 4 - operSize1 = 4 - } - case 0x67: - if addrSize == 8 { - addrSize1 = 4 - } else if addrSize == 4 { - dispSize1 = 2 - addrSize1 = 2 - } else if addrSize == 2 { - dispSize1 = 4 - addrSize1 = 4 - } - } - if rex&(1<<3) != 0 { - operSize1 = 8 - immSize1 = 4 - } - } - operSize, immSize, dispSize, addrSize = operSize1, immSize1, dispSize1, addrSize1 - } else { - // VEX/VOP - code = append(code, insn.Vex) - vexR = byte(1) - vexX = byte(1) - if cfg.Mode == ModeLong64 { - vexR = byte(r.Intn(2)) - vexX = byte(r.Intn(2)) - } - vexB = byte(r.Intn(2)) - W := byte(r.Intn(2)) - if insn.Rexw == 1 { - W = 1 - } else if insn.Rexw == -1 { - W = 0 - } - L := byte(r.Intn(2)) - if insn.VexL == 1 { - L = 1 - } else if insn.VexL == -1 { - L = 0 - } - pp := byte(r.Intn(4)) - if insn.VexP != -1 { - pp = byte(insn.VexP) - } - vvvv = 15 - if !insn.VexNoR { - vvvv = byte(r.Intn(16)) - } - code = append(code, vexR<<7|vexX<<6|vexB<<5|insn.VexMap) - code = append(code, W<<7|vvvv<<3|L<<2|pp) - // TODO: short encoding - if cfg.Mode != ModeLong64 { - vvvv |= 8 - } - } - - // OPCODE - code = append(code, insn.Opcode...) - - if insn.Srm { - rm := byte(insn.Rm) - if insn.Rm == -1 { - rm = byte(r.Intn(8)) - } - code[len(code)-1] |= rm - } else if insn.Modrm { - // MODRM - var mod byte - switch insn.Mod { - case 0, 1, 2, 3: - mod = byte(insn.Mod) - case -1: - mod = byte(r.Intn(4)) - case -3: - mod = byte(r.Intn(3)) - } - - reg := byte(insn.Reg) - if insn.Reg == -1 { - reg = byte(r.Intn(8)) - } else if insn.Reg == -6 { - reg = byte(r.Intn(6)) // segment register - } else if insn.Reg == -8 { - if rexR { - reg = 0 // CR8 - } else { - crs := []byte{0, 2, 3, 4} - reg = crs[r.Intn(len(crs))] - } - } - if insn.Avx2Gather { - if reg|(1-vexR)<<3 == vvvv^0xf { - reg = (reg + 1) & 7 - } - } - - rm := byte(insn.Rm) - if insn.Rm == -1 { - rm = byte(r.Intn(8)) - } - - modrm := mod<<6 | reg<<3 | rm - code = append(code, modrm) - - if !insn.NoSibDisp { - if addrSize == 2 { - if mod == 1 { - // disp8 - code = append(code, generateArg(cfg, r, 1)...) - } else if mod == 2 || mod == 0 && rm == 6 { - // disp16 - code = append(code, generateArg(cfg, r, 2)...) - } - } else { - var sibbase byte - if mod != 3 && rm == 4 { - // SIB - scale := byte(r.Intn(4)) - index := byte(r.Intn(8)) - sibbase = byte(r.Intn(8)) - if insn.Avx2Gather { - rrrr := reg | (1-vexR)<<3 - for { - iiii := index | (1-vexX)<<3 - if iiii != vvvv^0xf && iiii != rrrr { - break - } - index = (index + 1) & 7 - } - } - sib := scale<<6 | index<<3 | sibbase - code = append(code, sib) - } - - if mod == 1 { - // disp8 - code = append(code, generateArg(cfg, r, 1)...) - } else if mod == 2 || mod == 0 && rm == 5 || mod == 0 && sibbase == 5 { - // disp16/32 - code = append(code, generateArg(cfg, r, dispSize)...) - } - } - } - } - - addImm := func(imm int) { - if imm == -1 { - imm = immSize - } else if imm == -2 { - imm = addrSize - } else if imm == -3 { - imm = operSize - } - if imm != 0 { - code = append(code, generateArg(cfg, r, imm)...) - } - } - addImm(int(insn.Imm)) - addImm(int(insn.Imm2)) - - code = append(code, insn.Suffix...) - return code -} |
