aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/compiler/compiler.go20
-rw-r--r--pkg/compiler/compiler_test.go8
-rw-r--r--pkg/compiler/consts.go43
-rw-r--r--pkg/compiler/consts_test.go8
-rw-r--r--sys/syz-extract/fetch.go16
-rw-r--r--sys/syz-extract/netbsd.go16
-rw-r--r--sys/syz-extract/openbsd.go10
-rw-r--r--sys/syz-sysgen/sysgen.go15
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