aboutsummaryrefslogtreecommitdiff
path: root/cc/fuzz.go
diff options
context:
space:
mode:
Diffstat (limited to 'cc/fuzz.go')
-rw-r--r--cc/fuzz.go217
1 files changed, 81 insertions, 136 deletions
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 79874fc80..5798860b5 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -16,7 +16,6 @@ package cc
import (
"path/filepath"
- "sort"
"strings"
"github.com/google/blueprint/proptools"
@@ -141,10 +140,9 @@ func LibFuzzFactory() android.Module {
type fuzzBinary struct {
*binaryDecorator
*baseCompiler
- fuzzPackagedModule fuzz.FuzzPackagedModule
- installedSharedDeps []string
- sharedLibraries android.RuleBuilderInstalls
- data []android.DataPath
+ fuzzPackagedModule fuzz.FuzzPackagedModule
+ sharedLibraries InstallPairs
+ data []android.DataPath
}
func (fuzz *fuzzBinary) fuzzBinary() bool {
@@ -257,37 +255,15 @@ func isValidSharedDependency(ctx android.ModuleContext, dependency android.Modul
// If the same library is present both as source and a prebuilt we must pick
// only one to avoid a conflict. Always prefer the source since the prebuilt
// probably won't be built with sanitizers enabled.
- if prebuilt, ok := android.OtherModuleProvider(ctx, dependency, android.PrebuiltModuleInfoProvider); ok && prebuilt.SourceExists {
- return false
+ if info, ok := android.OtherModuleProvider(ctx, dependency, android.PrebuiltInfoProvider); ok {
+ if info.IsPrebuilt && info.PrebuiltSourceExists {
+ return false
+ }
}
return true
}
-func SharedLibraryInstallLocation(
- libraryBase string, isHost bool, isVendor bool, fuzzDir string, archString string) string {
- installLocation := "$(PRODUCT_OUT)/data"
- if isHost {
- installLocation = "$(HOST_OUT)"
- }
- subdir := "lib"
- if isVendor {
- subdir = "lib/vendor"
- }
- installLocation = filepath.Join(
- installLocation, fuzzDir, archString, subdir, libraryBase)
- return installLocation
-}
-
-// Get the device-only shared library symbols install directory.
-func SharedLibrarySymbolsInstallLocation(libraryBase string, isVendor bool, fuzzDir string, archString string) string {
- subdir := "lib"
- if isVendor {
- subdir = "lib/vendor"
- }
- return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, subdir, libraryBase)
-}
-
func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
fuzzBin.fuzzPackagedModule = PackageFuzzModule(ctx, fuzzBin.fuzzPackagedModule)
@@ -295,31 +271,12 @@ func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
// Grab the list of required shared libraries.
fuzzBin.sharedLibraries, _ = CollectAllSharedDependencies(ctx)
-
- // TODO: does not mirror Android linkernamespaces
- // the logic here has special cases for vendor, but it would need more work to
- // work in arbitrary partitions, so just surface errors early for a few cases
- //
- // Even without these, there are certain situations across linkernamespaces
- // that this won't support. For instance, you might have:
- //
- // my_fuzzer (vendor) -> libbinder_ndk (core) -> libbinder (vendor)
- //
- // This dependency chain wouldn't be possible to express in the current
- // logic because all the deps currently match the variant of the source
- // module.
-
- for _, ruleBuilderInstall := range fuzzBin.sharedLibraries {
- install := ruleBuilderInstall.To
- fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
- SharedLibraryInstallLocation(
- install, ctx.Host(), ctx.inVendor(), installBase, ctx.Arch().ArchType.String()))
-
- // Also add the dependency on the shared library symbols dir.
- if !ctx.Host() {
- fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
- SharedLibrarySymbolsInstallLocation(install, ctx.inVendor(), installBase, ctx.Arch().ArchType.String()))
- }
+ // Add the shared libraries to install deps.
+ for _, sharedLib := range fuzzBin.sharedLibraries {
+ fuzzBin.binaryDecorator.baseInstaller.installDeps = append(
+ fuzzBin.binaryDecorator.baseInstaller.installDeps,
+ sharedLib.Dst,
+ )
}
for _, d := range fuzzBin.fuzzPackagedModule.Corpus {
@@ -428,19 +385,15 @@ func NewFuzzer(hod android.HostOrDeviceSupported) *Module {
// their architecture & target/host specific zip file.
type ccRustFuzzPackager struct {
fuzz.FuzzPackager
- fuzzPackagingArchModules string
- fuzzTargetSharedDepsInstallPairs string
- allFuzzTargetsName string
- onlyIncludePresubmits bool
+ onlyIncludePresubmits bool
+ phonyName string
}
func fuzzPackagingFactory() android.Singleton {
fuzzPackager := &ccRustFuzzPackager{
- fuzzPackagingArchModules: "SOONG_FUZZ_PACKAGING_ARCH_MODULES",
- fuzzTargetSharedDepsInstallPairs: "FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
- allFuzzTargetsName: "ALL_FUZZ_TARGETS",
- onlyIncludePresubmits: false,
+ onlyIncludePresubmits: false,
+ phonyName: "haiku",
}
return fuzzPackager
}
@@ -448,10 +401,8 @@ func fuzzPackagingFactory() android.Singleton {
func fuzzPackagingFactoryPresubmit() android.Singleton {
fuzzPackager := &ccRustFuzzPackager{
- fuzzPackagingArchModules: "SOONG_PRESUBMIT_FUZZ_PACKAGING_ARCH_MODULES",
- fuzzTargetSharedDepsInstallPairs: "PRESUBMIT_FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
- allFuzzTargetsName: "ALL_PRESUBMIT_FUZZ_TARGETS",
- onlyIncludePresubmits: true,
+ onlyIncludePresubmits: true,
+ phonyName: "haiku-presubmit",
}
return fuzzPackager
}
@@ -468,7 +419,7 @@ func (s *ccRustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext)
// 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.
- sharedLibraryInstalled := make(map[string]bool)
+ sharedLibraryInstalled := make(map[string]InstallPair)
ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
ccModule, ok := android.OtherModuleProvider(ctx, module, LinkableInfoProvider)
@@ -511,9 +462,14 @@ func (s *ccRustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext)
files = s.PackageArtifacts(ctx, module, &fuzzInfo, archDir, builder)
// Package shared libraries
- files = append(files, GetSharedLibsToZip(ccModule.FuzzSharedLibraries, isHost, ccModule.InVendor, &s.FuzzPackager,
- archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
-
+ files = append(files, GetSharedLibsToZip(ccModule.FuzzSharedLibraries, sharedLibsInstallDirPrefix)...)
+ if !s.onlyIncludePresubmits { // Create the copy rules from the `fuzzPackagingFactory` singleton and not `fuzzPackagingFactoryPresubmit` singleton.
+ for _, sharedLib := range ccModule.FuzzSharedLibraries {
+ if _, exists := sharedLibraryInstalled[sharedLib.Dst.String()]; !exists {
+ sharedLibraryInstalled[sharedLib.Dst.String()] = sharedLib
+ }
+ }
+ }
// The executable.
files = append(files, fuzz.FileToZip{SourceFilePath: android.OutputFileForModule(ctx, module, "unstripped")})
@@ -531,71 +487,39 @@ func (s *ccRustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext)
}
})
- s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx)
-}
-
-func (s *ccRustFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
- packages := s.Packages.Strings()
- sort.Strings(packages)
- sort.Strings(s.FuzzPackager.SharedLibInstallStrings)
- // TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's
- // ready to handle phony targets created in Soong. In the meantime, this
- // exports the phony 'fuzz' target and dependencies on packages to
- // core/main.mk so that we can use dist-for-goals.
-
- ctx.Strict(s.fuzzPackagingArchModules, strings.Join(packages, " "))
+ for _, k := range android.SortedKeys(sharedLibraryInstalled) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CpIfChanged,
+ Input: sharedLibraryInstalled[k].Src,
+ Output: sharedLibraryInstalled[k].Dst,
+ })
+ }
- ctx.Strict(s.fuzzTargetSharedDepsInstallPairs,
- strings.Join(s.FuzzPackager.SharedLibInstallStrings, " "))
+ s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx)
- // Preallocate the slice of fuzz targets to minimise memory allocations.
- s.PreallocateSlice(ctx, s.allFuzzTargetsName)
+ // Create the phony and dist rules
+ ctx.Phony(s.phonyName, s.Packages...)
+ ctx.DistForGoals([]string{s.phonyName}, s.Packages...)
+ for _, target := range android.SortedKeys(s.FuzzTargets) {
+ ctx.Phony(s.phonyName, android.PathForPhony(ctx, target))
+ }
}
// GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for
// packaging.
-func GetSharedLibsToZip(sharedLibraries android.RuleBuilderInstalls, isHost bool, inVendor bool, s *fuzz.FuzzPackager,
- archString string, destinationPathPrefix string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip {
+func GetSharedLibsToZip(sharedLibraries InstallPairs, destinationPathPrefix string) []fuzz.FileToZip {
var files []fuzz.FileToZip
- fuzzDir := "fuzz"
-
- for _, ruleBuilderInstall := range sharedLibraries {
- library := ruleBuilderInstall.From
- install := ruleBuilderInstall.To
+ for _, installPair := range sharedLibraries {
+ if strings.Contains(installPair.Dst.String(), "symbols/data/fuzz") {
+ // The unstripped so files would be copied from the main data/fuzz direcgtory.
+ continue
+ }
files = append(files, fuzz.FileToZip{
- SourceFilePath: library,
+ SourceFilePath: installPair.Src,
DestinationPathPrefix: destinationPathPrefix,
- DestinationPath: install,
+ DestinationPath: installPair.Dst.Base(),
})
-
- // For each architecture-specific shared library dependency, we need to
- // install it to the output directory. Setup the install destination here,
- // which will be used by $(copy-many-files) in the Make backend.
- installDestination := SharedLibraryInstallLocation(
- install, isHost, inVendor, fuzzDir, archString)
- if (*sharedLibraryInstalled)[installDestination] {
- continue
- }
- (*sharedLibraryInstalled)[installDestination] = true
-
- // Escape all the variables, as the install destination here will be called
- // via. $(eval) in Make.
- installDestination = strings.ReplaceAll(
- installDestination, "$", "$$")
- s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
- library.String()+":"+installDestination)
-
- // Ensure that on device, the library is also reinstalled to the /symbols/
- // dir. Symbolized DSO's are always installed to the device when fuzzing, but
- // we want symbolization tools (like `stack`) to be able to find the symbols
- // in $ANDROID_PRODUCT_OUT/symbols automagically.
- if !isHost {
- symbolsInstallDestination := SharedLibrarySymbolsInstallLocation(install, inVendor, fuzzDir, archString)
- symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
- s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
- library.String()+":"+symbolsInstallDestination)
- }
}
return files
}
@@ -605,12 +529,35 @@ func GetSharedLibsToZip(sharedLibraries android.RuleBuilderInstalls, isHost bool
// VisitDirectDeps is used first to avoid incorrectly using the core libraries (sanitizer
// runtimes, libc, libdl, etc.) from a dependency. This may cause issues when dependencies
// have explicit sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
-func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilderInstalls, []android.ModuleProxy) {
+func CollectAllSharedDependencies(ctx android.ModuleContext) (InstallPairs, []android.ModuleProxy) {
+ sharedLibInstallPaths := func(src android.Path) InstallPairs {
+ var ret InstallPairs
+ // Install in data/fuzz
+ hostOrDevicePrefix := "data"
+ if ctx.Host() {
+ hostOrDevicePrefix = ""
+ }
+ installPath := android.PathForModuleInPartitionInstall(ctx, hostOrDevicePrefix, "fuzz", ctx.Target().Arch.ArchType.String(), "lib")
+ if ctx.InstallInVendor() {
+ installPath = installPath.Join(ctx, "vendor")
+ }
+ ret = append(ret, InstallPair{src, installPath.Join(ctx, src.Base())})
+ // Install in symbols/data/fuzz
+ if !ctx.Host() {
+ installPath := android.PathForModuleInPartitionInstall(ctx, "symbols", "data", "fuzz", ctx.Target().Arch.ArchType.String(), "lib")
+ if ctx.InstallInVendor() {
+ installPath = installPath.Join(ctx, "vendor")
+ }
+ ret = append(ret, InstallPair{src, installPath.Join(ctx, src.Base())})
+ }
+ return ret
+ }
+
seen := make(map[string]bool)
recursed := make(map[string]bool)
deps := []android.ModuleProxy{}
- var sharedLibraries android.RuleBuilderInstalls
+ var sharedLibraries InstallPairs
// Enumerate the first level of dependencies, as we discard all non-library
// modules in the BFS loop below.
@@ -618,7 +565,7 @@ func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilde
if !isValidSharedDependency(ctx, dep) {
return
}
- sharedLibraryInfo, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, SharedLibraryInfoProvider)
+ _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, SharedLibraryInfoProvider)
if !hasSharedLibraryInfo {
return
}
@@ -628,9 +575,8 @@ func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilde
seen[ctx.OtherModuleName(dep)] = true
deps = append(deps, dep)
- installDestination := sharedLibraryInfo.SharedLibrary.Base()
- ruleBuilderInstall := android.RuleBuilderInstall{android.OutputFileForModule(ctx, dep, "unstripped"), installDestination}
- sharedLibraries = append(sharedLibraries, ruleBuilderInstall)
+ src := android.OutputFileForModule(ctx, dep, "unstripped")
+ sharedLibraries = append(sharedLibraries, sharedLibInstallPaths(src)...)
})
ctx.WalkDepsProxy(func(child, _ android.ModuleProxy) bool {
@@ -650,7 +596,7 @@ func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilde
if !isValidSharedDependency(ctx, child) {
return false
}
- sharedLibraryInfo, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, child, SharedLibraryInfoProvider)
+ _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, child, SharedLibraryInfoProvider)
if !hasSharedLibraryInfo {
return false
}
@@ -658,9 +604,8 @@ func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilde
seen[ctx.OtherModuleName(child)] = true
deps = append(deps, child)
- installDestination := sharedLibraryInfo.SharedLibrary.Base()
- ruleBuilderInstall := android.RuleBuilderInstall{android.OutputFileForModule(ctx, child, "unstripped"), installDestination}
- sharedLibraries = append(sharedLibraries, ruleBuilderInstall)
+ src := android.OutputFileForModule(ctx, child, "unstripped")
+ sharedLibraries = append(sharedLibraries, sharedLibInstallPaths(src)...)
}
if recursed[ctx.OtherModuleName(child)] {