aboutsummaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-04-16 17:38:36 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-04-19 10:26:57 +0200
commit90d17ab8980674c6a59f47a062adccb37f99b88a (patch)
tree63c96e2abc46f63d9092f07b16c8e70458b11444 /sys
parent0781895e0f8359843b9215ac6ad16925a46b2703 (diff)
prog: introduce call attributes
Add common infrastructure for syscall attributes. Add few attributes we want, but they are not implemented for now (don't affect behavior, this will follow).
Diffstat (limited to 'sys')
-rw-r--r--sys/syz-sysgen/sysgen.go61
1 files changed, 50 insertions, 11 deletions
diff --git a/sys/syz-sysgen/sysgen.go b/sys/syz-sysgen/sysgen.go
index 6a89a1428..b453c4eb2 100644
--- a/sys/syz-sysgen/sysgen.go
+++ b/sys/syz-sysgen/sysgen.go
@@ -12,6 +12,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "reflect"
"runtime"
"runtime/pprof"
"sort"
@@ -37,6 +38,7 @@ type SyscallData struct {
CallName string
NR int32
NeedCall bool
+ Attrs []uint64
}
type ArchData struct {
@@ -55,6 +57,11 @@ type OSData struct {
Archs []ArchData
}
+type ExecutorData struct {
+ OSes []OSData
+ CallAttrs []string
+}
+
func main() {
flag.Parse()
@@ -64,7 +71,7 @@ func main() {
}
sort.Strings(OSList)
- var oses []OSData
+ data := &ExecutorData{}
for _, OS := range OSList {
top := ast.ParseGlob(filepath.Join("sys", OS, "*.txt"), nil)
if top == nil {
@@ -150,7 +157,7 @@ func main() {
unsupported[u]++
}
}
- oses = append(oses, OSData{
+ data.OSes = append(data.OSes, OSData{
GOOS: OS,
Archs: syscallArchs,
})
@@ -162,7 +169,12 @@ func main() {
}
}
- writeExecutorSyscalls(oses)
+ attrs := reflect.TypeOf(prog.SyscallAttrs{})
+ for i := 0; i < attrs.NumField(); i++ {
+ data.CallAttrs = append(data.CallAttrs, prog.CppName(attrs.Field(i).Name))
+ }
+
+ writeExecutorSyscalls(data)
if *flagMemProfile != "" {
f, err := os.Create(*flagMemProfile)
@@ -246,11 +258,33 @@ func generateExecutorSyscalls(target *targets.Target, syscalls []*prog.Syscall,
data.Shmem = 1
}
for _, c := range syscalls {
+ var attrVals []uint64
+ attrs := reflect.ValueOf(c.Attrs)
+ last := -1
+ for i := 0; i < attrs.NumField(); i++ {
+ attr := attrs.Field(i)
+ val := uint64(0)
+ switch attr.Type().Kind() {
+ case reflect.Bool:
+ if attr.Bool() {
+ val = 1
+ }
+ case reflect.Uint64:
+ val = attr.Uint()
+ default:
+ panic("unsupported syscall attribute type")
+ }
+ attrVals = append(attrVals, val)
+ if val != 0 {
+ last = i
+ }
+ }
data.Calls = append(data.Calls, SyscallData{
Name: c.Name,
CallName: c.CallName,
NR: int32(c.NR),
NeedCall: !target.SyscallNumbers || strings.HasPrefix(c.CallName, "syz_"),
+ Attrs: attrVals[:last+1],
})
}
sort.Slice(data.Calls, func(i, j int) bool {
@@ -259,17 +293,17 @@ func generateExecutorSyscalls(target *targets.Target, syscalls []*prog.Syscall,
return data
}
-func writeExecutorSyscalls(oses []OSData) {
- sort.Slice(oses, func(i, j int) bool {
- return oses[i].GOOS < oses[j].GOOS
+func writeExecutorSyscalls(data *ExecutorData) {
+ sort.Slice(data.OSes, func(i, j int) bool {
+ return data.OSes[i].GOOS < data.OSes[j].GOOS
})
buf := new(bytes.Buffer)
- if err := defsTempl.Execute(buf, oses); err != nil {
+ if err := defsTempl.Execute(buf, data); err != nil {
failf("failed to execute defs template: %v", err)
}
writeFile(filepath.FromSlash("executor/defs.h"), buf.Bytes())
buf.Reset()
- if err := syscallsTempl.Execute(buf, oses); err != nil {
+ if err := syscallsTempl.Execute(buf, data); err != nil {
failf("failed to execute syscalls template: %v", err)
}
writeFile(filepath.FromSlash("executor/syscalls.h"), buf.Bytes())
@@ -302,7 +336,11 @@ func failf(msg string, args ...interface{}) {
}
var defsTempl = template.Must(template.New("").Parse(`// AUTOGENERATED FILE
-{{range $os := $}}
+
+struct call_attrs_t { {{range $attr := $.CallAttrs}}
+ uint64_t {{$attr}};{{end}}
+};
+{{range $os := $.OSes}}
#if GOOS_{{$os.GOOS}}
#define GOOS "{{$os.GOOS}}"
{{range $arch := $os.Archs}}
@@ -320,13 +358,14 @@ var defsTempl = template.Must(template.New("").Parse(`// AUTOGENERATED FILE
{{end}}
`))
+// nolint: lll
var syscallsTempl = template.Must(template.New("").Parse(`// AUTOGENERATED FILE
-{{range $os := $}}
+{{range $os := $.OSes}}
#if GOOS_{{$os.GOOS}}
{{range $arch := $os.Archs}}
#if GOARCH_{{$arch.GOARCH}}
const call_t syscalls[] = {
-{{range $c := $arch.Calls}} {"{{$c.Name}}", {{$c.NR}}{{if $c.NeedCall}}, (syscall_t){{$c.CallName}}{{end}}},
+{{range $c := $arch.Calls}} {"{{$c.Name}}", {{$c.NR}}{{if or $c.Attrs $c.NeedCall}}, { {{range $attr := $c.Attrs}}{{$attr}},{{end}} }{{end}}{{if $c.NeedCall}}, (syscall_t){{$c.CallName}}{{end}}},
{{end}}
};
#endif