aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-12-06 09:43:19 +0100
committerDmitry Vyukov <dvyukov@google.com>2024-12-11 15:22:17 +0000
commitbfb4b3275371a3b53cd6562fa06e5a9dfb5627b7 (patch)
tree36d9f70965d8cf1080480c0d56de0b49f096cae5 /pkg/compiler
parenta9a0ffed7ef93dd86695100cf081438a918d6026 (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.go9
-rw-r--r--pkg/compiler/consts.go2
-rw-r--r--pkg/compiler/gen.go19
-rw-r--r--pkg/compiler/meta.go23
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,