From 90d17ab8980674c6a59f47a062adccb37f99b88a Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 16 Apr 2020 17:38:36 +0200 Subject: 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). --- sys/syz-sysgen/sysgen.go | 61 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 11 deletions(-) (limited to 'sys/syz-sysgen') 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 -- cgit mrf-deployment