Merge "Make fuzz rules reproducible"
This commit is contained in:
85
cc/fuzz.go
85
cc/fuzz.go
@@ -117,45 +117,46 @@ func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
|
// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
|
||||||
// from a dependency. This may cause issues when dependencies have explicit
|
// from a dependency. This may cause issues when dependencies have explicit
|
||||||
// sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
|
// sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
|
||||||
func collectAllSharedDependencies(
|
func collectAllSharedDependencies(ctx android.SingletonContext, module android.Module) android.Paths {
|
||||||
module android.Module,
|
|
||||||
sharedDeps map[string]android.Path,
|
|
||||||
ctx android.SingletonContext) {
|
|
||||||
var fringe []android.Module
|
var fringe []android.Module
|
||||||
|
|
||||||
|
seen := make(map[android.Module]bool)
|
||||||
|
|
||||||
// Enumerate the first level of dependencies, as we discard all non-library
|
// Enumerate the first level of dependencies, as we discard all non-library
|
||||||
// modules in the BFS loop below.
|
// modules in the BFS loop below.
|
||||||
ctx.VisitDirectDeps(module, func(dep android.Module) {
|
ctx.VisitDirectDeps(module, func(dep android.Module) {
|
||||||
if isValidSharedDependency(dep, sharedDeps) {
|
if isValidSharedDependency(dep) {
|
||||||
fringe = append(fringe, dep)
|
fringe = append(fringe, dep)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var sharedLibraries android.Paths
|
||||||
|
|
||||||
for i := 0; i < len(fringe); i++ {
|
for i := 0; i < len(fringe); i++ {
|
||||||
module := fringe[i]
|
module := fringe[i]
|
||||||
if _, exists := sharedDeps[module.Name()]; exists {
|
if seen[module] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
seen[module] = true
|
||||||
|
|
||||||
ccModule := module.(*Module)
|
ccModule := module.(*Module)
|
||||||
sharedDeps[ccModule.Name()] = ccModule.UnstrippedOutputFile()
|
sharedLibraries = append(sharedLibraries, ccModule.UnstrippedOutputFile())
|
||||||
ctx.VisitDirectDeps(module, func(dep android.Module) {
|
ctx.VisitDirectDeps(module, func(dep android.Module) {
|
||||||
if isValidSharedDependency(dep, sharedDeps) {
|
if isValidSharedDependency(dep) && !seen[dep] {
|
||||||
fringe = append(fringe, dep)
|
fringe = append(fringe, dep)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sharedLibraries
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function takes a module and determines if it is a unique shared library
|
// This function takes a module and determines if it is a unique shared library
|
||||||
// that should be installed in the fuzz target output directories. This function
|
// that should be installed in the fuzz target output directories. This function
|
||||||
// returns true, unless:
|
// returns true, unless:
|
||||||
// - The module already exists in `sharedDeps`, or
|
|
||||||
// - The module is not a shared library, or
|
// - The module is not a shared library, or
|
||||||
// - The module is a header, stub, or vendor-linked library.
|
// - The module is a header, stub, or vendor-linked library.
|
||||||
func isValidSharedDependency(
|
func isValidSharedDependency(dependency android.Module) bool {
|
||||||
dependency android.Module,
|
|
||||||
sharedDeps map[string]android.Path) bool {
|
|
||||||
// TODO(b/144090547): We should be parsing these modules using
|
// TODO(b/144090547): We should be parsing these modules using
|
||||||
// ModuleDependencyTag instead of the current brute-force checking.
|
// ModuleDependencyTag instead of the current brute-force checking.
|
||||||
|
|
||||||
@@ -177,10 +178,6 @@ func isValidSharedDependency(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this library has already been traversed, we don't need to do any more work.
|
|
||||||
if _, exists := sharedDeps[dependency.Name()]; exists {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,10 +233,16 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab the list of required shared libraries.
|
// Grab the list of required shared libraries.
|
||||||
sharedLibraries := make(map[string]android.Path)
|
seen := make(map[android.Module]bool)
|
||||||
|
var sharedLibraries android.Paths
|
||||||
ctx.WalkDeps(func(child, parent android.Module) bool {
|
ctx.WalkDeps(func(child, parent android.Module) bool {
|
||||||
if isValidSharedDependency(child, sharedLibraries) {
|
if seen[child] {
|
||||||
sharedLibraries[child.Name()] = child.(*Module).UnstrippedOutputFile()
|
return false
|
||||||
|
}
|
||||||
|
seen[child] = true
|
||||||
|
|
||||||
|
if isValidSharedDependency(child) {
|
||||||
|
sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -250,8 +253,6 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) {
|
|||||||
sharedLibraryInstallLocation(
|
sharedLibraryInstallLocation(
|
||||||
lib, ctx.Host(), ctx.Arch().ArchType.String()))
|
lib, ctx.Host(), ctx.Arch().ArchType.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(fuzz.installedSharedDeps)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFuzz(hod android.HostOrDeviceSupported) *Module {
|
func NewFuzz(hod android.HostOrDeviceSupported) *Module {
|
||||||
@@ -305,19 +306,21 @@ type fileToZip struct {
|
|||||||
DestinationPathPrefix string
|
DestinationPathPrefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
type archAndLibraryKey struct {
|
type archOs struct {
|
||||||
ArchDir android.OutputPath
|
hostOrTarget string
|
||||||
Library android.Path
|
arch string
|
||||||
|
dir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
|
func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
|
||||||
// Map between each architecture + host/device combination, and the files that
|
// Map between each architecture + host/device combination, and the files that
|
||||||
// need to be packaged (in the tuple of {source file, destination folder in
|
// need to be packaged (in the tuple of {source file, destination folder in
|
||||||
// archive}).
|
// archive}).
|
||||||
archDirs := make(map[android.OutputPath][]fileToZip)
|
archDirs := make(map[archOs][]fileToZip)
|
||||||
|
|
||||||
// List of shared library dependencies for each architecture + host/device combo.
|
// Map tracking whether each shared library has an install rule to avoid duplicate install rules from
|
||||||
archSharedLibraryDeps := make(map[archAndLibraryKey]bool)
|
// multiple fuzzers that depend on the same shared library.
|
||||||
|
sharedLibraryInstalled := make(map[string]bool)
|
||||||
|
|
||||||
// List of individual fuzz targets, so that 'make fuzz' also installs the targets
|
// List of individual fuzz targets, so that 'make fuzz' also installs the targets
|
||||||
// to the correct output directories as well.
|
// to the correct output directories as well.
|
||||||
@@ -351,10 +354,10 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
|
|
||||||
archString := ccModule.Arch().ArchType.String()
|
archString := ccModule.Arch().ArchType.String()
|
||||||
archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
|
archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
|
||||||
|
archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()}
|
||||||
|
|
||||||
// Grab the list of required shared libraries.
|
// Grab the list of required shared libraries.
|
||||||
sharedLibraries := make(map[string]android.Path)
|
sharedLibraries := collectAllSharedDependencies(ctx, module)
|
||||||
collectAllSharedDependencies(module, sharedLibraries, ctx)
|
|
||||||
|
|
||||||
var files []fileToZip
|
var files []fileToZip
|
||||||
builder := android.NewRuleBuilder()
|
builder := android.NewRuleBuilder()
|
||||||
@@ -374,16 +377,15 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
for _, library := range sharedLibraries {
|
for _, library := range sharedLibraries {
|
||||||
files = append(files, fileToZip{library, "lib"})
|
files = append(files, fileToZip{library, "lib"})
|
||||||
|
|
||||||
if _, exists := archSharedLibraryDeps[archAndLibraryKey{archDir, library}]; exists {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each architecture-specific shared library dependency, we need to
|
// For each architecture-specific shared library dependency, we need to
|
||||||
// install it to the output directory. Setup the install destination here,
|
// install it to the output directory. Setup the install destination here,
|
||||||
// which will be used by $(copy-many-files) in the Make backend.
|
// which will be used by $(copy-many-files) in the Make backend.
|
||||||
archSharedLibraryDeps[archAndLibraryKey{archDir, library}] = true
|
|
||||||
installDestination := sharedLibraryInstallLocation(
|
installDestination := sharedLibraryInstallLocation(
|
||||||
library, ccModule.Host(), archString)
|
library, ccModule.Host(), archString)
|
||||||
|
if sharedLibraryInstalled[installDestination] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sharedLibraryInstalled[installDestination] = true
|
||||||
// Escape all the variables, as the install destination here will be called
|
// Escape all the variables, as the install destination here will be called
|
||||||
// via. $(eval) in Make.
|
// via. $(eval) in Make.
|
||||||
installDestination = strings.ReplaceAll(
|
installDestination = strings.ReplaceAll(
|
||||||
@@ -421,12 +423,19 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
builder.Build(pctx, ctx, "create-"+fuzzZip.String(),
|
builder.Build(pctx, ctx, "create-"+fuzzZip.String(),
|
||||||
"Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
|
"Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
|
||||||
|
|
||||||
archDirs[archDir] = append(archDirs[archDir], fileToZip{fuzzZip, ""})
|
archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""})
|
||||||
})
|
})
|
||||||
|
|
||||||
for archDir, filesToZip := range archDirs {
|
var archOsList []archOs
|
||||||
arch := archDir.Base()
|
for archOs := range archDirs {
|
||||||
hostOrTarget := filepath.Base(filepath.Dir(archDir.String()))
|
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()
|
builder := android.NewRuleBuilder()
|
||||||
outputFile := android.PathForOutput(ctx, "fuzz-"+hostOrTarget+"-"+arch+".zip")
|
outputFile := android.PathForOutput(ctx, "fuzz-"+hostOrTarget+"-"+arch+".zip")
|
||||||
s.packages = append(s.packages, outputFile)
|
s.packages = append(s.packages, outputFile)
|
||||||
|
Reference in New Issue
Block a user