diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-09-05 13:31:14 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-09-05 15:52:42 +0200 |
| commit | ffe7e17368d7ae6c2b40da2ce0703d8ad8a116ac (patch) | |
| tree | 195b7c32977fdaab05acb1282a727fb480593431 /pkg | |
| parent | 4fc47026945ebec3fc81d0c897547670034cfb58 (diff) | |
prog, sys: move types to prog
Large overhaul moves syscalls and arg types from sys to prog.
Sys package now depends on prog and contains only generated
descriptions of syscalls.
Introduce prog.Target type that encapsulates all targer properties,
like syscall list, ptr/page size, etc. Also moves OS-dependent pieces
like mmap call generation from prog to sys.
Update #191
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/compiler/check.go | 22 | ||||
| -rw-r--r-- | pkg/compiler/compiler.go | 26 | ||||
| -rw-r--r-- | pkg/compiler/gen.go | 112 | ||||
| -rw-r--r-- | pkg/compiler/types.go | 172 | ||||
| -rw-r--r-- | pkg/csource/csource.go | 4 | ||||
| -rw-r--r-- | pkg/csource/csource_test.go | 1 | ||||
| -rw-r--r-- | pkg/host/host.go | 32 | ||||
| -rw-r--r-- | pkg/host/host_test.go | 11 | ||||
| -rw-r--r-- | pkg/ipc/ipc_test.go | 1 |
9 files changed, 192 insertions, 189 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go index 7b0cf34aa..99ac1d447 100644 --- a/pkg/compiler/check.go +++ b/pkg/compiler/check.go @@ -9,7 +9,7 @@ import ( "fmt" "github.com/google/syzkaller/pkg/ast" - "github.com/google/syzkaller/sys" + "github.com/google/syzkaller/prog" ) func (comp *compiler) check() { @@ -191,7 +191,7 @@ func (comp *compiler) checkLenType(t *ast.Type, name string, fields []*ast.Field } return } - _, args, _ := comp.getArgsBase(t, "", sys.DirIn, isArg) + _, args, _ := comp.getArgsBase(t, "", prog.DirIn, isArg) for i, arg := range args { argDesc := desc.Args[i] if argDesc.Type == typeArgLenTarget { @@ -232,7 +232,7 @@ func (comp *compiler) checkLenTarget(t *ast.Type, name, target string, fields [] type structDir struct { Struct string - Dir sys.Dir + Dir prog.Dir } func (comp *compiler) checkConstructors() { @@ -242,10 +242,10 @@ func (comp *compiler) checkConstructors() { switch n := decl.(type) { case *ast.Call: for _, arg := range n.Args { - comp.checkTypeCtors(arg.Type, sys.DirIn, true, ctors, checked) + comp.checkTypeCtors(arg.Type, prog.DirIn, true, ctors, checked) } if n.Ret != nil { - comp.checkTypeCtors(n.Ret, sys.DirOut, true, ctors, checked) + comp.checkTypeCtors(n.Ret, prog.DirOut, true, ctors, checked) } } } @@ -261,16 +261,16 @@ func (comp *compiler) checkConstructors() { } } -func (comp *compiler) checkTypeCtors(t *ast.Type, dir sys.Dir, isArg bool, +func (comp *compiler) checkTypeCtors(t *ast.Type, dir prog.Dir, isArg bool, ctors map[string]bool, checked map[structDir]bool) { desc := comp.getTypeDesc(t) if desc == typeResource { - // TODO(dvyukov): consider changing this to "dir == sys.DirOut". + // TODO(dvyukov): consider changing this to "dir == prog.DirOut". // We have few questionable cases where resources can be created // only by inout struct fields. These structs should be split // into two different structs: one is in and second is out. // But that will require attaching dir to individual fields. - if dir != sys.DirIn { + if dir != prog.DirIn { r := comp.resources[t.Ident] for r != nil && !ctors[r.Name.Name] { ctors[r.Name.Name] = true @@ -376,7 +376,7 @@ func (comp *compiler) recurseField(checked map[string]bool, t *ast.Type, path [] comp.checkStructRecursion(checked, comp.structs[t.Ident], path) return } - _, args, base := comp.getArgsBase(t, "", sys.DirIn, false) + _, args, base := comp.getArgsBase(t, "", prog.DirIn, false) if desc == typePtr && base.IsOptional { return // optional pointers prune recursion } @@ -464,7 +464,7 @@ func (comp *compiler) checkType(t *ast.Type, isArg, isRet, isStruct, isResourceB return } if desc.Check != nil { - _, args, base := comp.getArgsBase(t, "", sys.DirIn, isArg) + _, args, base := comp.getArgsBase(t, "", prog.DirIn, isArg) desc.Check(comp, t, args, base) } } @@ -574,7 +574,7 @@ func (comp *compiler) checkVarlens() { } func (comp *compiler) isVarlen(t *ast.Type) bool { - desc, args, base := comp.getArgsBase(t, "", sys.DirIn, false) + desc, args, base := comp.getArgsBase(t, "", prog.DirIn, false) return desc.Varlen != nil && desc.Varlen(comp, t, args, base) } diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 8cccf53c4..f6641f9c9 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -12,7 +12,7 @@ import ( "strings" "github.com/google/syzkaller/pkg/ast" - "github.com/google/syzkaller/sys" + "github.com/google/syzkaller/prog" ) // Overview of compilation process: @@ -22,20 +22,20 @@ import ( // This step also does verification of include/incdir/define AST nodes. // 3. User translates constants to values. // 4. Compile on AST and const values does the rest of the work and returns Prog -// containing generated sys objects. +// containing generated prog objects. // 4.1. assignSyscallNumbers: uses consts to assign syscall numbers. // This step also detects unsupported syscalls and discards no longer // needed AST nodes (inlcude, define, comments, etc). // 4.2. patchConsts: patches Int nodes refering to consts with corresponding values. // Also detects unsupported syscalls, structs, resources due to missing consts. // 4.3. check: does extensive semantical checks of AST. -// 4.4. gen: generates sys objects from AST. +// 4.4. gen: generates prog objects from AST. // Prog is description compilation result. type Prog struct { - Resources []*sys.ResourceDesc - Syscalls []*sys.Syscall - StructDescs []*sys.KeyedStruct + Resources []*prog.ResourceDesc + Syscalls []*prog.Syscall + StructDescs []*prog.KeyedStruct // Set of unsupported syscalls/flags. Unsupported map[string]bool } @@ -54,8 +54,8 @@ func Compile(desc *ast.Description, consts map[string]uint64, ptrSize uint64, eh structs: make(map[string]*ast.Struct), intFlags: make(map[string]*ast.IntFlags), strFlags: make(map[string]*ast.StrFlags), - structDescs: make(map[sys.StructKey]*sys.StructDesc), - structNodes: make(map[*sys.StructDesc]*ast.Struct), + structDescs: make(map[prog.StructKey]*prog.StructDesc), + structNodes: make(map[*prog.StructDesc]*ast.Struct), structVarlen: make(map[string]bool), } comp.assignSyscallNumbers(consts) @@ -89,8 +89,8 @@ type compiler struct { intFlags map[string]*ast.IntFlags strFlags map[string]*ast.StrFlags - structDescs map[sys.StructKey]*sys.StructDesc - structNodes map[*sys.StructDesc]*ast.Struct + structDescs map[prog.StructKey]*prog.StructDesc + structNodes map[*prog.StructDesc]*ast.Struct structVarlen map[string]bool } @@ -161,8 +161,8 @@ func (comp *compiler) getTypeDesc(t *ast.Type) *typeDesc { return nil } -func (comp *compiler) getArgsBase(t *ast.Type, field string, dir sys.Dir, isArg bool) ( - *typeDesc, []*ast.Type, sys.IntTypeCommon) { +func (comp *compiler) getArgsBase(t *ast.Type, field string, dir prog.Dir, isArg bool) ( + *typeDesc, []*ast.Type, prog.IntTypeCommon) { desc := comp.getTypeDesc(t) args, opt := removeOpt(t) size := sizeUnassigned @@ -173,7 +173,7 @@ func (comp *compiler) getArgsBase(t *ast.Type, field string, dir sys.Dir, isArg if !isArg { baseType := args[len(args)-1] args = args[:len(args)-1] - base = typeInt.Gen(comp, baseType, nil, base).(*sys.IntType).IntTypeCommon + base = typeInt.Gen(comp, baseType, nil, base).(*prog.IntType).IntTypeCommon } } return desc, args, base diff --git a/pkg/compiler/gen.go b/pkg/compiler/gen.go index e3b7ffd66..eeeed011c 100644 --- a/pkg/compiler/gen.go +++ b/pkg/compiler/gen.go @@ -8,13 +8,13 @@ import ( "sort" "github.com/google/syzkaller/pkg/ast" - "github.com/google/syzkaller/sys" + "github.com/google/syzkaller/prog" ) const sizeUnassigned = ^uint64(0) -func (comp *compiler) genResources() []*sys.ResourceDesc { - var resources []*sys.ResourceDesc +func (comp *compiler) genResources() []*prog.ResourceDesc { + var resources []*prog.ResourceDesc for _, decl := range comp.desc.Nodes { if n, ok := decl.(*ast.Resource); ok { resources = append(resources, comp.genResource(n)) @@ -26,8 +26,8 @@ func (comp *compiler) genResources() []*sys.ResourceDesc { return resources } -func (comp *compiler) genResource(n *ast.Resource) *sys.ResourceDesc { - res := &sys.ResourceDesc{ +func (comp *compiler) genResource(n *ast.Resource) *prog.ResourceDesc { + res := &prog.ResourceDesc{ Name: n.Name.Name, } var base *ast.Type @@ -40,12 +40,12 @@ func (comp *compiler) genResource(n *ast.Resource) *sys.ResourceDesc { if len(res.Values) == 0 { res.Values = []uint64{0} } - res.Type = comp.genType(base, "", sys.DirIn, false) + res.Type = comp.genType(base, "", prog.DirIn, false) return res } -func (comp *compiler) genSyscalls() []*sys.Syscall { - var calls []*sys.Syscall +func (comp *compiler) genSyscalls() []*prog.Syscall { + var calls []*prog.Syscall for _, decl := range comp.desc.Nodes { if n, ok := decl.(*ast.Call); ok { calls = append(calls, comp.genSyscall(n)) @@ -60,32 +60,32 @@ func (comp *compiler) genSyscalls() []*sys.Syscall { return calls } -func (comp *compiler) genSyscall(n *ast.Call) *sys.Syscall { - var ret sys.Type +func (comp *compiler) genSyscall(n *ast.Call) *prog.Syscall { + var ret prog.Type if n.Ret != nil { - ret = comp.genType(n.Ret, "ret", sys.DirOut, true) + ret = comp.genType(n.Ret, "ret", prog.DirOut, true) } - return &sys.Syscall{ + return &prog.Syscall{ Name: n.Name.Name, CallName: n.CallName, NR: n.NR, - Args: comp.genFieldArray(n.Args, sys.DirIn, true), + Args: comp.genFieldArray(n.Args, prog.DirIn, true), Ret: ret, } } -func (comp *compiler) genStructDescs(syscalls []*sys.Syscall) []*sys.KeyedStruct { +func (comp *compiler) genStructDescs(syscalls []*prog.Syscall) []*prog.KeyedStruct { // Calculate struct/union/array sizes, add padding to structs and detach // StructDesc's from StructType's. StructType's can be recursive so it's // not possible to write them out inline as other types. To break the // recursion detach them, and write StructDesc's out as separate array - // of KeyedStruct's. sys package will reattach them during init. + // of KeyedStruct's. prog package will reattach them during init. padded := make(map[interface{}]bool) - detach := make(map[**sys.StructDesc]bool) - var structs []*sys.KeyedStruct - var rec func(t sys.Type) - checkStruct := func(key sys.StructKey, descp **sys.StructDesc) bool { + detach := make(map[**prog.StructDesc]bool) + var structs []*prog.KeyedStruct + var rec func(t prog.Type) + checkStruct := func(key prog.StructKey, descp **prog.StructDesc) bool { detach[descp] = true desc := *descp if padded[desc] { @@ -101,17 +101,17 @@ func (comp *compiler) genStructDescs(syscalls []*sys.Syscall) []*sys.KeyedStruct return false } } - structs = append(structs, &sys.KeyedStruct{ + structs = append(structs, &prog.KeyedStruct{ Key: key, Desc: desc, }) return true } - rec = func(t0 sys.Type) { + rec = func(t0 prog.Type) { switch t := t0.(type) { - case *sys.PtrType: + case *prog.PtrType: rec(t.Type) - case *sys.ArrayType: + case *prog.ArrayType: if padded[t] { return } @@ -123,10 +123,10 @@ func (comp *compiler) genStructDescs(syscalls []*sys.Syscall) []*sys.KeyedStruct } padded[t] = true t.TypeSize = 0 - if t.Kind == sys.ArrayRangeLen && t.RangeBegin == t.RangeEnd && !t.Type.Varlen() { + if t.Kind == prog.ArrayRangeLen && t.RangeBegin == t.RangeEnd && !t.Type.Varlen() { t.TypeSize = t.RangeBegin * t.Type.Size() } - case *sys.StructType: + case *prog.StructType: if !checkStruct(t.Key, &t.StructDesc) { return } @@ -149,7 +149,7 @@ func (comp *compiler) genStructDescs(syscalls []*sys.Syscall) []*sys.KeyedStruct } } } - case *sys.UnionType: + case *prog.UnionType: if !checkStruct(t.Key, &t.StructDesc) { return } @@ -182,7 +182,7 @@ func (comp *compiler) genStructDescs(syscalls []*sys.Syscall) []*sys.KeyedStruct } } - // Detach StructDesc's from StructType's. sys will reattach them again. + // Detach StructDesc's from StructType's. prog will reattach them again. for descp := range detach { *descp = nil } @@ -197,10 +197,10 @@ func (comp *compiler) genStructDescs(syscalls []*sys.Syscall) []*sys.KeyedStruct return structs } -func (comp *compiler) genStructDesc(res *sys.StructDesc, n *ast.Struct, dir sys.Dir) { +func (comp *compiler) genStructDesc(res *prog.StructDesc, n *ast.Struct, dir prog.Dir) { // Leave node for genStructDescs to calculate size/padding. comp.structNodes[res] = n - *res = sys.StructDesc{ + *res = prog.StructDesc{ TypeCommon: genCommon(n.Name.Name, "", sizeUnassigned, dir, false), Fields: comp.genFieldArray(n.Fields, dir, false), } @@ -227,7 +227,7 @@ func (comp *compiler) isStructVarlen(name string) bool { return varlen } -func (comp *compiler) markBitfields(fields []sys.Type) { +func (comp *compiler) markBitfields(fields []prog.Type) { var bfOffset uint64 for i, f := range fields { if f.BitfieldLength() == 0 { @@ -245,25 +245,25 @@ func (comp *compiler) markBitfields(fields []sys.Type) { } } -func setBitfieldOffset(t0 sys.Type, offset uint64, middle bool) { +func setBitfieldOffset(t0 prog.Type, offset uint64, middle bool) { switch t := t0.(type) { - case *sys.IntType: + case *prog.IntType: t.BitfieldOff, t.BitfieldMdl = offset, middle - case *sys.ConstType: + case *prog.ConstType: t.BitfieldOff, t.BitfieldMdl = offset, middle - case *sys.LenType: + case *prog.LenType: t.BitfieldOff, t.BitfieldMdl = offset, middle - case *sys.FlagsType: + case *prog.FlagsType: t.BitfieldOff, t.BitfieldMdl = offset, middle - case *sys.ProcType: + case *prog.ProcType: t.BitfieldOff, t.BitfieldMdl = offset, middle default: panic(fmt.Sprintf("type %#v can't be a bitfield", t)) } } -func (comp *compiler) addAlignment(fields []sys.Type, varlen, packed bool, alignAttr uint64) []sys.Type { - var newFields []sys.Type +func (comp *compiler) addAlignment(fields []prog.Type, varlen, packed bool, alignAttr uint64) []prog.Type { + var newFields []prog.Type if packed { // If a struct is packed, statically sized and has explicitly set alignment, // add a padding at the end. @@ -312,19 +312,19 @@ func (comp *compiler) addAlignment(fields []sys.Type, varlen, packed bool, align return newFields } -func (comp *compiler) typeAlign(t0 sys.Type) uint64 { +func (comp *compiler) typeAlign(t0 prog.Type) uint64 { switch t0.(type) { - case *sys.IntType, *sys.ConstType, *sys.LenType, *sys.FlagsType, *sys.ProcType, - *sys.CsumType, *sys.PtrType, *sys.VmaType, *sys.ResourceType: + case *prog.IntType, *prog.ConstType, *prog.LenType, *prog.FlagsType, *prog.ProcType, + *prog.CsumType, *prog.PtrType, *prog.VmaType, *prog.ResourceType: return t0.Size() - case *sys.BufferType: + case *prog.BufferType: return 1 } switch t := t0.(type) { - case *sys.ArrayType: + case *prog.ArrayType: return comp.typeAlign(t.Type) - case *sys.StructType: + case *prog.StructType: packed, alignAttr := comp.parseStructAttrs(comp.structNodes[t.StructDesc]) if alignAttr != 0 { return alignAttr // overrided by user attribute @@ -339,7 +339,7 @@ func (comp *compiler) typeAlign(t0 sys.Type) uint64 { } } return align - case *sys.UnionType: + case *prog.UnionType: align := uint64(0) for _, f := range t.Fields { if a := comp.typeAlign(f); align < a { @@ -352,32 +352,32 @@ func (comp *compiler) typeAlign(t0 sys.Type) uint64 { } } -func genPad(size uint64) sys.Type { - return &sys.ConstType{ - IntTypeCommon: genIntCommon(genCommon("pad", "", size, sys.DirIn, false), 0, false), +func genPad(size uint64) prog.Type { + return &prog.ConstType{ + IntTypeCommon: genIntCommon(genCommon("pad", "", size, prog.DirIn, false), 0, false), IsPad: true, } } -func (comp *compiler) genField(f *ast.Field, dir sys.Dir, isArg bool) sys.Type { +func (comp *compiler) genField(f *ast.Field, dir prog.Dir, isArg bool) prog.Type { return comp.genType(f.Type, f.Name.Name, dir, isArg) } -func (comp *compiler) genFieldArray(fields []*ast.Field, dir sys.Dir, isArg bool) []sys.Type { - var res []sys.Type +func (comp *compiler) genFieldArray(fields []*ast.Field, dir prog.Dir, isArg bool) []prog.Type { + var res []prog.Type for _, f := range fields { res = append(res, comp.genField(f, dir, isArg)) } return res } -func (comp *compiler) genType(t *ast.Type, field string, dir sys.Dir, isArg bool) sys.Type { +func (comp *compiler) genType(t *ast.Type, field string, dir prog.Dir, isArg bool) prog.Type { desc, args, base := comp.getArgsBase(t, field, dir, isArg) return desc.Gen(comp, t, args, base) } -func genCommon(name, field string, size uint64, dir sys.Dir, opt bool) sys.TypeCommon { - return sys.TypeCommon{ +func genCommon(name, field string, size uint64, dir prog.Dir, opt bool) prog.TypeCommon { + return prog.TypeCommon{ TypeName: name, TypeSize: size, FldName: field, @@ -386,8 +386,8 @@ func genCommon(name, field string, size uint64, dir sys.Dir, opt bool) sys.TypeC } } -func genIntCommon(com sys.TypeCommon, bitLen uint64, bigEndian bool) sys.IntTypeCommon { - return sys.IntTypeCommon{ +func genIntCommon(com prog.TypeCommon, bitLen uint64, bigEndian bool) prog.IntTypeCommon { + return prog.IntTypeCommon{ TypeCommon: com, BigEndian: bigEndian, BitfieldLen: bitLen, diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go index 2a398e3fb..193617574 100644 --- a/pkg/compiler/types.go +++ b/pkg/compiler/types.go @@ -8,7 +8,7 @@ import ( "strconv" "github.com/google/syzkaller/pkg/ast" - "github.com/google/syzkaller/sys" + "github.com/google/syzkaller/prog" ) // typeDesc is arg/field type descriptor. @@ -23,11 +23,11 @@ type typeDesc struct { OptArgs int // number of optional arguments in Args array Args []namedArg // type arguments // Check does custom verification of the type (optional). - Check func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) + Check func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) // Varlen returns if the type is variable-length (false if not set). - Varlen func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) bool - // Gen generates corresponding sys.Type. - Gen func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type + Varlen func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) bool + // Gen generates corresponding prog.Type. + Gen func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type } // typeArg describes a type argument. @@ -58,17 +58,17 @@ var typeInt = &typeDesc{ ResourceBase: true, OptArgs: 1, Args: []namedArg{{"range", typeArgRange}}, - Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) { + Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) { typeArgBase.Type.Check(comp, t) }, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { size, be := comp.parseIntType(t.Ident) - kind, rangeBegin, rangeEnd := sys.IntPlain, uint64(0), uint64(0) + kind, rangeBegin, rangeEnd := prog.IntPlain, uint64(0), uint64(0) if len(args) > 0 { - kind, rangeBegin, rangeEnd = sys.IntRange, args[0].Value, args[0].Value2 + kind, rangeBegin, rangeEnd = prog.IntRange, args[0].Value, args[0].Value2 } base.TypeSize = size - return &sys.IntType{ + return &prog.IntType{ IntTypeCommon: genIntCommon(base.TypeCommon, t.Value2, be), Kind: kind, RangeBegin: rangeBegin, @@ -81,13 +81,13 @@ var typePtr = &typeDesc{ Names: []string{"ptr", "ptr64"}, CanBeArg: true, Args: []namedArg{{"direction", typeArgDir}, {"type", typeArgType}}, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { - base.ArgDir = sys.DirIn // pointers are always in + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { + base.ArgDir = prog.DirIn // pointers are always in base.TypeSize = comp.ptrSize if t.Ident == "ptr64" { base.TypeSize = 8 } - return &sys.PtrType{ + return &prog.PtrType{ TypeCommon: base.TypeCommon, Type: comp.genType(args[1], "", genDir(args[0]), false), } @@ -99,13 +99,13 @@ var typeArray = &typeDesc{ CantBeOpt: true, OptArgs: 1, Args: []namedArg{{"type", typeArgType}, {"size", typeArgRange}}, - Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) { + Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) { if len(args) > 1 && args[1].Value == 0 && args[1].Value2 == 0 { // This is the only case that can yield 0 static type size. comp.error(args[1].Pos, "arrays of size 0 are not supported") } }, - Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) bool { + Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) bool { if comp.isVarlen(args[0]) { return true } @@ -114,23 +114,23 @@ var typeArray = &typeDesc{ } return true }, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { elemType := comp.genType(args[0], "", base.ArgDir, false) - kind, begin, end := sys.ArrayRandLen, uint64(0), uint64(0) + kind, begin, end := prog.ArrayRandLen, uint64(0), uint64(0) if len(args) > 1 { - kind, begin, end = sys.ArrayRangeLen, args[1].Value, args[1].Value2 + kind, begin, end = prog.ArrayRangeLen, args[1].Value, args[1].Value2 } - if it, ok := elemType.(*sys.IntType); ok && it.Kind == sys.IntPlain && it.TypeSize == 1 { + if it, ok := elemType.(*prog.IntType); ok && it.Kind == prog.IntPlain && it.TypeSize == 1 { // Special case: buffer is better mutated. - bufKind := sys.BufferBlobRand + bufKind := prog.BufferBlobRand base.TypeSize = 0 - if kind == sys.ArrayRangeLen { - bufKind = sys.BufferBlobRange + if kind == prog.ArrayRangeLen { + bufKind = prog.BufferBlobRange if begin == end { base.TypeSize = begin * elemType.Size() } } - return &sys.BufferType{ + return &prog.BufferType{ TypeCommon: base.TypeCommon, Kind: bufKind, RangeBegin: begin, @@ -138,7 +138,7 @@ var typeArray = &typeDesc{ } } // TypeSize is assigned later in genStructDescs. - return &sys.ArrayType{ + return &prog.ArrayType{ TypeCommon: base.TypeCommon, Type: elemType, Kind: kind, @@ -155,7 +155,7 @@ var typeLen = &typeDesc{ CantBeRet: true, NeedBase: true, Args: []namedArg{{"len target", typeArgLenTarget}}, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { var byteSize uint64 switch t.Ident { case "bytesize": @@ -163,7 +163,7 @@ var typeLen = &typeDesc{ case "bytesize2", "bytesize4", "bytesize8": byteSize, _ = strconv.ParseUint(t.Ident[8:], 10, 8) } - return &sys.LenType{ + return &prog.LenType{ IntTypeCommon: base, Buf: args[0].Ident, ByteSize: byteSize, @@ -177,8 +177,8 @@ var typeConst = &typeDesc{ CantBeOpt: true, NeedBase: true, Args: []namedArg{{"value", typeArgInt}}, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { - return &sys.ConstType{ + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { + return &prog.ConstType{ IntTypeCommon: base, Val: args[0].Value, } @@ -195,18 +195,18 @@ var typeFlags = &typeDesc{ CantBeOpt: true, NeedBase: true, Args: []namedArg{{"flags", typeArgFlags}}, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { name := args[0].Ident base.TypeName = name f := comp.intFlags[name] if len(f.Values) == 0 { // We can get this if all values are unsupported consts. - return &sys.IntType{ + return &prog.IntType{ IntTypeCommon: base, - Kind: sys.IntPlain, + Kind: prog.IntPlain, } } - return &sys.FlagsType{ + return &prog.FlagsType{ IntTypeCommon: base, Vals: genIntArray(f.Values), } @@ -226,14 +226,14 @@ var typeArgFlags = &typeArg{ var typeFilename = &typeDesc{ Names: []string{"filename"}, CantBeOpt: true, - Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) bool { + Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) bool { return true }, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { base.TypeSize = 0 - return &sys.BufferType{ + return &prog.BufferType{ TypeCommon: base.TypeCommon, - Kind: sys.BufferFilename, + Kind: prog.BufferFilename, } }, } @@ -243,10 +243,10 @@ var typeFileoff = &typeDesc{ CanBeArg: true, CantBeOpt: true, NeedBase: true, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { - return &sys.IntType{ + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { + return &prog.IntType{ IntTypeCommon: base, - Kind: sys.IntFileoff, + Kind: prog.IntFileoff, } }, } @@ -256,13 +256,13 @@ var typeVMA = &typeDesc{ CanBeArg: true, OptArgs: 1, Args: []namedArg{{"size range", typeArgRange}}, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { begin, end := uint64(0), uint64(0) if len(args) > 0 { begin, end = args[0].Value, args[0].Value2 } base.TypeSize = comp.ptrSize - return &sys.VmaType{ + return &prog.VmaType{ TypeCommon: base.TypeCommon, RangeBegin: begin, RangeEnd: end, @@ -277,11 +277,11 @@ var typeSignalno = &typeDesc{ Names: []string{"signalno"}, CanBeArg: true, CantBeOpt: true, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { base.TypeSize = 4 - return &sys.IntType{ + return &prog.IntType{ IntTypeCommon: base, - Kind: sys.IntRange, + Kind: prog.IntRange, RangeBegin: 0, RangeEnd: 65, } @@ -295,17 +295,17 @@ var typeCsum = &typeDesc{ CantBeRet: true, OptArgs: 1, Args: []namedArg{{"csum target", typeArgLenTarget}, {"kind", typeArgCsumType}, {"proto", typeArgInt}}, - Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) { - if len(args) > 2 && genCsumKind(args[1]) != sys.CsumPseudo { + Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) { + if len(args) > 2 && genCsumKind(args[1]) != prog.CsumPseudo { comp.error(args[2].Pos, "only pseudo csum can have proto") } }, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { var proto uint64 if len(args) > 2 { proto = args[2].Value } - return &sys.CsumType{ + return &prog.CsumType{ IntTypeCommon: base, Buf: args[0].Ident, Kind: genCsumKind(args[1]), @@ -319,12 +319,12 @@ var typeArgCsumType = &typeArg{ Names: []string{"inet", "pseudo"}, } -func genCsumKind(t *ast.Type) sys.CsumKind { +func genCsumKind(t *ast.Type) prog.CsumKind { switch t.Ident { case "inet": - return sys.CsumInet + return prog.CsumInet case "pseudo": - return sys.CsumPseudo + return prog.CsumPseudo default: panic(fmt.Sprintf("unknown csum kind %q", t.Ident)) } @@ -336,7 +336,7 @@ var typeProc = &typeDesc{ CantBeOpt: true, NeedBase: true, Args: []namedArg{{"range start", typeArgInt}, {"per-proc values", typeArgInt}}, - Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) { + Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) { start := args[0].Value perProc := args[1].Value if perProc == 0 { @@ -354,8 +354,8 @@ var typeProc = &typeDesc{ } } }, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { - return &sys.ProcType{ + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { + return &prog.ProcType{ IntTypeCommon: base, ValuesStart: args[0].Value, ValuesPerProc: args[1].Value, @@ -367,14 +367,14 @@ var typeText = &typeDesc{ Names: []string{"text"}, CantBeOpt: true, Args: []namedArg{{"kind", typeArgTextType}}, - Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) bool { + Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) bool { return true }, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { base.TypeSize = 0 - return &sys.BufferType{ + return &prog.BufferType{ TypeCommon: base.TypeCommon, - Kind: sys.BufferText, + Kind: prog.BufferText, Text: genTextType(args[0]), } }, @@ -385,18 +385,18 @@ var typeArgTextType = &typeArg{ Names: []string{"x86_real", "x86_16", "x86_32", "x86_64", "arm64"}, } -func genTextType(t *ast.Type) sys.TextKind { +func genTextType(t *ast.Type) prog.TextKind { switch t.Ident { case "x86_real": - return sys.Text_x86_real + return prog.Text_x86_real case "x86_16": - return sys.Text_x86_16 + return prog.Text_x86_16 case "x86_32": - return sys.Text_x86_32 + return prog.Text_x86_32 case "x86_64": - return sys.Text_x86_64 + return prog.Text_x86_64 case "arm64": - return sys.Text_arm64 + return prog.Text_arm64 default: panic(fmt.Sprintf("unknown text type %q", t.Ident)) } @@ -406,14 +406,14 @@ var typeBuffer = &typeDesc{ Names: []string{"buffer"}, CanBeArg: true, Args: []namedArg{{"direction", typeArgDir}}, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { base.TypeSize = comp.ptrSize - return &sys.PtrType{ + return &prog.PtrType{ TypeCommon: base.TypeCommon, - Type: &sys.BufferType{ + Type: &prog.BufferType{ // BufferBlobRand is always varlen. TypeCommon: genCommon("", "", 0, genDir(args[0]), false), - Kind: sys.BufferBlobRand, + Kind: prog.BufferBlobRand, }, } }, @@ -423,7 +423,7 @@ var typeString = &typeDesc{ Names: []string{"string"}, OptArgs: 2, Args: []namedArg{{"literal or flags", typeArgStringFlags}, {"size", typeArgInt}}, - Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) { + Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) { if len(args) > 1 { size := args[1].Value vals := []string{args[0].String} @@ -439,10 +439,10 @@ var typeString = &typeDesc{ } } }, - Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) bool { + Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) bool { return comp.stringSize(args) == 0 }, - Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { subkind := "" var vals []string if len(args) > 0 { @@ -465,9 +465,9 @@ var typeString = &typeDesc{ vals[i] = s } base.TypeSize = comp.stringSize(args) - return &sys.BufferType{ + return &prog.BufferType{ TypeCommon: base.TypeCommon, - Kind: sys.BufferString, + Kind: prog.BufferString, SubKind: subkind, Values: vals, } @@ -527,15 +527,15 @@ var typeResource = &typeDesc{ } func init() { - typeResource.Gen = func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + typeResource.Gen = func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { // Find and generate base type to get its size. var baseType *ast.Type for r := comp.resources[t.Ident]; r != nil; { baseType = r.Base r = comp.resources[r.Base.Ident] } - base.TypeSize = comp.genType(baseType, "", sys.DirIn, false).Size() - return &sys.ResourceType{ + base.TypeSize = comp.genType(baseType, "", prog.DirIn, false).Size() + return &prog.ResourceType{ TypeCommon: base.TypeCommon, } } @@ -548,27 +548,27 @@ var typeStruct = &typeDesc{ } func init() { - typeStruct.Varlen = func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) bool { + typeStruct.Varlen = func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) bool { return comp.isStructVarlen(t.Ident) } - typeStruct.Gen = func(comp *compiler, t *ast.Type, args []*ast.Type, base sys.IntTypeCommon) sys.Type { + typeStruct.Gen = func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { s := comp.structs[t.Ident] - key := sys.StructKey{t.Ident, base.ArgDir} + key := prog.StructKey{t.Ident, base.ArgDir} desc := comp.structDescs[key] if desc == nil { // Need to assign to structDescs before calling genStructDesc to break recursion. - desc = new(sys.StructDesc) + desc = new(prog.StructDesc) comp.structDescs[key] = desc comp.genStructDesc(desc, s, base.ArgDir) } if s.IsUnion { - return &sys.UnionType{ + return &prog.UnionType{ Key: key, FldName: base.FldName, StructDesc: desc, } } else { - return &sys.StructType{ + return &prog.StructType{ Key: key, FldName: base.FldName, StructDesc: desc, @@ -582,14 +582,14 @@ var typeArgDir = &typeArg{ Names: []string{"in", "out", "inout"}, } -func genDir(t *ast.Type) sys.Dir { +func genDir(t *ast.Type) prog.Dir { switch t.Ident { case "in": - return sys.DirIn + return prog.DirIn case "out": - return sys.DirOut + return prog.DirOut case "inout": - return sys.DirInOut + return prog.DirInOut default: panic(fmt.Sprintf("unknown direction %q", t.Ident)) } diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index b46fda351..e1b32e752 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -20,7 +20,7 @@ import ( "unsafe" "github.com/google/syzkaller/prog" - "github.com/google/syzkaller/sys" + _ "github.com/google/syzkaller/sys" ) type Options struct { @@ -367,7 +367,7 @@ loop: fmt.Fprintf(w, "\twrite_file(\"/sys/kernel/debug/fail_futex/ignore-private\", \"N\");\n") fmt.Fprintf(w, "\tinject_fault(%v);\n", opts.FaultNth) } - meta := sys.Syscalls[instr] + meta := prog.Syscalls[instr] emitCall := true if meta.CallName == "syz_test" { emitCall = false diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go index e4e9e1f7f..fbe984b3c 100644 --- a/pkg/csource/csource_test.go +++ b/pkg/csource/csource_test.go @@ -13,6 +13,7 @@ import ( "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/prog" + _ "github.com/google/syzkaller/sys" ) func initTest(t *testing.T) (rand.Source, int) { diff --git a/pkg/host/host.go b/pkg/host/host.go index 9aafbce6e..0fa66dfa4 100644 --- a/pkg/host/host.go +++ b/pkg/host/host.go @@ -12,13 +12,13 @@ import ( "syscall" "github.com/google/syzkaller/pkg/osutil" - "github.com/google/syzkaller/sys" + "github.com/google/syzkaller/prog" ) // DetectSupportedSyscalls returns list on supported syscalls on host. -func DetectSupportedSyscalls() (map[*sys.Syscall]bool, error) { +func DetectSupportedSyscalls() (map[*prog.Syscall]bool, error) { // There are 3 possible strategies: - // 1. Executes all syscalls with presumably invalid arguments and check for ENOSYS. + // 1. Executes all syscalls with presumably invalid arguments and check for ENOprog. // But not all syscalls are safe to execute. For example, pause will hang, // while setpgrp will push the process into own process group. // 2. Check presence of /sys/kernel/debug/tracing/events/syscalls/sys_enter_* files. @@ -28,8 +28,8 @@ func DetectSupportedSyscalls() (map[*sys.Syscall]bool, error) { // Requires CONFIG_KALLSYMS. Seems to be the most reliable. That's what we use here. kallsyms, _ := ioutil.ReadFile("/proc/kallsyms") - supported := make(map[*sys.Syscall]bool) - for _, c := range sys.Syscalls { + supported := make(map[*prog.Syscall]bool) + for _, c := range prog.Syscalls { if isSupported(kallsyms, c) { supported[c] = true } @@ -37,7 +37,7 @@ func DetectSupportedSyscalls() (map[*sys.Syscall]bool, error) { return supported, nil } -func isSupported(kallsyms []byte, c *sys.Syscall) bool { +func isSupported(kallsyms []byte, c *prog.Syscall) bool { if c.NR == ^uint64(0) { return false // don't even have a syscall number } @@ -59,12 +59,12 @@ func isSupported(kallsyms []byte, c *sys.Syscall) bool { return bytes.Index(kallsyms, []byte(" T sys_"+c.CallName+"\n")) != -1 } -func isSupportedSyzkall(c *sys.Syscall) bool { +func isSupportedSyzkall(c *prog.Syscall) bool { switch c.CallName { case "syz_test": return false case "syz_open_dev": - if _, ok := c.Args[0].(*sys.ConstType); ok { + if _, ok := c.Args[0].(*prog.ConstType); ok { // This is for syz_open_dev$char/block. // They are currently commented out, but in case one enables them. return true @@ -112,8 +112,8 @@ func isSupportedSyzkall(c *sys.Syscall) bool { panic("unknown syzkall: " + c.Name) } -func isSupportedSocket(c *sys.Syscall) bool { - af, ok := c.Args[0].(*sys.ConstType) +func isSupportedSocket(c *prog.Syscall) bool { + af, ok := c.Args[0].(*prog.ConstType) if !ok { println(c.Name) panic("socket family is not const") @@ -125,7 +125,7 @@ func isSupportedSocket(c *sys.Syscall) bool { return err != syscall.ENOSYS && err != syscall.EAFNOSUPPORT } -func isSupportedOpen(c *sys.Syscall) bool { +func isSupportedOpen(c *prog.Syscall) bool { fname, ok := extractStringConst(c.Args[0]) if !ok { return true @@ -137,7 +137,7 @@ func isSupportedOpen(c *sys.Syscall) bool { return err == nil } -func isSupportedOpenAt(c *sys.Syscall) bool { +func isSupportedOpenAt(c *prog.Syscall) bool { fname, ok := extractStringConst(c.Args[1]) if !ok { return true @@ -149,13 +149,13 @@ func isSupportedOpenAt(c *sys.Syscall) bool { return err == nil } -func extractStringConst(typ sys.Type) (string, bool) { - ptr, ok := typ.(*sys.PtrType) +func extractStringConst(typ prog.Type) (string, bool) { + ptr, ok := typ.(*prog.PtrType) if !ok { panic("first open arg is not a pointer to string const") } - str, ok := ptr.Type.(*sys.BufferType) - if !ok || str.Kind != sys.BufferString || len(str.Values) != 1 { + str, ok := ptr.Type.(*prog.BufferType) + if !ok || str.Kind != prog.BufferString || len(str.Values) != 1 { return "", false } v := str.Values[0] diff --git a/pkg/host/host_test.go b/pkg/host/host_test.go index 1eea00fe6..dc9225d5a 100644 --- a/pkg/host/host_test.go +++ b/pkg/host/host_test.go @@ -7,7 +7,8 @@ import ( "syscall" "testing" - "github.com/google/syzkaller/sys" + "github.com/google/syzkaller/prog" + _ "github.com/google/syzkaller/sys" ) func TestLog(t *testing.T) { @@ -18,7 +19,7 @@ func TestLog(t *testing.T) { t.Skipf("skipping: %v", err) } t.Logf("unsupported:") - for _, c := range sys.Syscalls { + for _, c := range prog.Syscalls { s, ok := supp[c] if ok && !s { t.Fatalf("map contains false value") @@ -27,9 +28,9 @@ func TestLog(t *testing.T) { t.Logf("\t%v", c.Name) } } - trans := sys.TransitivelyEnabledCalls(supp) + trans := prog.TransitivelyEnabledCalls(supp) t.Logf("transitively unsupported:") - for _, c := range sys.Syscalls { + for _, c := range prog.Syscalls { s, ok := trans[c] if ok && !s { t.Fatalf("map contains false value") @@ -58,7 +59,7 @@ func TestSupportedSyscalls(t *testing.T) { "stat", } for _, name := range safe { - c := sys.SyscallMap[name] + c := prog.SyscallMap[name] if c == nil { t.Fatalf("can't find syscall '%v'", name) } diff --git a/pkg/ipc/ipc_test.go b/pkg/ipc/ipc_test.go index 68fbb94cd..b6bfca81d 100644 --- a/pkg/ipc/ipc_test.go +++ b/pkg/ipc/ipc_test.go @@ -13,6 +13,7 @@ import ( "github.com/google/syzkaller/pkg/csource" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/prog" + _ "github.com/google/syzkaller/sys" ) const timeout = 10 * time.Second |
