diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-02-20 20:44:04 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-02-20 20:51:41 +0100 |
| commit | 04cbdbd1ae105f4d9f11fda99b588168cec2b3a8 (patch) | |
| tree | 88d70df890b7e1b57aa41a30faab2e3357e770c1 /pkg/cover/cover.go | |
| parent | e5db1f4f47d782ef80eb15f3fb42acf3e14d9c07 (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.go | 184 |
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) } |
