aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/ifuzz
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-11-20 19:07:23 +0100
committerDmitry Vyukov <dvyukov@google.com>2020-11-21 08:46:20 +0100
commit6e337f5d06138208368afa1ee9f4b6037ef0f069 (patch)
treee192889f8e77ed1b95bf677d79e8719f9cb2402a /pkg/ifuzz
parent647ed6d0868f745bcfbf4cdbd521ea99377f278e (diff)
pkg/ifuzz/x86: deduplicate modeInsns population logic
It's currently duplicated in x86 and powerpc. Move to ifuzzimpl.
Diffstat (limited to 'pkg/ifuzz')
-rw-r--r--pkg/ifuzz/ifuzz_test.go2
-rw-r--r--pkg/ifuzz/ifuzzimpl/ifuzzimpl.go23
-rw-r--r--pkg/ifuzz/powerpc/powerpc.go30
-rw-r--r--pkg/ifuzz/x86/x86.go34
4 files changed, 37 insertions, 52 deletions
diff --git a/pkg/ifuzz/ifuzz_test.go b/pkg/ifuzz/ifuzz_test.go
index e82edc87a..edee05c9a 100644
--- a/pkg/ifuzz/ifuzz_test.go
+++ b/pkg/ifuzz/ifuzz_test.go
@@ -69,7 +69,7 @@ func testDecode(t *testing.T, arch string) {
}
failed := false
for _, insn := range allInsns(arch, mode, true, true) {
- name, pseudo := insn.Info()
+ name, _, pseudo, _ := insn.Info()
text0 := insn.Encode(cfg, r)
text := text0
repeat:
diff --git a/pkg/ifuzz/ifuzzimpl/ifuzzimpl.go b/pkg/ifuzz/ifuzzimpl/ifuzzimpl.go
index 31ca522cd..831e1ba3f 100644
--- a/pkg/ifuzz/ifuzzimpl/ifuzzimpl.go
+++ b/pkg/ifuzz/ifuzzimpl/ifuzzimpl.go
@@ -20,7 +20,7 @@ type (
)
type Insn interface {
- Info() (string, bool)
+ Info() (name string, mode Mode, pseudo, priv bool)
Encode(cfg *Config, r *rand.Rand) []byte
}
@@ -61,3 +61,24 @@ const (
)
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<<uint(m)) == 0 {
+ continue
+ }
+ set := &modeInsns[m]
+ if pseudo {
+ set[TypeExec] = append(set[TypeExec], insn)
+ } else if priv {
+ set[TypePriv] = append(set[TypePriv], insn)
+ set[TypeAll] = append(set[TypeAll], insn)
+ } else {
+ set[TypeUser] = append(set[TypeUser], insn)
+ set[TypeAll] = append(set[TypeAll], insn)
+ }
+ }
+}
diff --git a/pkg/ifuzz/powerpc/powerpc.go b/pkg/ifuzz/powerpc/powerpc.go
index 4a79f75a9..a78e0a251 100644
--- a/pkg/ifuzz/powerpc/powerpc.go
+++ b/pkg/ifuzz/powerpc/powerpc.go
@@ -40,7 +40,7 @@ type Insn struct {
type InsnSet struct {
Insns []*Insn
- modeInsns [ifuzzimpl.ModeLast][ifuzzimpl.TypeLast][]ifuzzimpl.Insn
+ modeInsns ifuzzimpl.ModeInsns
insnMap map[string]*Insn
}
@@ -105,35 +105,17 @@ func Register(insns []*Insn) {
insnset.insnMap[insn.Name] = insn
}
insnset.initPseudo()
- for mode := ifuzzimpl.Mode(0); mode < ifuzzimpl.ModeLast; mode++ {
- for _, insn := range insnset.Insns {
- if insn.mode()&(1<<uint(mode)) == 0 {
- continue
- }
- if insn.Pseudo {
- insnset.modeInsns[mode][ifuzzimpl.TypeExec] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypeExec], insn)
- } else if insn.Priv {
- insnset.modeInsns[mode][ifuzzimpl.TypePriv] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypePriv], insn)
- insnset.modeInsns[mode][ifuzzimpl.TypeAll] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypeAll], insn)
- } else {
- insnset.modeInsns[mode][ifuzzimpl.TypeUser] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypeUser], insn)
- insnset.modeInsns[mode][ifuzzimpl.TypeAll] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypeAll], insn)
- }
- }
+ for _, insn := range insnset.Insns {
+ insnset.modeInsns.Add(insn)
}
ifuzzimpl.Arches[ifuzzimpl.ArchPowerPC] = insnset
}
-func (insn *Insn) Info() (string, bool) {
- return insn.Name, insn.Pseudo
+func (insn *Insn) Info() (string, ifuzzimpl.Mode, bool, bool) {
+ return insn.Name, insn.mode(), insn.Pseudo, insn.Priv
}
-func (insn Insn) mode() int {
+func (insn Insn) mode() ifuzzimpl.Mode {
if insn.M64 {
return (1 << ifuzzimpl.ModeLong64)
}
diff --git a/pkg/ifuzz/x86/x86.go b/pkg/ifuzz/x86/x86.go
index 6cc9ea7c0..d9fed6cd9 100644
--- a/pkg/ifuzz/x86/x86.go
+++ b/pkg/ifuzz/x86/x86.go
@@ -16,9 +16,9 @@ type Insn struct {
Name string
Extension string
- Mode int // bitmask of compatible modes
- Priv bool // CPL=0
- Pseudo bool // pseudo instructions can consist of several real instructions
+ Mode ifuzzimpl.Mode // bitmask of compatible modes
+ Priv bool // CPL=0
+ Pseudo bool // pseudo instructions can consist of several real instructions
Opcode []byte
Prefix []byte
@@ -48,7 +48,7 @@ type Insn struct {
}
type InsnSet struct {
- modeInsns [ifuzzimpl.ModeLast][ifuzzimpl.TypeLast][]ifuzzimpl.Insn
+ modeInsns ifuzzimpl.ModeInsns
Insns []*Insn
}
@@ -59,26 +59,8 @@ func Register(insns []*Insn) {
insnset := &InsnSet{
Insns: append(insns, pseudo...),
}
- for mode := ifuzzimpl.Mode(0); mode < ifuzzimpl.ModeLast; mode++ {
- for _, insn := range insnset.Insns {
- if insn.Mode&(1<<uint(mode)) == 0 {
- continue
- }
- if insn.Pseudo {
- insnset.modeInsns[mode][ifuzzimpl.TypeExec] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypeExec], insn)
- } else if insn.Priv {
- insnset.modeInsns[mode][ifuzzimpl.TypePriv] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypePriv], insn)
- insnset.modeInsns[mode][ifuzzimpl.TypeAll] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypeAll], insn)
- } else {
- insnset.modeInsns[mode][ifuzzimpl.TypeUser] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypeUser], insn)
- insnset.modeInsns[mode][ifuzzimpl.TypeAll] =
- append(insnset.modeInsns[mode][ifuzzimpl.TypeAll], insn)
- }
- }
+ for _, insn := range insnset.Insns {
+ insnset.modeInsns.Add(insn)
}
ifuzzimpl.Arches[ifuzzimpl.ArchX86] = insnset
}
@@ -87,8 +69,8 @@ func (insnset *InsnSet) GetInsns(mode ifuzzimpl.Mode, typ ifuzzimpl.Type) []ifuz
return insnset.modeInsns[mode][typ]
}
-func (insn *Insn) Info() (string, bool) {
- return insn.Name, insn.Pseudo
+func (insn *Insn) Info() (string, ifuzzimpl.Mode, bool, bool) {
+ return insn.Name, insn.Mode, insn.Pseudo, insn.Priv
}
func generateArg(cfg *ifuzzimpl.Config, r *rand.Rand, size int) []byte {