xref: /aosp_15_r20/build/soong/cc/fuzz.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2016 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage cc
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
19*333d2b36SAndroid Build Coastguard Worker	"sort"
20*333d2b36SAndroid Build Coastguard Worker	"strings"
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
25*333d2b36SAndroid Build Coastguard Worker	"android/soong/cc/config"
26*333d2b36SAndroid Build Coastguard Worker	"android/soong/fuzz"
27*333d2b36SAndroid Build Coastguard Worker)
28*333d2b36SAndroid Build Coastguard Worker
29*333d2b36SAndroid Build Coastguard Workerfunc init() {
30*333d2b36SAndroid Build Coastguard Worker	android.RegisterModuleType("cc_fuzz", LibFuzzFactory)
31*333d2b36SAndroid Build Coastguard Worker	android.RegisterParallelSingletonType("cc_fuzz_packaging", fuzzPackagingFactory)
32*333d2b36SAndroid Build Coastguard Worker	android.RegisterParallelSingletonType("cc_fuzz_presubmit_packaging", fuzzPackagingFactoryPresubmit)
33*333d2b36SAndroid Build Coastguard Worker}
34*333d2b36SAndroid Build Coastguard Worker
35*333d2b36SAndroid Build Coastguard Workertype FuzzProperties struct {
36*333d2b36SAndroid Build Coastguard Worker	FuzzFramework fuzz.Framework `blueprint:"mutated"`
37*333d2b36SAndroid Build Coastguard Worker}
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Workertype fuzzer struct {
40*333d2b36SAndroid Build Coastguard Worker	Properties FuzzProperties
41*333d2b36SAndroid Build Coastguard Worker}
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Workerfunc (fuzzer *fuzzer) flags(ctx ModuleContext, flags Flags) Flags {
44*333d2b36SAndroid Build Coastguard Worker	if fuzzer.Properties.FuzzFramework == fuzz.AFL {
45*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, []string{
46*333d2b36SAndroid Build Coastguard Worker			"-fsanitize-coverage=trace-pc-guard",
47*333d2b36SAndroid Build Coastguard Worker			"-Wno-unused-result",
48*333d2b36SAndroid Build Coastguard Worker			"-Wno-unused-parameter",
49*333d2b36SAndroid Build Coastguard Worker			"-Wno-unused-function",
50*333d2b36SAndroid Build Coastguard Worker		}...)
51*333d2b36SAndroid Build Coastguard Worker	}
52*333d2b36SAndroid Build Coastguard Worker
53*333d2b36SAndroid Build Coastguard Worker	return flags
54*333d2b36SAndroid Build Coastguard Worker}
55*333d2b36SAndroid Build Coastguard Worker
56*333d2b36SAndroid Build Coastguard Workerfunc (fuzzer *fuzzer) props() []interface{} {
57*333d2b36SAndroid Build Coastguard Worker	return []interface{}{&fuzzer.Properties}
58*333d2b36SAndroid Build Coastguard Worker}
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Worker// fuzzTransitionMutator creates variants to propagate the FuzzFramework value down to dependencies.
61*333d2b36SAndroid Build Coastguard Workertype fuzzTransitionMutator struct{}
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Workerfunc (f *fuzzTransitionMutator) Split(ctx android.BaseModuleContext) []string {
64*333d2b36SAndroid Build Coastguard Worker	return []string{""}
65*333d2b36SAndroid Build Coastguard Worker}
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Workerfunc (f *fuzzTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
68*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(*Module)
69*333d2b36SAndroid Build Coastguard Worker	if !ok {
70*333d2b36SAndroid Build Coastguard Worker		return ""
71*333d2b36SAndroid Build Coastguard Worker	}
72*333d2b36SAndroid Build Coastguard Worker
73*333d2b36SAndroid Build Coastguard Worker	if m.fuzzer == nil {
74*333d2b36SAndroid Build Coastguard Worker		return ""
75*333d2b36SAndroid Build Coastguard Worker	}
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Worker	if m.sanitize == nil {
78*333d2b36SAndroid Build Coastguard Worker		return ""
79*333d2b36SAndroid Build Coastguard Worker	}
80*333d2b36SAndroid Build Coastguard Worker
81*333d2b36SAndroid Build Coastguard Worker	isFuzzerPointer := m.sanitize.getSanitizerBoolPtr(Fuzzer)
82*333d2b36SAndroid Build Coastguard Worker	if isFuzzerPointer == nil || !*isFuzzerPointer {
83*333d2b36SAndroid Build Coastguard Worker		return ""
84*333d2b36SAndroid Build Coastguard Worker	}
85*333d2b36SAndroid Build Coastguard Worker
86*333d2b36SAndroid Build Coastguard Worker	if m.fuzzer.Properties.FuzzFramework != "" {
87*333d2b36SAndroid Build Coastguard Worker		return m.fuzzer.Properties.FuzzFramework.Variant()
88*333d2b36SAndroid Build Coastguard Worker	}
89*333d2b36SAndroid Build Coastguard Worker
90*333d2b36SAndroid Build Coastguard Worker	return sourceVariation
91*333d2b36SAndroid Build Coastguard Worker}
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Workerfunc (f *fuzzTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
94*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(*Module)
95*333d2b36SAndroid Build Coastguard Worker	if !ok {
96*333d2b36SAndroid Build Coastguard Worker		return ""
97*333d2b36SAndroid Build Coastguard Worker	}
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Worker	if m.fuzzer == nil {
100*333d2b36SAndroid Build Coastguard Worker		return ""
101*333d2b36SAndroid Build Coastguard Worker	}
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Worker	if m.sanitize == nil {
104*333d2b36SAndroid Build Coastguard Worker		return ""
105*333d2b36SAndroid Build Coastguard Worker	}
106*333d2b36SAndroid Build Coastguard Worker
107*333d2b36SAndroid Build Coastguard Worker	isFuzzerPointer := m.sanitize.getSanitizerBoolPtr(Fuzzer)
108*333d2b36SAndroid Build Coastguard Worker	if isFuzzerPointer == nil || !*isFuzzerPointer {
109*333d2b36SAndroid Build Coastguard Worker		return ""
110*333d2b36SAndroid Build Coastguard Worker	}
111*333d2b36SAndroid Build Coastguard Worker
112*333d2b36SAndroid Build Coastguard Worker	return incomingVariation
113*333d2b36SAndroid Build Coastguard Worker}
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Workerfunc (f *fuzzTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
116*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(*Module)
117*333d2b36SAndroid Build Coastguard Worker	if !ok {
118*333d2b36SAndroid Build Coastguard Worker		return
119*333d2b36SAndroid Build Coastguard Worker	}
120*333d2b36SAndroid Build Coastguard Worker
121*333d2b36SAndroid Build Coastguard Worker	if m.fuzzer == nil {
122*333d2b36SAndroid Build Coastguard Worker		return
123*333d2b36SAndroid Build Coastguard Worker	}
124*333d2b36SAndroid Build Coastguard Worker
125*333d2b36SAndroid Build Coastguard Worker	if variation != "" {
126*333d2b36SAndroid Build Coastguard Worker		m.fuzzer.Properties.FuzzFramework = fuzz.FrameworkFromVariant(variation)
127*333d2b36SAndroid Build Coastguard Worker		m.SetHideFromMake()
128*333d2b36SAndroid Build Coastguard Worker		m.SetPreventInstall()
129*333d2b36SAndroid Build Coastguard Worker	}
130*333d2b36SAndroid Build Coastguard Worker}
131*333d2b36SAndroid Build Coastguard Worker
132*333d2b36SAndroid Build Coastguard Worker// cc_fuzz creates a host/device fuzzer binary. Host binaries can be found at
133*333d2b36SAndroid Build Coastguard Worker// $ANDROID_HOST_OUT/fuzz/, and device binaries can be found at /data/fuzz on
134*333d2b36SAndroid Build Coastguard Worker// your device, or $ANDROID_PRODUCT_OUT/data/fuzz in your build tree.
135*333d2b36SAndroid Build Coastguard Workerfunc LibFuzzFactory() android.Module {
136*333d2b36SAndroid Build Coastguard Worker	module := NewFuzzer(android.HostAndDeviceSupported)
137*333d2b36SAndroid Build Coastguard Worker	module.testModule = true
138*333d2b36SAndroid Build Coastguard Worker	return module.Init()
139*333d2b36SAndroid Build Coastguard Worker}
140*333d2b36SAndroid Build Coastguard Worker
141*333d2b36SAndroid Build Coastguard Workertype fuzzBinary struct {
142*333d2b36SAndroid Build Coastguard Worker	*binaryDecorator
143*333d2b36SAndroid Build Coastguard Worker	*baseCompiler
144*333d2b36SAndroid Build Coastguard Worker	fuzzPackagedModule  fuzz.FuzzPackagedModule
145*333d2b36SAndroid Build Coastguard Worker	installedSharedDeps []string
146*333d2b36SAndroid Build Coastguard Worker	sharedLibraries     android.RuleBuilderInstalls
147*333d2b36SAndroid Build Coastguard Worker	data                []android.DataPath
148*333d2b36SAndroid Build Coastguard Worker}
149*333d2b36SAndroid Build Coastguard Worker
150*333d2b36SAndroid Build Coastguard Workerfunc (fuzz *fuzzBinary) fuzzBinary() bool {
151*333d2b36SAndroid Build Coastguard Worker	return true
152*333d2b36SAndroid Build Coastguard Worker}
153*333d2b36SAndroid Build Coastguard Worker
154*333d2b36SAndroid Build Coastguard Workerfunc (fuzz *fuzzBinary) linkerProps() []interface{} {
155*333d2b36SAndroid Build Coastguard Worker	props := fuzz.binaryDecorator.linkerProps()
156*333d2b36SAndroid Build Coastguard Worker	props = append(props, &fuzz.fuzzPackagedModule.FuzzProperties)
157*333d2b36SAndroid Build Coastguard Worker
158*333d2b36SAndroid Build Coastguard Worker	return props
159*333d2b36SAndroid Build Coastguard Worker}
160*333d2b36SAndroid Build Coastguard Worker
161*333d2b36SAndroid Build Coastguard Workerfunc (fuzz *fuzzBinary) linkerInit(ctx BaseModuleContext) {
162*333d2b36SAndroid Build Coastguard Worker	fuzz.binaryDecorator.linkerInit(ctx)
163*333d2b36SAndroid Build Coastguard Worker}
164*333d2b36SAndroid Build Coastguard Worker
165*333d2b36SAndroid Build Coastguard Workerfunc (fuzzBin *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
166*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().Getenv("FUZZ_FRAMEWORK") == "AFL" {
167*333d2b36SAndroid Build Coastguard Worker		deps.HeaderLibs = append(deps.HeaderLibs, "libafl_headers")
168*333d2b36SAndroid Build Coastguard Worker	} else {
169*333d2b36SAndroid Build Coastguard Worker		deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary())
170*333d2b36SAndroid Build Coastguard Worker		// Fuzzers built with HWASAN should use the interceptors for better
171*333d2b36SAndroid Build Coastguard Worker		// mutation based on signals in strcmp, memcpy, etc. This is only needed for
172*333d2b36SAndroid Build Coastguard Worker		// fuzz targets, not generic HWASAN-ified binaries or libraries.
173*333d2b36SAndroid Build Coastguard Worker		if module, ok := ctx.Module().(*Module); ok {
174*333d2b36SAndroid Build Coastguard Worker			if module.IsSanitizerEnabled(Hwasan) {
175*333d2b36SAndroid Build Coastguard Worker				deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeInterceptors())
176*333d2b36SAndroid Build Coastguard Worker			}
177*333d2b36SAndroid Build Coastguard Worker		}
178*333d2b36SAndroid Build Coastguard Worker	}
179*333d2b36SAndroid Build Coastguard Worker
180*333d2b36SAndroid Build Coastguard Worker	deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps)
181*333d2b36SAndroid Build Coastguard Worker	return deps
182*333d2b36SAndroid Build Coastguard Worker}
183*333d2b36SAndroid Build Coastguard Worker
184*333d2b36SAndroid Build Coastguard Workerfunc (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
185*333d2b36SAndroid Build Coastguard Worker	subdir := "lib"
186*333d2b36SAndroid Build Coastguard Worker	if ctx.inVendor() {
187*333d2b36SAndroid Build Coastguard Worker		subdir = "lib/vendor"
188*333d2b36SAndroid Build Coastguard Worker	}
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard Worker	flags = fuzz.binaryDecorator.linkerFlags(ctx, flags)
191*333d2b36SAndroid Build Coastguard Worker	// RunPaths on devices isn't instantiated by the base linker. `../lib` for
192*333d2b36SAndroid Build Coastguard Worker	// installed fuzz targets (both host and device), and `./lib` for fuzz
193*333d2b36SAndroid Build Coastguard Worker	// target packages.
194*333d2b36SAndroid Build Coastguard Worker	flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/`+subdir)
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Worker	// When running on device, fuzz targets with vendor: true set will be in
197*333d2b36SAndroid Build Coastguard Worker	// fuzzer_name/vendor/fuzzer_name (note the extra 'vendor' and thus need to
198*333d2b36SAndroid Build Coastguard Worker	// link with libraries in ../../lib/. Non-vendor binaries only need to look
199*333d2b36SAndroid Build Coastguard Worker	// one level up, in ../lib/.
200*333d2b36SAndroid Build Coastguard Worker	if ctx.inVendor() {
201*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../../`+subdir)
202*333d2b36SAndroid Build Coastguard Worker	} else {
203*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../`+subdir)
204*333d2b36SAndroid Build Coastguard Worker	}
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Worker	return flags
207*333d2b36SAndroid Build Coastguard Worker}
208*333d2b36SAndroid Build Coastguard Worker
209*333d2b36SAndroid Build Coastguard Workerfunc (fuzz *fuzzBinary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
210*333d2b36SAndroid Build Coastguard Worker	fuzz.binaryDecorator.moduleInfoJSON(ctx, moduleInfoJSON)
211*333d2b36SAndroid Build Coastguard Worker	moduleInfoJSON.Class = []string{"EXECUTABLES"}
212*333d2b36SAndroid Build Coastguard Worker}
213*333d2b36SAndroid Build Coastguard Worker
214*333d2b36SAndroid Build Coastguard Worker// IsValidSharedDependency takes a module and determines if it is a unique shared library
215*333d2b36SAndroid Build Coastguard Worker// that should be installed in the fuzz target output directories. This function
216*333d2b36SAndroid Build Coastguard Worker// returns true, unless:
217*333d2b36SAndroid Build Coastguard Worker//   - The module is not an installable shared library, or
218*333d2b36SAndroid Build Coastguard Worker//   - The module is a header or stub, or
219*333d2b36SAndroid Build Coastguard Worker//   - The module is a prebuilt and its source is available, or
220*333d2b36SAndroid Build Coastguard Worker//   - The module is a versioned member of an SDK snapshot.
221*333d2b36SAndroid Build Coastguard Workerfunc IsValidSharedDependency(dependency android.Module) bool {
222*333d2b36SAndroid Build Coastguard Worker	// TODO(b/144090547): We should be parsing these modules using
223*333d2b36SAndroid Build Coastguard Worker	// ModuleDependencyTag instead of the current brute-force checking.
224*333d2b36SAndroid Build Coastguard Worker
225*333d2b36SAndroid Build Coastguard Worker	linkable, ok := dependency.(LinkableInterface)
226*333d2b36SAndroid Build Coastguard Worker	if !ok || !linkable.CcLibraryInterface() {
227*333d2b36SAndroid Build Coastguard Worker		// Discard non-linkables.
228*333d2b36SAndroid Build Coastguard Worker		return false
229*333d2b36SAndroid Build Coastguard Worker	}
230*333d2b36SAndroid Build Coastguard Worker
231*333d2b36SAndroid Build Coastguard Worker	if !linkable.Shared() {
232*333d2b36SAndroid Build Coastguard Worker		// Discard static libs.
233*333d2b36SAndroid Build Coastguard Worker		return false
234*333d2b36SAndroid Build Coastguard Worker	}
235*333d2b36SAndroid Build Coastguard Worker
236*333d2b36SAndroid Build Coastguard Worker	if lib := moduleLibraryInterface(dependency); lib != nil && lib.buildStubs() && linkable.CcLibrary() {
237*333d2b36SAndroid Build Coastguard Worker		// Discard stubs libs (only CCLibrary variants). Prebuilt libraries should not
238*333d2b36SAndroid Build Coastguard Worker		// be excluded on the basis of they're not CCLibrary()'s.
239*333d2b36SAndroid Build Coastguard Worker		return false
240*333d2b36SAndroid Build Coastguard Worker	}
241*333d2b36SAndroid Build Coastguard Worker
242*333d2b36SAndroid Build Coastguard Worker	// We discarded module stubs libraries above, but the LLNDK prebuilts stubs
243*333d2b36SAndroid Build Coastguard Worker	// libraries must be handled differently - by looking for the stubDecorator.
244*333d2b36SAndroid Build Coastguard Worker	// Discard LLNDK prebuilts stubs as well.
245*333d2b36SAndroid Build Coastguard Worker	if ccLibrary, isCcLibrary := dependency.(*Module); isCcLibrary {
246*333d2b36SAndroid Build Coastguard Worker		if _, isLLndkStubLibrary := ccLibrary.linker.(*stubDecorator); isLLndkStubLibrary {
247*333d2b36SAndroid Build Coastguard Worker			return false
248*333d2b36SAndroid Build Coastguard Worker		}
249*333d2b36SAndroid Build Coastguard Worker		// Discard installable:false libraries because they are expected to be absent
250*333d2b36SAndroid Build Coastguard Worker		// in runtime.
251*333d2b36SAndroid Build Coastguard Worker		if !proptools.BoolDefault(ccLibrary.Installable(), true) {
252*333d2b36SAndroid Build Coastguard Worker			return false
253*333d2b36SAndroid Build Coastguard Worker		}
254*333d2b36SAndroid Build Coastguard Worker	}
255*333d2b36SAndroid Build Coastguard Worker
256*333d2b36SAndroid Build Coastguard Worker	// If the same library is present both as source and a prebuilt we must pick
257*333d2b36SAndroid Build Coastguard Worker	// only one to avoid a conflict. Always prefer the source since the prebuilt
258*333d2b36SAndroid Build Coastguard Worker	// probably won't be built with sanitizers enabled.
259*333d2b36SAndroid Build Coastguard Worker	if prebuilt := android.GetEmbeddedPrebuilt(dependency); prebuilt != nil && prebuilt.SourceExists() {
260*333d2b36SAndroid Build Coastguard Worker		return false
261*333d2b36SAndroid Build Coastguard Worker	}
262*333d2b36SAndroid Build Coastguard Worker
263*333d2b36SAndroid Build Coastguard Worker	return true
264*333d2b36SAndroid Build Coastguard Worker}
265*333d2b36SAndroid Build Coastguard Worker
266*333d2b36SAndroid Build Coastguard Workerfunc SharedLibraryInstallLocation(
267*333d2b36SAndroid Build Coastguard Worker	libraryBase string, isHost bool, isVendor bool, fuzzDir string, archString string) string {
268*333d2b36SAndroid Build Coastguard Worker	installLocation := "$(PRODUCT_OUT)/data"
269*333d2b36SAndroid Build Coastguard Worker	if isHost {
270*333d2b36SAndroid Build Coastguard Worker		installLocation = "$(HOST_OUT)"
271*333d2b36SAndroid Build Coastguard Worker	}
272*333d2b36SAndroid Build Coastguard Worker	subdir := "lib"
273*333d2b36SAndroid Build Coastguard Worker	if isVendor {
274*333d2b36SAndroid Build Coastguard Worker		subdir = "lib/vendor"
275*333d2b36SAndroid Build Coastguard Worker	}
276*333d2b36SAndroid Build Coastguard Worker	installLocation = filepath.Join(
277*333d2b36SAndroid Build Coastguard Worker		installLocation, fuzzDir, archString, subdir, libraryBase)
278*333d2b36SAndroid Build Coastguard Worker	return installLocation
279*333d2b36SAndroid Build Coastguard Worker}
280*333d2b36SAndroid Build Coastguard Worker
281*333d2b36SAndroid Build Coastguard Worker// Get the device-only shared library symbols install directory.
282*333d2b36SAndroid Build Coastguard Workerfunc SharedLibrarySymbolsInstallLocation(libraryBase string, isVendor bool, fuzzDir string, archString string) string {
283*333d2b36SAndroid Build Coastguard Worker	subdir := "lib"
284*333d2b36SAndroid Build Coastguard Worker	if isVendor {
285*333d2b36SAndroid Build Coastguard Worker		subdir = "lib/vendor"
286*333d2b36SAndroid Build Coastguard Worker	}
287*333d2b36SAndroid Build Coastguard Worker	return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, subdir, libraryBase)
288*333d2b36SAndroid Build Coastguard Worker}
289*333d2b36SAndroid Build Coastguard Worker
290*333d2b36SAndroid Build Coastguard Workerfunc (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
291*333d2b36SAndroid Build Coastguard Worker	fuzzBin.fuzzPackagedModule = PackageFuzzModule(ctx, fuzzBin.fuzzPackagedModule, pctx)
292*333d2b36SAndroid Build Coastguard Worker
293*333d2b36SAndroid Build Coastguard Worker	installBase := "fuzz"
294*333d2b36SAndroid Build Coastguard Worker
295*333d2b36SAndroid Build Coastguard Worker	// Grab the list of required shared libraries.
296*333d2b36SAndroid Build Coastguard Worker	fuzzBin.sharedLibraries, _ = CollectAllSharedDependencies(ctx)
297*333d2b36SAndroid Build Coastguard Worker
298*333d2b36SAndroid Build Coastguard Worker	// TODO: does not mirror Android linkernamespaces
299*333d2b36SAndroid Build Coastguard Worker	// the logic here has special cases for vendor, but it would need more work to
300*333d2b36SAndroid Build Coastguard Worker	// work in arbitrary partitions, so just surface errors early for a few cases
301*333d2b36SAndroid Build Coastguard Worker	//
302*333d2b36SAndroid Build Coastguard Worker	// Even without these, there are certain situations across linkernamespaces
303*333d2b36SAndroid Build Coastguard Worker	// that this won't support. For instance, you might have:
304*333d2b36SAndroid Build Coastguard Worker	//
305*333d2b36SAndroid Build Coastguard Worker	//     my_fuzzer (vendor) -> libbinder_ndk (core) -> libbinder (vendor)
306*333d2b36SAndroid Build Coastguard Worker	//
307*333d2b36SAndroid Build Coastguard Worker	// This dependency chain wouldn't be possible to express in the current
308*333d2b36SAndroid Build Coastguard Worker	// logic because all the deps currently match the variant of the source
309*333d2b36SAndroid Build Coastguard Worker	// module.
310*333d2b36SAndroid Build Coastguard Worker
311*333d2b36SAndroid Build Coastguard Worker	for _, ruleBuilderInstall := range fuzzBin.sharedLibraries {
312*333d2b36SAndroid Build Coastguard Worker		install := ruleBuilderInstall.To
313*333d2b36SAndroid Build Coastguard Worker		fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
314*333d2b36SAndroid Build Coastguard Worker			SharedLibraryInstallLocation(
315*333d2b36SAndroid Build Coastguard Worker				install, ctx.Host(), ctx.inVendor(), installBase, ctx.Arch().ArchType.String()))
316*333d2b36SAndroid Build Coastguard Worker
317*333d2b36SAndroid Build Coastguard Worker		// Also add the dependency on the shared library symbols dir.
318*333d2b36SAndroid Build Coastguard Worker		if !ctx.Host() {
319*333d2b36SAndroid Build Coastguard Worker			fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
320*333d2b36SAndroid Build Coastguard Worker				SharedLibrarySymbolsInstallLocation(install, ctx.inVendor(), installBase, ctx.Arch().ArchType.String()))
321*333d2b36SAndroid Build Coastguard Worker		}
322*333d2b36SAndroid Build Coastguard Worker	}
323*333d2b36SAndroid Build Coastguard Worker
324*333d2b36SAndroid Build Coastguard Worker	for _, d := range fuzzBin.fuzzPackagedModule.Corpus {
325*333d2b36SAndroid Build Coastguard Worker		fuzzBin.data = append(fuzzBin.data, android.DataPath{SrcPath: d, RelativeInstallPath: "corpus", WithoutRel: true})
326*333d2b36SAndroid Build Coastguard Worker	}
327*333d2b36SAndroid Build Coastguard Worker
328*333d2b36SAndroid Build Coastguard Worker	for _, d := range fuzzBin.fuzzPackagedModule.Data {
329*333d2b36SAndroid Build Coastguard Worker		fuzzBin.data = append(fuzzBin.data, android.DataPath{SrcPath: d, RelativeInstallPath: "data"})
330*333d2b36SAndroid Build Coastguard Worker	}
331*333d2b36SAndroid Build Coastguard Worker
332*333d2b36SAndroid Build Coastguard Worker	if d := fuzzBin.fuzzPackagedModule.Dictionary; d != nil {
333*333d2b36SAndroid Build Coastguard Worker		fuzzBin.data = append(fuzzBin.data, android.DataPath{SrcPath: d, WithoutRel: true})
334*333d2b36SAndroid Build Coastguard Worker	}
335*333d2b36SAndroid Build Coastguard Worker
336*333d2b36SAndroid Build Coastguard Worker	if d := fuzzBin.fuzzPackagedModule.Config; d != nil {
337*333d2b36SAndroid Build Coastguard Worker		fuzzBin.data = append(fuzzBin.data, android.DataPath{SrcPath: d, WithoutRel: true})
338*333d2b36SAndroid Build Coastguard Worker	}
339*333d2b36SAndroid Build Coastguard Worker
340*333d2b36SAndroid Build Coastguard Worker	fuzzBin.binaryDecorator.baseInstaller.dir = filepath.Join(
341*333d2b36SAndroid Build Coastguard Worker		installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
342*333d2b36SAndroid Build Coastguard Worker	fuzzBin.binaryDecorator.baseInstaller.dir64 = filepath.Join(
343*333d2b36SAndroid Build Coastguard Worker		installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
344*333d2b36SAndroid Build Coastguard Worker	fuzzBin.binaryDecorator.baseInstaller.installTestData(ctx, fuzzBin.data)
345*333d2b36SAndroid Build Coastguard Worker	fuzzBin.binaryDecorator.baseInstaller.install(ctx, file)
346*333d2b36SAndroid Build Coastguard Worker}
347*333d2b36SAndroid Build Coastguard Worker
348*333d2b36SAndroid Build Coastguard Workerfunc PackageFuzzModule(ctx android.ModuleContext, fuzzPackagedModule fuzz.FuzzPackagedModule, pctx android.PackageContext) fuzz.FuzzPackagedModule {
349*333d2b36SAndroid Build Coastguard Worker	fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Corpus)
350*333d2b36SAndroid Build Coastguard Worker	fuzzPackagedModule.Corpus = append(fuzzPackagedModule.Corpus, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Device_common_corpus)...)
351*333d2b36SAndroid Build Coastguard Worker
352*333d2b36SAndroid Build Coastguard Worker	fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Data)
353*333d2b36SAndroid Build Coastguard Worker
354*333d2b36SAndroid Build Coastguard Worker	if fuzzPackagedModule.FuzzProperties.Dictionary != nil {
355*333d2b36SAndroid Build Coastguard Worker		fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzPackagedModule.FuzzProperties.Dictionary)
356*333d2b36SAndroid Build Coastguard Worker		if fuzzPackagedModule.Dictionary.Ext() != ".dict" {
357*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("dictionary",
358*333d2b36SAndroid Build Coastguard Worker				"Fuzzer dictionary %q does not have '.dict' extension",
359*333d2b36SAndroid Build Coastguard Worker				fuzzPackagedModule.Dictionary.String())
360*333d2b36SAndroid Build Coastguard Worker		}
361*333d2b36SAndroid Build Coastguard Worker	}
362*333d2b36SAndroid Build Coastguard Worker
363*333d2b36SAndroid Build Coastguard Worker	if fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
364*333d2b36SAndroid Build Coastguard Worker		configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
365*333d2b36SAndroid Build Coastguard Worker		android.WriteFileRule(ctx, configPath, fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
366*333d2b36SAndroid Build Coastguard Worker		fuzzPackagedModule.Config = configPath
367*333d2b36SAndroid Build Coastguard Worker	}
368*333d2b36SAndroid Build Coastguard Worker	return fuzzPackagedModule
369*333d2b36SAndroid Build Coastguard Worker}
370*333d2b36SAndroid Build Coastguard Worker
371*333d2b36SAndroid Build Coastguard Workerfunc NewFuzzer(hod android.HostOrDeviceSupported) *Module {
372*333d2b36SAndroid Build Coastguard Worker	module, binary := newBinary(hod)
373*333d2b36SAndroid Build Coastguard Worker	baseInstallerPath := "fuzz"
374*333d2b36SAndroid Build Coastguard Worker
375*333d2b36SAndroid Build Coastguard Worker	binary.baseInstaller = NewBaseInstaller(baseInstallerPath, baseInstallerPath, InstallInData)
376*333d2b36SAndroid Build Coastguard Worker
377*333d2b36SAndroid Build Coastguard Worker	fuzzBin := &fuzzBinary{
378*333d2b36SAndroid Build Coastguard Worker		binaryDecorator: binary,
379*333d2b36SAndroid Build Coastguard Worker		baseCompiler:    NewBaseCompiler(),
380*333d2b36SAndroid Build Coastguard Worker	}
381*333d2b36SAndroid Build Coastguard Worker	module.compiler = fuzzBin
382*333d2b36SAndroid Build Coastguard Worker	module.linker = fuzzBin
383*333d2b36SAndroid Build Coastguard Worker	module.installer = fuzzBin
384*333d2b36SAndroid Build Coastguard Worker
385*333d2b36SAndroid Build Coastguard Worker	module.fuzzer.Properties.FuzzFramework = fuzz.LibFuzzer
386*333d2b36SAndroid Build Coastguard Worker
387*333d2b36SAndroid Build Coastguard Worker	// The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin.
388*333d2b36SAndroid Build Coastguard Worker	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
389*333d2b36SAndroid Build Coastguard Worker
390*333d2b36SAndroid Build Coastguard Worker		extraProps := struct {
391*333d2b36SAndroid Build Coastguard Worker			Sanitize struct {
392*333d2b36SAndroid Build Coastguard Worker				Fuzzer *bool
393*333d2b36SAndroid Build Coastguard Worker			}
394*333d2b36SAndroid Build Coastguard Worker			Target struct {
395*333d2b36SAndroid Build Coastguard Worker				Darwin struct {
396*333d2b36SAndroid Build Coastguard Worker					Enabled *bool
397*333d2b36SAndroid Build Coastguard Worker				}
398*333d2b36SAndroid Build Coastguard Worker				Linux_bionic struct {
399*333d2b36SAndroid Build Coastguard Worker					Enabled *bool
400*333d2b36SAndroid Build Coastguard Worker				}
401*333d2b36SAndroid Build Coastguard Worker			}
402*333d2b36SAndroid Build Coastguard Worker		}{}
403*333d2b36SAndroid Build Coastguard Worker		extraProps.Sanitize.Fuzzer = BoolPtr(true)
404*333d2b36SAndroid Build Coastguard Worker		extraProps.Target.Darwin.Enabled = BoolPtr(false)
405*333d2b36SAndroid Build Coastguard Worker		extraProps.Target.Linux_bionic.Enabled = BoolPtr(false)
406*333d2b36SAndroid Build Coastguard Worker		ctx.AppendProperties(&extraProps)
407*333d2b36SAndroid Build Coastguard Worker
408*333d2b36SAndroid Build Coastguard Worker		targetFramework := fuzz.GetFramework(ctx, fuzz.Cc)
409*333d2b36SAndroid Build Coastguard Worker		if !fuzz.IsValidFrameworkForModule(targetFramework, fuzz.Cc, fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzzing_frameworks) {
410*333d2b36SAndroid Build Coastguard Worker			ctx.Module().Disable()
411*333d2b36SAndroid Build Coastguard Worker			return
412*333d2b36SAndroid Build Coastguard Worker		}
413*333d2b36SAndroid Build Coastguard Worker
414*333d2b36SAndroid Build Coastguard Worker		if targetFramework == fuzz.AFL {
415*333d2b36SAndroid Build Coastguard Worker			fuzzBin.baseCompiler.Properties.Srcs.AppendSimpleValue([]string{":aflpp_driver", ":afl-compiler-rt"})
416*333d2b36SAndroid Build Coastguard Worker			module.fuzzer.Properties.FuzzFramework = fuzz.AFL
417*333d2b36SAndroid Build Coastguard Worker		}
418*333d2b36SAndroid Build Coastguard Worker	})
419*333d2b36SAndroid Build Coastguard Worker
420*333d2b36SAndroid Build Coastguard Worker	return module
421*333d2b36SAndroid Build Coastguard Worker}
422*333d2b36SAndroid Build Coastguard Worker
423*333d2b36SAndroid Build Coastguard Worker// Responsible for generating GNU Make rules that package fuzz targets into
424*333d2b36SAndroid Build Coastguard Worker// their architecture & target/host specific zip file.
425*333d2b36SAndroid Build Coastguard Workertype ccRustFuzzPackager struct {
426*333d2b36SAndroid Build Coastguard Worker	fuzz.FuzzPackager
427*333d2b36SAndroid Build Coastguard Worker	fuzzPackagingArchModules         string
428*333d2b36SAndroid Build Coastguard Worker	fuzzTargetSharedDepsInstallPairs string
429*333d2b36SAndroid Build Coastguard Worker	allFuzzTargetsName               string
430*333d2b36SAndroid Build Coastguard Worker	onlyIncludePresubmits            bool
431*333d2b36SAndroid Build Coastguard Worker}
432*333d2b36SAndroid Build Coastguard Worker
433*333d2b36SAndroid Build Coastguard Workerfunc fuzzPackagingFactory() android.Singleton {
434*333d2b36SAndroid Build Coastguard Worker
435*333d2b36SAndroid Build Coastguard Worker	fuzzPackager := &ccRustFuzzPackager{
436*333d2b36SAndroid Build Coastguard Worker		fuzzPackagingArchModules:         "SOONG_FUZZ_PACKAGING_ARCH_MODULES",
437*333d2b36SAndroid Build Coastguard Worker		fuzzTargetSharedDepsInstallPairs: "FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
438*333d2b36SAndroid Build Coastguard Worker		allFuzzTargetsName:               "ALL_FUZZ_TARGETS",
439*333d2b36SAndroid Build Coastguard Worker		onlyIncludePresubmits:            false,
440*333d2b36SAndroid Build Coastguard Worker	}
441*333d2b36SAndroid Build Coastguard Worker	return fuzzPackager
442*333d2b36SAndroid Build Coastguard Worker}
443*333d2b36SAndroid Build Coastguard Worker
444*333d2b36SAndroid Build Coastguard Workerfunc fuzzPackagingFactoryPresubmit() android.Singleton {
445*333d2b36SAndroid Build Coastguard Worker
446*333d2b36SAndroid Build Coastguard Worker	fuzzPackager := &ccRustFuzzPackager{
447*333d2b36SAndroid Build Coastguard Worker		fuzzPackagingArchModules:         "SOONG_PRESUBMIT_FUZZ_PACKAGING_ARCH_MODULES",
448*333d2b36SAndroid Build Coastguard Worker		fuzzTargetSharedDepsInstallPairs: "PRESUBMIT_FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
449*333d2b36SAndroid Build Coastguard Worker		allFuzzTargetsName:               "ALL_PRESUBMIT_FUZZ_TARGETS",
450*333d2b36SAndroid Build Coastguard Worker		onlyIncludePresubmits:            true,
451*333d2b36SAndroid Build Coastguard Worker	}
452*333d2b36SAndroid Build Coastguard Worker	return fuzzPackager
453*333d2b36SAndroid Build Coastguard Worker}
454*333d2b36SAndroid Build Coastguard Worker
455*333d2b36SAndroid Build Coastguard Workerfunc (s *ccRustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
456*333d2b36SAndroid Build Coastguard Worker	// Map between each architecture + host/device combination, and the files that
457*333d2b36SAndroid Build Coastguard Worker	// need to be packaged (in the tuple of {source file, destination folder in
458*333d2b36SAndroid Build Coastguard Worker	// archive}).
459*333d2b36SAndroid Build Coastguard Worker	archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)
460*333d2b36SAndroid Build Coastguard Worker
461*333d2b36SAndroid Build Coastguard Worker	// List of individual fuzz targets, so that 'make fuzz' also installs the targets
462*333d2b36SAndroid Build Coastguard Worker	// to the correct output directories as well.
463*333d2b36SAndroid Build Coastguard Worker	s.FuzzTargets = make(map[string]bool)
464*333d2b36SAndroid Build Coastguard Worker
465*333d2b36SAndroid Build Coastguard Worker	// Map tracking whether each shared library has an install rule to avoid duplicate install rules from
466*333d2b36SAndroid Build Coastguard Worker	// multiple fuzzers that depend on the same shared library.
467*333d2b36SAndroid Build Coastguard Worker	sharedLibraryInstalled := make(map[string]bool)
468*333d2b36SAndroid Build Coastguard Worker
469*333d2b36SAndroid Build Coastguard Worker	ctx.VisitAllModules(func(module android.Module) {
470*333d2b36SAndroid Build Coastguard Worker		ccModule, ok := module.(LinkableInterface)
471*333d2b36SAndroid Build Coastguard Worker		if !ok || ccModule.PreventInstall() {
472*333d2b36SAndroid Build Coastguard Worker			return
473*333d2b36SAndroid Build Coastguard Worker		}
474*333d2b36SAndroid Build Coastguard Worker		// Discard non-fuzz targets.
475*333d2b36SAndroid Build Coastguard Worker		if ok := fuzz.IsValid(ctx, ccModule.FuzzModuleStruct()); !ok {
476*333d2b36SAndroid Build Coastguard Worker			return
477*333d2b36SAndroid Build Coastguard Worker		}
478*333d2b36SAndroid Build Coastguard Worker
479*333d2b36SAndroid Build Coastguard Worker		sharedLibsInstallDirPrefix := "lib"
480*333d2b36SAndroid Build Coastguard Worker		if ccModule.InVendor() {
481*333d2b36SAndroid Build Coastguard Worker			sharedLibsInstallDirPrefix = "lib/vendor"
482*333d2b36SAndroid Build Coastguard Worker		}
483*333d2b36SAndroid Build Coastguard Worker
484*333d2b36SAndroid Build Coastguard Worker		if !ccModule.IsFuzzModule() {
485*333d2b36SAndroid Build Coastguard Worker			return
486*333d2b36SAndroid Build Coastguard Worker		}
487*333d2b36SAndroid Build Coastguard Worker
488*333d2b36SAndroid Build Coastguard Worker		hostOrTargetString := "target"
489*333d2b36SAndroid Build Coastguard Worker		if ccModule.Target().HostCross {
490*333d2b36SAndroid Build Coastguard Worker			hostOrTargetString = "host_cross"
491*333d2b36SAndroid Build Coastguard Worker		} else if ccModule.Host() {
492*333d2b36SAndroid Build Coastguard Worker			hostOrTargetString = "host"
493*333d2b36SAndroid Build Coastguard Worker		}
494*333d2b36SAndroid Build Coastguard Worker		if s.onlyIncludePresubmits == true {
495*333d2b36SAndroid Build Coastguard Worker			hostOrTargetString = "presubmit-" + hostOrTargetString
496*333d2b36SAndroid Build Coastguard Worker		}
497*333d2b36SAndroid Build Coastguard Worker
498*333d2b36SAndroid Build Coastguard Worker		fpm := fuzz.FuzzPackagedModule{}
499*333d2b36SAndroid Build Coastguard Worker		if ok {
500*333d2b36SAndroid Build Coastguard Worker			fpm = ccModule.FuzzPackagedModule()
501*333d2b36SAndroid Build Coastguard Worker		}
502*333d2b36SAndroid Build Coastguard Worker
503*333d2b36SAndroid Build Coastguard Worker		intermediatePath := "fuzz"
504*333d2b36SAndroid Build Coastguard Worker
505*333d2b36SAndroid Build Coastguard Worker		archString := ccModule.Target().Arch.ArchType.String()
506*333d2b36SAndroid Build Coastguard Worker		archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString)
507*333d2b36SAndroid Build Coastguard Worker		archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
508*333d2b36SAndroid Build Coastguard Worker
509*333d2b36SAndroid Build Coastguard Worker		var files []fuzz.FileToZip
510*333d2b36SAndroid Build Coastguard Worker		builder := android.NewRuleBuilder(pctx, ctx)
511*333d2b36SAndroid Build Coastguard Worker
512*333d2b36SAndroid Build Coastguard Worker		// Package the corpus, data, dict and config into a zipfile.
513*333d2b36SAndroid Build Coastguard Worker		files = s.PackageArtifacts(ctx, module, fpm, archDir, builder)
514*333d2b36SAndroid Build Coastguard Worker
515*333d2b36SAndroid Build Coastguard Worker		// Package shared libraries
516*333d2b36SAndroid Build Coastguard Worker		files = append(files, GetSharedLibsToZip(ccModule.FuzzSharedLibraries(), ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
517*333d2b36SAndroid Build Coastguard Worker
518*333d2b36SAndroid Build Coastguard Worker		// The executable.
519*333d2b36SAndroid Build Coastguard Worker		files = append(files, fuzz.FileToZip{SourceFilePath: android.OutputFileForModule(ctx, ccModule, "unstripped")})
520*333d2b36SAndroid Build Coastguard Worker
521*333d2b36SAndroid Build Coastguard Worker		if s.onlyIncludePresubmits == true {
522*333d2b36SAndroid Build Coastguard Worker			if fpm.FuzzProperties.Fuzz_config == nil {
523*333d2b36SAndroid Build Coastguard Worker				return
524*333d2b36SAndroid Build Coastguard Worker			}
525*333d2b36SAndroid Build Coastguard Worker			if !BoolDefault(fpm.FuzzProperties.Fuzz_config.Use_for_presubmit, false) {
526*333d2b36SAndroid Build Coastguard Worker				return
527*333d2b36SAndroid Build Coastguard Worker			}
528*333d2b36SAndroid Build Coastguard Worker		}
529*333d2b36SAndroid Build Coastguard Worker		archDirs[archOs], ok = s.BuildZipFile(ctx, module, fpm, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
530*333d2b36SAndroid Build Coastguard Worker		if !ok {
531*333d2b36SAndroid Build Coastguard Worker			return
532*333d2b36SAndroid Build Coastguard Worker		}
533*333d2b36SAndroid Build Coastguard Worker	})
534*333d2b36SAndroid Build Coastguard Worker
535*333d2b36SAndroid Build Coastguard Worker	s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx)
536*333d2b36SAndroid Build Coastguard Worker}
537*333d2b36SAndroid Build Coastguard Worker
538*333d2b36SAndroid Build Coastguard Workerfunc (s *ccRustFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
539*333d2b36SAndroid Build Coastguard Worker	packages := s.Packages.Strings()
540*333d2b36SAndroid Build Coastguard Worker	sort.Strings(packages)
541*333d2b36SAndroid Build Coastguard Worker	sort.Strings(s.FuzzPackager.SharedLibInstallStrings)
542*333d2b36SAndroid Build Coastguard Worker	// TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's
543*333d2b36SAndroid Build Coastguard Worker	// ready to handle phony targets created in Soong. In the meantime, this
544*333d2b36SAndroid Build Coastguard Worker	// exports the phony 'fuzz' target and dependencies on packages to
545*333d2b36SAndroid Build Coastguard Worker	// core/main.mk so that we can use dist-for-goals.
546*333d2b36SAndroid Build Coastguard Worker
547*333d2b36SAndroid Build Coastguard Worker	ctx.Strict(s.fuzzPackagingArchModules, strings.Join(packages, " "))
548*333d2b36SAndroid Build Coastguard Worker
549*333d2b36SAndroid Build Coastguard Worker	ctx.Strict(s.fuzzTargetSharedDepsInstallPairs,
550*333d2b36SAndroid Build Coastguard Worker		strings.Join(s.FuzzPackager.SharedLibInstallStrings, " "))
551*333d2b36SAndroid Build Coastguard Worker
552*333d2b36SAndroid Build Coastguard Worker	// Preallocate the slice of fuzz targets to minimise memory allocations.
553*333d2b36SAndroid Build Coastguard Worker	s.PreallocateSlice(ctx, s.allFuzzTargetsName)
554*333d2b36SAndroid Build Coastguard Worker}
555*333d2b36SAndroid Build Coastguard Worker
556*333d2b36SAndroid Build Coastguard Worker// GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for
557*333d2b36SAndroid Build Coastguard Worker// packaging.
558*333d2b36SAndroid Build Coastguard Workerfunc GetSharedLibsToZip(sharedLibraries android.RuleBuilderInstalls, module LinkableInterface, s *fuzz.FuzzPackager, archString string, destinationPathPrefix string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip {
559*333d2b36SAndroid Build Coastguard Worker	var files []fuzz.FileToZip
560*333d2b36SAndroid Build Coastguard Worker
561*333d2b36SAndroid Build Coastguard Worker	fuzzDir := "fuzz"
562*333d2b36SAndroid Build Coastguard Worker
563*333d2b36SAndroid Build Coastguard Worker	for _, ruleBuilderInstall := range sharedLibraries {
564*333d2b36SAndroid Build Coastguard Worker		library := ruleBuilderInstall.From
565*333d2b36SAndroid Build Coastguard Worker		install := ruleBuilderInstall.To
566*333d2b36SAndroid Build Coastguard Worker		files = append(files, fuzz.FileToZip{
567*333d2b36SAndroid Build Coastguard Worker			SourceFilePath:        library,
568*333d2b36SAndroid Build Coastguard Worker			DestinationPathPrefix: destinationPathPrefix,
569*333d2b36SAndroid Build Coastguard Worker			DestinationPath:       install,
570*333d2b36SAndroid Build Coastguard Worker		})
571*333d2b36SAndroid Build Coastguard Worker
572*333d2b36SAndroid Build Coastguard Worker		// For each architecture-specific shared library dependency, we need to
573*333d2b36SAndroid Build Coastguard Worker		// install it to the output directory. Setup the install destination here,
574*333d2b36SAndroid Build Coastguard Worker		// which will be used by $(copy-many-files) in the Make backend.
575*333d2b36SAndroid Build Coastguard Worker		installDestination := SharedLibraryInstallLocation(
576*333d2b36SAndroid Build Coastguard Worker			install, module.Host(), module.InVendor(), fuzzDir, archString)
577*333d2b36SAndroid Build Coastguard Worker		if (*sharedLibraryInstalled)[installDestination] {
578*333d2b36SAndroid Build Coastguard Worker			continue
579*333d2b36SAndroid Build Coastguard Worker		}
580*333d2b36SAndroid Build Coastguard Worker		(*sharedLibraryInstalled)[installDestination] = true
581*333d2b36SAndroid Build Coastguard Worker
582*333d2b36SAndroid Build Coastguard Worker		// Escape all the variables, as the install destination here will be called
583*333d2b36SAndroid Build Coastguard Worker		// via. $(eval) in Make.
584*333d2b36SAndroid Build Coastguard Worker		installDestination = strings.ReplaceAll(
585*333d2b36SAndroid Build Coastguard Worker			installDestination, "$", "$$")
586*333d2b36SAndroid Build Coastguard Worker		s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
587*333d2b36SAndroid Build Coastguard Worker			library.String()+":"+installDestination)
588*333d2b36SAndroid Build Coastguard Worker
589*333d2b36SAndroid Build Coastguard Worker		// Ensure that on device, the library is also reinstalled to the /symbols/
590*333d2b36SAndroid Build Coastguard Worker		// dir. Symbolized DSO's are always installed to the device when fuzzing, but
591*333d2b36SAndroid Build Coastguard Worker		// we want symbolization tools (like `stack`) to be able to find the symbols
592*333d2b36SAndroid Build Coastguard Worker		// in $ANDROID_PRODUCT_OUT/symbols automagically.
593*333d2b36SAndroid Build Coastguard Worker		if !module.Host() {
594*333d2b36SAndroid Build Coastguard Worker			symbolsInstallDestination := SharedLibrarySymbolsInstallLocation(install, module.InVendor(), fuzzDir, archString)
595*333d2b36SAndroid Build Coastguard Worker			symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
596*333d2b36SAndroid Build Coastguard Worker			s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
597*333d2b36SAndroid Build Coastguard Worker				library.String()+":"+symbolsInstallDestination)
598*333d2b36SAndroid Build Coastguard Worker		}
599*333d2b36SAndroid Build Coastguard Worker	}
600*333d2b36SAndroid Build Coastguard Worker	return files
601*333d2b36SAndroid Build Coastguard Worker}
602*333d2b36SAndroid Build Coastguard Worker
603*333d2b36SAndroid Build Coastguard Worker// CollectAllSharedDependencies search over the provided module's dependencies using
604*333d2b36SAndroid Build Coastguard Worker// VisitDirectDeps and WalkDeps to enumerate all shared library dependencies.
605*333d2b36SAndroid Build Coastguard Worker// VisitDirectDeps is used first to avoid incorrectly using the core libraries (sanitizer
606*333d2b36SAndroid Build Coastguard Worker// runtimes, libc, libdl, etc.) from a dependency. This may cause issues when dependencies
607*333d2b36SAndroid Build Coastguard Worker// have explicit sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
608*333d2b36SAndroid Build Coastguard Workerfunc CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilderInstalls, []android.Module) {
609*333d2b36SAndroid Build Coastguard Worker	seen := make(map[string]bool)
610*333d2b36SAndroid Build Coastguard Worker	recursed := make(map[string]bool)
611*333d2b36SAndroid Build Coastguard Worker	deps := []android.Module{}
612*333d2b36SAndroid Build Coastguard Worker
613*333d2b36SAndroid Build Coastguard Worker	var sharedLibraries android.RuleBuilderInstalls
614*333d2b36SAndroid Build Coastguard Worker
615*333d2b36SAndroid Build Coastguard Worker	// Enumerate the first level of dependencies, as we discard all non-library
616*333d2b36SAndroid Build Coastguard Worker	// modules in the BFS loop below.
617*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDeps(func(dep android.Module) {
618*333d2b36SAndroid Build Coastguard Worker		if !IsValidSharedDependency(dep) {
619*333d2b36SAndroid Build Coastguard Worker			return
620*333d2b36SAndroid Build Coastguard Worker		}
621*333d2b36SAndroid Build Coastguard Worker		sharedLibraryInfo, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, SharedLibraryInfoProvider)
622*333d2b36SAndroid Build Coastguard Worker		if !hasSharedLibraryInfo {
623*333d2b36SAndroid Build Coastguard Worker			return
624*333d2b36SAndroid Build Coastguard Worker		}
625*333d2b36SAndroid Build Coastguard Worker		if seen[ctx.OtherModuleName(dep)] {
626*333d2b36SAndroid Build Coastguard Worker			return
627*333d2b36SAndroid Build Coastguard Worker		}
628*333d2b36SAndroid Build Coastguard Worker		seen[ctx.OtherModuleName(dep)] = true
629*333d2b36SAndroid Build Coastguard Worker		deps = append(deps, dep)
630*333d2b36SAndroid Build Coastguard Worker
631*333d2b36SAndroid Build Coastguard Worker		installDestination := sharedLibraryInfo.SharedLibrary.Base()
632*333d2b36SAndroid Build Coastguard Worker		ruleBuilderInstall := android.RuleBuilderInstall{android.OutputFileForModule(ctx, dep, "unstripped"), installDestination}
633*333d2b36SAndroid Build Coastguard Worker		sharedLibraries = append(sharedLibraries, ruleBuilderInstall)
634*333d2b36SAndroid Build Coastguard Worker	})
635*333d2b36SAndroid Build Coastguard Worker
636*333d2b36SAndroid Build Coastguard Worker	ctx.WalkDeps(func(child, parent android.Module) bool {
637*333d2b36SAndroid Build Coastguard Worker
638*333d2b36SAndroid Build Coastguard Worker		// If this is a Rust module which is not rust_ffi_shared, we still want to bundle any transitive
639*333d2b36SAndroid Build Coastguard Worker		// shared dependencies (even for rust_ffi_rlib or rust_ffi_static)
640*333d2b36SAndroid Build Coastguard Worker		if rustmod, ok := child.(LinkableInterface); ok && rustmod.RustLibraryInterface() && !rustmod.Shared() {
641*333d2b36SAndroid Build Coastguard Worker			if recursed[ctx.OtherModuleName(child)] {
642*333d2b36SAndroid Build Coastguard Worker				return false
643*333d2b36SAndroid Build Coastguard Worker			}
644*333d2b36SAndroid Build Coastguard Worker			recursed[ctx.OtherModuleName(child)] = true
645*333d2b36SAndroid Build Coastguard Worker			return true
646*333d2b36SAndroid Build Coastguard Worker		}
647*333d2b36SAndroid Build Coastguard Worker
648*333d2b36SAndroid Build Coastguard Worker		if !IsValidSharedDependency(child) {
649*333d2b36SAndroid Build Coastguard Worker			return false
650*333d2b36SAndroid Build Coastguard Worker		}
651*333d2b36SAndroid Build Coastguard Worker		sharedLibraryInfo, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, child, SharedLibraryInfoProvider)
652*333d2b36SAndroid Build Coastguard Worker		if !hasSharedLibraryInfo {
653*333d2b36SAndroid Build Coastguard Worker			return false
654*333d2b36SAndroid Build Coastguard Worker		}
655*333d2b36SAndroid Build Coastguard Worker		if !seen[ctx.OtherModuleName(child)] {
656*333d2b36SAndroid Build Coastguard Worker			seen[ctx.OtherModuleName(child)] = true
657*333d2b36SAndroid Build Coastguard Worker			deps = append(deps, child)
658*333d2b36SAndroid Build Coastguard Worker
659*333d2b36SAndroid Build Coastguard Worker			installDestination := sharedLibraryInfo.SharedLibrary.Base()
660*333d2b36SAndroid Build Coastguard Worker			ruleBuilderInstall := android.RuleBuilderInstall{android.OutputFileForModule(ctx, child, "unstripped"), installDestination}
661*333d2b36SAndroid Build Coastguard Worker			sharedLibraries = append(sharedLibraries, ruleBuilderInstall)
662*333d2b36SAndroid Build Coastguard Worker		}
663*333d2b36SAndroid Build Coastguard Worker
664*333d2b36SAndroid Build Coastguard Worker		if recursed[ctx.OtherModuleName(child)] {
665*333d2b36SAndroid Build Coastguard Worker			return false
666*333d2b36SAndroid Build Coastguard Worker		}
667*333d2b36SAndroid Build Coastguard Worker		recursed[ctx.OtherModuleName(child)] = true
668*333d2b36SAndroid Build Coastguard Worker		return true
669*333d2b36SAndroid Build Coastguard Worker	})
670*333d2b36SAndroid Build Coastguard Worker
671*333d2b36SAndroid Build Coastguard Worker	return sharedLibraries, deps
672*333d2b36SAndroid Build Coastguard Worker}
673