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

Commit 31d89b4e authored by Colin Cross's avatar Colin Cross
Browse files

Move fuzzer's CollectAllSharedDependencies into GenerateAndroidBuildActions

Make rust and cc fuzzers collect their shared libraries once in
GenerateAndroidBuildActions and store it for later use by the
packaging singleton.  Also use android.OutputFileForModule to get
the paths.  Together this will fix fuzzers that depend on architecture
specific prebuilt shared libraries that are missing a prebuilt for an
architecture when building with AllowMissingDependencies.

Bug: 250918230
Test: lunch aosp_riscv64-userdebug && m ALLOW_MISSING_DEPENDENCIES=true nothing
Change-Id: I154a6f3a767c883e9fe7067003615db73ee78e2d
parent 553a31be
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -3330,6 +3330,11 @@ func (c *Module) OutputFiles(tag string) (android.Paths, error) {
			return android.Paths{c.outputFile.Path()}, nil
		}
		return android.Paths{}, nil
	case "unstripped":
		if c.linker != nil {
			return android.PathsIfNonNil(c.linker.unstrippedOutputFilePath()), nil
		}
		return nil, nil
	default:
		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
	}
+48 −27
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ type fuzzBinary struct {
	*baseCompiler
	fuzzPackagedModule  fuzz.FuzzPackagedModule
	installedSharedDeps []string
	sharedLibraries     android.Paths
}

func (fuzz *fuzzBinary) fuzzBinary() bool {
@@ -142,13 +143,6 @@ func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
	return flags
}

func UnstrippedOutputFile(module android.Module) android.Path {
	if mod, ok := module.(LinkableInterface); ok {
		return mod.UnstrippedOutputFile()
	}
	panic("UnstrippedOutputFile called on non-LinkableInterface module: " + module.Name())
}

// IsValidSharedDependency takes a module and determines if it is a unique shared library
// that should be installed in the fuzz target output directories. This function
// returns true, unless:
@@ -270,22 +264,9 @@ func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
	}

	// Grab the list of required shared libraries.
	seen := make(map[string]bool)
	var sharedLibraries android.Paths
	ctx.WalkDeps(func(child, parent android.Module) bool {
		if seen[child.Name()] {
			return false
		}
		seen[child.Name()] = true
	fuzzBin.sharedLibraries = CollectAllSharedDependencies(ctx)

		if IsValidSharedDependency(child) {
			sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
			return true
		}
		return false
	})

	for _, lib := range sharedLibraries {
	for _, lib := range fuzzBin.sharedLibraries {
		fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
			sharedLibraryInstallLocation(
				lib, ctx.Host(), installBase, ctx.Arch().ArchType.String()))
@@ -412,9 +393,6 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
		archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString)
		archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}

		// Grab the list of required shared libraries.
		sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, UnstrippedOutputFile, IsValidSharedDependency)

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

@@ -422,10 +400,10 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
		files = s.PackageArtifacts(ctx, module, fpm, archDir, builder)

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

		// The executable.
		files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""})
		files = append(files, fuzz.FileToZip{android.OutputFileForModule(ctx, ccModule, "unstripped"), ""})

		archDirs[archOs], ok = s.BuildZipFile(ctx, module, fpm, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
		if !ok {
@@ -494,3 +472,46 @@ func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface,
	}
	return files
}

// CollectAllSharedDependencies search over the provided module's dependencies using
// VisitDirectDeps and WalkDeps to enumerate all shared library dependencies.
// 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.Paths {
	seen := make(map[string]bool)
	recursed := make(map[string]bool)

	var sharedLibraries android.Paths

	// Enumerate the first level of dependencies, as we discard all non-library
	// modules in the BFS loop below.
	ctx.VisitDirectDeps(func(dep android.Module) {
		if !IsValidSharedDependency(dep) {
			return
		}
		if seen[ctx.OtherModuleName(dep)] {
			return
		}
		seen[ctx.OtherModuleName(dep)] = true
		sharedLibraries = append(sharedLibraries, android.OutputFileForModule(ctx, dep, "unstripped"))
	})

	ctx.WalkDeps(func(child, parent android.Module) bool {
		if !IsValidSharedDependency(child) {
			return false
		}
		if !seen[ctx.OtherModuleName(child)] {
			seen[ctx.OtherModuleName(child)] = true
			sharedLibraries = append(sharedLibraries, android.OutputFileForModule(ctx, child, "unstripped"))
		}

		if recursed[ctx.OtherModuleName(child)] {
			return false
		}
		recursed[ctx.OtherModuleName(child)] = true
		return true
	})

	return sharedLibraries
}
+0 −39
Original line number Diff line number Diff line
@@ -379,42 +379,3 @@ func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets str
	sort.Strings(fuzzTargets)
	ctx.Strict(targets, strings.Join(fuzzTargets, " "))
}

// CollectAllSharedDependencies performs a breadth-first search over the provided module's
// dependencies using `visitDirectDeps` to enumerate all shared library
// dependencies. We require breadth-first expansion, as otherwise we may
// incorrectly use 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.SingletonContext, module android.Module, unstrippedOutputFile func(module android.Module) android.Path, isValidSharedDependency func(dependency android.Module) bool) android.Paths {
	var fringe []android.Module

	seen := make(map[string]bool)

	// Enumerate the first level of dependencies, as we discard all non-library
	// modules in the BFS loop below.
	ctx.VisitDirectDeps(module, func(dep android.Module) {
		if isValidSharedDependency(dep) {
			fringe = append(fringe, dep)
		}
	})

	var sharedLibraries android.Paths

	for i := 0; i < len(fringe); i++ {
		module := fringe[i]
		if seen[module.Name()] {
			continue
		}
		seen[module.Name()] = true

		sharedLibraries = append(sharedLibraries, unstrippedOutputFile(module))
		ctx.VisitDirectDeps(module, func(dep android.Module) {
			if isValidSharedDependency(dep) && !seen[dep.Name()] {
				fringe = append(fringe, dep)
			}
		})
	}

	return sharedLibraries
}
+11 −4
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ type fuzzDecorator struct {
	*binaryDecorator

	fuzzPackagedModule fuzz.FuzzPackagedModule
	sharedLibraries    android.Paths
}

var _ compiler = (*fuzzDecorator)(nil)
@@ -86,6 +87,15 @@ func (fuzzer *fuzzDecorator) compilerProps() []interface{} {
		&fuzzer.fuzzPackagedModule.FuzzProperties)
}

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)

	return out
}

func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage {
	return RlibLinkage
}
@@ -149,11 +159,8 @@ func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
		// The executable.
		files = append(files, fuzz.FileToZip{rustModule.UnstrippedOutputFile(), ""})

		// Grab the list of required shared libraries.
		sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, cc.UnstrippedOutputFile, cc.IsValidSharedDependency)

		// Package shared libraries
		files = append(files, cc.GetSharedLibsToZip(sharedLibraries, rustModule, &s.FuzzPackager, archString, "lib", &sharedLibraryInstalled)...)
		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 {