blob: d0f369f2f7fe31db1041875c9e6073bb1bcf5036 [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
Lukacs T. Berki8c77ae32022-05-12 16:30:16 +020053// IsSanitizerEnabledForJni implemented to make JavaFuzzLibrary implement
54// cc.JniSanitizeable. It returns a bool for whether a cc dependency should be
55// sanitized for the given sanitizer or not.
56func (j *JavaFuzzLibrary) IsSanitizerEnabledForJni(ctx android.BaseModuleContext, sanitizerName string) bool {
Muhammad Haseeb Ahmade6567fe2022-05-24 21:09:46 +000057 // TODO: once b/231370928 is resolved, please uncomment the loop
58 // for _, s := range j.jniProperties.Sanitizers {
59 // if sanitizerName == s {
60 // return true
61 // }
62 // }
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +000063 return false
64}
65
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +000066func (j *JavaFuzzLibrary) DepsMutator(mctx android.BottomUpMutatorContext) {
67 if len(j.jniProperties.Jni_libs) > 0 {
68 if j.fuzzPackagedModule.FuzzProperties.Fuzz_config == nil {
69 config := &fuzz.FuzzConfig{}
70 j.fuzzPackagedModule.FuzzProperties.Fuzz_config = config
71 }
72 // this will be used by the ingestion pipeline to determine the version
73 // of jazzer to add to the fuzzer package
74 j.fuzzPackagedModule.FuzzProperties.Fuzz_config.IsJni = proptools.BoolPtr(true)
75
76 for _, target := range mctx.MultiTargets() {
77 sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
78 mctx.AddFarVariationDependencies(sharedLibVariations, cc.JniFuzzLibTag, j.jniProperties.Jni_libs...)
79 }
80 }
81 j.Library.DepsMutator(mctx)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +000082}
83
84func (j *JavaFuzzLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +000085 if j.fuzzPackagedModule.FuzzProperties.Corpus != nil {
86 j.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Corpus)
87 }
88 if j.fuzzPackagedModule.FuzzProperties.Data != nil {
89 j.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Data)
90 }
91 if j.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
92 j.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *j.fuzzPackagedModule.FuzzProperties.Dictionary)
93 }
94
95 if j.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
96 configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
97 android.WriteFileRule(ctx, configPath, j.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
98 j.fuzzPackagedModule.Config = configPath
99 }
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000100
101 ctx.VisitDirectDepsWithTag(cc.JniFuzzLibTag, func(dep android.Module) {
102 sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo)
103 if sharedLibInfo.SharedLibrary != nil {
104 libPath := android.PathForModuleOut(ctx, sharedLibInfo.SharedLibrary.Base())
105 ctx.Build(pctx, android.BuildParams{
106 Rule: android.Cp,
107 Input: sharedLibInfo.SharedLibrary,
108 Output: libPath,
109 })
110 j.jniFilePaths = append(j.jniFilePaths, libPath)
111 } else {
112 ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
113 }
114 })
115
116 j.Library.GenerateAndroidBuildActions(ctx)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000117}
118
119// java_fuzz builds and links sources into a `.jar` file for the host.
120//
121// By default, a java_fuzz produces a `.jar` file containing `.class` files.
122// This jar is not suitable for installing on a device.
123func FuzzFactory() android.Module {
124 module := &JavaFuzzLibrary{}
125
126 module.addHostProperties()
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000127 module.AddProperties(&module.jniProperties)
128 module.Module.properties.Installable = proptools.BoolPtr(true)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000129 module.AddProperties(&module.fuzzPackagedModule.FuzzProperties)
130
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000131 // java_fuzz packaging rules collide when both linux_glibc and linux_bionic are enabled, disable the linux_bionic variants.
132 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
133 disableLinuxBionic := struct {
134 Target struct {
135 Linux_bionic struct {
136 Enabled *bool
137 }
138 }
139 }{}
140 disableLinuxBionic.Target.Linux_bionic.Enabled = proptools.BoolPtr(false)
141 ctx.AppendProperties(&disableLinuxBionic)
142 })
143
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000144 module.initModuleAndImport(module)
145 android.InitSdkAwareModule(module)
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000146 InitJavaModuleMultiTargets(module, android.HostSupported)
Muhammad Haseeb Ahmadaa1d0cf2022-01-01 05:14:32 +0000147 return module
148}
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000149
150// Responsible for generating rules that package fuzz targets into
151// their architecture & target/host specific zip file.
152type javaFuzzPackager struct {
153 fuzz.FuzzPackager
154}
155
156func javaFuzzPackagingFactory() android.Singleton {
157 return &javaFuzzPackager{}
158}
159
160func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
161 // Map between each architecture + host/device combination.
162 archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)
163
164 // List of individual fuzz targets.
165 s.FuzzTargets = make(map[string]bool)
166
167 ctx.VisitAllModules(func(module android.Module) {
168 // Discard non-fuzz targets.
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000169 javaFuzzModule, ok := module.(*JavaFuzzLibrary)
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000170 if !ok {
171 return
172 }
173
Colin Cross39a18142022-06-24 18:43:40 -0700174 if javaFuzzModule.Target().HostCross {
175 return
176 }
177
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000178 fuzzModuleValidator := fuzz.FuzzModule{
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000179 javaFuzzModule.ModuleBase,
180 javaFuzzModule.DefaultableModuleBase,
181 javaFuzzModule.ApexModuleBase,
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000182 }
183
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000184 if ok := fuzz.IsValid(fuzzModuleValidator); !ok {
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000185 return
186 }
187
188 hostOrTargetString := "target"
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000189 if javaFuzzModule.Host() {
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000190 hostOrTargetString = "host"
191 }
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000192 archString := javaFuzzModule.Arch().ArchType.String()
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000193
194 archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
195 archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
196
197 var files []fuzz.FileToZip
198 builder := android.NewRuleBuilder(pctx, ctx)
199
200 // Package the artifacts (data, corpus, config and dictionary into a zipfile.
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000201 files = s.PackageArtifacts(ctx, module, javaFuzzModule.fuzzPackagedModule, archDir, builder)
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000202
203 // Add .jar
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000204 files = append(files, fuzz.FileToZip{javaFuzzModule.outputFile, ""})
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000205
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000206 // Add jni .so files
207 for _, fPath := range javaFuzzModule.jniFilePaths {
208 files = append(files, fuzz.FileToZip{fPath, ""})
209 }
210
211 archDirs[archOs], ok = s.BuildZipFile(ctx, module, javaFuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000212 if !ok {
213 return
214 }
215
216 })
217 s.CreateFuzzPackage(ctx, archDirs, fuzz.Java, pctx)
218}
219
220func (s *javaFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
221 packages := s.Packages.Strings()
222 sort.Strings(packages)
223
224 ctx.Strict("SOONG_JAVA_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
225
226 // Preallocate the slice of fuzz targets to minimize memory allocations.
227 s.PreallocateSlice(ctx, "ALL_JAVA_FUZZ_TARGETS")
228}