huangcm
2025-02-24 69ed55dec4b2116a19e4cca4393cbc014fce5fb2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 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 ifuzz_test
 
import (
   "encoding/hex"
   "math/rand"
   "testing"
   "time"
 
   . "github.com/google/syzkaller/pkg/ifuzz"
   _ "github.com/google/syzkaller/pkg/ifuzz/generated"
)
 
func TestMode(t *testing.T) {
   all := make(map[*Insn]bool)
   for mode := 0; mode < ModeLast; mode++ {
       for priv := 0; priv < 2; priv++ {
           for exec := 0; exec < 2; exec++ {
               cfg := &Config{
                   Mode: mode,
                   Priv: priv != 0,
                   Exec: exec != 0,
               }
               insns := ModeInsns(cfg)
               t.Logf("mode=%v priv=%v exec=%v: %v instructions", mode, priv, exec, len(insns))
               for _, insn := range insns {
                   all[insn] = true
               }
           }
       }
   }
   t.Logf("total: %v instructions", len(all))
}
 
func TestDecode(t *testing.T) {
   seed := int64(time.Now().UnixNano())
   t.Logf("seed=%v", seed)
   r := rand.New(rand.NewSource(seed))
 
   for repeat := 0; repeat < 10; repeat++ {
       for mode := 0; mode < ModeLast; mode++ {
           cfg := &Config{
               Mode: mode,
               Priv: true,
               Exec: true,
           }
           failed := false
           for _, insn := range ModeInsns(cfg) {
               text0 := insn.Encode(cfg, r)
               text := text0
           repeat:
               size, err := Decode(mode, text)
               if err != nil {
                   t.Errorf("decoding %v %v failed (mode=%v): %v", insn.Name, hex.EncodeToString(text), mode, err)
                   if len(text) != len(text0) {
                       t.Errorf("whole: %v", hex.EncodeToString(text0))
                   }
                   failed = true
                   continue
               }
               if XedDecode != nil {
                   xedSize, xedErr := XedDecode(mode, text)
                   if xedErr != nil {
                       t.Errorf("xed decoding %v %v failed (mode=%v): %v", insn.Name, hex.EncodeToString(text), mode, xedErr)
                       if len(text) != len(text0) {
                           t.Errorf("whole: %v", hex.EncodeToString(text0))
                       }
                       failed = true
                       continue
                   }
                   if size != xedSize {
                       t.Errorf("decoding %v %v failed (mode=%v): decoded %v/%v, xed decoded %v/%v",
                           insn.Name, hex.EncodeToString(text), mode, size, xedSize, size, len(text))
                       if len(text) != len(text0) {
                           t.Errorf("whole: %v", hex.EncodeToString(text0))
                       }
                       failed = true
                       continue
                   }
               }
               if insn.Pseudo && size >= 0 && size < len(text) {
                   text = text[size:]
                   goto repeat
               }
               if size != len(text) {
                   t.Errorf("decoding %v %v failed (mode=%v): decoded %v/%v",
                       insn.Name, hex.EncodeToString(text), mode, size, len(text))
                   if len(text) != len(text0) {
                       t.Errorf("whole: %v", hex.EncodeToString(text0))
                   }
                   failed = true
               }
           }
           if failed {
               return
           }
       }
   }
}