diff options
| -rw-r--r-- | pkg/compiler/compiler.go | 20 | ||||
| -rw-r--r-- | pkg/compiler/compiler_test.go | 8 | ||||
| -rw-r--r-- | pkg/compiler/consts.go | 43 | ||||
| -rw-r--r-- | pkg/compiler/consts_test.go | 8 | ||||
| -rw-r--r-- | sys/syz-extract/fetch.go | 16 | ||||
| -rw-r--r-- | sys/syz-extract/netbsd.go | 16 | ||||
| -rw-r--r-- | sys/syz-extract/openbsd.go | 10 | ||||
| -rw-r--r-- | sys/syz-sysgen/sysgen.go | 15 |
8 files changed, 78 insertions, 58 deletions
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) { diff --git a/sys/syz-extract/fetch.go b/sys/syz-extract/fetch.go index a7a0e46fe..834189fff 100644 --- a/sys/syz-extract/fetch.go +++ b/sys/syz-extract/fetch.go @@ -39,8 +39,8 @@ func extract(info *compiler.ConstInfo, cc string, args []string, params *extract missingIncludes := make(map[string]bool) undeclared := make(map[string]bool) valMap := make(map[string]bool) - for _, val := range info.Consts { - valMap[val] = true + for _, def := range info.Consts { + valMap[def.Name] = true } for { bin1, out, err := compile(cc, args, data) @@ -74,11 +74,11 @@ func extract(info *compiler.ConstInfo, cc string, args []string, params *extract cc, args, err, out) } data.Values = nil - for _, v := range info.Consts { - if undeclared[v] { + for _, def := range info.Consts { + if undeclared[def.Name] { continue } - data.Values = append(data.Values, v) + data.Values = append(data.Values, def) } data.Includes = nil for _, v := range info.Includes { @@ -105,8 +105,8 @@ func extract(info *compiler.ConstInfo, cc string, args []string, params *extract len(flagVals), len(data.Values)) } res := make(map[string]uint64) - for i, name := range data.Values { - res[name] = flagVals[i] + for i, def := range data.Values { + res[def.Name] = flagVals[i] } return res, undeclared, nil } @@ -115,7 +115,7 @@ type CompileData struct { *extractParams Defines map[string]string Includes []string - Values []string + Values []*compiler.Const } func compile(cc string, args []string, data *CompileData) (string, []byte, error) { diff --git a/sys/syz-extract/netbsd.go b/sys/syz-extract/netbsd.go index 8cc5efac0..b2ce7d620 100644 --- a/sys/syz-extract/netbsd.go +++ b/sys/syz-extract/netbsd.go @@ -72,20 +72,20 @@ func (*netbsd) processFile(arch *Arch, info *compiler.ConstInfo) (map[string]uin // Syscall consts on netbsd have weird prefixes sometimes, // try to extract consts with these prefixes as well. compatNames := make(map[string][]string) - for _, val := range info.Consts { + for _, def := range info.Consts { const SYS = "SYS_" - if strings.HasPrefix(val, SYS) { + if strings.HasPrefix(def.Name, SYS) { for _, prefix := range []string{"_", "__", "___"} { for _, suffix := range []string{"30", "50"} { - compat := SYS + prefix + val[len(SYS):] + suffix - compatNames[val] = append(compatNames[val], compat) - info.Consts = append(info.Consts, compat) + compat := SYS + prefix + def.Name[len(SYS):] + suffix + compatNames[def.Name] = append(compatNames[def.Name], compat) + info.Consts = append(info.Consts, &compiler.Const{Name: compat}) } } } else { - compat := "LINUX_" + val - compatNames[val] = append(compatNames[val], compat) - info.Consts = append(info.Consts, compat) + compat := "LINUX_" + def.Name + compatNames[def.Name] = append(compatNames[def.Name], compat) + info.Consts = append(info.Consts, &compiler.Const{Name: compat}) } } params := &extractParams{ diff --git a/sys/syz-extract/openbsd.go b/sys/syz-extract/openbsd.go index f103d1949..9d9a7026e 100644 --- a/sys/syz-extract/openbsd.go +++ b/sys/syz-extract/openbsd.go @@ -71,11 +71,11 @@ func (*openbsd) processFile(arch *Arch, info *compiler.ConstInfo) (map[string]ui "SYS_tmpfd": true, } compatNames := make(map[string][]string) - for _, val := range info.Consts { - if _, ok := syscallsQuirks[val]; ok { - compat := "SYS___" + val[len("SYS_"):] - compatNames[val] = append(compatNames[val], compat) - info.Consts = append(info.Consts, compat) + for _, def := range info.Consts { + if _, ok := syscallsQuirks[def.Name]; ok { + compat := "SYS___" + def.Name[len("SYS_"):] + compatNames[def.Name] = append(compatNames[def.Name], compat) + info.Consts = append(info.Consts, &compiler.Const{Name: compat}) } } params := &extractParams{ diff --git a/sys/syz-sysgen/sysgen.go b/sys/syz-sysgen/sysgen.go index 0459d544f..70b38fee5 100644 --- a/sys/syz-sysgen/sysgen.go +++ b/sys/syz-sysgen/sysgen.go @@ -98,9 +98,17 @@ func main() { var jobs []*Job for _, arch := range archs { + target := targets.List[OS][arch] + constInfo := compiler.ExtractConsts(descriptions, target, nil) + if OS == targets.TestOS { + // The ConstFile object provides no guarantees re concurrent read-write, + // so let's patch it before we start goroutines. + compiler.FabricateSyscallConsts(target, constInfo, constFile) + } jobs = append(jobs, &Job{ - Target: targets.List[OS][arch], + Target: target, Unsupported: make(map[string]bool), + ConstInfo: constInfo, }) } sort.Slice(jobs, func(i, j int) bool { @@ -167,6 +175,7 @@ type Job struct { Errors []string Unsupported map[string]bool ArchData ArchData + ConstInfo map[string]*compiler.ConstInfo } func processJob(job *Job, descriptions *ast.Description, constFile *compiler.ConstFile) { @@ -174,10 +183,6 @@ func processJob(job *Job, descriptions *ast.Description, constFile *compiler.Con job.Errors = append(job.Errors, fmt.Sprintf("%v: %v\n", pos, msg)) } consts := constFile.Arch(job.Target.Arch) - if job.Target.OS == targets.TestOS { - constInfo := compiler.ExtractConsts(descriptions, job.Target, eh) - compiler.FabricateSyscallConsts(job.Target, constInfo, consts) - } prog := compiler.Compile(descriptions, consts, job.Target, eh) if prog == nil { return |
