xref: /aosp_15_r20/build/soong/rust/fuzz.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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