| // Copyright (C) 2022 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package selinux |
| |
| import ( |
| "encoding/json" |
| "fmt" |
| |
| "android/soong/android" |
| ) |
| |
| func init() { |
| android.RegisterModuleType("fuzzer_bindings_test", fuzzerBindingsTestFactory) |
| android.PreArchMutators(registerFuzzerMutators) |
| } |
| |
| func registerFuzzerMutators(ctx android.RegisterMutatorsContext) { |
| ctx.BottomUp("addFuzzerConfigDeps", addFuzzerConfigDeps).Parallel() |
| } |
| |
| func addFuzzerConfigDeps(ctx android.BottomUpMutatorContext) { |
| if _, ok := ctx.Module().(*fuzzerBindingsTestModule); ok { |
| for _, fuzzers := range ServiceFuzzerBindings { |
| for _, fuzzer := range fuzzers { |
| if !ctx.OtherModuleExists(fuzzer) && !ctx.Config().AllowMissingDependencies() { |
| panic(fmt.Errorf("Fuzzer doesn't exist : %s", fuzzer)) |
| } |
| } |
| } |
| } |
| } |
| |
| type bindingsTestProperties struct { |
| // Contexts files to be tested. |
| Srcs []string `android:"path"` |
| } |
| |
| type fuzzerBindingsTestModule struct { |
| android.ModuleBase |
| tool string |
| properties bindingsTestProperties |
| testTimestamp android.ModuleOutPath |
| } |
| |
| // fuzzer_bindings_test checks if a fuzzer is implemented for every service in service_contexts |
| func fuzzerBindingsTestFactory() android.Module { |
| m := &fuzzerBindingsTestModule{tool: "fuzzer_bindings_check"} |
| m.AddProperties(&m.properties) |
| android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) |
| return m |
| } |
| |
| func (m *fuzzerBindingsTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { |
| tool := m.tool |
| if tool != "fuzzer_bindings_check" { |
| panic(fmt.Errorf("%q: unknown tool name: %q", ctx.ModuleName(), tool)) |
| } |
| |
| if len(m.properties.Srcs) == 0 { |
| ctx.PropertyErrorf("srcs", "can't be empty") |
| return |
| } |
| |
| // Generate a json file which contains existing bindings |
| rootPath := android.PathForIntermediates(ctx, "bindings.json") |
| jsonString, parseError := json.Marshal(ServiceFuzzerBindings) |
| if parseError != nil { |
| panic(fmt.Errorf("Error while marshalling ServiceFuzzerBindings dict. Check Format")) |
| } |
| android.WriteFileRule(ctx, rootPath, string(jsonString)) |
| |
| //input module json, service context and binding files here |
| srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs) |
| rule := android.NewRuleBuilder(pctx, ctx) |
| |
| rule.Command().BuiltTool(tool).Flag("-s").Inputs(srcs).Flag("-b").Input(rootPath) |
| |
| // Every Soong module needs to generate an output even if it doesn't require it |
| m.testTimestamp = android.PathForModuleOut(ctx, "timestamp") |
| rule.Command().Text("touch").Output(m.testTimestamp) |
| rule.Build("fuzzer_bindings_test", "running service:fuzzer bindings test: "+ctx.ModuleName()) |
| } |
| |
| func (m *fuzzerBindingsTestModule) AndroidMkEntries() []android.AndroidMkEntries { |
| return []android.AndroidMkEntries{android.AndroidMkEntries{ |
| Class: "FAKE", |
| // OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it. |
| // Without OutputFile this module won't be exported to Makefile. |
| OutputFile: android.OptionalPathForPath(m.testTimestamp), |
| Include: "$(BUILD_PHONY_PACKAGE)", |
| ExtraEntries: []android.AndroidMkExtraEntriesFunc{ |
| func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { |
| entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", m.testTimestamp.String()) |
| }, |
| }, |
| }} |
| } |