From 8144982a26c6b8e5f0f5401c2a2de99e4ced04cd Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Tue, 19 Sep 2023 16:46:40 +0200 Subject: sys: refactor const extraction 1) Make FabricateSyscallConsts() operate on ConstFile. 2) Expose Pos inside ConstInfo. --- pkg/compiler/compiler.go | 20 +++++--------------- pkg/compiler/compiler_test.go | 8 ++++++-- pkg/compiler/consts.go | 43 ++++++++++++++++++++++++++++++------------- pkg/compiler/consts_test.go | 8 ++++++-- 4 files changed, 47 insertions(+), 32 deletions(-) (limited to 'pkg') diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index b3e39be06..15502e70b 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -8,7 +8,6 @@ package compiler import ( "fmt" "path/filepath" - "sort" "strconv" "strings" @@ -137,6 +136,7 @@ type compiler struct { structVarlen map[string]bool structTypes map[string]prog.Type builtinConsts map[string]uint64 + fileMeta map[string]Meta } type warn struct { @@ -154,10 +154,12 @@ func (comp *compiler) warning(pos ast.Pos, msg string, args ...interface{}) { } func (comp *compiler) filterArch() { - files := comp.fileList() + if comp.fileMeta == nil { + comp.fileMeta = comp.fileList() + } comp.desc = comp.desc.Filter(func(n ast.Node) bool { pos, typ, name := n.Info() - meta := files[filepath.Base(pos.File)] + meta := comp.fileMeta[filepath.Base(pos.File)] if meta.SupportsArch(comp.target.Arch) { return true } @@ -347,18 +349,6 @@ func (comp *compiler) parseIntType(name string) (size uint64, bigEndian bool) { return size, be } -func toArray(m map[string]bool) []string { - delete(m, "") - var res []string - for v := range m { - if v != "" { - res = append(res, v) - } - } - sort.Strings(res) - return res -} - func arrayContains(a []string, v string) bool { for _, s := range a { if s == v { diff --git a/pkg/compiler/compiler_test.go b/pkg/compiler/compiler_test.go index be40e817b..84ddb9f8e 100644 --- a/pkg/compiler/compiler_test.go +++ b/pkg/compiler/compiler_test.go @@ -87,15 +87,19 @@ func TestData(t *testing.T) { em.DumpErrors() t.Fatalf("const extraction failed") } - consts := map[string]uint64{ + cf := NewConstFile() + if err := cf.AddArch(arch, map[string]uint64{ "SYS_foo": 1, "C0": 0, "C1": 1, "C2": 2, "U8_MAX": 0xff, "U16_MAX": 0xffff, + }, nil); err != nil { + t.Fatal(err) } - FabricateSyscallConsts(target, constInfo, consts) + FabricateSyscallConsts(target, constInfo, cf) + consts := cf.Arch(arch) delete(consts, "SYS_unsupported") desc := Compile(astDesc, consts, target, em.ErrorHandler) if name == "errors2.txt" || name == "errors3.txt" { diff --git a/pkg/compiler/consts.go b/pkg/compiler/consts.go index 48a4f55aa..6652a381c 100644 --- a/pkg/compiler/consts.go +++ b/pkg/compiler/consts.go @@ -5,6 +5,7 @@ package compiler import ( "fmt" + "sort" "strings" "github.com/google/syzkaller/pkg/ast" @@ -13,13 +14,17 @@ import ( ) type ConstInfo struct { - File string - Consts []string + Consts []*Const Includes []string Incdirs []string Defines map[string]string } +type Const struct { + Name string + Pos ast.Pos +} + func ExtractConsts(desc *ast.Description, target *targets.Target, eh ast.ErrorHandler) map[string]*ConstInfo { res := Compile(desc, nil, target, eh) if res == nil { @@ -30,14 +35,14 @@ func ExtractConsts(desc *ast.Description, target *targets.Target, eh ast.ErrorHa // FabricateSyscallConsts adds syscall number constants to consts map. // Used for test OS to not bother specifying consts for all syscalls. -func FabricateSyscallConsts(target *targets.Target, constInfo map[string]*ConstInfo, consts map[string]uint64) { +func FabricateSyscallConsts(target *targets.Target, constInfo map[string]*ConstInfo, cf *ConstFile) { if !target.SyscallNumbers { return } for _, info := range constInfo { - for _, name := range info.Consts { - if strings.HasPrefix(name, target.SyscallPrefix) { - consts[name] = 0 + for _, c := range info.Consts { + if strings.HasPrefix(c.Name, target.SyscallPrefix) { + cf.addConst(target.Arch, c.Name, 0, true) } } } @@ -94,7 +99,7 @@ func (comp *compiler) extractConsts() map[string]*ConstInfo { comp.addConst(infos, n.Pos, n.Ident) } })) - return convertConstInfo(infos) + return convertConstInfo(infos, comp.fileMeta) } func (comp *compiler) extractTypeConsts(infos map[string]*constInfo, n ast.Node) { @@ -119,11 +124,14 @@ func (comp *compiler) addConst(infos map[string]*constInfo, pos ast.Pos, name st return } info := getConstInfo(infos, pos) - info.consts[name] = true + info.consts[name] = &Const{ + Pos: pos, + Name: name, + } } type constInfo struct { - consts map[string]bool + consts map[string]*Const defines map[string]string includeArray []string incdirArray []string @@ -133,7 +141,7 @@ func getConstInfo(infos map[string]*constInfo, pos ast.Pos) *constInfo { info := infos[pos.File] if info == nil { info = &constInfo{ - consts: make(map[string]bool), + consts: make(map[string]*Const), defines: make(map[string]string), } infos[pos.File] = info @@ -141,15 +149,24 @@ func getConstInfo(infos map[string]*constInfo, pos ast.Pos) *constInfo { return info } -func convertConstInfo(infos map[string]*constInfo) map[string]*ConstInfo { +func convertConstInfo(infos map[string]*constInfo, metas map[string]Meta) map[string]*ConstInfo { res := make(map[string]*ConstInfo) for file, info := range infos { if file == ast.BuiltinFile { continue } + var allConsts []*Const + for name, val := range info.consts { + if name == "" { + continue + } + allConsts = append(allConsts, val) + } + sort.Slice(allConsts, func(i, j int) bool { + return allConsts[i].Name < allConsts[j].Name + }) res[file] = &ConstInfo{ - File: file, - Consts: toArray(info.consts), + Consts: allConsts, Includes: info.includeArray, Incdirs: info.incdirArray, Defines: info.defines, diff --git a/pkg/compiler/consts_test.go b/pkg/compiler/consts_test.go index a0e4c1c8d..ab8bc48f7 100644 --- a/pkg/compiler/consts_test.go +++ b/pkg/compiler/consts_test.go @@ -41,8 +41,12 @@ func TestExtractConsts(t *testing.T) { "CONST26", } sort.Strings(wantConsts) - if !reflect.DeepEqual(info.Consts, wantConsts) { - t.Fatalf("got consts:\n%q\nwant:\n%q", info.Consts, wantConsts) + var constNames []string + for _, def := range info.Consts { + constNames = append(constNames, def.Name) + } + if !reflect.DeepEqual(constNames, wantConsts) { + t.Fatalf("got consts:\n%q\nwant:\n%q", constNames, wantConsts) } wantIncludes := []string{"foo/bar.h", "bar/foo.h"} if !reflect.DeepEqual(info.Includes, wantIncludes) { -- cgit mrf-deployment