diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-07-20 20:26:05 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-07-24 12:04:27 +0200 |
| commit | 9fe4bdc5f1037a409e82299f36117030114c7b94 (patch) | |
| tree | d3d73c1f69ded8152436be47684a07baa0e7f6ec /sys/syz-sysgen | |
| parent | db7957bc09bf5715d33e4c56b8614579aa94000a (diff) | |
executor: overhaul
Make as much code as possible shared between all OSes.
In particular main is now common across all OSes.
Make more code shared between executor and csource
(in particular, loop function and threaded execution logic).
Also make loop and threaded logic shared across all OSes.
Make more posix/unix code shared across OSes
(e.g. signal handling, pthread creation, etc).
Plus other changes along similar lines.
Also support test OS in executor (based on portable posix)
and add 4 arches that cover all execution modes
(fork server/no fork server, shmem/no shmem).
This change paves way for testing of executor code
and allows to preserve consistency across OSes and executor/csource.
Diffstat (limited to 'sys/syz-sysgen')
| -rw-r--r-- | sys/syz-sysgen/sysgen.go | 113 |
1 files changed, 74 insertions, 39 deletions
diff --git a/sys/syz-sysgen/sysgen.go b/sys/syz-sysgen/sysgen.go index 33dc535bf..65242910b 100644 --- a/sys/syz-sysgen/sysgen.go +++ b/sys/syz-sysgen/sysgen.go @@ -32,9 +32,33 @@ var ( flagMemProfile = flag.String("memprofile", "", "write a memory profile to the file") ) +type SyscallData struct { + Name string + CallName string + NR int32 + NeedCall bool +} + +type ArchData struct { + Revision string + ForkServer int + Shmem int + GOARCH string + PageSize uint64 + NumPages uint64 + DataOffset uint64 + Calls []SyscallData +} + +type OSData struct { + GOOS string + Archs []ArchData +} + func main() { flag.Parse() + var oses []OSData for OS, archs := range targets.List { top := ast.ParseGlob(filepath.Join("sys", OS, "*.txt"), nil) if top == nil { @@ -47,7 +71,7 @@ func main() { OK bool Errors []string Unsupported map[string]bool - ArchData []byte + ArchData ArchData } var jobs []*Job for _, target := range archs { @@ -86,12 +110,13 @@ func main() { writeSource(sysFile, out.Bytes()) job.ArchData = generateExecutorSyscalls(job.Target, prog.Syscalls, rev) + job.OK = true }() } wg.Wait() - var syscallArchs [][]byte + var syscallArchs []ArchData unsupported := make(map[string]int) for _, job := range jobs { fmt.Printf("generating %v/%v...\n", job.Target.OS, job.Target.Arch) @@ -107,16 +132,20 @@ func main() { } fmt.Printf("\n") } + oses = append(oses, OSData{ + GOOS: OS, + Archs: syscallArchs, + }) for what, count := range unsupported { if count == len(jobs) { failf("%v is unsupported on all arches (typo?)", what) } } - - writeExecutorSyscalls(OS, syscallArchs) } + writeExecutorSyscalls(oses) + if *flagMemProfile != "" { f, err := os.Create(*flagMemProfile) if err != nil { @@ -167,34 +196,20 @@ func generate(target *targets.Target, prg *compiler.Prog, consts map[string]uint fmt.Fprintf(out, "\n\n") } -func generateExecutorSyscalls(target *targets.Target, syscalls []*prog.Syscall, rev string) []byte { - type SyscallData struct { - Name string - CallName string - NR int32 - NeedCall bool - } - type ArchData struct { - Revision string - ForkServer bool - Shmem bool - GOARCH string - CARCH []string - PageSize uint64 - NumPages uint64 - DataOffset uint64 - Calls []SyscallData - } +func generateExecutorSyscalls(target *targets.Target, syscalls []*prog.Syscall, rev string) ArchData { data := ArchData{ Revision: rev, - ForkServer: target.ExecutorUsesForkServer, - Shmem: target.ExecutorUsesShmem, GOARCH: target.Arch, - CARCH: target.CArch, PageSize: target.PageSize, NumPages: target.NumPages, DataOffset: target.DataOffset, } + if target.ExecutorUsesForkServer { + data.ForkServer = 1 + } + if target.ExecutorUsesShmem { + data.Shmem = 1 + } for _, c := range syscalls { data.Calls = append(data.Calls, SyscallData{ Name: c.Name, @@ -206,20 +221,23 @@ func generateExecutorSyscalls(target *targets.Target, syscalls []*prog.Syscall, sort.Slice(data.Calls, func(i, j int) bool { return data.Calls[i].Name < data.Calls[j].Name }) - buf := new(bytes.Buffer) - if err := archTempl.Execute(buf, data); err != nil { - failf("failed to execute arch template: %v", err) - } - return buf.Bytes() + return data } -func writeExecutorSyscalls(OS string, archs [][]byte) { +func writeExecutorSyscalls(oses []OSData) { + sort.Slice(oses, func(i, j int) bool { + return oses[i].GOOS < oses[j].GOOS + }) buf := new(bytes.Buffer) - buf.WriteString("// AUTOGENERATED FILE\n\n") - for _, arch := range archs { - buf.Write(arch) + if err := defsTempl.Execute(buf, oses); 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 { + failf("failed to execute syscalls template: %v", err) } - writeFile(filepath.Join("executor", fmt.Sprintf("syscalls_%v.h", OS)), buf.Bytes()) + writeFile(filepath.FromSlash("executor/syscalls.h"), buf.Bytes()) } func writeSource(file string, data []byte) { @@ -248,8 +266,12 @@ func failf(msg string, args ...interface{}) { os.Exit(1) } -var archTempl = template.Must(template.New("").Parse(` -#if {{range $cdef := $.CARCH}}defined({{$cdef}}) || {{end}}0 +var defsTempl = template.Must(template.New("").Parse(`// AUTOGENERATED FILE +{{range $os := $}} +#if GOOS_{{$os.GOOS}} +#define GOOS "{{$os.GOOS}}" +{{range $arch := $os.Archs}} +#if GOARCH_{{$arch.GOARCH}} #define GOARCH "{{.GOARCH}}" #define SYZ_REVISION "{{.Revision}}" #define SYZ_EXECUTOR_USES_FORK_SERVER {{.ForkServer}} @@ -257,10 +279,23 @@ var archTempl = template.Must(template.New("").Parse(` #define SYZ_PAGE_SIZE {{.PageSize}} #define SYZ_NUM_PAGES {{.NumPages}} #define SYZ_DATA_OFFSET {{.DataOffset}} -#define SYZ_SYSCALL_COUNT {{len $.Calls}} +#endif +{{end}} +#endif +{{end}} +`)) + +var syscallsTempl = template.Must(template.New("").Parse(`// AUTOGENERATED FILE +{{range $os := $}} +#if GOOS_{{$os.GOOS}} +{{range $arch := $os.Archs}} +#if GOARCH_{{$arch.GOARCH}} const call_t syscalls[] = { -{{range $c := $.Calls}} {"{{$c.Name}}", {{$c.NR}}{{if $c.NeedCall}}, (syscall_t){{$c.CallName}}{{end}}}, +{{range $c := $arch.Calls}} {"{{$c.Name}}", {{$c.NR}}{{if $c.NeedCall}}, (syscall_t){{$c.CallName}}{{end}}}, {{end}} }; #endif +{{end}} +#endif +{{end}} `)) |
