github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/fuzzer/cover.go (about)

     1  // Copyright 2024 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package fuzzer
     5  
     6  import (
     7  	"sync"
     8  
     9  	"github.com/google/syzkaller/pkg/signal"
    10  	"github.com/google/syzkaller/pkg/stats"
    11  )
    12  
    13  // Cover keeps track of the signal known to the fuzzer.
    14  type Cover struct {
    15  	mu         sync.RWMutex
    16  	maxSignal  signal.Signal // max signal ever observed (including flakes)
    17  	newSignal  signal.Signal // newly identified max signal
    18  	dropSignal signal.Signal // the newly dropped max signal
    19  }
    20  
    21  func newCover() *Cover {
    22  	cover := new(Cover)
    23  	stats.Create("max signal", "Maximum fuzzing signal (including flakes)",
    24  		stats.Graph("signal"), stats.LenOf(&cover.maxSignal, &cover.mu))
    25  	return cover
    26  }
    27  
    28  // Signal that should no longer be chased after.
    29  // It is not returned in GrabSignalDelta().
    30  func (cover *Cover) AddMaxSignal(sign signal.Signal) {
    31  	cover.mu.Lock()
    32  	defer cover.mu.Unlock()
    33  	cover.maxSignal.Merge(sign)
    34  	cover.dropSignal.Subtract(sign)
    35  }
    36  
    37  func (cover *Cover) addRawMaxSignal(signal []uint32, prio uint8) signal.Signal {
    38  	cover.mu.Lock()
    39  	defer cover.mu.Unlock()
    40  	diff := cover.maxSignal.DiffRaw(signal, prio)
    41  	if diff.Empty() {
    42  		return diff
    43  	}
    44  	cover.maxSignal.Merge(diff)
    45  	cover.newSignal.Merge(diff)
    46  	cover.dropSignal.Subtract(diff)
    47  	return diff
    48  }
    49  
    50  func (cover *Cover) pureMaxSignal(corpus signal.Signal) signal.Signal {
    51  	cover.mu.RLock()
    52  	defer cover.mu.RUnlock()
    53  	return corpus.Diff(cover.maxSignal)
    54  }
    55  
    56  func (cover *Cover) CopyMaxSignal() signal.Signal {
    57  	cover.mu.RLock()
    58  	defer cover.mu.RUnlock()
    59  	return cover.maxSignal.Copy()
    60  }
    61  
    62  func (cover *Cover) GrabSignalDelta() (plus, minus signal.Signal) {
    63  	cover.mu.Lock()
    64  	defer cover.mu.Unlock()
    65  	plus = cover.newSignal
    66  	cover.newSignal = nil
    67  	minus = cover.dropSignal
    68  	cover.dropSignal = nil
    69  	return
    70  }
    71  
    72  func (cover *Cover) subtract(delta signal.Signal) {
    73  	cover.mu.Lock()
    74  	defer cover.mu.Unlock()
    75  	cover.maxSignal.Subtract(delta)
    76  	cover.newSignal.Subtract(delta)
    77  	cover.dropSignal.Merge(delta)
    78  }