diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-12-12 15:32:56 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-12-12 15:03:51 +0000 |
| commit | 5388eec6a1e6628f5ba367193f4131e82074ab3b (patch) | |
| tree | 69df85a8424f6cb9a1d2d30489d7754600a03b6d /tools | |
| parent | 7ab3e22624058d5d53f9de8291031344a8d09cc2 (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.md | 10 | ||||
| -rw-r--r-- | tools/syz-declextract/declextract.go | 68 | ||||
| -rw-r--r-- | tools/syz-declextract/declextract_test.go | 5 |
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") |
