diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-12-06 09:43:19 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-12-11 15:22:17 +0000 |
| commit | bfb4b3275371a3b53cd6562fa06e5a9dfb5627b7 (patch) | |
| tree | 36d9f70965d8cf1080480c0d56de0b49f096cae5 /pkg/compiler | |
| parent | a9a0ffed7ef93dd86695100cf081438a918d6026 (diff) | |
pkg/compiler: add automatic meta
Mark the whole file with "meta automatic" instead of marking each syscall.
This reduces size of descriptions + allows to do special things
with the whole file (e.g. we already treat auto consts specially).
Diffstat (limited to 'pkg/compiler')
| -rw-r--r-- | pkg/compiler/compiler.go | 9 | ||||
| -rw-r--r-- | pkg/compiler/consts.go | 2 | ||||
| -rw-r--r-- | pkg/compiler/gen.go | 19 | ||||
| -rw-r--r-- | pkg/compiler/meta.go | 23 |
4 files changed, 32 insertions, 21 deletions
diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index fa23ce6bf..713c21b08 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -7,7 +7,6 @@ package compiler import ( "fmt" - "path/filepath" "strconv" "strings" @@ -140,7 +139,7 @@ type compiler struct { structTypes map[string]prog.Type structFiles map[*ast.Struct]map[string]ast.Pos builtinConsts map[string]uint64 - fileMeta map[string]Meta + fileMetas map[string]Meta recursiveQuery map[ast.Node]bool } @@ -159,13 +158,9 @@ func (comp *compiler) warning(pos ast.Pos, msg string, args ...interface{}) { } func (comp *compiler) filterArch() { - if comp.fileMeta == nil { - comp.fileMeta = comp.fileList() - } comp.desc = comp.desc.Filter(func(n ast.Node) bool { pos, typ, name := n.Info() - meta := comp.fileMeta[filepath.Base(pos.File)] - if meta.SupportsArch(comp.target.Arch) { + if comp.fileMeta(pos).SupportsArch(comp.target.Arch) { return true } switch n.(type) { diff --git a/pkg/compiler/consts.go b/pkg/compiler/consts.go index 5e1ed9188..bcbd40e52 100644 --- a/pkg/compiler/consts.go +++ b/pkg/compiler/consts.go @@ -119,7 +119,7 @@ func (comp *compiler) extractConsts() map[string]*ConstInfo { comp.extractTypeConsts(ctx, decl) } } - return convertConstInfo(ctx, comp.fileMeta) + return convertConstInfo(ctx, comp.fileMetas) } func foreachFieldAttrConst(n *ast.Struct, cb func(*ast.Type)) { diff --git a/pkg/compiler/gen.go b/pkg/compiler/gen.go index fb803875a..fb406b815 100644 --- a/pkg/compiler/gen.go +++ b/pkg/compiler/gen.go @@ -78,7 +78,7 @@ func (comp *compiler) collectCallArgSizes() map[string][]uint64 { comp.error(arg.Pos, "%v arg %v is larger than pointer size", n.Name.Name, arg.Name.Name) continue } - argID := fmt.Sprintf("%v|%v", getCallName(n), i) + argID := fmt.Sprintf("%v|%v", comp.getCallName(n), i) if _, ok := argPos[argID]; !ok { argSizes[i] = typ.Size() argPos[argID] = arg.Pos @@ -90,16 +90,18 @@ func (comp *compiler) collectCallArgSizes() map[string][]uint64 { continue } } - callArgSizes[getCallName(n)] = argSizes + callArgSizes[comp.getCallName(n)] = argSizes } return callArgSizes } -func getCallName(n *ast.Call) string { - for _, attr := range n.Attrs { - if attr.Ident == "automatic" { - return n.Name.Name - } +func (comp *compiler) getCallName(n *ast.Call) string { + // getCallName is used for checking that all variants of the same syscall have same argument sizes + // for matching arguments. Automatically-generated syscalls may violate that condition, + // so for them we use full syscall name. As the result manual and automatic variants + // of the same syscall are not checked against each other. + if comp.fileMeta(n.Pos).Automatic { + return n.Name.Name } return n.CallName } @@ -109,7 +111,7 @@ func (comp *compiler) genSyscalls() []*prog.Syscall { var calls []*prog.Syscall for _, decl := range comp.desc.Nodes { if n, ok := decl.(*ast.Call); ok && n.NR != ^uint64(0) { - calls = append(calls, comp.genSyscall(n, callArgSizes[getCallName(n)])) + calls = append(calls, comp.genSyscall(n, callArgSizes[comp.getCallName(n)])) } } // We assign SquashableElem here rather than during pointer type generation @@ -132,6 +134,7 @@ func (comp *compiler) genSyscall(n *ast.Call, argSizes []uint64) *prog.Syscall { ret = comp.genType(n.Ret, comp.ptrSize) } var attrs prog.SyscallAttrs + attrs.Automatic = comp.fileMeta(n.Pos).Automatic intAttrs, _, stringAttrs := comp.parseAttrs(callAttrs, n, n.Attrs) for desc, val := range intAttrs { fld := reflect.ValueOf(&attrs).Elem().FieldByName(desc.Name) diff --git a/pkg/compiler/meta.go b/pkg/compiler/meta.go index f0221d0b9..a47ab8f0b 100644 --- a/pkg/compiler/meta.go +++ b/pkg/compiler/meta.go @@ -11,11 +11,12 @@ import ( ) type Meta struct { - NoExtract bool + Automatic bool // automatically-generated descriptions + NoExtract bool // do not run syz-extract on the descriptions by default Arches map[string]bool } -func (meta *Meta) SupportsArch(arch string) bool { +func (meta Meta) SupportsArch(arch string) bool { return len(meta.Arches) == 0 || meta.Arches[arch] } @@ -27,6 +28,13 @@ func FileList(desc *ast.Description, OS string, eh ast.ErrorHandler) map[string] return nil } +func (comp *compiler) fileMeta(pos ast.Pos) Meta { + if comp.fileMetas == nil { + comp.fileMetas = comp.fileList() + } + return comp.fileMetas[filepath.Base(pos.File)] +} + func (comp *compiler) fileList() map[string]Meta { files := make(map[string]Meta) for _, n := range comp.desc.Nodes { @@ -44,6 +52,8 @@ func (comp *compiler) fileList() map[string]Meta { break } switch n.Value.Ident { + case metaAutomatic.Names[0]: + meta.Automatic = true case metaNoExtract.Names[0]: meta.NoExtract = true case metaArches.Names[0]: @@ -55,17 +65,20 @@ func (comp *compiler) fileList() map[string]Meta { } files[file] = meta } - if comp.errors != 0 { - return nil - } return files } var metaTypes = map[string]*typeDesc{ + metaAutomatic.Names[0]: metaAutomatic, metaNoExtract.Names[0]: metaNoExtract, metaArches.Names[0]: metaArches, } +var metaAutomatic = &typeDesc{ + Names: []string{"automatic"}, + CantBeOpt: true, +} + var metaNoExtract = &typeDesc{ Names: []string{"noextract"}, CantBeOpt: true, |
