aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorMark Johnston <markjdb@gmail.com>2019-03-08 11:43:34 -0500
committerDmitry Vyukov <dvyukov@google.com>2019-03-12 14:30:21 +0100
commitb8de2a60a0290b0a60fe4667aead4b99243da76c (patch)
treeccf0a473b1cd4fe5c2b9b7877432cab19e64af23 /pkg
parent2806a9214b417b0a050b64f7032b51204f6a48a1 (diff)
pkg/build: add freebsd
For now we must assume that we're building on FreeBSD; cross-compilation support isn't quite there yet. During a build, we first build an updated kernel toolchain if required, generate a custom kernel configuration file with KCOV enabled, and build a new kernel. (When running on the custom kernel, "uname -i" will print "SYZKALLER" rather than "GENERIC".) Then, the image is mounted under a tmpdir and we install the custom kernel to /boot/kernel.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/build/build.go1
-rw-r--r--pkg/build/freebsd.go87
2 files changed, 88 insertions, 0 deletions
diff --git a/pkg/build/build.go b/pkg/build/build.go
index 620ac5e07..44ea043a8 100644
--- a/pkg/build/build.go
+++ b/pkg/build/build.go
@@ -76,6 +76,7 @@ func getBuilder(targetOS, targetArch, vmType string) (builder, error) {
{"akaros", "amd64", []string{"qemu"}, akaros{}},
{"openbsd", "amd64", []string{"gce", "vmm"}, openbsd{}},
{"netbsd", "amd64", []string{"gce", "qemu"}, netbsd{}},
+ {"freebsd", "amd64", []string{"gce", "qemu"}, freebsd{}},
}
for _, s := range supported {
if targetOS == s.OS && targetArch == s.arch {
diff --git a/pkg/build/freebsd.go b/pkg/build/freebsd.go
new file mode 100644
index 000000000..babbfe07c
--- /dev/null
+++ b/pkg/build/freebsd.go
@@ -0,0 +1,87 @@
+// Copyright 2019 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package build
+
+import (
+ "fmt"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/google/syzkaller/pkg/osutil"
+)
+
+type freebsd struct{}
+
+func (ctx freebsd) build(targetArch, vmType, kernelDir, outputDir, compiler, userspaceDir,
+ cmdlineFile, sysctlFile string, config []byte) error {
+ confFile := fmt.Sprintf("%v/sys/%v/conf/SYZKALLER", kernelDir, targetArch)
+
+ if config == nil {
+ config = []byte(`
+include "./GENERIC"
+
+ident SYZKALLER
+options COVERAGE
+options KCOV
+`)
+ }
+ if err := osutil.WriteFile(confFile, config); err != nil {
+ return err
+ }
+
+ objDir := filepath.Join(outputDir, "obj")
+ if err := ctx.make(kernelDir, objDir, "kernel-toolchain"); err != nil {
+ return err
+ }
+ if err := ctx.make(kernelDir, objDir, "buildkernel", "KERNCONF=SYZKALLER"); err != nil {
+ return err
+ }
+
+ for _, s := range []struct{ dir, src, dst string }{
+ {userspaceDir, "image", "image"},
+ {userspaceDir, "key", "key"},
+ } {
+ fullSrc := filepath.Join(s.dir, s.src)
+ fullDst := filepath.Join(outputDir, s.dst)
+ if err := osutil.CopyFile(fullSrc, fullDst); err != nil {
+ return fmt.Errorf("failed to copy %v -> %v: %v", fullSrc, fullDst, err)
+ }
+ }
+
+ script := fmt.Sprintf(`
+set -eux
+md=$(sudo mdconfig -a -t vnode image)
+tmpdir=$(mktemp -d)
+sudo mount /dev/${md}p3 $tmpdir
+
+sudo MAKEOBJDIRPREFIX=$(pwd)/obj make -C %s installkernel KERNCONF=SYZKALLER DESTDIR=$tmpdir
+
+sudo umount $tmpdir
+sudo mdconfig -d -u ${md#md}
+`, kernelDir)
+
+ if debugOut, err := osutil.RunCmd(10*time.Minute, outputDir, "/bin/sh", "-c", script); err != nil {
+ return fmt.Errorf("error copying kernel: %v\n%v", err, debugOut)
+ }
+ return nil
+}
+
+func (ctx freebsd) clean(kernelDir, targetArch string) error {
+ // Builds are non-incremental for now, so we don't need to do anything here.
+ return nil
+}
+
+func (ctx freebsd) make(kernelDir string, objDir string, makeArgs ...string) error {
+ args := append([]string{
+ fmt.Sprintf("MAKEOBJDIRPREFIX=%v", objDir),
+ "make",
+ "-C", kernelDir,
+ "-j", strconv.Itoa(runtime.NumCPU()),
+ }, makeArgs...)
+ _, err := osutil.RunCmd(3*time.Hour, kernelDir, "sh", "-c", strings.Join(args, " "))
+ return err
+}