1// Copyright 2020 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package rust 16 17import ( 18 "path/filepath" 19 20 "android/soong/android" 21 "android/soong/cc" 22 "android/soong/fuzz" 23 "android/soong/rust/config" 24) 25 26func init() { 27 android.RegisterModuleType("rust_fuzz", RustFuzzFactory) 28} 29 30type fuzzDecorator struct { 31 *binaryDecorator 32 33 fuzzPackagedModule fuzz.FuzzPackagedModule 34 sharedLibraries android.Paths 35 installedSharedDeps []string 36} 37 38var _ compiler = (*fuzzDecorator)(nil) 39 40// rust_binary produces a binary that is runnable on a device. 41func RustFuzzFactory() android.Module { 42 module, _ := NewRustFuzz(android.HostAndDeviceSupported) 43 return module.Init() 44} 45 46func NewRustFuzz(hod android.HostOrDeviceSupported) (*Module, *fuzzDecorator) { 47 module, binary := NewRustBinary(hod) 48 fuzz := &fuzzDecorator{ 49 binaryDecorator: binary, 50 } 51 52 // Change the defaults for the binaryDecorator's baseCompiler 53 fuzz.binaryDecorator.baseCompiler.dir = "fuzz" 54 fuzz.binaryDecorator.baseCompiler.dir64 = "fuzz" 55 fuzz.binaryDecorator.baseCompiler.location = InstallInData 56 module.sanitize.SetSanitizer(cc.Fuzzer, true) 57 module.compiler = fuzz 58 return module, fuzz 59} 60 61func (fuzzer *fuzzDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { 62 flags = fuzzer.binaryDecorator.compilerFlags(ctx, flags) 63 64 // `../lib` for installed fuzz targets (both host and device), and `./lib` for fuzz target packages. 65 flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/lib`) 66 67 if ctx.InstallInVendor() { 68 flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/../../lib`) 69 } else { 70 flags.LinkFlags = append(flags.LinkFlags, `-Wl,-rpath,\$$ORIGIN/../lib`) 71 72 } 73 return flags 74} 75 76func (fuzzer *fuzzDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { 77 if libFuzzerRuntimeLibrary := config.LibFuzzerRuntimeLibrary(ctx.toolchain()); libFuzzerRuntimeLibrary != "" { 78 deps.StaticLibs = append(deps.StaticLibs, libFuzzerRuntimeLibrary) 79 } 80 deps.SharedLibs = append(deps.SharedLibs, "libc++") 81 deps.Rlibs = append(deps.Rlibs, "liblibfuzzer_sys") 82 83 deps = fuzzer.binaryDecorator.compilerDeps(ctx, deps) 84 85 return deps 86} 87 88func (fuzzer *fuzzDecorator) compilerProps() []interface{} { 89 return append(fuzzer.binaryDecorator.compilerProps(), 90 &fuzzer.fuzzPackagedModule.FuzzProperties) 91} 92 93func (fuzzer *fuzzDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { 94 95 out := fuzzer.binaryDecorator.compile(ctx, flags, deps) 96 97 return out 98} 99 100func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage { 101 return RlibLinkage 102} 103 104func (fuzzer *fuzzDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { 105 return rlibAutoDep 106} 107 108func (fuzz *fuzzDecorator) install(ctx ModuleContext) { 109 fuzz.binaryDecorator.baseCompiler.dir = filepath.Join( 110 "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) 111 fuzz.binaryDecorator.baseCompiler.dir64 = filepath.Join( 112 "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) 113 fuzz.binaryDecorator.baseCompiler.install(ctx) 114 115 fuzz.fuzzPackagedModule = cc.PackageFuzzModule(ctx, fuzz.fuzzPackagedModule, pctx) 116 117 installBase := "fuzz" 118 119 // Grab the list of required shared libraries. 120 fuzz.sharedLibraries, _ = cc.CollectAllSharedDependencies(ctx) 121 122 for _, lib := range fuzz.sharedLibraries { 123 fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, 124 cc.SharedLibraryInstallLocation( 125 lib, ctx.Host(), installBase, ctx.Arch().ArchType.String())) 126 127 // Also add the dependency on the shared library symbols dir. 128 if !ctx.Host() { 129 fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, 130 cc.SharedLibrarySymbolsInstallLocation(lib, installBase, ctx.Arch().ArchType.String())) 131 } 132 } 133} 134