diff options
| author | Marco Elver <elver@google.com> | 2019-06-06 18:44:34 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-06-07 14:03:39 +0200 |
| commit | ce9107d08661be9dfd81b6f69700eaac7f93b270 (patch) | |
| tree | 98dac4c47a08719a3d10a01cfd54d5cd1e68df1f /prog/mutation.go | |
| parent | b004e95a3aead2d756c208ba19bae2cea3bd50e5 (diff) | |
prog/mutation: Add internal comments
Diffstat (limited to 'prog/mutation.go')
| -rw-r--r-- | prog/mutation.go | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/prog/mutation.go b/prog/mutation.go index 86cf487aa..3a4c8cddb 100644 --- a/prog/mutation.go +++ b/prog/mutation.go @@ -9,8 +9,16 @@ import ( "unsafe" ) +// Maximum length of generated binary blobs inserted into the program. const maxBlobLen = uint64(100 << 10) +// Mutate program p. +// +// p: The program to mutate. +// rs: Random source. +// ncalls: The allowed maximum calls in mutated program. +// ct: ChoiceTable for syscalls. +// corpus: The entire corpus, including original program p. func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable, corpus []*Prog) { r := newRand(p.Target, rs) ctx := &mutator{ @@ -42,14 +50,19 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable, corpus []*Pro p.debugValidate() } +// Internal state required for performing mutations -- currently this matches +// the arguments passed to Mutate(). type mutator struct { - p *Prog - r *randGen - ncalls int - ct *ChoiceTable - corpus []*Prog + p *Prog // The program to mutate. + r *randGen // The randGen instance. + ncalls int // The allowed maximum calls in mutated program. + ct *ChoiceTable // ChoiceTable for syscalls. + corpus []*Prog // The entire corpus, including original program p. } +// This function selects a random other program p0 out of the corpus, and +// mutates ctx.p as follows: preserve ctx.p's Calls up to a random index i +// (exclusive) concatenated with p0's calls from index i (inclusive). func (ctx *mutator) splice() bool { p, r := ctx.p, ctx.r if len(ctx.corpus) == 0 || len(p.Calls) == 0 { @@ -65,6 +78,8 @@ func (ctx *mutator) splice() bool { return true } +// Picks a random complex pointer and squashes its arguments into an ANY. +// Subsequently, if the ANY contains blobs, mutates a random blob. func (ctx *mutator) squashAny() bool { p, r := ctx.p, ctx.r complexPtrs := p.complexPtrs() @@ -104,6 +119,8 @@ func (ctx *mutator) squashAny() bool { return true } +// Inserts a new call at a randomly chosen point (with bias towards the end of +// existing program). Does not insert a call if program already has ncalls. func (ctx *mutator) insertCall() bool { p, r := ctx.p, ctx.r if len(p.Calls) >= ctx.ncalls { @@ -120,6 +137,7 @@ func (ctx *mutator) insertCall() bool { return true } +// Removes a random call from program. func (ctx *mutator) removeCall() bool { p, r := ctx.p, ctx.r if len(p.Calls) == 0 { @@ -130,6 +148,7 @@ func (ctx *mutator) removeCall() bool { return true } +// Mutate an argument of a random call. func (ctx *mutator) mutateArg() bool { p, r := ctx.p, ctx.r if len(p.Calls) == 0 { @@ -429,7 +448,8 @@ func mutateData(r *randGen, data []byte, minLen, maxLen uint64) []byte { return data } -const maxInc = 35 +// The maximum delta for integer mutations. +const maxDelta = 35 var mutateDataFuncs = [...]func(r *randGen, data []byte, minLen, maxLen uint64) ([]byte, bool){ // TODO(dvyukov): duplicate part of data. @@ -520,7 +540,7 @@ var mutateDataFuncs = [...]func(r *randGen, data []byte, minLen, maxLen uint64) } i := r.Intn(len(data) - width + 1) v := loadInt(data[i:], width) - delta := r.rand(2*maxInc+1) - maxInc + delta := r.rand(2*maxDelta+1) - maxDelta if delta == 0 { delta = 1 } |
