1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
// Copyright 2025 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 kernel
import (
"fmt"
"io/fs"
"os"
"path"
"path/filepath"
"runtime"
"time"
"github.com/google/syzkaller/pkg/aflow"
"github.com/google/syzkaller/pkg/build"
"github.com/google/syzkaller/pkg/hash"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/sys/targets"
)
// Build action builds the Linux kernel from the given sources,
// outputs directory with build artifacts.
var Build = aflow.NewFuncAction("kernel-builder", buildKernel)
type buildArgs struct {
KernelSrc string
KernelCommit string
KernelConfig string
}
type buildResult struct {
KernelObj string // Directory with build artifacts.
}
func buildKernel(ctx *aflow.Context, args buildArgs) (buildResult, error) {
desc := fmt.Sprintf("kernel commit %v, kernel config hash %v",
args.KernelCommit, hash.String(args.KernelConfig))
dir, err := ctx.Cache("build", desc, func(dir string) error {
if err := osutil.WriteFile(filepath.Join(dir, ".config"), []byte(args.KernelConfig)); err != nil {
return err
}
target := targets.List[targets.Linux][targets.AMD64]
image := filepath.FromSlash(build.LinuxKernelImage(targets.AMD64))
makeArgs := build.LinuxMakeArgs(target, targets.DefaultLLVMCompiler, targets.DefaultLLVMLinker,
"ccache", dir, runtime.NumCPU())
compileCommnads := "compile_commands.json"
makeArgs = append(makeArgs, path.Base(image), compileCommnads)
if _, err := osutil.RunCmd(time.Hour, args.KernelSrc, "make", makeArgs...); err != nil {
return aflow.FlowError(err)
}
// Remove main intermediate build files, we don't need them anymore
// and they take lots of space. Keep generated source files.
keepExt := map[string]bool{".h": true, ".c": true, ".s": true, ".S": true}
keepFiles := map[string]bool{
filepath.Join(dir, image): true,
filepath.Join(dir, target.KernelObject): true,
filepath.Join(dir, compileCommnads): true,
}
return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
if err != nil || d.IsDir() || keepFiles[path] || keepExt[filepath.Ext(d.Name())] {
return err
}
return os.Remove(path)
})
})
return buildResult{KernelObj: dir}, err
}
|