diff options
| -rw-r--r-- | pkg/csource/csource_test.go | 17 | ||||
| -rw-r--r-- | prog/rand.go | 36 |
2 files changed, 48 insertions, 5 deletions
diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go index 3e2c75a23..2eb8cd150 100644 --- a/pkg/csource/csource_test.go +++ b/pkg/csource/csource_test.go @@ -53,6 +53,23 @@ func TestGenerate(t *testing.T) { checked[target.OS] = true t.Parallel() testTarget(t, target, full) + testPseudoSyscalls(t, target) + }) + } +} + +func testPseudoSyscalls(t *testing.T, target *prog.Target) { + // Use options that are as minimal as possible. + // We want to ensure that the code can always be compiled. + opts := Options{ + Slowdown: 1, + } + rs := testutil.RandSource(t) + for _, meta := range target.PseudoSyscalls() { + p := target.GenSampleProg(meta, rs) + t.Run(fmt.Sprintf("single_%s", meta.CallName), func(t *testing.T) { + t.Parallel() + testOne(t, p, opts) }) } } diff --git a/prog/rand.go b/prog/rand.go index c91ffeee4..560e1e176 100644 --- a/prog/rand.go +++ b/prog/rand.go @@ -593,7 +593,23 @@ func (target *Target) GenerateAllSyzProg(rs rand.Source) *Prog { } r := newRand(target, rs) s := newState(target, target.DefaultChoiceTable(), nil) + for _, meta := range target.PseudoSyscalls() { + calls := r.generateParticularCall(s, meta) + for _, c := range calls { + s.analyze(c) + p.Calls = append(p.Calls, c) + } + } + if err := p.validate(); err != nil { + panic(err) + } + return p +} + +// PseudoSyscalls selects one *Syscall for each pseudosyscall. +func (target *Target) PseudoSyscalls() []*Syscall { handled := make(map[string]bool) + var ret []*Syscall for _, meta := range target.Syscalls { if !strings.HasPrefix(meta.CallName, "syz_") || handled[meta.CallName] || @@ -601,12 +617,22 @@ func (target *Target) GenerateAllSyzProg(rs rand.Source) *Prog { meta.Attrs.NoGenerate { continue } + ret = append(ret, meta) handled[meta.CallName] = true - calls := r.generateParticularCall(s, meta) - for _, c := range calls { - s.analyze(c) - p.Calls = append(p.Calls, c) - } + } + return ret +} + +// GenSampleProg generates a single sample program for the call. +func (target *Target) GenSampleProg(meta *Syscall, rs rand.Source) *Prog { + r := newRand(target, rs) + s := newState(target, target.DefaultChoiceTable(), nil) + p := &Prog{ + Target: target, + } + for _, c := range r.generateParticularCall(s, meta) { + s.analyze(c) + p.Calls = append(p.Calls, c) } if err := p.validate(); err != nil { panic(err) |
