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