Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e37e1578 authored by Ivan Lozano's avatar Ivan Lozano Committed by Gerrit Code Review
Browse files

Merge "Copy Rust fuzzer dependencies to /data."

parents 2411ffde 0f9963e9
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -1066,6 +1066,31 @@ func (c *Module) CcLibraryInterface() bool {
	return false
}

func (c *Module) IsFuzzModule() bool {
	if _, ok := c.compiler.(*fuzzBinary); ok {
		return true
	}
	return false
}

func (c *Module) FuzzModuleStruct() fuzz.FuzzModule {
	return c.FuzzModule
}

func (c *Module) FuzzPackagedModule() fuzz.FuzzPackagedModule {
	if fuzzer, ok := c.compiler.(*fuzzBinary); ok {
		return fuzzer.fuzzPackagedModule
	}
	panic(fmt.Errorf("FuzzPackagedModule called on non-fuzz module: %q", c.BaseModuleName()))
}

func (c *Module) FuzzSharedLibraries() android.Paths {
	if fuzzer, ok := c.compiler.(*fuzzBinary); ok {
		return fuzzer.sharedLibraries
	}
	panic(fmt.Errorf("FuzzSharedLibraries called on non-fuzz module: %q", c.BaseModuleName()))
}

func (c *Module) NonCcVariants() bool {
	return false
}
+48 −44
Original line number Diff line number Diff line
@@ -212,7 +212,7 @@ func IsValidSharedDependency(dependency android.Module) bool {
	return true
}

func sharedLibraryInstallLocation(
func SharedLibraryInstallLocation(
	libraryPath android.Path, isHost bool, fuzzDir string, archString string) string {
	installLocation := "$(PRODUCT_OUT)/data"
	if isHost {
@@ -224,7 +224,7 @@ func sharedLibraryInstallLocation(
}

// Get the device-only shared library symbols install directory.
func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, fuzzDir string, archString string) string {
func SharedLibrarySymbolsInstallLocation(libraryPath android.Path, fuzzDir string, archString string) string {
	return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, "/lib/", libraryPath.Base())
}

@@ -237,57 +237,62 @@ func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
		installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
	fuzzBin.binaryDecorator.baseInstaller.install(ctx, file)

	fuzzBin.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Corpus)
	fuzzBin.fuzzPackagedModule = PackageFuzzModule(ctx, fuzzBin.fuzzPackagedModule, pctx)

	// Grab the list of required shared libraries.
	fuzzBin.sharedLibraries, _ = CollectAllSharedDependencies(ctx)

	for _, lib := range fuzzBin.sharedLibraries {
		fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
			SharedLibraryInstallLocation(
				lib, ctx.Host(), installBase, ctx.Arch().ArchType.String()))

		// Also add the dependency on the shared library symbols dir.
		if !ctx.Host() {
			fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
				SharedLibrarySymbolsInstallLocation(lib, installBase, ctx.Arch().ArchType.String()))
		}
	}
}

func PackageFuzzModule(ctx android.ModuleContext, fuzzPackagedModule fuzz.FuzzPackagedModule, pctx android.PackageContext) fuzz.FuzzPackagedModule {
	fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Corpus)
	builder := android.NewRuleBuilder(pctx, ctx)
	intermediateDir := android.PathForModuleOut(ctx, "corpus")
	for _, entry := range fuzzBin.fuzzPackagedModule.Corpus {
	for _, entry := range fuzzPackagedModule.Corpus {
		builder.Command().Text("cp").
			Input(entry).
			Output(intermediateDir.Join(ctx, entry.Base()))
	}
	builder.Build("copy_corpus", "copy corpus")
	fuzzBin.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir
	fuzzPackagedModule.CorpusIntermediateDir = intermediateDir

	fuzzBin.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Data)
	fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Data)
	builder = android.NewRuleBuilder(pctx, ctx)
	intermediateDir = android.PathForModuleOut(ctx, "data")
	for _, entry := range fuzzBin.fuzzPackagedModule.Data {
	for _, entry := range fuzzPackagedModule.Data {
		builder.Command().Text("cp").
			Input(entry).
			Output(intermediateDir.Join(ctx, entry.Rel()))
	}
	builder.Build("copy_data", "copy data")
	fuzzBin.fuzzPackagedModule.DataIntermediateDir = intermediateDir
	fuzzPackagedModule.DataIntermediateDir = intermediateDir

	if fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
		fuzzBin.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary)
		if fuzzBin.fuzzPackagedModule.Dictionary.Ext() != ".dict" {
	if fuzzPackagedModule.FuzzProperties.Dictionary != nil {
		fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzPackagedModule.FuzzProperties.Dictionary)
		if fuzzPackagedModule.Dictionary.Ext() != ".dict" {
			ctx.PropertyErrorf("dictionary",
				"Fuzzer dictionary %q does not have '.dict' extension",
				fuzzBin.fuzzPackagedModule.Dictionary.String())
				fuzzPackagedModule.Dictionary.String())
		}
	}

	if fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
	if fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
		configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
		android.WriteFileRule(ctx, configPath, fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
		fuzzBin.fuzzPackagedModule.Config = configPath
	}

	// Grab the list of required shared libraries.
	fuzzBin.sharedLibraries, _ = CollectAllSharedDependencies(ctx)

	for _, lib := range fuzzBin.sharedLibraries {
		fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
			sharedLibraryInstallLocation(
				lib, ctx.Host(), installBase, ctx.Arch().ArchType.String()))

		// Also add the dependency on the shared library symbols dir.
		if !ctx.Host() {
			fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
				sharedLibrarySymbolsInstallLocation(lib, installBase, ctx.Arch().ArchType.String()))
		}
		android.WriteFileRule(ctx, configPath, fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
		fuzzPackagedModule.Config = configPath
	}
	return fuzzPackagedModule
}

func NewFuzzer(hod android.HostOrDeviceSupported) *Module {
@@ -344,7 +349,7 @@ func NewFuzzer(hod android.HostOrDeviceSupported) *Module {

// Responsible for generating GNU Make rules that package fuzz targets into
// their architecture & target/host specific zip file.
type ccFuzzPackager struct {
type ccRustFuzzPackager struct {
	fuzz.FuzzPackager
	fuzzPackagingArchModules         string
	fuzzTargetSharedDepsInstallPairs string
@@ -353,7 +358,7 @@ type ccFuzzPackager struct {

func fuzzPackagingFactory() android.Singleton {

	fuzzPackager := &ccFuzzPackager{
	fuzzPackager := &ccRustFuzzPackager{
		fuzzPackagingArchModules:         "SOONG_FUZZ_PACKAGING_ARCH_MODULES",
		fuzzTargetSharedDepsInstallPairs: "FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
		allFuzzTargetsName:               "ALL_FUZZ_TARGETS",
@@ -361,7 +366,7 @@ func fuzzPackagingFactory() android.Singleton {
	return fuzzPackager
}

func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
func (s *ccRustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
	// 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}).
@@ -376,19 +381,18 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
	sharedLibraryInstalled := make(map[string]bool)

	ctx.VisitAllModules(func(module android.Module) {
		ccModule, ok := module.(*Module)
		if !ok || ccModule.Properties.PreventInstall {
		ccModule, ok := module.(LinkableInterface)
		if !ok || ccModule.PreventInstall() {
			return
		}

		// Discard non-fuzz targets.
		if ok := fuzz.IsValid(ccModule.FuzzModule); !ok {
		if ok := fuzz.IsValid(ccModule.FuzzModuleStruct()); !ok {
			return
		}

		sharedLibsInstallDirPrefix := "lib"
		fuzzModule, ok := ccModule.compiler.(*fuzzBinary)
		if !ok {
		if !ccModule.IsFuzzModule() {
			return
		}

@@ -399,12 +403,12 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {

		fpm := fuzz.FuzzPackagedModule{}
		if ok {
			fpm = fuzzModule.fuzzPackagedModule
			fpm = ccModule.FuzzPackagedModule()
		}

		intermediatePath := "fuzz"

		archString := ccModule.Arch().ArchType.String()
		archString := ccModule.Target().Arch.ArchType.String()
		archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString)
		archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}

@@ -415,7 +419,7 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
		files = s.PackageArtifacts(ctx, module, fpm, archDir, builder)

		// Package shared libraries
		files = append(files, GetSharedLibsToZip(fuzzModule.sharedLibraries, ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
		files = append(files, GetSharedLibsToZip(ccModule.FuzzSharedLibraries(), ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)

		// The executable.
		files = append(files, fuzz.FileToZip{android.OutputFileForModule(ctx, ccModule, "unstripped"), ""})
@@ -429,7 +433,7 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
	s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx)
}

func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
func (s *ccRustFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
	packages := s.Packages.Strings()
	sort.Strings(packages)
	sort.Strings(s.FuzzPackager.SharedLibInstallStrings)
@@ -460,7 +464,7 @@ func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface,
		// 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(
		installDestination := SharedLibraryInstallLocation(
			library, module.Host(), fuzzDir, archString)
		if (*sharedLibraryInstalled)[installDestination] {
			continue
@@ -479,7 +483,7 @@ func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface,
		// we want symbolization tools (like `stack`) to be able to find the symbols
		// in $ANDROID_PRODUCT_OUT/symbols automagically.
		if !module.Host() {
			symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, fuzzDir, archString)
			symbolsInstallDestination := SharedLibrarySymbolsInstallLocation(library, fuzzDir, archString)
			symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
			s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
				library.String()+":"+symbolsInstallDestination)
+15 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ package cc
import (
	"android/soong/android"
	"android/soong/bazel/cquery"
	"android/soong/fuzz"
	"android/soong/snapshot"

	"github.com/google/blueprint"
@@ -120,6 +121,17 @@ type LinkableInterface interface {
	IsPrebuilt() bool
	Toc() android.OptionalPath

	// IsFuzzModule returns true if this a *_fuzz module.
	IsFuzzModule() bool

	// FuzzPackagedModule returns the fuzz.FuzzPackagedModule for this module.
	// Expects that IsFuzzModule returns true.
	FuzzPackagedModule() fuzz.FuzzPackagedModule

	// FuzzSharedLibraries returns the shared library dependencies for this module.
	// Expects that IsFuzzModule returns true.
	FuzzSharedLibraries() android.Paths

	Device() bool
	Host() bool

@@ -256,6 +268,9 @@ type LinkableInterface interface {

	// Partition returns the partition string for this module.
	Partition() string

	// FuzzModule returns the fuzz.FuzzModule associated with the module.
	FuzzModuleStruct() fuzz.FuzzModule
}

var (
+6 −3
Original line number Diff line number Diff line
@@ -205,8 +205,8 @@ func (compiler *baseCompiler) AndroidMk(ctx AndroidMkContext, ret *android.Andro
		})
}

func (fuzz *fuzzDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
	ctx.SubAndroidMk(entries, fuzz.binaryDecorator)
func (fuzz *fuzzDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
	ctx.SubAndroidMk(ret, fuzz.binaryDecorator)

	var fuzzFiles []string
	for _, d := range fuzz.fuzzPackagedModule.Corpus {
@@ -229,11 +229,14 @@ func (fuzz *fuzzDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *andro
			filepath.Dir(fuzz.fuzzPackagedModule.Config.String())+":config.json")
	}

	entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext,
	ret.ExtraEntries = append(ret.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext,
		entries *android.AndroidMkEntries) {
		entries.SetBool("LOCAL_IS_FUZZ_TARGET", true)
		if len(fuzzFiles) > 0 {
			entries.AddStrings("LOCAL_TEST_DATA", fuzzFiles...)
		}
		if fuzz.installedSharedDeps != nil {
			entries.AddStrings("LOCAL_FUZZ_INSTALLED_SHARED_DEPS", fuzz.installedSharedDeps...)
		}
	})
}
+27 −94
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@ package rust

import (
	"path/filepath"
	"sort"
	"strings"

	"android/soong/android"
	"android/soong/cc"
@@ -27,7 +25,6 @@ import (

func init() {
	android.RegisterModuleType("rust_fuzz", RustFuzzFactory)
	android.RegisterSingletonType("rust_fuzz_packaging", rustFuzzPackagingFactory)
}

type fuzzDecorator struct {
@@ -35,6 +32,7 @@ type fuzzDecorator struct {

	fuzzPackagedModule  fuzz.FuzzPackagedModule
	sharedLibraries     android.Paths
	installedSharedDeps []string
}

var _ compiler = (*fuzzDecorator)(nil)
@@ -64,9 +62,14 @@ func (fuzzer *fuzzDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags
	flags = fuzzer.binaryDecorator.compilerFlags(ctx, flags)

	// `../lib` for installed fuzz targets (both host and device), and `./lib` for fuzz target packages.
	flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/../lib`)
	flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/lib`)

	if ctx.InstallInVendor() {
		flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/../../lib`)
	} else {
		flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/../lib`)

	}
	return flags
}

@@ -88,10 +91,8 @@ func (fuzzer *fuzzDecorator) compilerProps() []interface{} {
}

func (fuzzer *fuzzDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
	out := fuzzer.binaryDecorator.compile(ctx, flags, deps)

	// Grab the list of required shared libraries.
	fuzzer.sharedLibraries, _ = cc.CollectAllSharedDependencies(ctx)
	out := fuzzer.binaryDecorator.compile(ctx, flags, deps)

	return out
}
@@ -104,83 +105,6 @@ func (fuzzer *fuzzDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep
	return rlibAutoDep
}

// Responsible for generating GNU Make rules that package fuzz targets into
// their architecture & target/host specific zip file.
type rustFuzzPackager struct {
	fuzz.FuzzPackager
}

func rustFuzzPackagingFactory() android.Singleton {
	return &rustFuzzPackager{}
}

func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
	// Map between each architecture + host/device combination.
	archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)

	// List of individual fuzz targets.
	s.FuzzTargets = make(map[string]bool)

	// 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)

	ctx.VisitAllModules(func(module android.Module) {
		// Discard non-fuzz targets.
		rustModule, ok := module.(*Module)
		if !ok {
			return
		}

		if ok := fuzz.IsValid(rustModule.FuzzModule); !ok || rustModule.Properties.PreventInstall {
			return
		}

		fuzzModule, ok := rustModule.compiler.(*fuzzDecorator)
		if !ok {
			return
		}

		hostOrTargetString := "target"
		if rustModule.Host() {
			hostOrTargetString = "host"
		}

		archString := rustModule.Arch().ArchType.String()
		archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
		archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}

		var files []fuzz.FileToZip
		builder := android.NewRuleBuilder(pctx, ctx)

		// Package the artifacts (data, corpus, config and dictionary into a zipfile.
		files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder)

		// The executable.
		files = append(files, fuzz.FileToZip{rustModule.UnstrippedOutputFile(), ""})

		// Package shared libraries
		files = append(files, cc.GetSharedLibsToZip(fuzzModule.sharedLibraries, rustModule, &s.FuzzPackager, archString, "lib", &sharedLibraryInstalled)...)

		archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
		if !ok {
			return
		}

	})
	s.CreateFuzzPackage(ctx, archDirs, fuzz.Rust, pctx)
}

func (s *rustFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
	packages := s.Packages.Strings()
	sort.Strings(packages)

	ctx.Strict("SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))

	// Preallocate the slice of fuzz targets to minimize memory allocations.
	s.PreallocateSlice(ctx, "ALL_RUST_FUZZ_TARGETS")
}

func (fuzz *fuzzDecorator) install(ctx ModuleContext) {
	fuzz.binaryDecorator.baseCompiler.dir = filepath.Join(
		"fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
@@ -188,13 +112,22 @@ func (fuzz *fuzzDecorator) install(ctx ModuleContext) {
		"fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
	fuzz.binaryDecorator.baseCompiler.install(ctx)

	if fuzz.fuzzPackagedModule.FuzzProperties.Corpus != nil {
		fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus)
	}
	if fuzz.fuzzPackagedModule.FuzzProperties.Data != nil {
		fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data)
	fuzz.fuzzPackagedModule = cc.PackageFuzzModule(ctx, fuzz.fuzzPackagedModule, pctx)

	installBase := "fuzz"

	// Grab the list of required shared libraries.
	fuzz.sharedLibraries, _ = cc.CollectAllSharedDependencies(ctx)

	for _, lib := range fuzz.sharedLibraries {
		fuzz.installedSharedDeps = append(fuzz.installedSharedDeps,
			cc.SharedLibraryInstallLocation(
				lib, ctx.Host(), installBase, ctx.Arch().ArchType.String()))

		// Also add the dependency on the shared library symbols dir.
		if !ctx.Host() {
			fuzz.installedSharedDeps = append(fuzz.installedSharedDeps,
				cc.SharedLibrarySymbolsInstallLocation(lib, installBase, ctx.Arch().ArchType.String()))
		}
	if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
		fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary)
	}
}
Loading