From e72f8f11e096d36aefc41a35c718dced97c45dea Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 2 Sep 2020 18:11:22 +1000 Subject: pkg/ifuzz: reorganize files to allow other architectures At the moment ifuzz only generates x86 instructions. In order to support instruction fuzzing for others (ARM, POWERPC), some separation of the common and arch layers is needed. This adds 2 packages: 1. "x86" where x86 instruction generator goes to 2. "ifuzzimpl which contains some common code. The goal was to keep changes to the rand.go to the minimum. The next patch will use this when adding PPC64. This should cause no behavioural change. Signed-off-by: Alexey Kardashevskiy --- pkg/ifuzz/encode.go | 259 ---------------------------------------------------- 1 file changed, 259 deletions(-) delete mode 100644 pkg/ifuzz/encode.go (limited to 'pkg/ifuzz/encode.go') 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 -} -- cgit mrf-deployment