• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 syzkaller project authors. All rights reserved.
2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4package main
5
6import (
7	"fmt"
8	"os"
9	"path/filepath"
10	"strings"
11
12	"github.com/google/syzkaller/pkg/compiler"
13)
14
15type netbsd struct{}
16
17func (*netbsd) prepare(sourcedir string, build bool, arches []string) error {
18	if sourcedir == "" {
19		return fmt.Errorf("provide path to kernel checkout via -sourcedir flag (or make extract SOURCEDIR)")
20	}
21	if !build {
22		return fmt.Errorf("netbsd requires -build flag")
23	}
24	return nil
25}
26
27func (*netbsd) prepareArch(arch *Arch) error {
28	links := [][2]string{
29		{"amd64", "machine"},
30		{"amd64", "amd64"},
31		{"x86", "x86"},
32	}
33	for _, v := range links {
34		if err := machineLink(arch, v[0], v[1]); err != nil {
35			return err
36		}
37	}
38	return nil
39}
40
41func machineLink(arch *Arch, machine string, dest string) error {
42	if err := os.Symlink(machineInclude(arch, machine),
43		filepath.Join(arch.buildDir, dest)); err != nil {
44		return fmt.Errorf("failed to create link: %v", err)
45	}
46	return nil
47}
48
49func machineInclude(arch *Arch, machine string) string {
50	return filepath.Join(arch.sourceDir, "sys", "arch", machine, "include")
51}
52
53func (*netbsd) processFile(arch *Arch, info *compiler.ConstInfo) (map[string]uint64, map[string]bool, error) {
54	args := []string{
55		"-fmessage-length=0",
56		"-nostdinc",
57		"-D_KERNEL",
58		"-D__BSD_VISIBLE=1",
59		"-I", filepath.Join(arch.sourceDir, "sys"),
60		"-I", filepath.Join(arch.sourceDir, "sys", "sys"),
61		"-I", filepath.Join(arch.sourceDir, "sys", "arch", "amd64"),
62		"-I", filepath.Join(arch.sourceDir, "common", "include"),
63		"-I", filepath.Join(arch.sourceDir, "sys", "compat", "linux", "common"),
64		"-I", arch.buildDir,
65	}
66	for _, incdir := range info.Incdirs {
67		args = append(args, "-I"+filepath.Join(arch.sourceDir, incdir))
68	}
69	// Syscall consts on netbsd have weird prefixes sometimes,
70	// try to extract consts with these prefixes as well.
71	compatNames := make(map[string][]string)
72	for _, val := range info.Consts {
73		const SYS = "SYS_"
74		if strings.HasPrefix(val, SYS) {
75			for _, prefix := range []string{"_", "__", "___"} {
76				for _, suffix := range []string{"30", "50"} {
77					compat := SYS + prefix + val[len(SYS):] + suffix
78					compatNames[val] = append(compatNames[val], compat)
79					info.Consts = append(info.Consts, compat)
80				}
81			}
82		} else {
83			compat := "LINUX_" + val
84			compatNames[val] = append(compatNames[val], compat)
85			info.Consts = append(info.Consts, compat)
86		}
87	}
88	res, undeclared, err := extract(info, "gcc", args, "#include <sys/syscall.h>", false)
89	for orig, compats := range compatNames {
90		for _, compat := range compats {
91			if undeclared[orig] && !undeclared[compat] {
92				res[orig] = res[compat]
93				delete(res, compat)
94				delete(undeclared, orig)
95			}
96			delete(undeclared, compat)
97		}
98	}
99	return res, undeclared, err
100}
101