aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-12-12 15:32:56 +0100
committerDmitry Vyukov <dvyukov@google.com>2024-12-12 15:03:51 +0000
commit5388eec6a1e6628f5ba367193f4131e82074ab3b (patch)
tree69df85a8424f6cb9a1d2d30489d7754600a03b6d /tools
parent7ab3e22624058d5d53f9de8291031344a8d09cc2 (diff)
tools/syz-declextract: parallelize
Do kernel probing, source code analysis and loading of syscall rename map in parallel. Also change probe caching to the scheme we now use for the clang tool cache so the same reasons.
Diffstat (limited to 'tools')
-rw-r--r--tools/syz-declextract/README.md10
-rw-r--r--tools/syz-declextract/declextract.go68
-rw-r--r--tools/syz-declextract/declextract_test.go5
3 files changed, 56 insertions, 27 deletions
diff --git a/tools/syz-declextract/README.md b/tools/syz-declextract/README.md
index 934059810..c306c67c7 100644
--- a/tools/syz-declextract/README.md
+++ b/tools/syz-declextract/README.md
@@ -46,8 +46,8 @@ go run tools/syz-declextract -binary=$LLVM_BUILD/bin/syz-declextract -config=man
syz-env make extract SOURCEDIR=$KERNEL
```
-The tool caches results of static kernel analysis in manager.workdir/declextract.cache,
-and results of the dynamic kernel probing in manager.workdir/interfaces.json.
-These can be examined for debugging purposes, and reused separately by passing
--cache-extract and -cache-probe flags. Caching greatly saves time if only part
-of the system has changed. If only the Go tool has changed, then both caches can be reused.
+The tool caches results of static kernel analysis in manager.workdir/declextract.cache file,
+and results of the dynamic kernel probing in manager.workdir/interfaces.json file.
+These can be examined for debugging purposes, and will be reused in future runs if exist
+(greatly saves time). If the clang tool/kernel has changed, delete these cache files
+so that they are updated.
diff --git a/tools/syz-declextract/declextract.go b/tools/syz-declextract/declextract.go
index ab8eac92b..63e6089ac 100644
--- a/tools/syz-declextract/declextract.go
+++ b/tools/syz-declextract/declextract.go
@@ -27,6 +27,7 @@ import (
_ "github.com/google/syzkaller/pkg/subsystem/lists"
"github.com/google/syzkaller/pkg/tool"
"github.com/google/syzkaller/sys/targets"
+ "golang.org/x/sync/errgroup"
)
// The target we currently assume for extracted descriptions.
@@ -34,21 +35,18 @@ var target = targets.Get(targets.Linux, targets.AMD64)
func main() {
var (
- flagConfig = flag.String("config", "", "manager config file")
- flagBinary = flag.String("binary", "syz-declextract", "path to syz-declextract binary")
- flagCacheProbe = flag.Bool("cache-probe", false, "use cached probe results if present"+
- " (cached in manager.workdir/interfaces.json)")
+ flagConfig = flag.String("config", "", "manager config file")
+ flagBinary = flag.String("binary", "syz-declextract", "path to syz-declextract binary")
)
defer tool.Init()()
cfg, err := mgrconfig.LoadFile(*flagConfig)
if err != nil {
tool.Fail(err)
}
- probeInfo, err := probe(cfg, *flagConfig, *flagCacheProbe)
- if err != nil {
- tool.Failf("kernel probing failed: %v", err)
+ loadProbeInfo := func() (*ifaceprobe.Info, error) {
+ return probe(cfg, *flagConfig)
}
- if err := run(filepath.FromSlash("sys/linux/auto.txt"), probeInfo, &clangtool.Config{
+ if err := run(filepath.FromSlash("sys/linux/auto.txt"), loadProbeInfo, &clangtool.Config{
ToolBin: *flagBinary,
KernelSrc: cfg.KernelSrc,
KernelObj: cfg.KernelObj,
@@ -58,12 +56,8 @@ func main() {
}
}
-func run(autoFile string, probeInfo *ifaceprobe.Info, cfg *clangtool.Config) error {
- syscallRename, err := buildSyscallRenameMap(cfg.KernelSrc)
- if err != nil {
- return fmt.Errorf("failed to build syscall rename map: %w", err)
- }
- out, err := clangtool.Run(cfg)
+func run(autoFile string, loadProbeInfo func() (*ifaceprobe.Info, error), cfg *clangtool.Config) error {
+ out, probeInfo, syscallRename, err := prepare(loadProbeInfo, cfg)
if err != nil {
return err
}
@@ -113,15 +107,47 @@ func run(autoFile string, probeInfo *ifaceprobe.Info, cfg *clangtool.Config) err
return osutil.WriteFile(autoFile, formatted)
}
-func probe(cfg *mgrconfig.Config, cfgFile string, cache bool) (*ifaceprobe.Info, error) {
- cacheFile := filepath.Join(cfg.Workdir, "interfaces.json")
- if cache {
- info, err := readProbeResult(cacheFile)
- if err == nil {
- return info, nil
+func prepare(loadProbeInfo func() (*ifaceprobe.Info, error), cfg *clangtool.Config) (
+ *declextract.Output, *ifaceprobe.Info, map[string][]string, error) {
+ var eg errgroup.Group
+ var out *declextract.Output
+ eg.Go(func() error {
+ var err error
+ out, err = clangtool.Run(cfg)
+ if err != nil {
+ return err
+ }
+ return nil
+ })
+ var probeInfo *ifaceprobe.Info
+ eg.Go(func() error {
+ var err error
+ probeInfo, err = loadProbeInfo()
+ if err != nil {
+ return fmt.Errorf("kernel probing failed: %w", err)
}
+ return nil
+ })
+ var syscallRename map[string][]string
+ eg.Go(func() error {
+ var err error
+ syscallRename, err = buildSyscallRenameMap(cfg.KernelSrc)
+ if err != nil {
+ return fmt.Errorf("failed to build syscall rename map: %w", err)
+ }
+ return nil
+ })
+ err := eg.Wait()
+ return out, probeInfo, syscallRename, err
+}
+
+func probe(cfg *mgrconfig.Config, cfgFile string) (*ifaceprobe.Info, error) {
+ cacheFile := filepath.Join(cfg.Workdir, "interfaces.json")
+ info, err := readProbeResult(cacheFile)
+ if err == nil {
+ return info, nil
}
- _, err := osutil.RunCmd(30*time.Minute, "", filepath.Join(cfg.Syzkaller, "bin", "syz-manager"),
+ _, err = osutil.RunCmd(30*time.Minute, "", filepath.Join(cfg.Syzkaller, "bin", "syz-manager"),
"-config", cfgFile, "-mode", "iface-probe")
if err != nil {
return nil, err
diff --git a/tools/syz-declextract/declextract_test.go b/tools/syz-declextract/declextract_test.go
index 6d0f12039..2f8dd70d5 100644
--- a/tools/syz-declextract/declextract_test.go
+++ b/tools/syz-declextract/declextract_test.go
@@ -63,8 +63,11 @@ func TestDeclextract(t *testing.T) {
t.Fatal(err)
}
}
+ loadProbeInfo := func() (*ifaceprobe.Info, error) {
+ return probeInfo, nil
+ }
autoFile := filepath.Join(cfg.KernelObj, filepath.Base(file)+".txt")
- if err := run(autoFile, probeInfo, cfg); err != nil {
+ if err := run(autoFile, loadProbeInfo, cfg); err != nil {
if *flagUpdate {
osutil.CopyFile(autoFile, file+".txt")
osutil.CopyFile(autoFile+".info", file+".info")