aboutsummaryrefslogtreecommitdiffstats
path: root/prog
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-09-04 19:53:05 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-09-04 20:25:23 +0200
commit399addc8754ed0b484d3c159ac35befe1d3f652c (patch)
tree38f937a6c625d253b50b0f51e988ed1c22630b57 /prog
parent94e151ceb51191698a068d96191cdd86326050f9 (diff)
sys, pkg/compiler: move padding computation to compiler
This makes types constant during execution, everything is precomputed.
Diffstat (limited to 'prog')
-rw-r--r--prog/analysis.go4
-rw-r--r--prog/encoding.go2
-rw-r--r--prog/encodingexec_test.go2
-rw-r--r--prog/hints_test.go2
-rw-r--r--prog/mutation.go12
-rw-r--r--prog/prog.go25
-rw-r--r--prog/rand.go2
-rw-r--r--prog/size_test.go2
-rw-r--r--prog/validation.go7
9 files changed, 28 insertions, 30 deletions
diff --git a/prog/analysis.go b/prog/analysis.go
index 81dc94956..2edd8f7dd 100644
--- a/prog/analysis.go
+++ b/prog/analysis.go
@@ -52,13 +52,13 @@ func (s *state) analyze(c *Call) {
foreachArgArray(&c.Args, c.Ret, func(arg, base Arg, _ *[]Arg) {
switch typ := arg.Type().(type) {
case *sys.ResourceType:
- if arg.Type().Dir() != sys.DirIn {
+ if typ.Dir() != sys.DirIn {
s.resources[typ.Desc.Name] = append(s.resources[typ.Desc.Name], arg)
// TODO: negative PIDs and add them as well (that's process groups).
}
case *sys.BufferType:
a := arg.(*DataArg)
- if a.Type().Dir() != sys.DirOut && len(a.Data) != 0 {
+ if typ.Dir() != sys.DirOut && len(a.Data) != 0 {
switch typ.Kind {
case sys.BufferString:
s.strings[string(a.Data)] = true
diff --git a/prog/encoding.go b/prog/encoding.go
index 8ba634d12..d31d0bb62 100644
--- a/prog/encoding.go
+++ b/prog/encoding.go
@@ -346,7 +346,7 @@ func parseArg(typ sys.Type, p *parser, vars map[string]Arg) (Arg, error) {
name := p.Ident()
p.Parse('=')
var optType sys.Type
- for _, t2 := range t1.Options {
+ for _, t2 := range t1.Fields {
if name == t2.FieldName() {
optType = t2
break
diff --git a/prog/encodingexec_test.go b/prog/encodingexec_test.go
index ec8d74bba..bc9e1d705 100644
--- a/prog/encodingexec_test.go
+++ b/prog/encodingexec_test.go
@@ -133,7 +133,7 @@ func TestSerializeForExec(t *testing.T) {
instrCopyin, dataOffset + 16, argConst, 2, 0x44, 0, 0,
instrCopyin, dataOffset + 18, argConst, 2, 0x45, 0, 0,
instrCopyin, dataOffset + 20, argConst, 2, 0x46, 0, 0,
- instrCopyin, dataOffset + 24, argConst, 1, 0x47, 0, 0,
+ instrCopyin, dataOffset + 22, argConst, 1, 0x47, 0, 0,
callID("syz_test$align5"), 1, argConst, ptrSize, dataOffset, 0, 0,
instrEOF,
},
diff --git a/prog/hints_test.go b/prog/hints_test.go
index 0490e6d6f..945f9bcd9 100644
--- a/prog/hints_test.go
+++ b/prog/hints_test.go
@@ -158,7 +158,7 @@ func TestHintsCheckDataArg(t *testing.T) {
res := make(map[string]bool)
// Whatever type here. It's just needed to pass the
// dataArg.Type().Dir() == sys.DirIn check.
- typ := sys.ArrayType{sys.TypeCommon{"", "", sys.DirIn, false}, nil, 0, 0, 0}
+ typ := sys.ArrayType{sys.TypeCommon{"", "", 0, sys.DirIn, false}, nil, 0, 0, 0}
argCommon := ArgCommon{&typ}
dataArg := &DataArg{argCommon, []byte(test.in)}
checkDataArg(dataArg, test.comps, func(arg Arg) {
diff --git a/prog/mutation.go b/prog/mutation.go
index a6b39385c..780b5882e 100644
--- a/prog/mutation.go
+++ b/prog/mutation.go
@@ -112,11 +112,9 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable, corpus []*Pro
a.Data = mutateData(r, data, minLen, maxLen)
case sys.BufferString:
if r.bin() {
- var minLen uint64
- maxLen := ^uint64(0)
- if t.Length != 0 {
- minLen = t.Length
- maxLen = t.Length
+ minLen, maxLen := uint64(0), ^uint64(0)
+ if t.TypeSize != 0 {
+ minLen, maxLen = t.TypeSize, t.TypeSize
}
a.Data = mutateData(r, append([]byte{}, a.Data...), minLen, maxLen)
} else {
@@ -191,10 +189,10 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable, corpus []*Pro
}
case *sys.UnionType:
a := arg.(*UnionArg)
- optType := t.Options[r.Intn(len(t.Options))]
+ optType := t.Fields[r.Intn(len(t.Fields))]
maxIters := 1000
for i := 0; optType.FieldName() == a.OptionType.FieldName(); i++ {
- optType = t.Options[r.Intn(len(t.Options))]
+ optType = t.Fields[r.Intn(len(t.Fields))]
if i >= maxIters {
panic(fmt.Sprintf("couldn't generate a different union option after %v iterations, type: %+v", maxIters, t))
}
diff --git a/prog/prog.go b/prog/prog.go
index edb5c9e2d..18ff1ddf8 100644
--- a/prog/prog.go
+++ b/prog/prog.go
@@ -102,7 +102,11 @@ type GroupArg struct {
}
func (arg *GroupArg) Size() uint64 {
- switch typ := (*arg).Type().(type) {
+ typ0 := arg.Type()
+ if !typ0.Varlen() {
+ return typ0.Size()
+ }
+ switch typ := typ0.(type) {
case *sys.StructType:
var size uint64
for _, fld := range arg.Inner {
@@ -110,19 +114,14 @@ func (arg *GroupArg) Size() uint64 {
size += fld.Size()
}
}
- align := typ.Align()
- if size%align != 0 {
- if typ.Varlen() {
- size += align - size%align
- } else {
- panic(fmt.Sprintf("struct %+v with type %+v has static size %v, which isn't aligned to %v", arg, typ, size, align))
- }
+ if typ.AlignAttr != 0 && size%typ.AlignAttr != 0 {
+ size += typ.AlignAttr - size%typ.AlignAttr
}
return size
case *sys.ArrayType:
var size uint64
- for _, in := range arg.Inner {
- size += in.Size()
+ for _, elem := range arg.Inner {
+ size += elem.Size()
}
return size
default:
@@ -274,8 +273,8 @@ func defaultArg(t sys.Type) Arg {
return resultArg(t, nil, typ.Desc.Type.Default())
case *sys.BufferType:
var data []byte
- if typ.Kind == sys.BufferString && typ.Length != 0 {
- data = make([]byte, typ.Length)
+ if typ.Kind == sys.BufferString && typ.TypeSize != 0 {
+ data = make([]byte, typ.TypeSize)
}
return dataArg(t, data)
case *sys.ArrayType:
@@ -287,7 +286,7 @@ func defaultArg(t sys.Type) Arg {
}
return groupArg(t, inner)
case *sys.UnionType:
- return unionArg(t, defaultArg(typ.Options[0]), typ.Options[0])
+ return unionArg(t, defaultArg(typ.Fields[0]), typ.Fields[0])
case *sys.VmaType:
return pointerArg(t, 0, 0, 1, nil)
case *sys.PtrType:
diff --git a/prog/rand.go b/prog/rand.go
index ea89dd33d..516aa2831 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -755,7 +755,7 @@ func (r *randGen) generateArg(s *state, typ sys.Type) (arg Arg, calls []*Call) {
group := groupArg(a, args)
return group, calls
case *sys.UnionType:
- optType := a.Options[r.Intn(len(a.Options))]
+ optType := a.Fields[r.Intn(len(a.Fields))]
opt, calls := r.generateArg(s, optType)
return unionArg(a, opt, optType), calls
case *sys.PtrType:
diff --git a/prog/size_test.go b/prog/size_test.go
index d206a0faa..c72e5283f 100644
--- a/prog/size_test.go
+++ b/prog/size_test.go
@@ -70,7 +70,7 @@ func TestAssignSize(t *testing.T) {
},
{
"syz_test$length8(&(0x7f000001f000)={0x00, {0xff, 0x0, 0x00, [0xff, 0xff, 0xff]}, [{0xff, 0x0, 0x00, [0xff, 0xff, 0xff]}], 0x00, 0x0, [0xff, 0xff]})",
- "syz_test$length8(&(0x7f000001f000)={0x38, {0xff, 0x1, 0x10, [0xff, 0xff, 0xff]}, [{0xff, 0x1, 0x10, [0xff, 0xff, 0xff]}], 0x10, 0x1, [0xff, 0xff]})",
+ "syz_test$length8(&(0x7f000001f000)={0x32, {0xff, 0x1, 0x10, [0xff, 0xff, 0xff]}, [{0xff, 0x1, 0x10, [0xff, 0xff, 0xff]}], 0x10, 0x1, [0xff, 0xff]})",
},
{
"syz_test$length9(&(0x7f000001f000)={&(0x7f0000000000/0x5000)=nil, 0x0000})",
diff --git a/prog/validation.go b/prog/validation.go
index b3c4ad3e6..7b5f02e1c 100644
--- a/prog/validation.go
+++ b/prog/validation.go
@@ -125,8 +125,9 @@ func (c *Call) validate(ctx *validCtx) error {
case *DataArg:
switch typ1.Kind {
case sys.BufferString:
- if typ1.Length != 0 && len(a.Data) != int(typ1.Length) {
- return fmt.Errorf("syscall %v: string arg '%v' has size %v, which should be %v", c.Meta.Name, a.Type().Name(), len(a.Data), typ1.Length)
+ if typ1.TypeSize != 0 && uint64(len(a.Data)) != typ1.TypeSize {
+ return fmt.Errorf("syscall %v: string arg '%v' has size %v, which should be %v",
+ c.Meta.Name, a.Type().Name(), len(a.Data), typ1.TypeSize)
}
}
default:
@@ -210,7 +211,7 @@ func (c *Call) validate(ctx *validCtx) error {
return fmt.Errorf("syscall %v: union arg '%v' has bad type", c.Meta.Name, a.Type().Name())
}
found := false
- for _, typ2 := range typ1.Options {
+ for _, typ2 := range typ1.Fields {
if a.OptionType.Name() == typ2.Name() {
found = true
break