diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2016-08-26 07:09:25 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2016-08-26 07:09:25 +0200 |
| commit | 0d0fbbe73f5b02bfeac0aedd0b6b9e8417ab0b0f (patch) | |
| tree | a412c7d3e6d9af44a29c35c6d3f1ecfe8067419f /sysgen/syscallnr.go | |
| parent | 34120ddc6e1ab0de360d3467b0d678fa6693e4c9 (diff) | |
overhaul syscall description generation process
This splits generation process into two phases:
1. Extract values of constants from linux kernel sources.
2. Generate Go code.
Constant values are checked in.
The advantage is that the second phase is now completely independent
from linux source files, kernel version, presence of headers for
particular drivers, etc. This allows to change what Go code we generate
any time without access to all kernel headers (which in future won't be
limited to only upstream headers).
Constant extraction process does require proper kernel sources,
but this can be done only once by the person who added the driver
and has access to the required sources. Then the constant values
are checked in for others to use.
Consant extraction process is per-file/per-arch. That is,
if I am adding a driver that is not present upstream and that
works only on a single arch, I will check in constants only for
that driver and for that arch.
Diffstat (limited to 'sysgen/syscallnr.go')
| -rw-r--r-- | sysgen/syscallnr.go | 84 |
1 files changed, 17 insertions, 67 deletions
diff --git a/sysgen/syscallnr.go b/sysgen/syscallnr.go index e39545c27..ca017d821 100644 --- a/sysgen/syscallnr.go +++ b/sysgen/syscallnr.go @@ -6,87 +6,48 @@ package main import ( "bytes" "sort" - "strconv" "text/template" + + . "github.com/google/syzkaller/sysparser" ) type Arch struct { - GOARCH string - CARCH []string - KernelHeaderArch string - KernelInclude string - CFlags []string - Numbers []int + Name string + CARCH []string } var archs = []*Arch{ - {"amd64", []string{"__x86_64__"}, "x86", "asm/unistd.h", []string{"-m64"}, nil}, - {"386", []string{"__i386__"}, "x86", "asm/unistd.h", []string{"-D__SYSCALL_COMPAT", "-DCONFIG_COMPAT", "-DCONFIG_X86_32"}, nil}, - {"arm64", []string{"__aarch64__"}, "arm64", "asm/unistd.h", []string{}, nil}, - {"ppc64le", []string{"__ppc64__", "__PPC64__", "__powerpc64__"}, "powerpc", "asm/unistd.h", []string{}, nil}, + {"amd64", []string{"__x86_64__"}}, + {"arm64", []string{"__aarch64__"}}, + {"ppc64le", []string{"__ppc64__", "__PPC64__", "__powerpc64__"}}, } -var syzkalls = map[string]int{ +var syzkalls = map[string]uint64{ "syz_open_dev": 1000001, "syz_open_pts": 1000002, "syz_fuse_mount": 1000003, "syz_fuseblk_mount": 1000004, } -func generateSyscallsNumbers(syscalls []Syscall) { - for _, arch := range archs { - fetchSyscallsNumbers(arch, syscalls) - generateSyscallsNumbersArch(arch, syscalls) - } - generateExecutorSyscalls(syscalls) -} - -func fetchSyscallsNumbers(arch *Arch, syscalls []Syscall) { - includes := []string{arch.KernelInclude} - var vals []string - defines := make(map[string]string) - for _, sc := range syscalls { - name := "__NR_" + sc.CallName - vals = append(vals, name) - defines[name] = "-1" - if nr := syzkalls[sc.CallName]; nr != 0 { - defines[name] = strconv.Itoa(nr) - } - } - for _, s := range fetchValues(arch.KernelHeaderArch, vals, includes, defines, arch.CFlags) { - n, err := strconv.ParseUint(s, 10, 64) - if err != nil { - failf("failed to parse syscall number '%v': %v", s, err) - } - arch.Numbers = append(arch.Numbers, int(n)) - } -} - -func generateSyscallsNumbersArch(arch *Arch, syscalls []Syscall) { - var archcode string = "sys/sys_" + arch.GOARCH + ".go" - logf(1, "Generate code with syscall numbers for arch=%v in %v", arch.GOARCH, archcode) - buf := new(bytes.Buffer) - if err := archTempl.Execute(buf, arch); err != nil { - failf("failed to execute arch template: %v", err) - } - writeSource(archcode, buf.Bytes()) -} - -func generateExecutorSyscalls(syscalls []Syscall) { +func generateExecutorSyscalls(syscalls []Syscall, consts map[string]map[string]uint64) { var data SyscallsData for _, arch := range archs { var calls []SyscallData - for i, c := range syscalls { - calls = append(calls, SyscallData{c.Name, arch.Numbers[i]}) + for _, c := range syscalls { + syscallNR := -1 + if nr, ok := consts[arch.Name]["__NR_"+c.CallName]; ok { + syscallNR = int(nr) + } + calls = append(calls, SyscallData{c.Name, syscallNR}) } data.Archs = append(data.Archs, ArchData{arch.CARCH, calls}) } for name, nr := range syzkalls { - data.FakeCalls = append(data.FakeCalls, SyscallData{name, nr}) + data.FakeCalls = append(data.FakeCalls, SyscallData{name, int(nr)}) } sort.Sort(SyscallArray(data.FakeCalls)) - var hdrcode string = "executor/syscalls.h" + hdrcode := "executor/syscalls.h" logf(1, "Generate header with syscall numbers in %v", hdrcode) buf := new(bytes.Buffer) if err := syscallsTempl.Execute(buf, data); err != nil { @@ -116,17 +77,6 @@ func (a SyscallArray) Len() int { return len(a) } func (a SyscallArray) Less(i, j int) bool { return a[i].Name < a[j].Name } func (a SyscallArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -var archTempl = template.Must(template.New("").Parse( - `// AUTOGENERATED FILE - -// +build {{$.GOARCH}} - -package sys - -// Maps internal syscall ID onto kernel syscall number. -var numbers = []int{ {{range $nr := $.Numbers}}{{$nr}}, {{end}} } -`)) - var syscallsTempl = template.Must(template.New("").Parse( `// AUTOGENERATED FILE |
