aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-05-01 17:19:27 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-05-02 12:16:06 +0200
commit58da4c35b15200b7279f18ea15bc8644618aae78 (patch)
tree412d59572c980c4eb582d6d0e187eb6ec32345c9 /tools
parentbc734e7ada413654f1b7d948b2a857260a52dd9c (diff)
prog: introduce Field type
Remvoe FieldName from Type and add a separate Field type that holds field name. Use Field for struct fields, union options and syscalls arguments, only these really have names. Reduces size of sys/linux/gen/amd64.go from 5665583 to 5201321 (-8.2%). Allows to not create new type for squashed any pointer. But main advantages will follow, e.g. removing StructDesc, using TypeRef in Arg, etc. Update #1580
Diffstat (limited to 'tools')
-rw-r--r--tools/syz-check/check.go45
-rw-r--r--tools/syz-trace2syz/proggen/call_selector.go4
-rw-r--r--tools/syz-trace2syz/proggen/generate_unions.go10
-rw-r--r--tools/syz-trace2syz/proggen/proggen.go12
4 files changed, 36 insertions, 35 deletions
diff --git a/tools/syz-check/check.go b/tools/syz-check/check.go
index 45506261a..1d74584af 100644
--- a/tools/syz-check/check.go
+++ b/tools/syz-check/check.go
@@ -258,26 +258,26 @@ func checkStruct(typ *prog.StructDesc, astStruct *ast.Struct, str *dwarf.StructT
ai := 0
offset := uint64(0)
for _, field := range typ.Fields {
- if field.Varlen() {
+ if field.Type.Varlen() {
ai = len(str.Field)
break
}
- if prog.IsPad(field) {
- offset += field.Size()
+ if prog.IsPad(field.Type) {
+ offset += field.Type.Size()
continue
}
if ai < len(str.Field) {
fld := str.Field[ai]
pos := astStruct.Fields[ai].Pos
- desc := fmt.Sprintf("%v.%v", name, field.FieldName())
- if field.FieldName() != fld.Name {
+ desc := fmt.Sprintf("%v.%v", name, fld.Name)
+ if field.Name != fld.Name {
desc += "/" + fld.Name
}
- if field.UnitSize() != uint64(fld.Type.Size()) {
+ if field.Type.UnitSize() != uint64(fld.Type.Size()) {
warn(pos, WarnBadFieldSize, "%v: syz=%v kernel=%v",
- desc, field.UnitSize(), fld.Type.Size())
+ desc, field.Type.UnitSize(), fld.Type.Size())
}
- byteOffset := offset - field.UnitOffset()
+ byteOffset := offset - field.Type.UnitOffset()
if byteOffset != uint64(fld.ByteOffset) {
warn(pos, WarnBadFieldOffset, "%v: syz=%v kernel=%v",
desc, byteOffset, fld.ByteOffset)
@@ -291,10 +291,10 @@ func checkStruct(typ *prog.StructDesc, astStruct *ast.Struct, str *dwarf.StructT
// does not work for normal variables.
bitOffset = 0
}
- if field.BitfieldLength() != uint64(fld.BitSize) ||
- field.BitfieldOffset() != uint64(bitOffset) {
+ if field.Type.BitfieldLength() != uint64(fld.BitSize) ||
+ field.Type.BitfieldOffset() != uint64(bitOffset) {
warn(pos, WarnBadBitfield, "%v: size/offset: syz=%v/%v kernel=%v/%v",
- desc, field.BitfieldLength(), field.BitfieldOffset(),
+ desc, field.Type.BitfieldLength(), field.Type.BitfieldOffset(),
fld.BitSize, bitOffset)
}
}
@@ -501,7 +501,8 @@ func checkMissingAttrs(checkedAttrs map[string]*checkAttr) []Warn {
func isNetlinkPolicy(typ *prog.StructDesc) bool {
haveAttr := false
- for _, field := range typ.Fields {
+ for _, fld := range typ.Fields {
+ field := fld.Type
if prog.IsPad(field) {
continue
}
@@ -541,39 +542,39 @@ func checkNetlinkPolicy(structMap map[string]*prog.StructDesc, typ *prog.StructD
checked := make(map[int]bool)
ai := 0
for _, field := range typ.Fields {
- if prog.IsPad(field) {
+ if prog.IsPad(field.Type) {
continue
}
fld := astStruct.Fields[ai]
ai++
- if !isNlattr(field) {
+ if !isNlattr(field.Type) {
continue
}
- ft := structMap[field.Name()]
- attr := int(ft.Fields[1].(*prog.ConstType).Val)
+ ft := structMap[field.Type.Name()]
+ attr := int(ft.Fields[1].Type.(*prog.ConstType).Val)
if attr >= len(policy) {
warn(fld.Pos, WarnNetlinkBadAttrType, "%v.%v: type %v, kernel policy size %v",
- typ.TemplateName(), field.FieldName(), attr, len(policy))
+ typ.TemplateName(), field.Name, attr, len(policy))
continue
}
if checked[attr] {
warn(fld.Pos, WarnNetlinkBadAttr, "%v.%v: duplicate attribute",
- typ.TemplateName(), field.FieldName())
+ typ.TemplateName(), field.Name)
}
checked[attr] = true
w := checkNetlinkAttr(ft, policy[attr])
if w != "" {
warn(fld.Pos, WarnNetlinkBadAttr, "%v.%v: %v",
- typ.TemplateName(), field.FieldName(), w)
+ typ.TemplateName(), field.Name, w)
}
}
return warnings, checked, nil
}
func checkNetlinkAttr(typ *prog.StructDesc, policy nlaPolicy) string {
- payload := typ.Fields[2]
+ payload := typ.Fields[2].Type
if typ.TemplateName() == "nlattr_tt" {
- payload = typ.Fields[4]
+ payload = typ.Fields[4].Type
}
if warn := checkAttrType(typ, payload, policy); warn != "" {
return warn
@@ -643,7 +644,7 @@ func checkAttrType(typ *prog.StructDesc, payload prog.Type, policy nlaPolicy) st
return "expect string"
}
case NLA_NESTED:
- if typ.TemplateName() != "nlattr_tt" || typ.Fields[3].(*prog.ConstType).Val != 1 {
+ if typ.TemplateName() != "nlattr_tt" || typ.Fields[3].Type.(*prog.ConstType).Val != 1 {
return "should be nlnest"
}
case NLA_BITFIELD32:
diff --git a/tools/syz-trace2syz/proggen/call_selector.go b/tools/syz-trace2syz/proggen/call_selector.go
index 4808432a3..48a70ba88 100644
--- a/tools/syz-trace2syz/proggen/call_selector.go
+++ b/tools/syz-trace2syz/proggen/call_selector.go
@@ -141,7 +141,7 @@ func (cs *openCallSelector) Select(call *parser.Syscall) *prog.Syscall {
func (cs *openCallSelector) matchOpen(meta *prog.Syscall, call *parser.Syscall) (bool, int) {
straceFileArg := call.Args[openDiscriminatorArgs[call.CallName]]
straceBuf := straceFileArg.(*parser.BufferType).Val
- syzFileArg := meta.Args[openDiscriminatorArgs[meta.CallName]]
+ syzFileArg := meta.Args[openDiscriminatorArgs[meta.CallName]].Type
if _, ok := syzFileArg.(*prog.PtrType); !ok {
return false, -1
}
@@ -186,7 +186,7 @@ func (cs *defaultCallSelector) matchCall(meta *prog.Syscall, call *parser.Syscal
if i >= len(meta.Args) || i >= len(call.Args) {
return -1
}
- typ := meta.Args[i]
+ typ := meta.Args[i].Type
arg := call.Args[i]
switch t := typ.(type) {
case *prog.ConstType:
diff --git a/tools/syz-trace2syz/proggen/generate_unions.go b/tools/syz-trace2syz/proggen/generate_unions.go
index 3a70033d8..d4f50a570 100644
--- a/tools/syz-trace2syz/proggen/generate_unions.go
+++ b/tools/syz-trace2syz/proggen/generate_unions.go
@@ -14,7 +14,7 @@ import (
func (ctx *context) genSockaddrStorage(syzType *prog.UnionType, dir prog.Dir, straceType parser.IrType) prog.Arg {
field2Opt := make(map[string]int)
for i, field := range syzType.Fields {
- field2Opt[field.FieldName()] = i
+ field2Opt[field.Name] = i
}
idx := 0
switch strType := straceType.(type) {
@@ -44,14 +44,14 @@ func (ctx *context) genSockaddrStorage(syzType *prog.UnionType, dir prog.Dir, st
default:
log.Fatalf("unable to parse sockaddr_storage. Unsupported type: %#v", strType)
}
- return prog.MakeUnionArg(syzType, dir, ctx.genArg(syzType.Fields[idx], dir, straceType))
+ return prog.MakeUnionArg(syzType, dir, ctx.genArg(syzType.Fields[idx].Type, dir, straceType), idx)
}
func (ctx *context) genSockaddrNetlink(syzType *prog.UnionType, dir prog.Dir, straceType parser.IrType) prog.Arg {
var idx = 2
field2Opt := make(map[string]int)
for i, field := range syzType.Fields {
- field2Opt[field.FieldName()] = i
+ field2Opt[field.Name] = i
}
switch a := straceType.(type) {
case *parser.GroupType:
@@ -74,7 +74,7 @@ func (ctx *context) genSockaddrNetlink(syzType *prog.UnionType, dir prog.Dir, st
}
}
}
- return prog.MakeUnionArg(syzType, dir, ctx.genArg(syzType.Fields[idx], dir, straceType))
+ return prog.MakeUnionArg(syzType, dir, ctx.genArg(syzType.Fields[idx].Type, dir, straceType), idx)
}
func (ctx *context) genIfrIfru(syzType *prog.UnionType, dir prog.Dir, straceType parser.IrType) prog.Arg {
@@ -83,5 +83,5 @@ func (ctx *context) genIfrIfru(syzType *prog.UnionType, dir prog.Dir, straceType
case parser.Constant:
idx = 2
}
- return prog.MakeUnionArg(syzType, dir, ctx.genArg(syzType.Fields[idx], dir, straceType))
+ return prog.MakeUnionArg(syzType, dir, ctx.genArg(syzType.Fields[idx].Type, dir, straceType), idx)
}
diff --git a/tools/syz-trace2syz/proggen/proggen.go b/tools/syz-trace2syz/proggen/proggen.go
index 371050c56..7fff07a5f 100644
--- a/tools/syz-trace2syz/proggen/proggen.go
+++ b/tools/syz-trace2syz/proggen/proggen.go
@@ -115,7 +115,7 @@ func (ctx *context) genCall() *prog.Call {
if i < len(straceCall.Args) {
strArg = straceCall.Args[i]
}
- res := ctx.genArg(syzCall.Meta.Args[i], prog.DirIn, strArg)
+ res := ctx.genArg(syzCall.Meta.Args[i].Type, prog.DirIn, strArg)
syzCall.Args = append(syzCall.Args, res)
}
ctx.genResult(syzCall.Meta.Ret, straceCall.Ret)
@@ -218,7 +218,7 @@ func (ctx *context) genStruct(syzType *prog.StructType, dir prog.Dir, traceType
return ret
}
for i := range syzType.Fields {
- if prog.IsPad(syzType.Fields[i]) {
+ if prog.IsPad(syzType.Fields[i].Type) {
args = append(args, syzType.Fields[i].DefaultArg(dir))
continue
}
@@ -228,7 +228,7 @@ func (ctx *context) genStruct(syzType *prog.StructType, dir prog.Dir, traceType
if j >= len(a.Elems) {
args = append(args, syzType.Fields[i].DefaultArg(dir))
} else {
- args = append(args, ctx.genArg(syzType.Fields[i], dir, a.Elems[j]))
+ args = append(args, ctx.genArg(syzType.Fields[i].Type, dir, a.Elems[j]))
}
j++
}
@@ -253,7 +253,7 @@ func (ctx *context) recurseStructs(syzType *prog.StructType, dir prog.Dir, trace
// only consider structs with one non-padded field
numFields := 0
for _, field := range syzType.Fields {
- if prog.IsPad(field) {
+ if prog.IsPad(field.Type) {
continue
}
numFields++
@@ -266,7 +266,7 @@ func (ctx *context) recurseStructs(syzType *prog.StructType, dir prog.Dir, trace
return nil, false
}
// first field needs to be a struct
- switch t := syzType.Fields[0].(type) {
+ switch t := syzType.Fields[0].Type.(type) {
case *prog.StructType:
var args []prog.Arg
// first element and traceType should have the same number of elements
@@ -301,7 +301,7 @@ func (ctx *context) genUnionArg(syzType *prog.UnionType, dir prog.Dir, straceTyp
case "ifr_ifru":
return ctx.genIfrIfru(syzType, dir, straceType)
}
- return prog.MakeUnionArg(syzType, dir, ctx.genArg(syzType.Fields[0], dir, straceType))
+ return prog.MakeUnionArg(syzType, dir, ctx.genArg(syzType.Fields[0].Type, dir, straceType), 0)
}
func (ctx *context) genBuffer(syzType *prog.BufferType, dir prog.Dir, traceType parser.IrType) prog.Arg {