Moving common fuzzing code to fuzz package
Test: make haiku and make haiku-rust
Change-Id: Ife80cc10672f51bd6afbae7061cc9373a2a15e7d
diff --git a/cc/Android.bp b/cc/Android.bp
index 164d32b..bff2761 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -13,6 +13,7 @@
"soong-bazel",
"soong-cc-config",
"soong-etc",
+ "soong-fuzz",
"soong-genrule",
"soong-snapshot",
"soong-tradefed",
@@ -59,7 +60,6 @@
"binary.go",
"binary_sdk_member.go",
"fuzz.go",
- "fuzz_common.go",
"library.go",
"library_headers.go",
"library_sdk_member.go",
diff --git a/cc/cc.go b/cc/cc.go
index e4f4761..f65af30 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -29,6 +29,7 @@
"android/soong/android"
"android/soong/cc/config"
+ "android/soong/fuzz"
"android/soong/genrule"
)
@@ -762,7 +763,7 @@
// members of the cc.Module to this decorator. Thus, a cc_binary module has custom linker and
// installer logic.
type Module struct {
- FuzzModule
+ fuzz.FuzzModule
android.SdkBase
android.BazelModuleBase
@@ -3415,7 +3416,7 @@
&TestProperties{},
&TestBinaryProperties{},
&BenchmarkProperties{},
- &FuzzProperties{},
+ &fuzz.FuzzProperties{},
&StlProperties{},
&SanitizeProperties{},
&StripProperties{},
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 8b0f93e..fbef12b 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -15,7 +15,6 @@
package cc
import (
- "encoding/json"
"path/filepath"
"sort"
"strings"
@@ -24,55 +23,9 @@
"android/soong/android"
"android/soong/cc/config"
+ "android/soong/fuzz"
)
-type FuzzConfig struct {
- // Email address of people to CC on bugs or contact about this fuzz target.
- Cc []string `json:"cc,omitempty"`
- // Specify whether to enable continuous fuzzing on devices. Defaults to true.
- Fuzz_on_haiku_device *bool `json:"fuzz_on_haiku_device,omitempty"`
- // Specify whether to enable continuous fuzzing on host. Defaults to true.
- Fuzz_on_haiku_host *bool `json:"fuzz_on_haiku_host,omitempty"`
- // Component in Google's bug tracking system that bugs should be filed to.
- Componentid *int64 `json:"componentid,omitempty"`
- // Hotlists in Google's bug tracking system that bugs should be marked with.
- Hotlists []string `json:"hotlists,omitempty"`
- // Specify whether this fuzz target was submitted by a researcher. Defaults
- // to false.
- Researcher_submitted *bool `json:"researcher_submitted,omitempty"`
- // Specify who should be acknowledged for CVEs in the Android Security
- // Bulletin.
- Acknowledgement []string `json:"acknowledgement,omitempty"`
- // Additional options to be passed to libfuzzer when run in Haiku.
- Libfuzzer_options []string `json:"libfuzzer_options,omitempty"`
- // Additional options to be passed to HWASAN when running on-device in Haiku.
- Hwasan_options []string `json:"hwasan_options,omitempty"`
- // Additional options to be passed to HWASAN when running on host in Haiku.
- Asan_options []string `json:"asan_options,omitempty"`
-}
-
-func (f *FuzzConfig) String() string {
- b, err := json.Marshal(f)
- if err != nil {
- panic(err)
- }
-
- return string(b)
-}
-
-type FuzzProperties struct {
- // Optional list of seed files to be installed to the fuzz target's output
- // directory.
- Corpus []string `android:"path"`
- // Optional list of data files to be installed to the fuzz target's output
- // directory. Directory structure relative to the module is preserved.
- Data []string `android:"path"`
- // Optional dictionary to be installed to the fuzz target's output directory.
- Dictionary *string `android:"path"`
- // Config for running the target on fuzzing infrastructure.
- Fuzz_config *FuzzConfig
-}
-
func init() {
android.RegisterModuleType("cc_fuzz", FuzzFactory)
android.RegisterSingletonType("cc_fuzz_packaging", fuzzPackagingFactory)
@@ -94,7 +47,7 @@
*binaryDecorator
*baseCompiler
- fuzzPackagedModule FuzzPackagedModule
+ fuzzPackagedModule fuzz.FuzzPackagedModule
installedSharedDeps []string
}
@@ -355,7 +308,7 @@
// Responsible for generating GNU Make rules that package fuzz targets into
// their architecture & target/host specific zip file.
type ccFuzzPackager struct {
- FuzzPackager
+ fuzz.FuzzPackager
sharedLibInstallStrings []string
}
@@ -367,7 +320,7 @@
// Map between each architecture + host/device combination, and the files that
// need to be packaged (in the tuple of {source file, destination folder in
// archive}).
- archDirs := make(map[ArchOs][]FileToZip)
+ archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)
// Map tracking whether each shared library has an install rule to avoid duplicate install rules from
// multiple fuzzers that depend on the same shared library.
@@ -384,7 +337,7 @@
}
// Discard non-fuzz targets.
- if ok := IsValid(ccModule.FuzzModule); !ok {
+ if ok := fuzz.IsValid(ccModule.FuzzModule); !ok {
return
}
@@ -400,12 +353,12 @@
archString := ccModule.Arch().ArchType.String()
archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
- archOs := ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
+ archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
// Grab the list of required shared libraries.
sharedLibraries := collectAllSharedDependencies(ctx, module)
- var files []FileToZip
+ var files []fuzz.FileToZip
builder := android.NewRuleBuilder(pctx, ctx)
// Package the corpus, data, dict and config into a zipfile.
@@ -414,7 +367,7 @@
// Find and mark all the transiently-dependent shared libraries for
// packaging.
for _, library := range sharedLibraries {
- files = append(files, FileToZip{library, "lib"})
+ files = append(files, fuzz.FileToZip{library, "lib"})
// For each architecture-specific shared library dependency, we need to
// install it to the output directory. Setup the install destination here,
@@ -446,7 +399,7 @@
}
// The executable.
- files = append(files, FileToZip{ccModule.UnstrippedOutputFile(), ""})
+ files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""})
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok {
@@ -454,7 +407,7 @@
}
})
- s.CreateFuzzPackage(ctx, archDirs, Cc)
+ s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx)
}
diff --git a/cc/fuzz_common.go b/cc/fuzz_common.go
deleted file mode 100644
index 98ed7f4..0000000
--- a/cc/fuzz_common.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2021 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cc
-
-// This file contains the common code for compiling C/C++ and Rust fuzzers for Android.
-
-import (
- "sort"
- "strings"
-
- "android/soong/android"
-)
-
-type Lang string
-
-const (
- Cc Lang = ""
- Rust Lang = "rust"
-)
-
-type FuzzModule struct {
- android.ModuleBase
- android.DefaultableModuleBase
- android.ApexModuleBase
-}
-
-type FuzzPackager struct {
- Packages android.Paths
- FuzzTargets map[string]bool
-}
-
-type FileToZip struct {
- SourceFilePath android.Path
- DestinationPathPrefix string
-}
-
-type ArchOs struct {
- HostOrTarget string
- Arch string
- Dir string
-}
-
-type FuzzPackagedModule struct {
- FuzzProperties FuzzProperties
- Dictionary android.Path
- Corpus android.Paths
- CorpusIntermediateDir android.Path
- Config android.Path
- Data android.Paths
- DataIntermediateDir android.Path
-}
-
-func IsValid(fuzzModule FuzzModule) bool {
- // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
- // fuzz targets we're going to package anyway.
- if !fuzzModule.Enabled() || fuzzModule.InRamdisk() || fuzzModule.InVendorRamdisk() || fuzzModule.InRecovery() {
- return false
- }
-
- // Discard modules that are in an unavailable namespace.
- if !fuzzModule.ExportedToMake() {
- return false
- }
-
- return true
-}
-
-func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip {
- // Package the corpora into a zipfile.
- var files []FileToZip
- if fuzzModule.Corpus != nil {
- corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip")
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", corpusZip)
- rspFile := corpusZip.ReplaceExtension(ctx, "rsp")
- command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.Corpus)
- files = append(files, FileToZip{corpusZip, ""})
- }
-
- // Package the data into a zipfile.
- if fuzzModule.Data != nil {
- dataZip := archDir.Join(ctx, module.Name()+"_data.zip")
- command := builder.Command().BuiltTool("soong_zip").
- FlagWithOutput("-o ", dataZip)
- for _, f := range fuzzModule.Data {
- intermediateDir := strings.TrimSuffix(f.String(), f.Rel())
- command.FlagWithArg("-C ", intermediateDir)
- command.FlagWithInput("-f ", f)
- }
- files = append(files, FileToZip{dataZip, ""})
- }
-
- // The dictionary.
- if fuzzModule.Dictionary != nil {
- files = append(files, FileToZip{fuzzModule.Dictionary, ""})
- }
-
- // Additional fuzz config.
- if fuzzModule.Config != nil {
- files = append(files, FileToZip{fuzzModule.Config, ""})
- }
-
- return files
-}
-
-func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) {
- fuzzZip := archDir.Join(ctx, module.Name()+".zip")
-
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", fuzzZip)
-
- for _, file := range files {
- if file.DestinationPathPrefix != "" {
- command.FlagWithArg("-P ", file.DestinationPathPrefix)
- } else {
- command.Flag("-P ''")
- }
- command.FlagWithInput("-f ", file.SourceFilePath)
- }
-
- builder.Build("create-"+fuzzZip.String(),
- "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
-
- // Don't add modules to 'make haiku-rust' that are set to not be
- // exported to the fuzzing infrastructure.
- if config := fuzzModule.FuzzProperties.Fuzz_config; config != nil {
- if strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_host, true) {
- return archDirs[archOs], false
- } else if !BoolDefault(config.Fuzz_on_haiku_device, true) {
- return archDirs[archOs], false
- }
- }
-
- s.FuzzTargets[module.Name()] = true
- archDirs[archOs] = append(archDirs[archOs], FileToZip{fuzzZip, ""})
-
- return archDirs[archOs], true
-}
-
-func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, lang Lang) {
- var archOsList []ArchOs
- for archOs := range archDirs {
- archOsList = append(archOsList, archOs)
- }
- sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].Dir < archOsList[j].Dir })
-
- for _, archOs := range archOsList {
- filesToZip := archDirs[archOs]
- arch := archOs.Arch
- hostOrTarget := archOs.HostOrTarget
- builder := android.NewRuleBuilder(pctx, ctx)
- zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip"
- if lang == Rust {
- zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip"
- }
- outputFile := android.PathForOutput(ctx, zipFileName)
-
- s.Packages = append(s.Packages, outputFile)
-
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", outputFile).
- Flag("-L 0") // No need to try and re-compress the zipfiles.
-
- for _, fileToZip := range filesToZip {
-
- if fileToZip.DestinationPathPrefix != "" {
- command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
- } else {
- command.Flag("-P ''")
- }
- command.FlagWithInput("-f ", fileToZip.SourceFilePath)
-
- }
- builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget,
- "Create fuzz target packages for "+arch+"-"+hostOrTarget)
- }
-}
-
-func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets string) {
- fuzzTargets := make([]string, 0, len(s.FuzzTargets))
- for target, _ := range s.FuzzTargets {
- fuzzTargets = append(fuzzTargets, target)
- }
- sort.Strings(fuzzTargets)
- ctx.Strict(targets, strings.Join(fuzzTargets, " "))
-}