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