diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2026-02-05 13:59:08 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2026-02-06 09:29:18 +0000 |
| commit | fd36daf55d7f9e8ab412fcbf0441658a8d8be727 (patch) | |
| tree | 6d0a982741820007d1a15212e0227df85eb1b501 | |
| parent | f03c419189ef8ed823e306a342ee4d330fb2c394 (diff) | |
tools/clang: compile clang tools into the binary
Compiled clang tools into Go binaries using cgo.
This significantly simplifies building and deployment.
This also enables unit testing of clang tools.
Now raw go test for clang tools will build them, run,
and verify output.
Each clang tool is still started as a subprocess.
I've experimented with running them in-process,
but this makes stdout/stderr interception extremly complicated,
and it seems that clang tools still use unsynchronized global state,
which breaks when invoked multiple times.
Subprocesses also make it safer in the face of potential memory leaks,
or memory corruptions in clang tools.
Fixes #6645
| -rw-r--r-- | Makefile | 18 | ||||
| -rw-r--r-- | pkg/aflow/tool/codesearcher/codesearcher.go | 3 | ||||
| -rw-r--r-- | pkg/clangtool/clangtool.go | 22 | ||||
| -rw-r--r-- | pkg/clangtool/tooltest/tooltest.go | 16 | ||||
| -rw-r--r-- | pkg/codesearch/codesearch_test.go | 3 | ||||
| -rw-r--r-- | tools/clang/build.go | 33 | ||||
| -rw-r--r-- | tools/clang/codesearch/README.md | 9 | ||||
| l--------- | tools/clang/codesearch/build.go | 1 | ||||
| -rw-r--r-- | tools/clang/codesearch/codesearch.cpp | 21 | ||||
| -rw-r--r-- | tools/clang/codesearch/codesearch.go | 6 | ||||
| l--------- | tools/clang/declextract/build.go | 1 | ||||
| -rw-r--r-- | tools/clang/declextract/declextract.cpp | 32 | ||||
| -rw-r--r-- | tools/clang/declextract/declextract.go | 6 | ||||
| -rw-r--r-- | tools/clang/json.h | 4 | ||||
| -rw-r--r-- | tools/syz-codesearch/codesearch.go | 5 | ||||
| -rw-r--r-- | tools/syz-declextract/README.md | 32 | ||||
| -rw-r--r-- | tools/syz-declextract/declextract.go | 4 | ||||
| -rw-r--r-- | tools/syz-declextract/declextract_test.go | 7 |
18 files changed, 136 insertions, 87 deletions
@@ -114,7 +114,7 @@ endif check_copyright check_language check_whitespace check_links check_diff check_commits check_shebang check_html \ presubmit presubmit_aux presubmit_build presubmit_arch_linux presubmit_arch_freebsd \ presubmit_arch_netbsd presubmit_arch_openbsd presubmit_arch_darwin presubmit_arch_windows \ - presubmit_arch_executor presubmit_dashboard presubmit_race presubmit_race_dashboard presubmit_old codesearch + presubmit_arch_executor presubmit_dashboard presubmit_race presubmit_race_dashboard presubmit_old all: host target host: manager repro mutate prog2c db upgrade @@ -173,7 +173,8 @@ hub: descriptions GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-hub github.com/google/syzkaller/syz-hub agent: descriptions - GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-agent github.com/google/syzkaller/syz-agent + # syz-agent uses codesearch clang tool which requires cgo. + CGO_ENABLED=1 GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-agent github.com/google/syzkaller/syz-agent repro: descriptions GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o ./bin/syz-repro github.com/google/syzkaller/tools/syz-repro @@ -240,16 +241,6 @@ extract: bin/syz-extract bin/syz-extract: GOOS=$(HOSTOS) GOARCH=$(HOSTARCH) $(HOSTGO) build $(GOHOSTFLAGS) -o $@ ./sys/syz-extract -codesearch: bin/syz-codesearch - -bin/syz-codesearch: tools/clang/codesearch/* tools/clang/* - mkdir -p bin - $(CXX) -Itools/clang $(shell llvm-config --cxxflags) -O2 -o $@ tools/clang/codesearch/codesearch.cpp \ - -lclangTooling -lclangFrontend -lclangSerialization -lclangDriver \ - -lclangToolingCore -lclangParse -lclangSema -lclangAPINotes -lclangAnalysis \ - -lclangASTMatchers -lclangRewrite -lclangEdit -lclangAST -lclangLex -lclangBasic -lclangSupport \ - $(shell llvm-config --ldflags --libs --system-libs) - # `generate` does *not* depend on any kernel sources, and generates everything # in one pass, for all arches. It can be run on a bare syzkaller checkout. generate: @@ -407,7 +398,8 @@ presubmit_gvisor: host target ./tools/gvisor-smoke-test.sh test: descriptions - $(GO) test -short -coverprofile=.coverage.txt ./... + # Clang tools require cgo. + CGO_ENABLED=1 $(GO) test -short -coverprofile=.coverage.txt ./... clean: rm -rf ./bin .descriptions executor/defs.h executor/syscalls.h sys/gen sys/register.go diff --git a/pkg/aflow/tool/codesearcher/codesearcher.go b/pkg/aflow/tool/codesearcher/codesearcher.go index 1c3e50031..50a5627dc 100644 --- a/pkg/aflow/tool/codesearcher/codesearcher.go +++ b/pkg/aflow/tool/codesearcher/codesearcher.go @@ -11,6 +11,7 @@ import ( "github.com/google/syzkaller/pkg/clangtool" "github.com/google/syzkaller/pkg/codesearch" "github.com/google/syzkaller/pkg/hash" + "github.com/google/syzkaller/tools/clang/codesearch" ) var Tools = []aflow.Tool{ @@ -154,7 +155,7 @@ func prepare(ctx *aflow.Context, args prepareArgs) (prepareResult, error) { args.KernelCommit, hash.String(args.KernelConfig), codesearch.DatabaseFormatHash) dir, err := ctx.Cache("codesearch", desc, func(dir string) error { cfg := &clangtool.Config{ - ToolBin: args.CodesearchToolBin, + Tool: clangtoolimpl.Tool, KernelSrc: args.KernelSrc, KernelObj: args.KernelObj, CacheFile: filepath.Join(dir, "index.json"), diff --git a/pkg/clangtool/clangtool.go b/pkg/clangtool/clangtool.go index dd7c22f0a..c0c834e2d 100644 --- a/pkg/clangtool/clangtool.go +++ b/pkg/clangtool/clangtool.go @@ -23,7 +23,7 @@ import ( ) type Config struct { - ToolBin string + Tool string // one of compiled-in tool names KernelSrc string KernelObj string CacheFile string @@ -137,7 +137,7 @@ func (v *Verifier) Filename(file string) { return } v.fileCache[file] = -1 - fmt.Fprintf(&v.err, "missing file: %v\n", file) + fmt.Fprintf(&v.err, "missing file: %v (src dirs %+v)\n", file, v.srcDirs) } func (v *Verifier) LineRange(file string, start, end int) { @@ -160,8 +160,12 @@ func runTool[Output any, OutputPtr OutputDataPtr[Output]](cfg *Config, dbFile, f // version that produces more warnings. // Comments are needed for codesearch tool, but may be useful for declextract // in the future if we try to parse them with LLMs. - data, err := exec.Command(cfg.ToolBin, "-p", dbFile, - "--extra-arg=-w", "--extra-arg=-fparse-all-comments", file).Output() + cmd := exec.Command(os.Args[0], "-p", dbFile, + "--extra-arg=-w", "--extra-arg=-fparse-all-comments", file) + cmd.Dir = cfg.KernelObj + // This tells the C++ clang tool to execute in a constructor. + cmd.Env = append([]string{fmt.Sprintf("%v=%v", runToolEnv, cfg.Tool)}, os.Environ()...) + data, err := cmd.Output() if err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { @@ -185,6 +189,16 @@ func runTool[Output any, OutputPtr OutputDataPtr[Output]](cfg *Config, dbFile, f return out, nil } +const runToolEnv = "SYZ_RUN_CLANGTOOL" + +func init() { + // The C++ clang tool was supposed to intercept execution in a constructor, + // execute and exit. If we got here with the env var set, something is wrong. + if name := os.Getenv(runToolEnv); name != "" { + panic(fmt.Sprintf("clang tool %q is not compiled in", name)) + } +} + type compileCommand struct { Command string Directory string diff --git a/pkg/clangtool/tooltest/tooltest.go b/pkg/clangtool/tooltest/tooltest.go index 4f0b3bced..e78a85b62 100644 --- a/pkg/clangtool/tooltest/tooltest.go +++ b/pkg/clangtool/tooltest/tooltest.go @@ -18,16 +18,10 @@ import ( "github.com/google/syzkaller/pkg/testutil" ) -var ( - FlagBin = flag.String("bin", "", "path to the clang tool binary to use") - FlagUpdate = flag.Bool("update", false, "update golden files") -) +var FlagUpdate = flag.Bool("update", false, "update golden files") -func TestClangTool[Output any, OutputPtr clangtool.OutputDataPtr[Output]](t *testing.T) { - if *FlagBin == "" { - t.Skipf("clang tool path is not specified, run with -bin=clangtool flag") - } - ForEachTestFile(t, func(t *testing.T, cfg *clangtool.Config, file string) { +func TestClangTool[Output any, OutputPtr clangtool.OutputDataPtr[Output]](t *testing.T, tool string) { + ForEachTestFile(t, tool, func(t *testing.T, cfg *clangtool.Config, file string) { out, err := clangtool.Run[Output, OutputPtr](cfg) if err != nil { t.Fatal(err) @@ -57,7 +51,7 @@ func LoadOutput[Output any, OutputPtr clangtool.OutputDataPtr[Output]](t *testin return out } -func ForEachTestFile(t *testing.T, fn func(t *testing.T, cfg *clangtool.Config, file string)) { +func ForEachTestFile(t *testing.T, tool string, fn func(t *testing.T, cfg *clangtool.Config, file string)) { forEachTestFile(t, func(t *testing.T, file string) { t.Run(filepath.Base(file), func(t *testing.T) { t.Parallel() @@ -73,7 +67,7 @@ func ForEachTestFile(t *testing.T, fn func(t *testing.T, cfg *clangtool.Config, t.Fatal(err) } cfg := &clangtool.Config{ - ToolBin: *FlagBin, + Tool: tool, KernelSrc: osutil.Abs("testdata"), KernelObj: buildDir, CacheFile: filepath.Join(buildDir, filepath.Base(file)+".json"), diff --git a/pkg/codesearch/codesearch_test.go b/pkg/codesearch/codesearch_test.go index 35671567e..5deed53bb 100644 --- a/pkg/codesearch/codesearch_test.go +++ b/pkg/codesearch/codesearch_test.go @@ -12,10 +12,11 @@ import ( "github.com/google/syzkaller/pkg/clangtool/tooltest" "github.com/google/syzkaller/pkg/osutil" + "github.com/google/syzkaller/tools/clang/codesearch" ) func TestClangTool(t *testing.T) { - tooltest.TestClangTool[Database](t) + tooltest.TestClangTool[Database](t, clangtoolimpl.Tool) } func TestCommands(t *testing.T) { diff --git a/tools/clang/build.go b/tools/clang/build.go new file mode 100644 index 000000000..35a4affd3 --- /dev/null +++ b/tools/clang/build.go @@ -0,0 +1,33 @@ +// Copyright 2026 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 clangtoolimpl + +//// Common build flags for all C++ clang tools. +//// We install this file into all tool subdirs as a symbolic link. +// +// #cgo CXXFLAGS: -std=c++23 -O2 -fno-exceptions -I.. +// #cgo CXXFLAGS: -Wno-changes-meaning -Wno-deprecated-enum-enum-conversion +// +// #cgo LDFLAGS: -lclangTooling -lclangFrontend -lclangSerialization -lclangDriver +// #cgo LDFLAGS: -lclangToolingCore -lclangParse -lclangSema -lclangAPINotes -lclangAnalysis +// #cgo LDFLAGS: -lclangASTMatchers -lclangRewrite -lclangEdit -lclangAST -lclangLex +// #cgo LDFLAGS: -lclangBasic -lclangSupport -lLLVM +// +//// These flags are distro/version specific. +//// Cgo does not support running shell commands to produce flags. +//// We would need to run: +//// llvm-config --cxxflags +//// llvm-config --ldflags --libs --system-libs +//// There are some work-arounds like exporting CGO_CXXFLAGS/LDLFAGS in the Makefile, +//// or using go generate, but these won't work for bare go test runs. +//// For now, we hardcode typical path the several supported llvm versions. +//// The compiler will search in all of them in order, and pick the first +//// that is actually present and contains files. +// +// #cgo CXXFLAGS: -I/usr/include/llvm-21 -I/usr/lib/llvm-21/include -I/usr/include/llvm-c-21 +// #cgo LDFLAGS: -L/usr/lib/llvm-21/lib +// +// #cgo CXXFLAGS: -I/usr/lib/llvm-19/include +// #cgo LDFLAGS: -L/usr/lib/llvm-19/lib +import "C" diff --git a/tools/clang/codesearch/README.md b/tools/clang/codesearch/README.md deleted file mode 100644 index 6d876c78e..000000000 --- a/tools/clang/codesearch/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# syz-codesearch - -Clang-based tool that indexes kernel source code to power -[pkg/aflow/tool/codesearcher](/pkg/aflow/tool/codesearcher/codesearcher.go) -agentic tool. - -The tool can be built following the procedure described for -[syz-declextract tool](/tools/syz-declextract/README.md) or with `make -codesearch`. diff --git a/tools/clang/codesearch/build.go b/tools/clang/codesearch/build.go new file mode 120000 index 000000000..0308541aa --- /dev/null +++ b/tools/clang/codesearch/build.go @@ -0,0 +1 @@ +../build.go
\ No newline at end of file diff --git a/tools/clang/codesearch/codesearch.cpp b/tools/clang/codesearch/codesearch.cpp index 047edad10..a2d6883a2 100644 --- a/tools/clang/codesearch/codesearch.cpp +++ b/tools/clang/codesearch/codesearch.cpp @@ -1,6 +1,9 @@ // 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. +// Clang-based tool that indexes kernel source code to power +// pkg/aflow/tool/codesearcher/codesearcher.go agentic tool. + #include "json.h" #include "output.h" @@ -12,6 +15,7 @@ #include "clang/AST/RecordLayout.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Version.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" @@ -311,7 +315,11 @@ bool Indexer::TraverseRecordDecl(RecordDecl* Decl) { uint64_t OffsetInBits = Layout.getFieldOffset(Field->getFieldIndex()); uint64_t SizeInBits; if (Field->isBitField()) { - SizeInBits = Field->getBitWidthValue(Context); + SizeInBits = Field->getBitWidthValue( +#if CLANG_VERSION_MAJOR == 19 + Context +#endif + ); } else { TypeInfo Info = Context.getTypeInfo(Field->getType()); SizeInBits = Info.Width; @@ -338,8 +346,8 @@ bool Indexer::TraverseTypedefDecl(TypedefDecl* Decl) { return Base::TraverseTypedefDecl(Decl); } -int main(int argc, const char** argv) { - llvm::cl::OptionCategory Options("syz-indexer options"); +static int Main(int argc, const char** argv) { + llvm::cl::OptionCategory Options("codesearch options"); auto OptionsParser = tooling::CommonOptionsParser::create(argc, argv, Options); if (!OptionsParser) { llvm::errs() << OptionsParser.takeError(); @@ -351,5 +359,12 @@ int main(int argc, const char** argv) { if (Tool.run(tooling::newFrontendActionFactory(&Instance, &Instance).get())) return 1; Output.print(); + fflush(stdout); return 0; } + +__attribute__((constructor(1000))) static void ctor(int argc, const char** argv) { + const char* run = getenv("SYZ_RUN_CLANGTOOL"); + if (run && !strcmp(run, "codesearch")) + exit(Main(argc, argv)); +} diff --git a/tools/clang/codesearch/codesearch.go b/tools/clang/codesearch/codesearch.go new file mode 100644 index 000000000..6fa5d7de0 --- /dev/null +++ b/tools/clang/codesearch/codesearch.go @@ -0,0 +1,6 @@ +// Copyright 2026 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 clangtoolimpl + +const Tool = "codesearch" diff --git a/tools/clang/declextract/build.go b/tools/clang/declextract/build.go new file mode 120000 index 000000000..0308541aa --- /dev/null +++ b/tools/clang/declextract/build.go @@ -0,0 +1 @@ +../build.go
\ No newline at end of file diff --git a/tools/clang/declextract/declextract.cpp b/tools/clang/declextract/declextract.cpp index d7230a578..620c81f17 100644 --- a/tools/clang/declextract/declextract.cpp +++ b/tools/clang/declextract/declextract.cpp @@ -21,6 +21,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TypeTraits.h" +#include "clang/Basic/Version.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" @@ -297,7 +298,12 @@ FieldType Extractor::extractRecord(QualType QT, const RecordType* Typ, const std IsAnonymous = true; } FieldType FieldType = genType(F->getType(), BackupFieldName); - int BitWidth = F->isBitField() ? F->getBitWidthValue() : 0; + int BitWidth = F->isBitField() ? F->getBitWidthValue( +#if CLANG_VERSION_MAJOR == 19 + *Context +#endif + ) + : 0; int CountedBy = F->getType()->isCountAttributedType() ? llvm::dyn_cast<FieldDecl>( F->getType()->getAs<CountAttributedType>()->getCountExpr()->getReferencedDeclOfCallee()) @@ -338,9 +344,16 @@ std::string Extractor::extractEnum(QualType QT, const EnumDecl* Decl) { if (Name.empty()) { // This is an unnamed enum declared with a typedef: // typedef enum {...} enum_name; - auto Typedef = dyn_cast<TypedefType>(QT.getTypePtr()); - if (Typedef) - Name = Typedef->getDecl()->getNameAsString(); + auto Elaborated = dyn_cast<ElaboratedType>(QT.getTypePtr()); + if (Elaborated) { + auto Typedef = dyn_cast<TypedefType>(Elaborated->getNamedType().getTypePtr()); + if (Typedef) + Name = Typedef->getDecl()->getNameAsString(); + } + // This is the code we will need for one of future versions (past 21). + // auto Typedef = dyn_cast<TypedefType>(QT.getTypePtr()); + // if (Typedef) + // Name = Typedef->getDecl()->getNameAsString(); if (Name.empty()) { QT.dump(); llvm::report_fatal_error("enum with empty name"); @@ -993,8 +1006,8 @@ void Extractor::extractIoctl(const Expr* Cmd, const ConstDesc& Const) { }); } -int main(int argc, const char** argv) { - llvm::cl::OptionCategory Options("syz-declextract options"); +static int Main(int argc, const char** argv) { + llvm::cl::OptionCategory Options("declextract options"); auto OptionsParser = tooling::CommonOptionsParser::create(argc, argv, Options); if (!OptionsParser) { llvm::errs() << OptionsParser.takeError(); @@ -1005,5 +1018,12 @@ int main(int argc, const char** argv) { if (Tool.run(tooling::newFrontendActionFactory(&Ex, &Ex).get())) return 1; Ex.print(); + fflush(stdout); return 0; } + +__attribute__((constructor(1000))) static void ctor(int argc, const char** argv) { + const char* run = getenv("SYZ_RUN_CLANGTOOL"); + if (run && !strcmp(run, "declextract")) + exit(Main(argc, argv)); +} diff --git a/tools/clang/declextract/declextract.go b/tools/clang/declextract/declextract.go new file mode 100644 index 000000000..f419604c9 --- /dev/null +++ b/tools/clang/declextract/declextract.go @@ -0,0 +1,6 @@ +// Copyright 2026 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 clangtoolimpl + +const Tool = "declextract" diff --git a/tools/clang/json.h b/tools/clang/json.h index 596868da3..93c726fd3 100644 --- a/tools/clang/json.h +++ b/tools/clang/json.h @@ -1,8 +1,8 @@ // Copyright 2024 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. -#ifndef SYZ_DECLEXTRACT_JSON_H -#define SYZ_DECLEXTRACT_JSON_H +#ifndef SYZ_CLANGTOOL_JSON_H +#define SYZ_CLANGTOOL_JSON_H #include <cassert> #include <cstdint> diff --git a/tools/syz-codesearch/codesearch.go b/tools/syz-codesearch/codesearch.go index be1efbba5..6042c643e 100644 --- a/tools/syz-codesearch/codesearch.go +++ b/tools/syz-codesearch/codesearch.go @@ -11,6 +11,7 @@ import ( "github.com/google/syzkaller/pkg/clangtool" "github.com/google/syzkaller/pkg/codesearch" "github.com/google/syzkaller/pkg/tool" + "github.com/google/syzkaller/tools/clang/codesearch" ) func main() { @@ -25,11 +26,11 @@ func main() { } cmd, args := flag.Args()[0], flag.Args()[1:] if cmd == "index" { - if len(args) != 1 { + if len(args) != 0 { printUsageAndExit() } cfg := &clangtool.Config{ - ToolBin: args[0], + Tool: clangtoolimpl.Tool, KernelSrc: *flagKernelSrc, KernelObj: *flagKernelObj, CacheFile: *flagDatabase, diff --git a/tools/syz-declextract/README.md b/tools/syz-declextract/README.md index 99fb8d23a..23a0bb56b 100644 --- a/tools/syz-declextract/README.md +++ b/tools/syz-declextract/README.md @@ -8,34 +8,7 @@ cd $KERNEL make CC=clang defconfig ./scripts/config -e FTRACE_SYSCALLS make CC=clang olddefconfig -make CC=clang -j`nproc` # kernel has to be built at least once for the script to work -./scripts/clang-tools/gen_compile_commands.py -``` - -## LLVM Project -``` -LLVM=$PWD/llvm-project -git clone https://github.com/llvm/llvm-project.git $LLVM -cd $LLVM -git checkout d9dfe7540f81663f75350bb5ceb66d2f94dac078 # In case of any breaking changes, this commit works -echo ' -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++20-designator -Wno-missing-designated-field-initializers") -add_clang_executable(syz-declextract syz-declextract/declextract.cpp) -target_link_libraries(syz-declextract PRIVATE clangTooling) -' >> $LLVM/clang/CMakeLists.txt -``` - -## syz-declextract -``` -mkdir $LLVM/clang/syz-declextract -``` -Copy `tools/clang/declextract/*.{cpp,h}` and `tools/clang/*.h` files to `$LLVM/clang/syz-declextract/` directory. -``` -LLVM_BUILD=$PWD/syz -mkdir $LLVM_BUILD && cd $LLVM_BUILD -cmake -DLLVM_ENABLE_PROJECTS="clang" -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=On \ --DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -GNinja $LLVM/llvm -ninja syz-declextract +make CC=clang -j`nproc` vmlinux compile_commands.json # kernel has to be built at least once for the script to work ``` ## Running on a single source file @@ -54,8 +27,7 @@ should be used for the rest of the process as well. ## Running on the whole kernel ``` -go run ./tools/syz-declextract -binary=$LLVM_BUILD/bin/syz-declextract -config=manager.cfg \ - -coverage coverage.jsonl +go run ./tools/syz-declextract -config=manager.cfg -coverage coverage.jsonl syz-env make extract SOURCEDIR=$KERNEL ``` diff --git a/tools/syz-declextract/declextract.go b/tools/syz-declextract/declextract.go index d2bb505e4..cc47330e8 100644 --- a/tools/syz-declextract/declextract.go +++ b/tools/syz-declextract/declextract.go @@ -29,6 +29,7 @@ import ( _ "github.com/google/syzkaller/pkg/subsystem/lists" "github.com/google/syzkaller/pkg/tool" "github.com/google/syzkaller/sys/targets" + "github.com/google/syzkaller/tools/clang/declextract" "golang.org/x/sync/errgroup" ) @@ -38,7 +39,6 @@ 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") flagCoverage = flag.String("coverage", "", "syzbot coverage jsonl file") flagArches = flag.String("arches", "", "comma-separated list of arches to extract (all if empty)") ) @@ -56,7 +56,7 @@ func main() { coverFile: *flagCoverage, loadProbeInfo: loadProbeInfo, Config: &clangtool.Config{ - ToolBin: *flagBinary, + Tool: clangtoolimpl.Tool, KernelSrc: mgrcfg.KernelSrc, KernelObj: mgrcfg.KernelObj, CacheFile: filepath.Join(mgrcfg.Workdir, "declextract.cache"), diff --git a/tools/syz-declextract/declextract_test.go b/tools/syz-declextract/declextract_test.go index bf1af7bdf..794844ffe 100644 --- a/tools/syz-declextract/declextract_test.go +++ b/tools/syz-declextract/declextract_test.go @@ -15,14 +15,15 @@ import ( "github.com/google/syzkaller/pkg/declextract" "github.com/google/syzkaller/pkg/ifaceprobe" "github.com/google/syzkaller/pkg/osutil" + "github.com/google/syzkaller/tools/clang/declextract" ) func TestClangTool(t *testing.T) { - tooltest.TestClangTool[declextract.Output](t) + tooltest.TestClangTool[declextract.Output](t, clangtoolimpl.Tool) } func TestDeclextract(t *testing.T) { - tooltest.ForEachTestFile(t, func(t *testing.T, cfg *clangtool.Config, file string) { + tooltest.ForEachTestFile(t, clangtoolimpl.Tool, func(t *testing.T, cfg *clangtool.Config, file string) { // Created cache file to avoid running the clang tool. goldenFile := file + ".json" cacheFile := filepath.Join(cfg.KernelObj, filepath.Base(goldenFile)) @@ -33,7 +34,7 @@ func TestDeclextract(t *testing.T) { filepath.Join(cfg.KernelObj, "manual.txt")); err != nil { t.Fatal(err) } - cfg.ToolBin = "this-is-not-supposed-to-run" + cfg.Tool = "this-is-not-supposed-to-run" probeInfo := new(ifaceprobe.Info) probeFile := filepath.Join(cfg.KernelSrc, filepath.Base(file)+".probe") if osutil.IsExist(probeFile) { |
