aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prog/mutation.go20
-rw-r--r--prog/prio.go2
-rw-r--r--prog/rand.go12
-rw-r--r--sys/align.go7
-rw-r--r--sys/decl.go12
-rw-r--r--sysgen/sysgen.go34
6 files changed, 63 insertions, 24 deletions
diff --git a/prog/mutation.go b/prog/mutation.go
index f50f60e06..068ebb849 100644
--- a/prog/mutation.go
+++ b/prog/mutation.go
@@ -67,7 +67,7 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable) {
size = size1
case sys.BufferType:
switch a.Kind {
- case sys.BufferBlob:
+ case sys.BufferBlobRand, sys.BufferBlobRange:
var data []byte
switch arg.Kind {
case ArgData:
@@ -80,10 +80,16 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable) {
default:
panic(fmt.Sprintf("bad arg kind for BufferType: %v", arg.Kind))
}
- arg.Data = mutateData(r, data)
+ minLen := int(0)
+ maxLen := ^int(0)
+ if a.Kind == sys.BufferBlobRange {
+ minLen = int(a.RangeBegin)
+ maxLen = int(a.RangeEnd)
+ }
+ arg.Data = mutateData(r, data, minLen, maxLen)
case sys.BufferString:
if r.bin() {
- arg.Data = mutateData(r, append([]byte{}, arg.Data...))
+ arg.Data = mutateData(r, append([]byte{}, arg.Data...), int(0), ^int(0))
} else {
arg.Data = r.randString(s)
}
@@ -424,16 +430,22 @@ func swap64(v uint64) uint64 {
return v
}
-func mutateData(r *randGen, data []byte) []byte {
+func mutateData(r *randGen, data []byte, minLen, maxLen int) []byte {
const maxInc = 35
for stop := false; !stop; stop = r.bin() {
r.choose(
100, func() {
// Append byte.
+ if len(data) == maxLen {
+ return
+ }
data = append(data, byte(r.rand(256)))
},
100, func() {
// Remove byte.
+ if len(data) == minLen {
+ return
+ }
if len(data) == 0 {
return
}
diff --git a/prog/prio.go b/prog/prio.go
index 9291b3d09..8983c1c92 100644
--- a/prog/prio.go
+++ b/prog/prio.go
@@ -80,7 +80,7 @@ func calcStaticPriorities() [][]float32 {
}
case sys.BufferType:
switch a.Kind {
- case sys.BufferBlob, sys.BufferFilesystem, sys.BufferAlgType, sys.BufferAlgName:
+ case sys.BufferBlobRand, sys.BufferBlobRange, sys.BufferFilesystem, sys.BufferAlgType, sys.BufferAlgName:
case sys.BufferString:
noteUsage(0.2, "str")
case sys.BufferSockaddr:
diff --git a/prog/rand.go b/prog/rand.go
index 26063b626..b96ecbe9a 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -706,14 +706,16 @@ func (r *randGen) generateArg(s *state, typ sys.Type, dir ArgDir, sizes map[stri
return arg, nil, nil
case sys.BufferType:
switch a.Kind {
- case sys.BufferBlob:
+ case sys.BufferBlobRand, sys.BufferBlobRange:
sz := r.randBufLen()
- if dir == DirOut {
- return nil, constArg(sz), nil
+ if a.Kind == sys.BufferBlobRange {
+ sz = r.randRange(int(a.RangeBegin), int(a.RangeEnd))
}
data := make([]byte, sz)
- for i := range data {
- data[i] = byte(r.Intn(256))
+ if dir != DirOut {
+ for i := range data {
+ data[i] = byte(r.Intn(256))
+ }
}
return dataArg(data), constArg(sz), nil
case sys.BufferString:
diff --git a/sys/align.go b/sys/align.go
index 6e8563da4..055a433f8 100644
--- a/sys/align.go
+++ b/sys/align.go
@@ -48,14 +48,19 @@ func addAlignment(t *StructType) {
off += pad
fields = append(fields, makePad(pad))
}
- off += f.Size()
fields = append(fields, f)
if at, ok := f.(ArrayType); ok && (at.Kind == ArrayRandLen || (at.Kind == ArrayRangeLen && at.RangeBegin != at.RangeEnd)) {
varLen = true
}
+ if at, ok := f.(BufferType); ok && (at.Kind == BufferBlobRand || (at.Kind == BufferBlobRange && at.RangeBegin != at.RangeEnd)) {
+ varLen = true
+ }
if varLen && i != len(t.Fields)-1 {
panic("embed array in middle of a struct")
}
+ if !varLen {
+ off += f.Size()
+ }
}
if align != 0 && off%align != 0 && !varLen {
pad := align - off%align
diff --git a/sys/decl.go b/sys/decl.go
index f792f541c..275bbb380 100644
--- a/sys/decl.go
+++ b/sys/decl.go
@@ -100,7 +100,8 @@ func (t FileoffType) Align() uintptr {
type BufferKind int
const (
- BufferBlob BufferKind = iota
+ BufferBlobRand BufferKind = iota
+ BufferBlobRange
BufferString
BufferSockaddr
BufferFilesystem
@@ -110,7 +111,9 @@ const (
type BufferType struct {
TypeCommon
- Kind BufferKind
+ Kind BufferKind
+ RangeBegin uintptr // for BufferBlobRange kind
+ RangeEnd uintptr // for BufferBlobRange kind
}
func (t BufferType) Size() uintptr {
@@ -119,6 +122,11 @@ func (t BufferType) Size() uintptr {
return 14
case BufferAlgName:
return 64
+ case BufferBlobRange:
+ if t.RangeBegin == t.RangeEnd {
+ return t.RangeBegin
+ }
+ fallthrough
default:
panic(fmt.Sprintf("buffer size is not statically known: %v", t.Name()))
}
diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go
index c27e413c3..c09a7cd7e 100644
--- a/sysgen/sysgen.go
+++ b/sysgen/sysgen.go
@@ -345,7 +345,7 @@ func generateArg(
}
commonHdr := common()
opt = false
- fmt.Fprintf(out, "PtrType{%v, Dir: %v, Type: BufferType{%v, Kind: BufferBlob}}", commonHdr, fmtDir(a[0]), common())
+ fmt.Fprintf(out, "PtrType{%v, Dir: %v, Type: BufferType{%v, Kind: BufferBlobRand}}", commonHdr, fmtDir(a[0]), common())
case "string":
canBeArg = true
if want := 0; len(a) != want {
@@ -490,22 +490,34 @@ func generateArg(
opt = false
fmt.Fprintf(out, "PtrType{%v, Dir: DirIn, Type: FilenameType{%v}}", commonHdr, common())
case "array":
- switch len(a) {
- case 1:
- fmt.Fprintf(out, "ArrayType{%v, Type: %v, Kind: ArrayRandLen}", common(), generateType(a[0], desc, consts))
- case 2:
+ if len(a) != 1 && len(a) != 2 {
+ failf("wrong number of arguments for %v arg %v, want 1 or 2, got %v", typ, name, len(a))
+ }
+ if len(a) == 1 {
+ if a[0] == "int8" {
+ fmt.Fprintf(out, "BufferType{%v, Kind: BufferBlobRand}", common())
+ } else {
+ fmt.Fprintf(out, "ArrayType{%v, Type: %v, Kind: ArrayRandLen}", common(), generateType(a[0], desc, consts))
+ }
+ } else {
var begin, end uintptr
- sz := a[1]
- if _, err := fmt.Sscanf(sz, "%d:%d", &begin, &end); err != nil {
+ var beginStr, endStr string
+ if _, err := fmt.Sscanf(a[1], "%d:%d", &begin, &end); err == nil {
+ beginStr = fmt.Sprint(begin)
+ endStr = fmt.Sprint(end)
+ } else {
+ sz := a[1]
if v, ok := consts[sz]; ok {
sz = fmt.Sprint(v)
}
- fmt.Fprintf(out, "ArrayType{%v, Type: %v, Kind: ArrayRangeLen, RangeBegin: %v, RangeEnd: %v}", common(), generateType(a[0], desc, consts), sz, sz)
+ beginStr = sz
+ endStr = sz
+ }
+ if a[0] == "int8" {
+ fmt.Fprintf(out, "BufferType{%v, Kind: BufferBlobRange, RangeBegin: %v, RangeEnd: %v}", common(), beginStr, endStr)
} else {
- fmt.Fprintf(out, "ArrayType{%v, Type: %v, Kind: ArrayRangeLen, RangeBegin: %v, RangeEnd: %v}", common(), generateType(a[0], desc, consts), begin, end)
+ fmt.Fprintf(out, "ArrayType{%v, Type: %v, Kind: ArrayRangeLen, RangeBegin: %v, RangeEnd: %v}", common(), generateType(a[0], desc, consts), beginStr, endStr)
}
- default:
- failf("wrong number of arguments for %v arg %v, want 1 or 2, got %v", typ, name, len(a))
}
case "ptr":
canBeArg = true