aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/build/cuttlefish.go
diff options
context:
space:
mode:
authorKris Alder <kalder@google.com>2023-02-10 17:26:30 -0800
committerAleksandr Nogikh <wp32pw@gmail.com>2023-02-13 10:46:51 +0100
commit957959cbd5c40f4e7be0c363495e34454cd2fde6 (patch)
tree1756f861b1e74a14b704698e7f1a09bde45e7cee /pkg/build/cuttlefish.go
parent93e26d605eebce2ad19e6f37d9e96a872ca55cce (diff)
pkg/build: rename android.go to cuttlefish.go
Building images for physical Android devices has different logic and options and should be in separate files. This makes it less ambiguous and frees up android.go for Android device code.
Diffstat (limited to 'pkg/build/cuttlefish.go')
-rw-r--r--pkg/build/cuttlefish.go160
1 files changed, 160 insertions, 0 deletions
diff --git a/pkg/build/cuttlefish.go b/pkg/build/cuttlefish.go
new file mode 100644
index 000000000..42ec8af26
--- /dev/null
+++ b/pkg/build/cuttlefish.go
@@ -0,0 +1,160 @@
+// Copyright 2022 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 (
+ "archive/tar"
+ "compress/gzip"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/google/syzkaller/pkg/osutil"
+)
+
+const (
+ kernelConfig = "common/build.config.gki_kasan.x86_64"
+ moduleConfig = "common-modules/virtual-device/build.config.virtual_device_kasan.x86_64"
+ bazelTarget = "//common-modules/virtual-device:virtual_device_x86_64_dist"
+)
+
+type cuttlefish struct{}
+
+func (c cuttlefish) runBuild(kernelDir, buildConfig string) error {
+ cmd := osutil.Command("build/build.sh")
+ cmd.Dir = kernelDir
+ cmd.Env = append(cmd.Env, "OUT_DIR=out", "DIST_DIR=dist", fmt.Sprintf("BUILD_CONFIG=%s", buildConfig))
+
+ _, err := osutil.Run(time.Hour, cmd)
+ return err
+}
+
+func (c cuttlefish) runBazel(kernelDir string) error {
+ cmd := osutil.Command("tools/bazel", "run", "--kasan", bazelTarget, "--", "--dist_dir=dist")
+ cmd.Dir = kernelDir
+ _, err := osutil.Run(time.Hour, cmd)
+ return err
+}
+
+func (c cuttlefish) readCompiler(archivePath string) (string, error) {
+ f, err := os.Open(archivePath)
+ if err != nil {
+ return "", err
+ }
+ defer f.Close()
+
+ gr, err := gzip.NewReader(f)
+ if err != nil {
+ return "", err
+ }
+ defer gr.Close()
+
+ tr := tar.NewReader(gr)
+
+ h, err := tr.Next()
+ for ; err == nil; h, err = tr.Next() {
+ if filepath.Base(h.Name) == "compile.h" {
+ bytes, err := ioutil.ReadAll(tr)
+ if err != nil {
+ return "", err
+ }
+ result := linuxCompilerRegexp.FindSubmatch(bytes)
+ if result == nil {
+ return "", fmt.Errorf("include/generated/compile.h does not contain build information")
+ }
+
+ return string(result[1]), nil
+ }
+ }
+
+ return "", fmt.Errorf("archive %s doesn't contain include/generated/compile.h", archivePath)
+}
+
+func (c cuttlefish) build(params Params) (ImageDetails, error) {
+ var details ImageDetails
+
+ if params.CmdlineFile != "" {
+ return details, fmt.Errorf("cmdline file is not supported for android cuttlefish images")
+ }
+ if params.SysctlFile != "" {
+ return details, fmt.Errorf("sysctl file is not supported for android cuttlefish images")
+ }
+
+ var config string
+ var err error
+ // Default to build.sh if compiler is not specified.
+ if params.Compiler == "bazel" {
+ if err := c.runBazel(params.KernelDir); err != nil {
+ return details, fmt.Errorf("failed to build kernel: %s", err)
+ }
+ // Find the .config file; it is placed in a temporary output directory during the build.
+ cmd := osutil.Command("find", ".", "-wholename", "*virtual_device_x86_64_config/out_dir/.config")
+ cmd.Dir = params.KernelDir
+ configBytes, err := osutil.Run(time.Minute, cmd)
+ if err != nil {
+ return details, fmt.Errorf("failed to find build config: %v", err)
+ }
+ config = filepath.Join(params.KernelDir, strings.TrimSpace(string(configBytes)))
+ } else {
+ if err := c.runBuild(params.KernelDir, kernelConfig); err != nil {
+ return details, fmt.Errorf("failed to build kernel: %s", err)
+ }
+ if err := c.runBuild(params.KernelDir, moduleConfig); err != nil {
+ return details, fmt.Errorf("failed to build modules: %s", err)
+ }
+ config = filepath.Join(params.KernelDir, "out", "common", ".config")
+ }
+
+ buildDistDir := filepath.Join(params.KernelDir, "dist")
+ bzImage := filepath.Join(buildDistDir, "bzImage")
+ vmlinux := filepath.Join(buildDistDir, "vmlinux")
+ initramfs := filepath.Join(buildDistDir, "initramfs.img")
+
+ details.CompilerID, err = c.readCompiler(filepath.Join(buildDistDir, "kernel-headers.tar.gz"))
+ if err != nil {
+ return details, err
+ }
+
+ if err := embedFiles(params, func(mountDir string) error {
+ homeDir := filepath.Join(mountDir, "root")
+
+ if err := osutil.CopyFile(bzImage, filepath.Join(homeDir, "bzImage")); err != nil {
+ return err
+ }
+ if err := osutil.CopyFile(vmlinux, filepath.Join(homeDir, "vmlinux")); err != nil {
+ return err
+ }
+ if err := osutil.CopyFile(initramfs, filepath.Join(homeDir, "initramfs.img")); err != nil {
+ return err
+ }
+
+ return nil
+ }); err != nil {
+ return details, err
+ }
+
+ if err := osutil.CopyFile(vmlinux, filepath.Join(params.OutputDir, "obj", "vmlinux")); err != nil {
+ return details, err
+ }
+ if err := osutil.CopyFile(initramfs, filepath.Join(params.OutputDir, "obj", "initrd")); err != nil {
+ return details, err
+ }
+ if err := osutil.CopyFile(config, filepath.Join(params.OutputDir, "kernel.config")); err != nil {
+ return details, err
+ }
+
+ details.Signature, err = elfBinarySignature(vmlinux, params.Tracer)
+ if err != nil {
+ return details, fmt.Errorf("failed to generate signature: %s", err)
+ }
+
+ return details, nil
+}
+
+func (c cuttlefish) clean(kernelDir, targetArch string) error {
+ return osutil.RemoveAll(filepath.Join(kernelDir, "out"))
+}