diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-09-04 19:53:05 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-09-04 20:25:23 +0200 |
| commit | 399addc8754ed0b484d3c159ac35befe1d3f652c (patch) | |
| tree | 38f937a6c625d253b50b0f51e988ed1c22630b57 /prog | |
| parent | 94e151ceb51191698a068d96191cdd86326050f9 (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.go | 4 | ||||
| -rw-r--r-- | prog/encoding.go | 2 | ||||
| -rw-r--r-- | prog/encodingexec_test.go | 2 | ||||
| -rw-r--r-- | prog/hints_test.go | 2 | ||||
| -rw-r--r-- | prog/mutation.go | 12 | ||||
| -rw-r--r-- | prog/prog.go | 25 | ||||
| -rw-r--r-- | prog/rand.go | 2 | ||||
| -rw-r--r-- | prog/size_test.go | 2 | ||||
| -rw-r--r-- | prog/validation.go | 7 |
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 |
