aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/cover/cover.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-02-20 20:44:04 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-02-20 20:51:41 +0100
commit04cbdbd1ae105f4d9f11fda99b588168cec2b3a8 (patch)
tree88d70df890b7e1b57aa41a30faab2e3357e770c1 /pkg/cover/cover.go
parente5db1f4f47d782ef80eb15f3fb42acf3e14d9c07 (diff)
syz-fuzzer: prioritize signal from successful syscalls
Signal on successful syscalls is more valuable than signal on unsuccessful syscalls.y
Diffstat (limited to 'pkg/cover/cover.go')
-rw-r--r--pkg/cover/cover.go184
1 files changed, 16 insertions, 168 deletions
diff --git a/pkg/cover/cover.go b/pkg/cover/cover.go
index 4913d1e2f..367f68d4d 100644
--- a/pkg/cover/cover.go
+++ b/pkg/cover/cover.go
@@ -1,182 +1,30 @@
// Copyright 2015 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 cover implements set operations on slices (arrays of coverage PCs). */
+// Package cover provides types for working with coverage information (arrays of covered PCs).
package cover
-import (
- "sort"
-)
+type Cover map[uint32]struct{}
-type Cover []uint32
-
-func (a Cover) Len() int { return len(a) }
-func (a Cover) Less(i, j int) bool { return a[i] < a[j] }
-func (a Cover) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
-const sent = ^uint32(0)
-
-func Copy(cov Cover) Cover {
- return append(Cover{}, cov...)
-}
-
-func RestorePC(pc uint32, base uint32) uint64 {
- return uint64(base)<<32 + uint64(pc)
-}
-
-// Canonicalize sorts and removes duplicates.
-func Canonicalize(cov []uint32) Cover {
- sort.Sort(Cover(cov))
- i := 0
- last := sent
- for _, pc := range cov {
- if pc != last {
- last = pc
- cov[i] = pc
- i++
- }
- }
- return Cover(cov[:i])
-}
-
-func Difference(cov0, cov1 Cover) Cover {
- return foreach(cov0, cov1, func(v0, v1 uint32) uint32 {
- if v0 < v1 {
- return v0
- }
- return sent
- })
-}
-
-func SymmetricDifference(cov0, cov1 Cover) Cover {
- return foreach(cov0, cov1, func(v0, v1 uint32) uint32 {
- if v0 < v1 {
- return v0
- }
- if v1 < v0 {
- return v1
- }
- return sent
- })
-}
-
-func Union(cov0, cov1 Cover) Cover {
- return foreach(cov0, cov1, func(v0, v1 uint32) uint32 {
- if v0 <= v1 {
- return v0
- }
- return v1
- })
-}
-
-func Intersection(cov0, cov1 Cover) Cover {
- return foreach(cov0, cov1, func(v0, v1 uint32) uint32 {
- if v0 == v1 {
- return v0
- }
- return sent
- })
-}
-
-func foreach(cov0, cov1 Cover, f func(uint32, uint32) uint32) Cover {
- var res []uint32
- for i0, i1 := 0, 0; i0 < len(cov0) || i1 < len(cov1); {
- v0, v1 := sent, sent
- if i0 < len(cov0) {
- v0 = cov0[i0]
- }
- if i1 < len(cov1) {
- v1 = cov1[i1]
- }
- if v0 <= v1 {
- i0++
- }
- if v1 <= v0 {
- i1++
- }
- if v := f(v0, v1); v != sent {
- res = append(res, v)
- }
+func (covp *Cover) Merge(raw []uint32) {
+ cov := *covp
+ if cov == nil {
+ cov = make(Cover)
+ *covp = cov
}
- return res
-}
-
-// HasDifference returns true if cov0 has some coverage that is not present in cov1.
-// This is called on fuzzer hot path.
-func HasDifference(cov0, cov1 Cover) bool {
- i1 := 0
- for _, v0 := range cov0 {
- for ; i1 < len(cov1) && cov1[i1] < v0; i1++ {
- }
- if i1 == len(cov1) || cov1[i1] > v0 {
- return true
- }
- i1++
+ for _, pc := range raw {
+ cov[pc] = struct{}{}
}
- return false
}
-// Minimize returns a minimal set of inputs that give the same coverage as the full corpus.
-func Minimize(corpus []Cover) []int {
- inputs := make([]*minInput, len(corpus))
- for i, cov := range corpus {
- inputs[i] = &minInput{
- idx: i,
- cov: cov,
- }
- }
- sort.Sort(minInputArray(inputs))
- var min []int
- covered := make(map[uint32]struct{})
- for _, inp := range inputs {
- hit := false
- for _, pc := range inp.cov {
- if !hit {
- if _, ok := covered[pc]; !ok {
- hit = true
- min = append(min, inp.idx)
- }
- }
- if hit {
- covered[pc] = struct{}{}
- }
- }
+func (cov Cover) Serialize() []uint32 {
+ res := make([]uint32, 0, len(cov))
+ for pc := range cov {
+ res = append(res, pc)
}
- return min
-}
-
-type minInput struct {
- idx int
- cov Cover
-}
-
-type minInputArray []*minInput
-
-// Inputs with larger coverage come first.
-func (a minInputArray) Len() int { return len(a) }
-func (a minInputArray) Less(i, j int) bool { return len(a[i].cov) > len(a[j].cov) }
-func (a minInputArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
-func SignalNew(base map[uint32]struct{}, signal []uint32) bool {
- for _, s := range signal {
- if _, ok := base[s]; !ok {
- return true
- }
- }
- return false
-}
-
-func SignalDiff(base map[uint32]struct{}, signal []uint32) (diff []uint32) {
- for _, s := range signal {
- if _, ok := base[s]; !ok {
- diff = append(diff, s)
- }
- }
- return
+ return res
}
-func SignalAdd(base map[uint32]struct{}, signal []uint32) {
- for _, s := range signal {
- base[s] = struct{}{}
- }
+func RestorePC(pc uint32, base uint32) uint64 {
+ return uint64(base)<<32 + uint64(pc)
}