1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 The Android Open Source Project 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 rust 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 19*333d2b36SAndroid Build Coastguard Worker "android/soong/cc" 20*333d2b36SAndroid Build Coastguard Worker "android/soong/fuzz" 21*333d2b36SAndroid Build Coastguard Worker "android/soong/rust/config" 22*333d2b36SAndroid Build Coastguard Worker "path/filepath" 23*333d2b36SAndroid Build Coastguard Worker) 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Workerfunc init() { 26*333d2b36SAndroid Build Coastguard Worker android.RegisterModuleType("rust_fuzz", RustFuzzFactory) 27*333d2b36SAndroid Build Coastguard Worker android.RegisterModuleType("rust_fuzz_host", RustFuzzHostFactory) 28*333d2b36SAndroid Build Coastguard Worker} 29*333d2b36SAndroid Build Coastguard Worker 30*333d2b36SAndroid Build Coastguard Workertype fuzzDecorator struct { 31*333d2b36SAndroid Build Coastguard Worker *binaryDecorator 32*333d2b36SAndroid Build Coastguard Worker 33*333d2b36SAndroid Build Coastguard Worker fuzzPackagedModule fuzz.FuzzPackagedModule 34*333d2b36SAndroid Build Coastguard Worker sharedLibraries android.RuleBuilderInstalls 35*333d2b36SAndroid Build Coastguard Worker installedSharedDeps []string 36*333d2b36SAndroid Build Coastguard Worker} 37*333d2b36SAndroid Build Coastguard Worker 38*333d2b36SAndroid Build Coastguard Workervar _ compiler = (*fuzzDecorator)(nil) 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker// rust_binary produces a binary that is runnable on a device. 41*333d2b36SAndroid Build Coastguard Workerfunc RustFuzzFactory() android.Module { 42*333d2b36SAndroid Build Coastguard Worker module, _ := NewRustFuzz(android.HostAndDeviceSupported) 43*333d2b36SAndroid Build Coastguard Worker return module.Init() 44*333d2b36SAndroid Build Coastguard Worker} 45*333d2b36SAndroid Build Coastguard Worker 46*333d2b36SAndroid Build Coastguard Workerfunc RustFuzzHostFactory() android.Module { 47*333d2b36SAndroid Build Coastguard Worker module, _ := NewRustFuzz(android.HostSupported) 48*333d2b36SAndroid Build Coastguard Worker return module.Init() 49*333d2b36SAndroid Build Coastguard Worker} 50*333d2b36SAndroid Build Coastguard Worker 51*333d2b36SAndroid Build Coastguard Workerfunc NewRustFuzz(hod android.HostOrDeviceSupported) (*Module, *fuzzDecorator) { 52*333d2b36SAndroid Build Coastguard Worker module, binary := NewRustBinary(hod) 53*333d2b36SAndroid Build Coastguard Worker fuzz := &fuzzDecorator{ 54*333d2b36SAndroid Build Coastguard Worker binaryDecorator: binary, 55*333d2b36SAndroid Build Coastguard Worker } 56*333d2b36SAndroid Build Coastguard Worker 57*333d2b36SAndroid Build Coastguard Worker // Change the defaults for the binaryDecorator's baseCompiler 58*333d2b36SAndroid Build Coastguard Worker fuzz.binaryDecorator.baseCompiler.dir = "fuzz" 59*333d2b36SAndroid Build Coastguard Worker fuzz.binaryDecorator.baseCompiler.dir64 = "fuzz" 60*333d2b36SAndroid Build Coastguard Worker fuzz.binaryDecorator.baseCompiler.location = InstallInData 61*333d2b36SAndroid Build Coastguard Worker module.sanitize.SetSanitizer(cc.Fuzzer, true) 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Worker // The fuzzer runtime is not present for darwin or bionic host modules, so disable rust_fuzz modules for these. 64*333d2b36SAndroid Build Coastguard Worker android.AddLoadHook(module, func(ctx android.LoadHookContext) { 65*333d2b36SAndroid Build Coastguard Worker 66*333d2b36SAndroid Build Coastguard Worker extraProps := struct { 67*333d2b36SAndroid Build Coastguard Worker Target struct { 68*333d2b36SAndroid Build Coastguard Worker Darwin struct { 69*333d2b36SAndroid Build Coastguard Worker Enabled *bool 70*333d2b36SAndroid Build Coastguard Worker } 71*333d2b36SAndroid Build Coastguard Worker Linux_bionic struct { 72*333d2b36SAndroid Build Coastguard Worker Enabled *bool 73*333d2b36SAndroid Build Coastguard Worker } 74*333d2b36SAndroid Build Coastguard Worker } 75*333d2b36SAndroid Build Coastguard Worker }{} 76*333d2b36SAndroid Build Coastguard Worker extraProps.Target.Darwin.Enabled = cc.BoolPtr(false) 77*333d2b36SAndroid Build Coastguard Worker extraProps.Target.Linux_bionic.Enabled = cc.BoolPtr(false) 78*333d2b36SAndroid Build Coastguard Worker ctx.AppendProperties(&extraProps) 79*333d2b36SAndroid Build Coastguard Worker }) 80*333d2b36SAndroid Build Coastguard Worker 81*333d2b36SAndroid Build Coastguard Worker module.compiler = fuzz 82*333d2b36SAndroid Build Coastguard Worker return module, fuzz 83*333d2b36SAndroid Build Coastguard Worker} 84*333d2b36SAndroid Build Coastguard Worker 85*333d2b36SAndroid Build Coastguard Workerfunc (fuzzer *fuzzDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { 86*333d2b36SAndroid Build Coastguard Worker flags = fuzzer.binaryDecorator.compilerFlags(ctx, flags) 87*333d2b36SAndroid Build Coastguard Worker 88*333d2b36SAndroid Build Coastguard Worker // `../lib` for installed fuzz targets (both host and device), and `./lib` for fuzz target packages. 89*333d2b36SAndroid Build Coastguard Worker flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/lib`) 90*333d2b36SAndroid Build Coastguard Worker 91*333d2b36SAndroid Build Coastguard Worker if ctx.InstallInVendor() { 92*333d2b36SAndroid Build Coastguard Worker flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/../../lib`) 93*333d2b36SAndroid Build Coastguard Worker } else { 94*333d2b36SAndroid Build Coastguard Worker flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/../lib`) 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker } 97*333d2b36SAndroid Build Coastguard Worker return flags 98*333d2b36SAndroid Build Coastguard Worker} 99*333d2b36SAndroid Build Coastguard Worker 100*333d2b36SAndroid Build Coastguard Workerfunc (fuzzer *fuzzDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { 101*333d2b36SAndroid Build Coastguard Worker if libFuzzerRuntimeLibrary := config.LibFuzzerRuntimeLibrary(ctx.toolchain()); libFuzzerRuntimeLibrary != "" { 102*333d2b36SAndroid Build Coastguard Worker deps.StaticLibs = append(deps.StaticLibs, libFuzzerRuntimeLibrary) 103*333d2b36SAndroid Build Coastguard Worker } 104*333d2b36SAndroid Build Coastguard Worker deps.SharedLibs = append(deps.SharedLibs, "libc++") 105*333d2b36SAndroid Build Coastguard Worker deps.Rlibs = append(deps.Rlibs, "liblibfuzzer_sys") 106*333d2b36SAndroid Build Coastguard Worker 107*333d2b36SAndroid Build Coastguard Worker deps = fuzzer.binaryDecorator.compilerDeps(ctx, deps) 108*333d2b36SAndroid Build Coastguard Worker 109*333d2b36SAndroid Build Coastguard Worker return deps 110*333d2b36SAndroid Build Coastguard Worker} 111*333d2b36SAndroid Build Coastguard Worker 112*333d2b36SAndroid Build Coastguard Workerfunc (fuzzer *fuzzDecorator) compilerProps() []interface{} { 113*333d2b36SAndroid Build Coastguard Worker return append(fuzzer.binaryDecorator.compilerProps(), 114*333d2b36SAndroid Build Coastguard Worker &fuzzer.fuzzPackagedModule.FuzzProperties) 115*333d2b36SAndroid Build Coastguard Worker} 116*333d2b36SAndroid Build Coastguard Worker 117*333d2b36SAndroid Build Coastguard Workerfunc (fuzzer *fuzzDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { 118*333d2b36SAndroid Build Coastguard Worker 119*333d2b36SAndroid Build Coastguard Worker out := fuzzer.binaryDecorator.compile(ctx, flags, deps) 120*333d2b36SAndroid Build Coastguard Worker 121*333d2b36SAndroid Build Coastguard Worker return out 122*333d2b36SAndroid Build Coastguard Worker} 123*333d2b36SAndroid Build Coastguard Worker 124*333d2b36SAndroid Build Coastguard Workerfunc (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage { 125*333d2b36SAndroid Build Coastguard Worker return RlibLinkage 126*333d2b36SAndroid Build Coastguard Worker} 127*333d2b36SAndroid Build Coastguard Worker 128*333d2b36SAndroid Build Coastguard Workerfunc (fuzzer *fuzzDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { 129*333d2b36SAndroid Build Coastguard Worker return rlibAutoDep 130*333d2b36SAndroid Build Coastguard Worker} 131*333d2b36SAndroid Build Coastguard Worker 132*333d2b36SAndroid Build Coastguard Workerfunc (fuzz *fuzzDecorator) install(ctx ModuleContext) { 133*333d2b36SAndroid Build Coastguard Worker fuzz.fuzzPackagedModule = cc.PackageFuzzModule(ctx, fuzz.fuzzPackagedModule, pctx) 134*333d2b36SAndroid Build Coastguard Worker 135*333d2b36SAndroid Build Coastguard Worker installBase := "fuzz" 136*333d2b36SAndroid Build Coastguard Worker 137*333d2b36SAndroid Build Coastguard Worker // Grab the list of required shared libraries. 138*333d2b36SAndroid Build Coastguard Worker fuzz.sharedLibraries, _ = cc.CollectAllSharedDependencies(ctx) 139*333d2b36SAndroid Build Coastguard Worker 140*333d2b36SAndroid Build Coastguard Worker for _, ruleBuilderInstall := range fuzz.sharedLibraries { 141*333d2b36SAndroid Build Coastguard Worker install := ruleBuilderInstall.To 142*333d2b36SAndroid Build Coastguard Worker 143*333d2b36SAndroid Build Coastguard Worker fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, 144*333d2b36SAndroid Build Coastguard Worker cc.SharedLibraryInstallLocation( 145*333d2b36SAndroid Build Coastguard Worker install, ctx.Host(), ctx.InstallInVendor(), installBase, ctx.Arch().ArchType.String())) 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Worker // Also add the dependency on the shared library symbols dir. 148*333d2b36SAndroid Build Coastguard Worker if !ctx.Host() { 149*333d2b36SAndroid Build Coastguard Worker fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, 150*333d2b36SAndroid Build Coastguard Worker cc.SharedLibrarySymbolsInstallLocation(install, ctx.InstallInVendor(), installBase, ctx.Arch().ArchType.String())) 151*333d2b36SAndroid Build Coastguard Worker } 152*333d2b36SAndroid Build Coastguard Worker } 153*333d2b36SAndroid Build Coastguard Worker 154*333d2b36SAndroid Build Coastguard Worker var fuzzData []android.DataPath 155*333d2b36SAndroid Build Coastguard Worker for _, d := range fuzz.fuzzPackagedModule.Corpus { 156*333d2b36SAndroid Build Coastguard Worker fuzzData = append(fuzzData, android.DataPath{SrcPath: d, RelativeInstallPath: "corpus", WithoutRel: true}) 157*333d2b36SAndroid Build Coastguard Worker } 158*333d2b36SAndroid Build Coastguard Worker 159*333d2b36SAndroid Build Coastguard Worker for _, d := range fuzz.fuzzPackagedModule.Data { 160*333d2b36SAndroid Build Coastguard Worker fuzzData = append(fuzzData, android.DataPath{SrcPath: d, RelativeInstallPath: "data"}) 161*333d2b36SAndroid Build Coastguard Worker } 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Worker if d := fuzz.fuzzPackagedModule.Dictionary; d != nil { 164*333d2b36SAndroid Build Coastguard Worker fuzzData = append(fuzzData, android.DataPath{SrcPath: d, WithoutRel: true}) 165*333d2b36SAndroid Build Coastguard Worker } 166*333d2b36SAndroid Build Coastguard Worker 167*333d2b36SAndroid Build Coastguard Worker if d := fuzz.fuzzPackagedModule.Config; d != nil { 168*333d2b36SAndroid Build Coastguard Worker fuzzData = append(fuzzData, android.DataPath{SrcPath: d, WithoutRel: true}) 169*333d2b36SAndroid Build Coastguard Worker } 170*333d2b36SAndroid Build Coastguard Worker 171*333d2b36SAndroid Build Coastguard Worker fuzz.binaryDecorator.baseCompiler.dir = filepath.Join( 172*333d2b36SAndroid Build Coastguard Worker "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) 173*333d2b36SAndroid Build Coastguard Worker fuzz.binaryDecorator.baseCompiler.dir64 = filepath.Join( 174*333d2b36SAndroid Build Coastguard Worker "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) 175*333d2b36SAndroid Build Coastguard Worker fuzz.binaryDecorator.baseCompiler.installTestData(ctx, fuzzData) 176*333d2b36SAndroid Build Coastguard Worker 177*333d2b36SAndroid Build Coastguard Worker fuzz.binaryDecorator.baseCompiler.install(ctx) 178*333d2b36SAndroid Build Coastguard Worker 179*333d2b36SAndroid Build Coastguard Worker} 180