From af193429d46bfdb6f2074a4167b5c2ea1a350adc Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Wed, 23 Jun 2021 23:29:09 +0100 Subject: [PATCH] Verify the modular stub flags are subsets of the monolithic stub flags Bug: 179354495 Test: m out/soong/hiddenapi/hiddenapi-stub-flags.txt - check that an error is reported if a modular stub-flags.csv file, i.e. one created by a fragment is not a subset of the monolithic file, e.g. because a signature in the modular file has different flags than it does in the monolithic or is not present there. Merged-In: I46ebb495cb093a5e3abe7571c49933c845318549 Change-Id: I46ebb495cb093a5e3abe7571c49933c845318549 (cherry picked from commit 2e880971528cd4a2d93062072c7d8e9ff7998ade) --- java/hiddenapi_modular.go | 63 +++++++++++++++++----------- java/platform_bootclasspath.go | 2 +- scripts/hiddenapi/verify_overlaps.py | 6 +-- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 019365734..8a0d6349e 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -236,7 +236,7 @@ func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android. // // The rule is initialized but not built so that the caller can modify it and select an appropriate // name. -func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput) { +func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, moduleStubFlagsPaths android.Paths) { // Singleton rule which applies hiddenapi on all boot class path dex files. rule := android.NewRuleBuilder(pctx, ctx) @@ -276,6 +276,18 @@ func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, // Add the output path. command.FlagWithOutput("--out-api-flags=", tempPath) + // If there are stub flag files that have been generated by fragments on which this depends then + // use them to validate the stub flag file generated by the rules created by this method. + if len(moduleStubFlagsPaths) > 0 { + validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, moduleStubFlagsPaths) + + // Add the file that indicates that the file generated by this is valid. + // + // This will cause the validation rule above to be run any time that the output of this rule + // changes but the validation will run in parallel with other rules that depend on this file. + command.Validation(validFile) + } + commitChangeForRestat(rule, tempPath, outputPath) rule.Build(name, desc) @@ -712,28 +724,6 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlagPaths android.Paths, flagFilesByCategory FlagFilesByCategory, allFlagsPaths android.Paths, generatedRemovedDexSignatures android.OptionalPath) { - // The file which is used to record that the flags file is valid. - var validFile android.WritablePath - - // If there are flag files that have been generated by fragments on which this depends then use - // them to validate the flag file generated by the rules created by this method. - if len(allFlagsPaths) > 0 { - // The flags file generated by the rule created by this method needs to be validated to ensure - // that it is consistent with the flag files generated by the individual fragments. - - validFile = pathForValidation(ctx, outputPath) - - // Create a rule to validate the output from the following rule. - rule := android.NewRuleBuilder(pctx, ctx) - rule.Command(). - BuiltTool("verify_overlaps"). - Input(outputPath). - Inputs(allFlagsPaths). - // If validation passes then update the file that records that. - Text("&& touch").Output(validFile) - rule.Build(name+"Validation", desc+" validation") - } - // Create the rule that will generate the flag files. tempPath := tempPathForRestat(ctx, outputPath) rule := android.NewRuleBuilder(pctx, ctx) @@ -759,7 +749,11 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st commitChangeForRestat(rule, tempPath, outputPath) - if validFile != nil { + // If there are flag files that have been generated by fragments on which this depends then use + // them to validate the flag file generated by the rules created by this method. + if len(allFlagsPaths) > 0 { + validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, allFlagsPaths) + // Add the file that indicates that the file generated by this is valid. // // This will cause the validation rule above to be run any time that the output of this rule @@ -770,6 +764,25 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st rule.Build(name, desc) } +// buildRuleValidateOverlappingCsvFiles checks that the modular CSV files, i.e. the files generated +// by the individual bootclasspath_fragment modules are subsets of the monolithic CSV file. +func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, monolithicFilePath android.WritablePath, modularFilePaths android.Paths) android.WritablePath { + // The file which is used to record that the flags file is valid. + validFile := pathForValidation(ctx, monolithicFilePath) + + // Create a rule to validate the output from the following rule. + rule := android.NewRuleBuilder(pctx, ctx) + rule.Command(). + BuiltTool("verify_overlaps"). + Input(monolithicFilePath). + Inputs(modularFilePaths). + // If validation passes then update the file that records that. + Text("&& touch").Output(validFile) + rule.Build(name+"Validation", desc+" validation") + + return validFile +} + // hiddenAPIRulesForBootclasspathFragment will generate all the flags for a fragment of the // bootclasspath and then encode the flags into the boot dex files. // @@ -793,7 +806,7 @@ func hiddenAPIRulesForBootclasspathFragment(ctx android.ModuleContext, contents // Generate the stub-flags.csv. stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv") - buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input) + buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil) // Extract the classes jars from the contents. classesJars := extractClassesJarsFromModules(contents) diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 667ef3ce7..41b5f1ee2 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -299,7 +299,7 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android. // Generate the monolithic stub-flags.csv file. stubFlags := hiddenAPISingletonPaths(ctx).stubFlags - buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags", stubFlags, bootDexJarByModule.bootDexJars(), input) + buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags", stubFlags, bootDexJarByModule.bootDexJars(), input, monolithicInfo.StubFlagsPaths) // Generate the annotation-flags.csv file from all the module annotations. annotationFlags := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "annotation-flags-from-classes.csv") diff --git a/scripts/hiddenapi/verify_overlaps.py b/scripts/hiddenapi/verify_overlaps.py index c8e387931..bb0917e53 100755 --- a/scripts/hiddenapi/verify_overlaps.py +++ b/scripts/hiddenapi/verify_overlaps.py @@ -47,9 +47,9 @@ for subsetPath in args.subsets: if signature in allFlagsBySignature: allFlags = allFlagsBySignature.get(signature) if allFlags != row: - mismatchingSignatures.append((signature, row[None], allFlags[None])) + mismatchingSignatures.append((signature, row.get(None, []), allFlags.get(None, []))) else: - mismatchingSignatures.append((signature, row[None], [])) + mismatchingSignatures.append((signature, row.get(None, []), [])) if mismatchingSignatures: @@ -60,7 +60,7 @@ for subsetPath in args.subsets: for mismatch in mismatchingSignatures: print() print("< " + mismatch[0] + "," + ",".join(mismatch[1])) - if mismatch[2] != None: + if mismatch[2] != []: print("> " + mismatch[0] + "," + ",".join(mismatch[2])) else: print("> " + mismatch[0] + " - missing")