From 418476ecb925e5d58ba9c22928a4e37dc30909df Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 20 Nov 2020 19:28:53 +0100 Subject: pkg/ifuzz/iset: rename ifuzzimpl to iset ifuzzimpl is too lenghty and too clumsy on my taste (nm/vmimpl worked better b/c it's shorter and used less). I've tried to come up with something shorter and nicer. We could use "insn" as a common name for "instruction" in ifuzz, but it's a commonly used name already so would cause lots of conflicts. "iset" is somewhat descriptive, short and nice. --- pkg/ifuzz/ifuzz.go | 34 ++++++------- pkg/ifuzz/ifuzz_test.go | 22 ++++----- pkg/ifuzz/ifuzzimpl/ifuzzimpl.go | 101 -------------------------------------- pkg/ifuzz/iset/iset.go | 102 +++++++++++++++++++++++++++++++++++++++ pkg/ifuzz/powerpc/powerpc.go | 24 ++++----- pkg/ifuzz/powerpc/pseudo.go | 12 ++--- pkg/ifuzz/x86/decode.go | 16 +++--- pkg/ifuzz/x86/encode.go | 18 +++---- pkg/ifuzz/x86/gen/gen.go | 16 +++--- pkg/ifuzz/x86/pseudo.go | 84 ++++++++++++++++---------------- pkg/ifuzz/x86/x86.go | 24 ++++----- 11 files changed, 227 insertions(+), 226 deletions(-) delete mode 100644 pkg/ifuzz/ifuzzimpl/ifuzzimpl.go create mode 100644 pkg/ifuzz/iset/iset.go (limited to 'pkg/ifuzz') diff --git a/pkg/ifuzz/ifuzz.go b/pkg/ifuzz/ifuzz.go index 45082834d..01137b6ea 100644 --- a/pkg/ifuzz/ifuzz.go +++ b/pkg/ifuzz/ifuzz.go @@ -6,24 +6,24 @@ package ifuzz import ( "math/rand" - "github.com/google/syzkaller/pkg/ifuzz/ifuzzimpl" + "github.com/google/syzkaller/pkg/ifuzz/iset" _ "github.com/google/syzkaller/pkg/ifuzz/powerpc/generated" // pull in generated instruction descriptions _ "github.com/google/syzkaller/pkg/ifuzz/x86/generated" // pull in generated instruction descriptions ) type ( - Config = ifuzzimpl.Config - MemRegion = ifuzzimpl.MemRegion - Mode = ifuzzimpl.Mode + Config = iset.Config + MemRegion = iset.MemRegion + Mode = iset.Mode ) const ( - ArchX86 = ifuzzimpl.ArchX86 - ArchPowerPC = ifuzzimpl.ArchPowerPC - ModeLong64 = ifuzzimpl.ModeLong64 - ModeProt32 = ifuzzimpl.ModeProt32 - ModeProt16 = ifuzzimpl.ModeProt16 - ModeReal16 = ifuzzimpl.ModeReal16 + ArchX86 = iset.ArchX86 + ArchPowerPC = iset.ArchPowerPC + ModeLong64 = iset.ModeLong64 + ModeProt32 = iset.ModeProt32 + ModeProt16 = iset.ModeProt16 + ModeReal16 = iset.ModeReal16 ) func Generate(cfg *Config, r *rand.Rand) []byte { @@ -99,21 +99,21 @@ func Mutate(cfg *Config, r *rand.Rand, text []byte) []byte { return text } -func randInsn(cfg *Config, r *rand.Rand) ifuzzimpl.Insn { - insnset := ifuzzimpl.Arches[cfg.Arch] - var insns []ifuzzimpl.Insn +func randInsn(cfg *Config, r *rand.Rand) iset.Insn { + insnset := iset.Arches[cfg.Arch] + var insns []iset.Insn if cfg.Priv && cfg.Exec { - insns = insnset.GetInsns(cfg.Mode, ifuzzimpl.Type(r.Intn(3))) + insns = insnset.GetInsns(cfg.Mode, iset.Type(r.Intn(3))) } else if cfg.Priv { - insns = insnset.GetInsns(cfg.Mode, ifuzzimpl.Type(r.Intn(2))) + insns = insnset.GetInsns(cfg.Mode, iset.Type(r.Intn(2))) } else { - insns = insnset.GetInsns(cfg.Mode, ifuzzimpl.TypeUser) + insns = insnset.GetInsns(cfg.Mode, iset.TypeUser) } return insns[r.Intn(len(insns))] } func split(cfg *Config, text []byte) [][]byte { - insnset := ifuzzimpl.Arches[cfg.Arch] + insnset := iset.Arches[cfg.Arch] text = append([]byte{}, text...) var insns [][]byte var bad []byte diff --git a/pkg/ifuzz/ifuzz_test.go b/pkg/ifuzz/ifuzz_test.go index edee05c9a..eee8afe00 100644 --- a/pkg/ifuzz/ifuzz_test.go +++ b/pkg/ifuzz/ifuzz_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/google/syzkaller/pkg/ifuzz/ifuzzimpl" + "github.com/google/syzkaller/pkg/ifuzz/iset" ) var allArches = []string{ArchX86, ArchPowerPC} @@ -24,8 +24,8 @@ func TestMode(t *testing.T) { } func testMode(t *testing.T, arch string) { - all := make(map[ifuzzimpl.Insn]bool) - for mode := ifuzzimpl.Mode(0); mode < ifuzzimpl.ModeLast; mode++ { + all := make(map[iset.Insn]bool) + for mode := iset.Mode(0); mode < iset.ModeLast; mode++ { for priv := 0; priv < 2; priv++ { for exec := 0; exec < 2; exec++ { insns := allInsns(arch, mode, priv != 0, exec != 0) @@ -48,7 +48,7 @@ func TestDecode(t *testing.T) { } func testDecode(t *testing.T, arch string) { - insnset := ifuzzimpl.Arches[arch] + insnset := iset.Arches[arch] xedEnabled := false if _, err := insnset.DecodeExt(0, nil); err == nil { xedEnabled = true @@ -61,8 +61,8 @@ func testDecode(t *testing.T, arch string) { r := rand.New(rand.NewSource(seed)) for repeat := 0; repeat < 10; repeat++ { - for mode := ifuzzimpl.Mode(0); mode < ifuzzimpl.ModeLast; mode++ { - cfg := &ifuzzimpl.Config{ + for mode := iset.Mode(0); mode < iset.ModeLast; mode++ { + cfg := &iset.Config{ Mode: mode, Priv: true, Exec: true, @@ -122,13 +122,13 @@ func testDecode(t *testing.T, arch string) { } } -func allInsns(arch string, mode ifuzzimpl.Mode, priv, exec bool) []ifuzzimpl.Insn { - insnset := ifuzzimpl.Arches[arch] - insns := insnset.GetInsns(mode, ifuzzimpl.TypeUser) +func allInsns(arch string, mode iset.Mode, priv, exec bool) []iset.Insn { + insnset := iset.Arches[arch] + insns := insnset.GetInsns(mode, iset.TypeUser) if priv { - insns = append(insns, insnset.GetInsns(mode, ifuzzimpl.TypePriv)...) + insns = append(insns, insnset.GetInsns(mode, iset.TypePriv)...) if exec { - insns = append(insns, insnset.GetInsns(mode, ifuzzimpl.TypeExec)...) + insns = append(insns, insnset.GetInsns(mode, iset.TypeExec)...) } } return insns diff --git a/pkg/ifuzz/ifuzzimpl/ifuzzimpl.go b/pkg/ifuzz/ifuzzimpl/ifuzzimpl.go deleted file mode 100644 index 32f285250..000000000 --- a/pkg/ifuzz/ifuzzimpl/ifuzzimpl.go +++ /dev/null @@ -1,101 +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. - -package ifuzzimpl - -import ( - "math/rand" -) - -const ( - ArchX86 = "x86" - ArchPowerPC = "powerpc" -) - -var Arches = make(map[string]InsnSet) - -type ( - Mode int - Type int -) - -type Insn interface { - Info() (name string, mode Mode, pseudo, priv bool) - Encode(cfg *Config, r *rand.Rand) []byte -} - -type InsnSet interface { - GetInsns(mode Mode, typ Type) []Insn - Decode(mode Mode, text []byte) (int, error) - DecodeExt(mode Mode, text []byte) (int, error) // XED, to keep ifuzz_test happy -} - -type Config struct { - Arch string - Len int // number of instructions to generate - Mode Mode // one of ModeXXX - Priv bool // generate CPL=0 instructions (x86), HV/!PR mode (PPC) - Exec bool // generate instructions sequences interesting for execution - MemRegions []MemRegion // generated instructions will reference these regions -} - -type MemRegion struct { - Start uint64 - Size uint64 -} - -const ( - ModeLong64 Mode = iota - ModeProt32 - ModeProt16 - ModeReal16 - ModeLast -) - -const ( - TypeExec Type = iota - TypePriv - TypeUser - TypeAll - TypeLast -) - -var SpecialNumbers = [...]uint64{0, 1 << 15, 1 << 16, 1 << 31, 1 << 32, 1 << 47, 1 << 47, 1 << 63} - -type ModeInsns [ModeLast][TypeLast][]Insn - -func (modeInsns *ModeInsns) Add(insn Insn) { - _, mode, pseudo, priv := insn.Info() - for m := Mode(0); m < ModeLast; m++ { - if mode&(1<= ModeLast { - panic("bad mode") - } - if priv && !cfg.Priv { - return false - } - if pseudo && !cfg.Exec { - return false - } - if mode&(1<= ModeLast { + panic("bad mode") + } + if priv && !cfg.Priv { + return false + } + if pseudo && !cfg.Exec { + return false + } + if mode&(1< 1 { // There are only 2 32-bit instructions that look like VEX-prefixed but are actually not: LDS, LES. // They always reference memory (mod!=3), but all VEX instructions have "mod=3" where LDS/LES would have mod. - if (text[0] == 0xc4 || text[0] == 0xc5) && (mode == ifuzzimpl.ModeLong64 || text[1]&0xc0 == 0xc0) { + if (text[0] == 0xc4 || text[0] == 0xc5) && (mode == iset.ModeLong64 || text[1]&0xc0 == 0xc0) { vex = true } // There is only one instruction that looks like XOP-prefixed but is actually not: POP. @@ -208,7 +208,7 @@ nextInsn: return 0, fmt.Errorf("unknown instruction") } -var XedDecode func(mode ifuzzimpl.Mode, text []byte) (int, error) +var XedDecode func(mode iset.Mode, text []byte) (int, error) var ( prefixes32 = map[byte]bool{ @@ -226,7 +226,7 @@ var ( } ) -func (insnset *InsnSet) DecodeExt(mode ifuzzimpl.Mode, text []byte) (int, error) { +func (insnset *InsnSet) DecodeExt(mode iset.Mode, text []byte) (int, error) { if XedDecode != nil && text != nil && len(text) > 0 { return XedDecode(mode, text) } diff --git a/pkg/ifuzz/x86/encode.go b/pkg/ifuzz/x86/encode.go index 9203d51c3..59b9a294a 100644 --- a/pkg/ifuzz/x86/encode.go +++ b/pkg/ifuzz/x86/encode.go @@ -10,11 +10,11 @@ package x86 import ( "math/rand" - "github.com/google/syzkaller/pkg/ifuzz/ifuzzimpl" + "github.com/google/syzkaller/pkg/ifuzz/iset" ) // nolint: gocyclo, nestif, gocognit, funlen -func (insn *Insn) Encode(cfg *ifuzzimpl.Config, r *rand.Rand) []byte { +func (insn *Insn) Encode(cfg *iset.Config, r *rand.Rand) []byte { if !cfg.IsCompatible(insn) { panic("instruction is not suitable for this mode") } @@ -24,11 +24,11 @@ func (insn *Insn) Encode(cfg *ifuzzimpl.Config, r *rand.Rand) []byte { var operSize, immSize, dispSize, addrSize int switch cfg.Mode { - case ifuzzimpl.ModeLong64: + case iset.ModeLong64: operSize, immSize, dispSize, addrSize = 4, 4, 4, 8 - case ifuzzimpl.ModeProt32: + case iset.ModeProt32: operSize, immSize, dispSize, addrSize = 4, 4, 4, 4 - case ifuzzimpl.ModeProt16, ifuzzimpl.ModeReal16: + case iset.ModeProt16, iset.ModeReal16: operSize, immSize, dispSize, addrSize = 2, 2, 2, 2 default: panic("bad mode") @@ -54,7 +54,7 @@ func (insn *Insn) Encode(cfg *ifuzzimpl.Config, r *rand.Rand) []byte { if !insn.No66Prefix { prefixes = append(prefixes, 0x66) // operand size } - if cfg.Mode == ifuzzimpl.ModeLong64 || !insn.Mem32 { + if cfg.Mode == iset.ModeLong64 || !insn.Mem32 { prefixes = append(prefixes, 0x67) // address size } if !insn.NoRepPrefix { @@ -71,7 +71,7 @@ func (insn *Insn) Encode(cfg *ifuzzimpl.Config, r *rand.Rand) []byte { // REX var rex byte - if cfg.Mode == ifuzzimpl.ModeLong64 && r.Intn(2) == 0 { + if cfg.Mode == iset.ModeLong64 && r.Intn(2) == 0 { // bit 0 - B // bit 1 - X // bit 2 - R @@ -119,7 +119,7 @@ func (insn *Insn) Encode(cfg *ifuzzimpl.Config, r *rand.Rand) []byte { code = append(code, insn.Vex) vexR = byte(1) vexX = byte(1) - if cfg.Mode == ifuzzimpl.ModeLong64 { + if cfg.Mode == iset.ModeLong64 { vexR = byte(r.Intn(2)) vexX = byte(r.Intn(2)) } @@ -147,7 +147,7 @@ func (insn *Insn) Encode(cfg *ifuzzimpl.Config, r *rand.Rand) []byte { 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 != ifuzzimpl.ModeLong64 { + if cfg.Mode != iset.ModeLong64 { vvvv |= 8 } } diff --git a/pkg/ifuzz/x86/gen/gen.go b/pkg/ifuzz/x86/gen/gen.go index 3622ba248..284ea9033 100644 --- a/pkg/ifuzz/x86/gen/gen.go +++ b/pkg/ifuzz/x86/gen/gen.go @@ -13,7 +13,7 @@ import ( "strconv" "strings" - "github.com/google/syzkaller/pkg/ifuzz/ifuzzimpl" + "github.com/google/syzkaller/pkg/ifuzz/iset" "github.com/google/syzkaller/pkg/ifuzz/x86" "github.com/google/syzkaller/pkg/serializer" ) @@ -102,7 +102,7 @@ func main() { insn.Extension = vals[0] switch insn.Extension { case "FMA", "AVX2", "AVX", "F16C", "BMI2", "BMI", "XOP", "FMA4", "AVXAES", "BMI1", "AVX2GATHER": - insn.Mode = 1<> 4 } reg := uint8(r.Intn(6)) @@ -169,14 +169,14 @@ var pseudo = []*Insn{ }, { Name: "PSEUDO_FAR_JMP", - Mode: 1<