blob: 584c80b0cee7c763f2d3c1592ba3a96a0e54e4c6 [file] [log] [blame]
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +00001// Copyright 2021 Google Inc. All rights reserved.
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 java
16
17import (
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +000018 "sort"
19 "strings"
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +000020
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +000021 "github.com/google/blueprint"
22 "github.com/google/blueprint/proptools"
23
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +000024 "android/soong/android"
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +000025 "android/soong/cc"
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +000026 "android/soong/fuzz"
27)
28
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +000029type jniProperties struct {
30 // list of jni libs
31 Jni_libs []string
32
33 // sanitization
34 Sanitizers []string
35}
36
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +000037func init() {
38 RegisterJavaFuzzBuildComponents(android.InitRegistrationContext)
39}
40
41func RegisterJavaFuzzBuildComponents(ctx android.RegistrationContext) {
42 ctx.RegisterModuleType("java_fuzz_host", FuzzFactory)
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +000043 ctx.RegisterSingletonType("java_fuzz_packaging", javaFuzzPackagingFactory)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +000044}
45
46type JavaFuzzLibrary struct {
47 Library
48 fuzzPackagedModule fuzz.FuzzPackagedModule
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +000049 jniProperties jniProperties
50 jniFilePaths android.Paths
51}
52
53// IsSanitizerEnabled implemented to make JavaFuzzLibrary implement
54// cc.Sanitizeable
55func (j *JavaFuzzLibrary) IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool {
56 for _, s := range j.jniProperties.Sanitizers {
57 if sanitizerName == s {
58 return true
59 }
60 }
61 return false
62}
63
64// IsSanitizerEnabledForJni implemented to make JavaFuzzLibrary implement
65// cc.JniSanitizeable. It returns a bool for whether a cc dependency should be
66// sanitized for the given sanitizer or not.
67func (j *JavaFuzzLibrary) IsSanitizerEnabledForJni(ctx android.BaseModuleContext, sanitizerName string) bool {
68 return j.IsSanitizerEnabled(ctx, sanitizerName)
69}
70
71// EnableSanitizer implemented to make JavaFuzzLibrary implement
72// cc.Sanitizeable
73func (j *JavaFuzzLibrary) EnableSanitizer(sanitizerName string) {
74}
75
76// AddSanitizerDependencies implemented to make JavaFuzzLibrary implement
77// cc.Sanitizeable
78func (j *JavaFuzzLibrary) AddSanitizerDependencies(mctx android.BottomUpMutatorContext, sanitizerName string) {
79}
80
81// To verify that JavaFuzzLibrary implements cc.Sanitizeable
82var _ cc.Sanitizeable = (*JavaFuzzLibrary)(nil)
83
84func (j *JavaFuzzLibrary) DepsMutator(mctx android.BottomUpMutatorContext) {
85 if len(j.jniProperties.Jni_libs) > 0 {
86 if j.fuzzPackagedModule.FuzzProperties.Fuzz_config == nil {
87 config := &fuzz.FuzzConfig{}
88 j.fuzzPackagedModule.FuzzProperties.Fuzz_config = config
89 }
90 // this will be used by the ingestion pipeline to determine the version
91 // of jazzer to add to the fuzzer package
92 j.fuzzPackagedModule.FuzzProperties.Fuzz_config.IsJni = proptools.BoolPtr(true)
93
94 for _, target := range mctx.MultiTargets() {
95 sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
96 mctx.AddFarVariationDependencies(sharedLibVariations, cc.JniFuzzLibTag, j.jniProperties.Jni_libs...)
97 }
98 }
99 j.Library.DepsMutator(mctx)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000100}
101
102func (j *JavaFuzzLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000103 if j.fuzzPackagedModule.FuzzProperties.Corpus != nil {
104 j.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Corpus)
105 }
106 if j.fuzzPackagedModule.FuzzProperties.Data != nil {
107 j.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Data)
108 }
109 if j.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
110 j.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *j.fuzzPackagedModule.FuzzProperties.Dictionary)
111 }
112
113 if j.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
114 configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
115 android.WriteFileRule(ctx, configPath, j.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
116 j.fuzzPackagedModule.Config = configPath
117 }
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000118
119 ctx.VisitDirectDepsWithTag(cc.JniFuzzLibTag, func(dep android.Module) {
120 sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo)
121 if sharedLibInfo.SharedLibrary != nil {
122 libPath := android.PathForModuleOut(ctx, sharedLibInfo.SharedLibrary.Base())
123 ctx.Build(pctx, android.BuildParams{
124 Rule: android.Cp,
125 Input: sharedLibInfo.SharedLibrary,
126 Output: libPath,
127 })
128 j.jniFilePaths = append(j.jniFilePaths, libPath)
129 } else {
130 ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
131 }
132 })
133
134 j.Library.GenerateAndroidBuildActions(ctx)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000135}
136
137// java_fuzz builds and links sources into a `.jar` file for the host.
138//
139// By default, a java_fuzz produces a `.jar` file containing `.class` files.
140// This jar is not suitable for installing on a device.
141func FuzzFactory() android.Module {
142 module := &JavaFuzzLibrary{}
143
144 module.addHostProperties()
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000145 module.AddProperties(&module.jniProperties)
146 module.Module.properties.Installable = proptools.BoolPtr(true)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000147 module.AddProperties(&module.fuzzPackagedModule.FuzzProperties)
148
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000149 // java_fuzz packaging rules collide when both linux_glibc and linux_bionic are enabled, disable the linux_bionic variants.
150 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
151 disableLinuxBionic := struct {
152 Target struct {
153 Linux_bionic struct {
154 Enabled *bool
155 }
156 }
157 }{}
158 disableLinuxBionic.Target.Linux_bionic.Enabled = proptools.BoolPtr(false)
159 ctx.AppendProperties(&disableLinuxBionic)
160 })
161
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000162 module.initModuleAndImport(module)
163 android.InitSdkAwareModule(module)
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000164 InitJavaModuleMultiTargets(module, android.HostSupported)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000165 return module
166}
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000167
168// Responsible for generating rules that package fuzz targets into
169// their architecture & target/host specific zip file.
170type javaFuzzPackager struct {
171 fuzz.FuzzPackager
172}
173
174func javaFuzzPackagingFactory() android.Singleton {
175 return &javaFuzzPackager{}
176}
177
178func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
179 // Map between each architecture + host/device combination.
180 archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)
181
182 // List of individual fuzz targets.
183 s.FuzzTargets = make(map[string]bool)
184
185 ctx.VisitAllModules(func(module android.Module) {
186 // Discard non-fuzz targets.
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000187 javaFuzzModule, ok := module.(*JavaFuzzLibrary)
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000188 if !ok {
189 return
190 }
191
192 fuzzModuleValidator := fuzz.FuzzModule{
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000193 javaFuzzModule.ModuleBase,
194 javaFuzzModule.DefaultableModuleBase,
195 javaFuzzModule.ApexModuleBase,
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000196 }
197
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000198 if ok := fuzz.IsValid(fuzzModuleValidator); !ok {
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000199 return
200 }
201
202 hostOrTargetString := "target"
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000203 if javaFuzzModule.Host() {
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000204 hostOrTargetString = "host"
205 }
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000206 archString := javaFuzzModule.Arch().ArchType.String()
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000207
208 archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
209 archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
210
211 var files []fuzz.FileToZip
212 builder := android.NewRuleBuilder(pctx, ctx)
213
214 // Package the artifacts (data, corpus, config and dictionary into a zipfile.
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000215 files = s.PackageArtifacts(ctx, module, javaFuzzModule.fuzzPackagedModule, archDir, builder)
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000216
217 // Add .jar
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000218 files = append(files, fuzz.FileToZip{javaFuzzModule.outputFile, ""})
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000219
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000220 // Add jni .so files
221 for _, fPath := range javaFuzzModule.jniFilePaths {
222 files = append(files, fuzz.FileToZip{fPath, ""})
223 }
224
225 archDirs[archOs], ok = s.BuildZipFile(ctx, module, javaFuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000226 if !ok {
227 return
228 }
229
230 })
231 s.CreateFuzzPackage(ctx, archDirs, fuzz.Java, pctx)
232}
233
234func (s *javaFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
235 packages := s.Packages.Strings()
236 sort.Strings(packages)
237
238 ctx.Strict("SOONG_JAVA_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
239
240 // Preallocate the slice of fuzz targets to minimize memory allocations.
241 s.PreallocateSlice(ctx, "ALL_JAVA_FUZZ_TARGETS")
242}