aboutsummaryrefslogtreecommitdiffstats
path: root/tools/syz-check
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-05-03 11:29:12 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-05-03 12:55:42 +0200
commit58ae5e18624eaaac79cab00e63d6f32c9bd64ee0 (patch)
tree00515dd9b2e461102e898930df00bc80400bf996 /tools/syz-check
parent5457883a514281287bbd81364c4e26e25828563d (diff)
prog: remove StructDesc
Remove StructDesc, KeyedStruct, StructKey and all associated logic/complexity in prog and pkg/compiler. We can now handle recursion more generically with the Ref type, and Dir/FieldName are not a part of the type anymore. This makes StructType/UnionType simpler and more natural. Reduces size of sys/linux/gen/amd64.go from 5201321 to 4180861 (-20%). Update #1580
Diffstat (limited to 'tools/syz-check')
-rw-r--r--tools/syz-check/check.go62
1 files changed, 28 insertions, 34 deletions
diff --git a/tools/syz-check/check.go b/tools/syz-check/check.go
index 1d74584af..49152f481 100644
--- a/tools/syz-check/check.go
+++ b/tools/syz-check/check.go
@@ -89,7 +89,7 @@ func check(OS, arch, obj string, dwarf, netlink bool) ([]Warn, error) {
if obj == "" {
return nil, fmt.Errorf("no object file in -obj-%v flag", arch)
}
- structDescs, locs, warnings1, err := parseDescriptions(OS, arch)
+ structTypes, locs, warnings1, err := parseDescriptions(OS, arch)
if err != nil {
return nil, err
}
@@ -99,14 +99,14 @@ func check(OS, arch, obj string, dwarf, netlink bool) ([]Warn, error) {
if err != nil {
return nil, err
}
- warnings2, err := checkImpl(structs, structDescs, locs)
+ warnings2, err := checkImpl(structs, structTypes, locs)
if err != nil {
return nil, err
}
warnings = append(warnings, warnings2...)
}
if netlink {
- warnings3, err := checkNetlink(OS, arch, obj, structDescs, locs)
+ warnings3, err := checkNetlink(OS, arch, obj, structTypes, locs)
if err != nil {
return nil, err
}
@@ -197,16 +197,10 @@ func writeWarnings(OS string, narches int, warnings []Warn) error {
return nil
}
-func checkImpl(structs map[string]*dwarf.StructType, structDescs []*prog.KeyedStruct,
+func checkImpl(structs map[string]*dwarf.StructType, structTypes []*prog.StructType,
locs map[string]*ast.Struct) ([]Warn, error) {
var warnings []Warn
- checked := make(map[string]bool)
- for _, str := range structDescs {
- typ := str.Desc
- if checked[typ.Name()] {
- continue
- }
- checked[typ.Name()] = true
+ for _, typ := range structTypes {
name := typ.TemplateName()
astStruct := locs[name]
if astStruct == nil {
@@ -221,7 +215,7 @@ func checkImpl(structs map[string]*dwarf.StructType, structDescs []*prog.KeyedSt
return warnings, nil
}
-func checkStruct(typ *prog.StructDesc, astStruct *ast.Struct, str *dwarf.StructType) ([]Warn, error) {
+func checkStruct(typ *prog.StructType, astStruct *ast.Struct, str *dwarf.StructType) ([]Warn, error) {
var warnings []Warn
warn := func(pos ast.Pos, typ, msg string, args ...interface{}) {
warnings = append(warnings, Warn{pos: pos, typ: typ, msg: fmt.Sprintf(msg, args...)})
@@ -307,7 +301,7 @@ func checkStruct(typ *prog.StructDesc, astStruct *ast.Struct, str *dwarf.StructT
return warnings, nil
}
-func parseDescriptions(OS, arch string) ([]*prog.KeyedStruct, map[string]*ast.Struct, []Warn, error) {
+func parseDescriptions(OS, arch string) ([]*prog.StructType, map[string]*ast.Struct, []Warn, error) {
errorBuf := new(bytes.Buffer)
var warnings []Warn
eh := func(pos ast.Pos, msg string) {
@@ -326,7 +320,7 @@ func parseDescriptions(OS, arch string) ([]*prog.KeyedStruct, map[string]*ast.St
if prg == nil {
return nil, nil, nil, fmt.Errorf("failed to compile descriptions:\n%s", errorBuf.Bytes())
}
- prog.RestoreLinks(prg.Syscalls, prg.Resources, prg.StructDescs, prg.Types)
+ prog.RestoreLinks(prg.Syscalls, prg.Resources, prg.Types)
locs := make(map[string]*ast.Struct)
for _, decl := range top.Nodes {
switch n := decl.(type) {
@@ -338,7 +332,13 @@ func parseDescriptions(OS, arch string) ([]*prog.KeyedStruct, map[string]*ast.St
}
}
}
- return prg.StructDescs, locs, warnings, nil
+ var structs []*prog.StructType
+ for _, typ := range prg.Types {
+ if t, ok := typ.(*prog.StructType); ok {
+ structs = append(structs, t)
+ }
+ }
+ return structs, locs, warnings, nil
}
// Overall idea of netlink checking.
@@ -350,7 +350,7 @@ func parseDescriptions(OS, arch string) ([]*prog.KeyedStruct, map[string]*ast.St
// Then read in the symbol data, which is an array of nla_policy structs.
// These structs allow to easily figure out type/size of attributes.
// Finally we compare our descriptions with the kernel policy description.
-func checkNetlink(OS, arch, obj string, structDescs []*prog.KeyedStruct,
+func checkNetlink(OS, arch, obj string, structTypes []*prog.StructType,
locs map[string]*ast.Struct) ([]Warn, error) {
if arch != "amd64" {
// Netlink policies are arch-independent (?),
@@ -374,24 +374,18 @@ func checkNetlink(OS, arch, obj string, structDescs []*prog.KeyedStruct,
warn := func(pos ast.Pos, typ, msg string, args ...interface{}) {
warnings = append(warnings, Warn{pos: pos, typ: typ, msg: fmt.Sprintf(msg, args...)})
}
- structMap := make(map[string]*prog.StructDesc)
- for _, str := range structDescs {
- structMap[str.Desc.Name()] = str.Desc
+ structMap := make(map[string]*prog.StructType)
+ for _, typ := range structTypes {
+ structMap[typ.Name()] = typ
}
- checked := make(map[string]bool)
checkedAttrs := make(map[string]*checkAttr)
- for _, str := range structDescs {
- typ := str.Desc
- if checked[typ.Name()] {
- continue
- }
- checked[typ.Name()] = true
+ for _, typ := range structTypes {
name := typ.TemplateName()
astStruct := locs[name]
if astStruct == nil {
continue
}
- if !isNetlinkPolicy(typ) {
+ if !isNetlinkPolicy(typ.Fields) {
continue
}
kernelName := name
@@ -499,9 +493,9 @@ func checkMissingAttrs(checkedAttrs map[string]*checkAttr) []Warn {
return warnings
}
-func isNetlinkPolicy(typ *prog.StructDesc) bool {
+func isNetlinkPolicy(fields []prog.Field) bool {
haveAttr := false
- for _, fld := range typ.Fields {
+ for _, fld := range fields {
field := fld.Type
if prog.IsPad(field) {
continue
@@ -514,12 +508,12 @@ func isNetlinkPolicy(typ *prog.StructDesc) bool {
field = arr.Elem
}
if field1, ok := field.(*prog.StructType); ok {
- if isNetlinkPolicy(field1.StructDesc) {
+ if isNetlinkPolicy(field1.Fields) {
continue
}
}
if field1, ok := field.(*prog.UnionType); ok {
- if isNetlinkPolicy(field1.StructDesc) {
+ if isNetlinkPolicy(field1.Fields) {
continue
}
}
@@ -533,7 +527,7 @@ func isNlattr(typ prog.Type) bool {
return name == "nlattr_t" || name == "nlattr_tt"
}
-func checkNetlinkPolicy(structMap map[string]*prog.StructDesc, typ *prog.StructDesc,
+func checkNetlinkPolicy(structMap map[string]*prog.StructType, typ *prog.StructType,
astStruct *ast.Struct, policy []nlaPolicy) ([]Warn, map[int]bool, error) {
var warnings []Warn
warn := func(pos ast.Pos, typ, msg string, args ...interface{}) {
@@ -571,7 +565,7 @@ func checkNetlinkPolicy(structMap map[string]*prog.StructDesc, typ *prog.StructD
return warnings, checked, nil
}
-func checkNetlinkAttr(typ *prog.StructDesc, policy nlaPolicy) string {
+func checkNetlinkAttr(typ *prog.StructType, policy nlaPolicy) string {
payload := typ.Fields[2].Type
if typ.TemplateName() == "nlattr_tt" {
payload = typ.Fields[4].Type
@@ -637,7 +631,7 @@ func minTypeSize(typ prog.Type) int {
return -1
}
-func checkAttrType(typ *prog.StructDesc, payload prog.Type, policy nlaPolicy) string {
+func checkAttrType(typ *prog.StructType, payload prog.Type, policy nlaPolicy) string {
switch policy.typ {
case NLA_STRING, NLA_NUL_STRING:
if _, ok := payload.(*prog.BufferType); !ok {