diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2020-04-16 17:38:36 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-04-19 10:26:57 +0200 |
| commit | 90d17ab8980674c6a59f47a062adccb37f99b88a (patch) | |
| tree | 63c96e2abc46f63d9092f07b16c8e70458b11444 /sys/syz-sysgen/sysgen.go | |
| parent | 0781895e0f8359843b9215ac6ad16925a46b2703 (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/syz-sysgen/sysgen.go')
| -rw-r--r-- | sys/syz-sysgen/sysgen.go | 61 |
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 |
