Merge "make system server modules use filtered lint database"
diff --git a/android/module.go b/android/module.go
index 07d82f1..196b095 100644
--- a/android/module.go
+++ b/android/module.go
@@ -344,8 +344,18 @@
// Deprecated: use ModuleContext.Build instead.
ModuleBuild(pctx PackageContext, params ModuleBuildParams)
+ // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
+ // be tagged with `android:"path" to support automatic source module dependency resolution.
+ //
+ // Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
ExpandSources(srcFiles, excludes []string) Paths
+
+ // Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
+ // be tagged with `android:"path" to support automatic source module dependency resolution.
+ //
+ // Deprecated: use PathForModuleSrc instead.
ExpandSource(srcFile, prop string) Path
+
ExpandOptionalSource(srcFile *string, prop string) OptionalPath
// InstallExecutable creates a rule to copy srcPath to name in the installPath directory,
@@ -473,6 +483,7 @@
InitRc() Paths
VintfFragments() Paths
NoticeFiles() Paths
+ EffectiveLicenseFiles() Paths
AddProperties(props ...interface{})
GetProperties() []interface{}
@@ -1505,6 +1516,10 @@
return m.commonProperties.NamespaceExportedToMake
}
+func (m *ModuleBase) EffectiveLicenseFiles() Paths {
+ return m.commonProperties.Effective_license_text
+}
+
// computeInstallDeps finds the installed paths of all dependencies that have a dependency
// tag that is annotated as needing installation via the IsInstallDepNeeded method.
func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*installPathsDepSet, []*packagingSpecsDepSet) {
@@ -2832,8 +2847,26 @@
return sourceOrOutputDependencyTag{tag: tag}
}
+// Deprecated, use IsSourceDepTagWithOutputTag(tag, "") instead.
var SourceDepTag = sourceOrOutputDepTag("")
+// IsSourceDepTag returns true if the supplied blueprint.DependencyTag is one that was used to add
+// dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for properties
+// tagged with `android:"path"`.
+func IsSourceDepTag(depTag blueprint.DependencyTag) bool {
+ _, ok := depTag.(sourceOrOutputDependencyTag)
+ return ok
+}
+
+// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
+// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
+// properties tagged with `android:"path"` AND it was added using a module reference of
+// :moduleName{outputTag}.
+func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
+ t, ok := depTag.(sourceOrOutputDependencyTag)
+ return ok && t.tag == outputTag
+}
+
// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
// using ":module" syntax, if any.
//
diff --git a/android/namespace.go b/android/namespace.go
index d137636..4f727e1 100644
--- a/android/namespace.go
+++ b/android/namespace.go
@@ -27,7 +27,11 @@
)
func init() {
- RegisterModuleType("soong_namespace", NamespaceFactory)
+ registerNamespaceBuildComponents(InitRegistrationContext)
+}
+
+func registerNamespaceBuildComponents(ctx RegistrationContext) {
+ ctx.RegisterModuleType("soong_namespace", NamespaceFactory)
}
// threadsafe sorted list
diff --git a/android/namespace_test.go b/android/namespace_test.go
index 08e221a..ea399da 100644
--- a/android/namespace_test.go
+++ b/android/namespace_test.go
@@ -636,13 +636,12 @@
result := GroupFixturePreparers(
FixtureModifyContext(func(ctx *TestContext) {
ctx.RegisterModuleType("test_module", newTestModule)
- ctx.RegisterModuleType("soong_namespace", NamespaceFactory)
ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule)
- ctx.PreArchMutators(RegisterNamespaceMutator)
ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
ctx.BottomUp("rename", renameMutator)
})
}),
+ PrepareForTestWithNamespace,
bps.AddToFixture(),
).
// Ignore errors for now so tests can check them later.
diff --git a/android/path_properties_test.go b/android/path_properties_test.go
index 568f868..07b4869 100644
--- a/android/path_properties_test.go
+++ b/android/path_properties_test.go
@@ -63,7 +63,8 @@
if p.props.Foo != "" {
// Make sure there is only one dependency on a module listed in a property present in multiple property structs
- if ctx.GetDirectDepWithTag(SrcIsModule(p.props.Foo), sourceOrOutputDepTag("")) == nil {
+ m := SrcIsModule(p.props.Foo)
+ if GetModuleFromPathDep(ctx, m, "") == nil {
ctx.ModuleErrorf("GetDirectDepWithTag failed")
}
}
diff --git a/android/paths.go b/android/paths.go
index 128ec12..c5e4806 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -446,7 +446,7 @@
// If the dependency is not found, a missingErrorDependency is returned.
// If the module dependency is not a SourceFileProducer or OutputFileProducer, appropriate errors will be returned.
func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag string) (Paths, error) {
- module := ctx.GetDirectDepWithTag(moduleName, sourceOrOutputDepTag(tag))
+ module := GetModuleFromPathDep(ctx, moduleName, tag)
if module == nil {
return nil, missingDependencyError{[]string{moduleName}}
}
@@ -474,6 +474,22 @@
}
}
+// GetModuleFromPathDep will return the module that was added as a dependency automatically for
+// properties tagged with `android:"path"` or manually using ExtractSourceDeps or
+// ExtractSourcesDeps.
+//
+// The moduleName and tag supplied to this should be the values returned from SrcIsModuleWithTag.
+// Or, if no tag is expected then the moduleName should be the value returned by SrcIsModule and
+// the tag must be "".
+//
+// If tag is "" then the returned module will be the dependency that was added for ":moduleName".
+// Otherwise, it is the dependency that was added for ":moduleName{tag}".
+//
+// TODO(b/193228441) Make this handle fully qualified names, e.g. //namespace:moduleName.
+func GetModuleFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag string) blueprint.Module {
+ return ctx.GetDirectDepWithTag(moduleName, sourceOrOutputDepTag(tag))
+}
+
// PathsAndMissingDepsForModuleSrcExcludes returns a Paths{} containing the resolved references in
// paths, minus those listed in excludes. Elements of paths and excludes are resolved as:
// * filepath, relative to local module directory, resolves as a filepath relative to the local
diff --git a/android/testing.go b/android/testing.go
index b36f62c..17a812e 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -110,6 +110,11 @@
FixtureAddFile("build/soong/licenses/LICENSE", nil),
)
+var PrepareForTestWithNamespace = FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ registerNamespaceBuildComponents(ctx)
+ ctx.PreArchMutators(RegisterNamespaceMutator)
+})
+
// Test fixture preparer that will register most java build components.
//
// Singletons and mutators should only be added here if they are needed for a majority of java
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 9640024..adb0a7b 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -130,7 +130,11 @@
},
{
Name: "removePdkProperty",
- Fix: runPatchListMod(removePdkProperty),
+ Fix: runPatchListMod(removeObsoleteProperty("product_variables.pdk")),
+ },
+ {
+ Name: "removeScudoProperty",
+ Fix: runPatchListMod(removeObsoleteProperty("sanitize.scudo")),
},
}
@@ -392,7 +396,7 @@
continue
}
- if !strings.HasPrefix(mod.Type, "java_") && !strings.HasPrefix(mod.Type, "android_") {
+ if !strings.HasPrefix(mod.Type, "java_") && !strings.HasPrefix(mod.Type, "android_") && mod.Type != "cc_binary" {
continue
}
@@ -420,6 +424,14 @@
mod.Type = "java_test_host"
}
}
+
+ // when a cc_binary module has a nonempty test_suites field, modify the type to cc_test
+ if mod.Type == "cc_binary" {
+ hasTestSuites := hasNonEmptyLiteralListProperty(mod, "test_suites")
+ if hasTestSuites {
+ mod.Type = "cc_test"
+ }
+ }
}
return nil
@@ -855,7 +867,9 @@
}
}
-func runPatchListMod(modFunc func(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error) func(*Fixer) error {
+type patchListModFunction func(*parser.Module, []byte, *parser.PatchList) error
+
+func runPatchListMod(modFunc patchListModFunction) func(*Fixer) error {
return func(f *Fixer) error {
// Make sure all the offsets are accurate
buf, err := f.reparse()
@@ -1025,23 +1039,63 @@
return patchlist.Add(prop.Pos().Offset, prop.End().Offset+2, replaceStr)
}
-func removePdkProperty(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error {
- prop, ok := mod.GetProperty("product_variables")
- if !ok {
- return nil
+type propertyProvider interface {
+ GetProperty(string) (*parser.Property, bool)
+ RemoveProperty(string) bool
+}
+
+func removeNestedProperty(mod *parser.Module, patchList *parser.PatchList, propName string) error {
+ propNames := strings.Split(propName, ".")
+
+ var propProvider, toRemoveFrom propertyProvider
+ propProvider = mod
+
+ var propToRemove *parser.Property
+ for i, name := range propNames {
+ p, ok := propProvider.GetProperty(name)
+ if !ok {
+ return nil
+ }
+ // if this is the inner most element, it's time to delete
+ if i == len(propNames)-1 {
+ if propToRemove == nil {
+ // if we cannot remove the properties that the current property is nested in,
+ // remove only the current property
+ propToRemove = p
+ toRemoveFrom = propProvider
+ }
+
+ // remove the property from the list, in case we remove other properties in this list
+ toRemoveFrom.RemoveProperty(propToRemove.Name)
+ // only removing the property would leave blank line(s), remove with a patch
+ if err := patchList.Add(propToRemove.Pos().Offset, propToRemove.End().Offset+2, ""); err != nil {
+ return err
+ }
+ } else {
+ propMap, ok := p.Value.(*parser.Map)
+ if !ok {
+ return nil
+ }
+ if len(propMap.Properties) > 1 {
+ // if there are other properties in this struct, we need to keep this struct
+ toRemoveFrom = nil
+ propToRemove = nil
+ } else if propToRemove == nil {
+ // otherwise, we can remove the empty struct entirely
+ toRemoveFrom = propProvider
+ propToRemove = p
+ }
+ propProvider = propMap
+ }
}
- propMap, ok := prop.Value.(*parser.Map)
- if !ok {
- return nil
+
+ return nil
+}
+
+func removeObsoleteProperty(propName string) patchListModFunction {
+ return func(mod *parser.Module, buf []byte, patchList *parser.PatchList) error {
+ return removeNestedProperty(mod, patchList, propName)
}
- pdkProp, ok := propMap.GetProperty("pdk")
- if !ok {
- return nil
- }
- if len(propMap.Properties) > 1 {
- return patchlist.Add(pdkProp.Pos().Offset, pdkProp.End().Offset+2, "")
- }
- return patchlist.Add(prop.Pos().Offset, prop.End().Offset+2, "")
}
func mergeMatchingModuleProperties(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error {
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index ebfeb22..b994e25 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -999,7 +999,171 @@
}
}
-func TestRemovePdkProperty(t *testing.T) {
+func TestRemoveNestedProperty(t *testing.T) {
+ tests := []struct {
+ name string
+ in string
+ out string
+ propertyName string
+ }{
+ {
+ name: "remove no nesting",
+ in: `
+cc_library {
+ name: "foo",
+ foo: true,
+}`,
+ out: `
+cc_library {
+ name: "foo",
+}
+`,
+ propertyName: "foo",
+ },
+ {
+ name: "remove one nest",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: true,
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+}
+`,
+ propertyName: "foo.bar",
+ },
+ {
+ name: "remove one nest, multiple props",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: true,
+ baz: false,
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+ foo: {
+ baz: false,
+ },
+}
+`,
+ propertyName: "foo.bar",
+ },
+ {
+ name: "remove multiple nest",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ a: true,
+ }
+ },
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+}
+`,
+ propertyName: "foo.bar.baz.a",
+ },
+ {
+ name: "remove multiple nest, outer non-empty",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ a: true,
+ }
+ },
+ other: true,
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+ foo: {
+ other: true,
+ },
+}
+`,
+ propertyName: "foo.bar.baz.a",
+ },
+ {
+ name: "remove multiple nest, inner non-empty",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ a: true,
+ },
+ other: true,
+ },
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ other: true,
+ },
+ },
+}
+`,
+ propertyName: "foo.bar.baz.a",
+ },
+ {
+ name: "remove multiple nest, inner-most non-empty",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ a: true,
+ other: true,
+ },
+ },
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ other: true,
+ },
+ },
+ },
+}
+`,
+ propertyName: "foo.bar.baz.a",
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ runPass(t, test.in, test.out, runPatchListMod(removeObsoleteProperty(test.propertyName)))
+ })
+ }
+}
+
+func TestRemoveObsoleteProperties(t *testing.T) {
tests := []struct {
name string
in string
@@ -1052,7 +1216,7 @@
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- runPass(t, test.in, test.out, runPatchListMod(removePdkProperty))
+ runPass(t, test.in, test.out, runPatchListMod(removeObsoleteProperty("product_variables.pdk")))
})
}
}
@@ -1124,3 +1288,51 @@
})
}
}
+
+func TestRewriteTestModuleTypes(t *testing.T) {
+ tests := []struct {
+ name string
+ in string
+ out string
+ }{
+ {
+ name: "cc_binary with test_suites",
+ in: `
+ cc_binary {
+ name: "foo",
+ srcs: ["srcs"],
+ test_suites: ["test_suite1"],
+ }
+ `,
+ out: `
+ cc_test {
+ name: "foo",
+ srcs: ["srcs"],
+ test_suites: ["test_suite1"],
+ }
+ `,
+ },
+ {
+ name: "cc_binary without test_suites",
+ in: `
+ cc_binary {
+ name: "foo",
+ srcs: ["srcs"],
+ }
+ `,
+ out: `
+ cc_binary {
+ name: "foo",
+ srcs: ["srcs"],
+ }
+ `,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ runPass(t, test.in, test.out, func(fixer *Fixer) error {
+ return rewriteTestModuleTypes(fixer)
+ })
+ })
+ }
+}
diff --git a/cc/binary.go b/cc/binary.go
index 48f70d9..c177a08 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -183,11 +183,6 @@
return deps
}
-func (binary *binaryDecorator) isDependencyRoot() bool {
- // Binaries are always the dependency root.
- return true
-}
-
// NewBinary builds and returns a new Module corresponding to a C++ binary.
// Individual module implementations which comprise a C++ binary should call this function,
// set some fields on the result, and then call the Init function.
diff --git a/cc/cc.go b/cc/cc.go
index 1f73149..aeebaef 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -53,25 +53,9 @@
})
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("asan_deps", sanitizerDepsMutator(Asan))
- ctx.BottomUp("asan", sanitizerMutator(Asan)).Parallel()
-
- ctx.TopDown("hwasan_deps", sanitizerDepsMutator(Hwasan))
- ctx.BottomUp("hwasan", sanitizerMutator(Hwasan)).Parallel()
-
- ctx.TopDown("fuzzer_deps", sanitizerDepsMutator(Fuzzer))
- ctx.BottomUp("fuzzer", sanitizerMutator(Fuzzer)).Parallel()
-
- // cfi mutator shouldn't run before sanitizers that return true for
- // incompatibleWithCfi()
- ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi))
- ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel()
-
- ctx.TopDown("scs_deps", sanitizerDepsMutator(scs))
- ctx.BottomUp("scs", sanitizerMutator(scs)).Parallel()
-
- ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
- ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
+ for _, san := range Sanitizers {
+ san.registerMutators(ctx)
+ }
ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
@@ -1119,17 +1103,6 @@
return c
}
-// Returns true for dependency roots (binaries)
-// TODO(ccross): also handle dlopenable libraries
-func (c *Module) IsDependencyRoot() bool {
- if root, ok := c.linker.(interface {
- isDependencyRoot() bool
- }); ok {
- return root.isDependencyRoot()
- }
- return false
-}
-
func (c *Module) UseVndk() bool {
return c.Properties.VndkVersion != ""
}
@@ -2041,9 +2014,9 @@
}
func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo {
- // Only modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of
+ // Only device modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of
// SnapshotInfo, which provides no mappings.
- if *snapshotInfo == nil {
+ if *snapshotInfo == nil && c.Device() {
// Only retrieve the snapshot on demand in order to avoid circular dependencies
// between the modules in the snapshot and the snapshot itself.
var snapshotModule []blueprint.Module
@@ -2052,16 +2025,16 @@
} else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() {
snapshotModule = actx.AddVariationDependencies(nil, nil, "recovery_snapshot")
}
- if len(snapshotModule) > 0 {
+ if len(snapshotModule) > 0 && snapshotModule[0] != nil {
snapshot := actx.OtherModuleProvider(snapshotModule[0], SnapshotInfoProvider).(SnapshotInfo)
*snapshotInfo = &snapshot
// republish the snapshot for use in later mutators on this module
actx.SetProvider(SnapshotInfoProvider, snapshot)
- } else {
- *snapshotInfo = &SnapshotInfo{}
}
}
-
+ if *snapshotInfo == nil {
+ *snapshotInfo = &SnapshotInfo{}
+ }
return **snapshotInfo
}
diff --git a/cc/linkable.go b/cc/linkable.go
index dd87334..6232efb 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -14,11 +14,6 @@
// SanitizePropDefined returns whether the Sanitizer properties struct for this module is defined.
SanitizePropDefined() bool
- // IsDependencyRoot returns whether a module is of a type which cannot be a linkage dependency
- // of another module. For example, cc_binary and rust_binary represent dependency roots as other
- // modules cannot have linkage dependencies against these types.
- IsDependencyRoot() bool
-
// IsSanitizerEnabled returns whether a sanitizer is enabled.
IsSanitizerEnabled(t SanitizerType) bool
@@ -88,6 +83,9 @@
// SnapshotLibrary returns true if this module is a snapshot library.
IsSnapshotLibrary() bool
+ // EffectiveLicenseFiles returns the list of License files for this module.
+ EffectiveLicenseFiles() android.Paths
+
// SnapshotRuntimeLibs returns a list of libraries needed by this module at runtime but which aren't build dependencies.
SnapshotRuntimeLibs() []string
@@ -127,6 +125,7 @@
IsPrebuilt() bool
Toc() android.OptionalPath
+ Device() bool
Host() bool
InRamdisk() bool
diff --git a/cc/lto.go b/cc/lto.go
index fccb597..d9a0118 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -15,6 +15,8 @@
package cc
import (
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
)
@@ -67,14 +69,14 @@
func (lto *lto) begin(ctx BaseModuleContext) {
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
- lto.Properties.Lto.Never = boolPtr(true)
+ lto.Properties.Lto.Never = proptools.BoolPtr(true)
} else if ctx.Config().IsEnvTrue("GLOBAL_THINLTO") {
staticLib := ctx.static() && !ctx.staticBinary()
hostBin := ctx.Host()
vndk := ctx.isVndk() // b/169217596
if !staticLib && !hostBin && !vndk {
if !lto.Never() && !lto.FullLTO() {
- lto.Properties.Lto.Thin = boolPtr(true)
+ lto.Properties.Lto.Thin = proptools.BoolPtr(true)
}
}
}
@@ -229,12 +231,12 @@
// LTO properties for dependencies
if name == "lto-full" {
- variation.lto.Properties.Lto.Full = boolPtr(true)
- variation.lto.Properties.Lto.Thin = boolPtr(false)
+ variation.lto.Properties.Lto.Full = proptools.BoolPtr(true)
+ variation.lto.Properties.Lto.Thin = proptools.BoolPtr(false)
}
if name == "lto-thin" {
- variation.lto.Properties.Lto.Full = boolPtr(false)
- variation.lto.Properties.Lto.Thin = boolPtr(true)
+ variation.lto.Properties.Lto.Full = proptools.BoolPtr(false)
+ variation.lto.Properties.Lto.Thin = proptools.BoolPtr(true)
}
variation.Properties.PreventInstall = true
variation.Properties.HideFromMake = true
diff --git a/cc/sanitize.go b/cc/sanitize.go
index cdd7dfb..defe8fd 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -21,6 +21,7 @@
"sync"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/cc/config"
@@ -73,25 +74,28 @@
type SanitizerType int
-func boolPtr(v bool) *bool {
- if v {
- return &v
- } else {
- return nil
- }
-}
-
const (
Asan SanitizerType = iota + 1
Hwasan
tsan
intOverflow
- cfi
scs
Fuzzer
memtag_heap
+ cfi // cfi is last to prevent it running before incompatible mutators
)
+var Sanitizers = []SanitizerType{
+ Asan,
+ Hwasan,
+ tsan,
+ intOverflow,
+ scs,
+ Fuzzer,
+ memtag_heap,
+ cfi, // cfi is last to prevent it running before incompatible mutators
+}
+
// Name of the sanitizer variation for this sanitizer type
func (t SanitizerType) variationName() string {
switch t {
@@ -140,6 +144,18 @@
}
}
+func (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) {
+ switch t {
+ case Asan, Hwasan, Fuzzer, scs, tsan, cfi:
+ ctx.TopDown(t.variationName()+"_deps", sanitizerDepsMutator(t))
+ ctx.BottomUp(t.variationName(), sanitizerMutator(t))
+ case memtag_heap, intOverflow:
+ // do nothing
+ default:
+ panic(fmt.Errorf("unknown SanitizerType %d", t))
+ }
+}
+
func (*Module) SanitizerSupported(t SanitizerType) bool {
switch t {
case Asan:
@@ -167,24 +183,46 @@
}
type SanitizeUserProps struct {
+ // Prevent use of any sanitizers on this module
Never *bool `android:"arch_variant"`
- // main sanitizers
- Address *bool `android:"arch_variant"`
- Thread *bool `android:"arch_variant"`
+ // ASan (Address sanitizer), incompatible with static binaries.
+ // Always runs in a diagnostic mode.
+ // Use of address sanitizer disables cfi sanitizer.
+ // Hwaddress sanitizer takes precedence over this sanitizer.
+ Address *bool `android:"arch_variant"`
+ // TSan (Thread sanitizer), incompatible with static binaries and 32 bit architectures.
+ // Always runs in a diagnostic mode.
+ // Use of thread sanitizer disables cfi and scudo sanitizers.
+ // Hwaddress sanitizer takes precedence over this sanitizer.
+ Thread *bool `android:"arch_variant"`
+ // HWASan (Hardware Address sanitizer).
+ // Use of hwasan sanitizer disables cfi, address, thread, and scudo sanitizers.
Hwaddress *bool `android:"arch_variant"`
- // local sanitizers
- Undefined *bool `android:"arch_variant"`
- All_undefined *bool `android:"arch_variant"`
- Misc_undefined []string `android:"arch_variant"`
- Fuzzer *bool `android:"arch_variant"`
- Safestack *bool `android:"arch_variant"`
- Cfi *bool `android:"arch_variant"`
- Integer_overflow *bool `android:"arch_variant"`
- Scudo *bool `android:"arch_variant"`
- Scs *bool `android:"arch_variant"`
- Memtag_heap *bool `android:"arch_variant"`
+ // Undefined behavior sanitizer
+ All_undefined *bool `android:"arch_variant"`
+ // Subset of undefined behavior sanitizer
+ Undefined *bool `android:"arch_variant"`
+ // List of specific undefined behavior sanitizers to enable
+ Misc_undefined []string `android:"arch_variant"`
+ // Fuzzer, incompatible with static binaries.
+ Fuzzer *bool `android:"arch_variant"`
+ // safe-stack sanitizer, incompatible with 32-bit architectures.
+ Safestack *bool `android:"arch_variant"`
+ // cfi sanitizer, incompatible with asan, hwasan, fuzzer, or Darwin
+ Cfi *bool `android:"arch_variant"`
+ // signed/unsigned integer overflow sanitizer, incompatible with Darwin.
+ Integer_overflow *bool `android:"arch_variant"`
+ // scudo sanitizer, incompatible with asan, hwasan, tsan
+ // This should not be used in Android 11+ : https://source.android.com/devices/tech/debug/scudo
+ // deprecated
+ Scudo *bool `android:"arch_variant"`
+ // shadow-call-stack sanitizer, only available on arm64
+ Scs *bool `android:"arch_variant"`
+ // Memory-tagging, only available on arm64
+ // if diag.memtag unset or false, enables async memory tagging
+ Memtag_heap *bool `android:"arch_variant"`
// A modifier for ASAN and HWASAN for write only instrumentation
Writeonly *bool `android:"arch_variant"`
@@ -193,12 +231,22 @@
// Replaces abort() on error with a human-readable error message.
// Address and Thread sanitizers always run in diagnostic mode.
Diag struct {
- Undefined *bool `android:"arch_variant"`
- Cfi *bool `android:"arch_variant"`
- Integer_overflow *bool `android:"arch_variant"`
- Memtag_heap *bool `android:"arch_variant"`
- Misc_undefined []string `android:"arch_variant"`
- No_recover []string `android:"arch_variant"`
+ // Undefined behavior sanitizer, diagnostic mode
+ Undefined *bool `android:"arch_variant"`
+ // cfi sanitizer, diagnostic mode, incompatible with asan, hwasan, fuzzer, or Darwin
+ Cfi *bool `android:"arch_variant"`
+ // signed/unsigned integer overflow sanitizer, diagnostic mode, incompatible with Darwin.
+ Integer_overflow *bool `android:"arch_variant"`
+ // Memory-tagging, only available on arm64
+ // requires sanitizer.memtag: true
+ // if set, enables sync memory tagging
+ Memtag_heap *bool `android:"arch_variant"`
+ // List of specific undefined behavior sanitizers to enable in diagnostic mode
+ Misc_undefined []string `android:"arch_variant"`
+ // List of sanitizers to pass to -fno-sanitize-recover
+ // results in only the first detected error for these sanitizers being reported and program then
+ // exits with a non-zero exit code.
+ No_recover []string `android:"arch_variant"`
} `android:"arch_variant"`
// Sanitizers to run with flag configuration specified
@@ -207,7 +255,9 @@
Cfi_assembly_support *bool `android:"arch_variant"`
} `android:"arch_variant"`
- // value to pass to -fsanitize-recover=
+ // List of sanitizers to pass to -fsanitize-recover
+ // allows execution to continue for these sanitizers to detect multiple errors rather than only
+ // the first one
Recover []string
// value to pass to -fsanitize-blacklist
@@ -215,9 +265,7 @@
}
type SanitizeProperties struct {
- // Enable AddressSanitizer, ThreadSanitizer, UndefinedBehaviorSanitizer, and
- // others. Please see SanitizerUserProps in build/soong/cc/sanitize.go for
- // details.
+ // Sanitizers are not supported for Fuchsia.
Sanitize SanitizeUserProps `android:"arch_variant"`
SanitizerEnabled bool `blueprint:"mutated"`
SanitizeDep bool `blueprint:"mutated"`
@@ -268,9 +316,13 @@
}
// cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}).
- if ctx.testBinary() && s.Memtag_heap == nil {
- s.Memtag_heap = boolPtr(true)
- s.Diag.Memtag_heap = boolPtr(true)
+ if ctx.testBinary() {
+ if s.Memtag_heap == nil {
+ s.Memtag_heap = proptools.BoolPtr(true)
+ }
+ if s.Diag.Memtag_heap == nil {
+ s.Diag.Memtag_heap = proptools.BoolPtr(true)
+ }
}
var globalSanitizers []string
@@ -291,48 +343,48 @@
if len(globalSanitizers) > 0 {
var found bool
if found, globalSanitizers = removeFromList("undefined", globalSanitizers); found && s.All_undefined == nil {
- s.All_undefined = boolPtr(true)
+ s.All_undefined = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("default-ub", globalSanitizers); found && s.Undefined == nil {
- s.Undefined = boolPtr(true)
+ s.Undefined = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("address", globalSanitizers); found && s.Address == nil {
- s.Address = boolPtr(true)
+ s.Address = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("thread", globalSanitizers); found && s.Thread == nil {
- s.Thread = boolPtr(true)
+ s.Thread = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil {
- s.Fuzzer = boolPtr(true)
+ s.Fuzzer = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("safe-stack", globalSanitizers); found && s.Safestack == nil {
- s.Safestack = boolPtr(true)
+ s.Safestack = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("cfi", globalSanitizers); found && s.Cfi == nil {
if !ctx.Config().CFIDisabledForPath(ctx.ModuleDir()) {
- s.Cfi = boolPtr(true)
+ s.Cfi = proptools.BoolPtr(true)
}
}
// Global integer_overflow builds do not support static libraries.
if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) && !ctx.static() {
- s.Integer_overflow = boolPtr(true)
+ s.Integer_overflow = proptools.BoolPtr(true)
}
}
if found, globalSanitizers = removeFromList("scudo", globalSanitizers); found && s.Scudo == nil {
- s.Scudo = boolPtr(true)
+ s.Scudo = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil {
- s.Hwaddress = boolPtr(true)
+ s.Hwaddress = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("writeonly", globalSanitizers); found && s.Writeonly == nil {
@@ -341,11 +393,11 @@
if s.Address == nil && s.Hwaddress == nil {
ctx.ModuleErrorf("writeonly modifier cannot be used without 'address' or 'hwaddress'")
}
- s.Writeonly = boolPtr(true)
+ s.Writeonly = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("memtag_heap", globalSanitizers); found && s.Memtag_heap == nil {
if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) {
- s.Memtag_heap = boolPtr(true)
+ s.Memtag_heap = proptools.BoolPtr(true)
}
}
@@ -356,17 +408,17 @@
// Global integer_overflow builds do not support static library diagnostics.
if found, globalSanitizersDiag = removeFromList("integer_overflow", globalSanitizersDiag); found &&
s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) && !ctx.static() {
- s.Diag.Integer_overflow = boolPtr(true)
+ s.Diag.Integer_overflow = proptools.BoolPtr(true)
}
if found, globalSanitizersDiag = removeFromList("cfi", globalSanitizersDiag); found &&
s.Diag.Cfi == nil && Bool(s.Cfi) {
- s.Diag.Cfi = boolPtr(true)
+ s.Diag.Cfi = proptools.BoolPtr(true)
}
if found, globalSanitizersDiag = removeFromList("memtag_heap", globalSanitizersDiag); found &&
s.Diag.Memtag_heap == nil && Bool(s.Memtag_heap) {
- s.Diag.Memtag_heap = boolPtr(true)
+ s.Diag.Memtag_heap = proptools.BoolPtr(true)
}
if len(globalSanitizersDiag) > 0 {
@@ -378,30 +430,30 @@
if ctx.Arch().ArchType == android.Arm64 {
if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
if s.Memtag_heap == nil {
- s.Memtag_heap = boolPtr(true)
+ s.Memtag_heap = proptools.BoolPtr(true)
}
if s.Diag.Memtag_heap == nil {
- s.Diag.Memtag_heap = boolPtr(true)
+ s.Diag.Memtag_heap = proptools.BoolPtr(true)
}
} else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) {
if s.Memtag_heap == nil {
- s.Memtag_heap = boolPtr(true)
+ s.Memtag_heap = proptools.BoolPtr(true)
}
}
}
// Enable CFI for all components in the include paths (for Aarch64 only)
if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 {
- s.Cfi = boolPtr(true)
+ s.Cfi = proptools.BoolPtr(true)
if inList("cfi", ctx.Config().SanitizeDeviceDiag()) {
- s.Diag.Cfi = boolPtr(true)
+ s.Diag.Cfi = proptools.BoolPtr(true)
}
}
// Is CFI actually enabled?
if !ctx.Config().EnableCFI() {
- s.Cfi = boolPtr(false)
- s.Diag.Cfi = boolPtr(false)
+ s.Cfi = nil
+ s.Diag.Cfi = nil
}
// HWASan requires AArch64 hardware feature (top-byte-ignore).
@@ -421,14 +473,14 @@
// Also disable CFI if ASAN is enabled.
if Bool(s.Address) || Bool(s.Hwaddress) {
- s.Cfi = boolPtr(false)
- s.Diag.Cfi = boolPtr(false)
+ s.Cfi = nil
+ s.Diag.Cfi = nil
}
// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
if !ctx.Os().Linux() {
- s.Cfi = boolPtr(false)
- s.Diag.Cfi = boolPtr(false)
+ s.Cfi = nil
+ s.Diag.Cfi = nil
s.Misc_undefined = nil
s.Undefined = nil
s.All_undefined = nil
@@ -443,8 +495,8 @@
s.Cfi = nil
s.Diag.Cfi = nil
} else {
- s.Cfi = boolPtr(false)
- s.Diag.Cfi = boolPtr(false)
+ s.Cfi = nil
+ s.Diag.Cfi = nil
}
}
@@ -495,7 +547,7 @@
// TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
// mutually incompatible.
if Bool(s.Fuzzer) {
- s.Cfi = boolPtr(false)
+ s.Cfi = nil
}
}
@@ -781,23 +833,27 @@
}
func (sanitize *sanitize) SetSanitizer(t SanitizerType, b bool) {
+ bPtr := proptools.BoolPtr(b)
+ if !b {
+ bPtr = nil
+ }
switch t {
case Asan:
- sanitize.Properties.Sanitize.Address = boolPtr(b)
+ sanitize.Properties.Sanitize.Address = bPtr
case Hwasan:
- sanitize.Properties.Sanitize.Hwaddress = boolPtr(b)
+ sanitize.Properties.Sanitize.Hwaddress = bPtr
case tsan:
- sanitize.Properties.Sanitize.Thread = boolPtr(b)
+ sanitize.Properties.Sanitize.Thread = bPtr
case intOverflow:
- sanitize.Properties.Sanitize.Integer_overflow = boolPtr(b)
+ sanitize.Properties.Sanitize.Integer_overflow = bPtr
case cfi:
- sanitize.Properties.Sanitize.Cfi = boolPtr(b)
+ sanitize.Properties.Sanitize.Cfi = bPtr
case scs:
- sanitize.Properties.Sanitize.Scs = boolPtr(b)
+ sanitize.Properties.Sanitize.Scs = bPtr
case memtag_heap:
- sanitize.Properties.Sanitize.Memtag_heap = boolPtr(b)
+ sanitize.Properties.Sanitize.Memtag_heap = bPtr
case Fuzzer:
- sanitize.Properties.Sanitize.Fuzzer = boolPtr(b)
+ sanitize.Properties.Sanitize.Fuzzer = bPtr
default:
panic(fmt.Errorf("unknown SanitizerType %d", t))
}
@@ -1253,7 +1309,7 @@
func sanitizerMutator(t SanitizerType) func(android.BottomUpMutatorContext) {
return func(mctx android.BottomUpMutatorContext) {
if c, ok := mctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
- if c.IsDependencyRoot() && c.IsSanitizerEnabled(t) {
+ if c.Binary() && c.IsSanitizerEnabled(t) {
modules := mctx.CreateVariations(t.variationName())
modules[0].(PlatformSanitizeable).SetSanitizer(t, true)
} else if c.IsSanitizerEnabled(t) || c.SanitizeDep() {
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 4430fc3..0070e40 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -222,11 +222,12 @@
case Async:
return "async"
default:
- panic("invalid note type")
+ panic("type_note_invalid")
}
}
func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) {
+ t.Helper()
note_async := "note_memtag_heap_async"
note_sync := "note_memtag_heap_sync"
@@ -251,75 +252,86 @@
android.FixtureModifyMockFS(func(fs android.MockFS) {
templateBp := `
cc_test {
- name: "%[1]s_test",
+ name: "unset_test_%[1]s",
gtest: false,
}
cc_test {
- name: "%[1]s_test_false",
+ name: "no_memtag_test_%[1]s",
gtest: false,
sanitize: { memtag_heap: false },
}
cc_test {
- name: "%[1]s_test_true",
+ name: "set_memtag_test_%[1]s",
gtest: false,
sanitize: { memtag_heap: true },
}
cc_test {
- name: "%[1]s_test_true_nodiag",
+ name: "set_memtag_set_async_test_%[1]s",
gtest: false,
sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
}
cc_test {
- name: "%[1]s_test_true_diag",
+ name: "set_memtag_set_sync_test_%[1]s",
gtest: false,
sanitize: { memtag_heap: true, diag: { memtag_heap: true } },
}
- cc_binary {
- name: "%[1]s_binary",
+ cc_test {
+ name: "unset_memtag_set_sync_test_%[1]s",
+ gtest: false,
+ sanitize: { diag: { memtag_heap: true } },
}
cc_binary {
- name: "%[1]s_binary_false",
+ name: "unset_binary_%[1]s",
+ }
+
+ cc_binary {
+ name: "no_memtag_binary_%[1]s",
sanitize: { memtag_heap: false },
}
cc_binary {
- name: "%[1]s_binary_true",
+ name: "set_memtag_binary_%[1]s",
sanitize: { memtag_heap: true },
}
cc_binary {
- name: "%[1]s_binary_true_nodiag",
+ name: "set_memtag_set_async_binary_%[1]s",
sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
}
cc_binary {
- name: "%[1]s_binary_true_diag",
+ name: "set_memtag_set_sync_binary_%[1]s",
sanitize: { memtag_heap: true, diag: { memtag_heap: true } },
}
+
+ cc_binary {
+ name: "unset_memtag_set_sync_binary_%[1]s",
+ sanitize: { diag: { memtag_heap: true } },
+ }
`
- subdirDefaultBp := fmt.Sprintf(templateBp, "default")
- subdirExcludeBp := fmt.Sprintf(templateBp, "exclude")
- subdirSyncBp := fmt.Sprintf(templateBp, "sync")
- subdirAsyncBp := fmt.Sprintf(templateBp, "async")
+ subdirNoOverrideBp := fmt.Sprintf(templateBp, "no_override")
+ subdirOverrideDefaultDisableBp := fmt.Sprintf(templateBp, "override_default_disable")
+ subdirSyncBp := fmt.Sprintf(templateBp, "override_default_sync")
+ subdirAsyncBp := fmt.Sprintf(templateBp, "override_default_async")
fs.Merge(android.MockFS{
- "subdir_default/Android.bp": []byte(subdirDefaultBp),
- "subdir_exclude/Android.bp": []byte(subdirExcludeBp),
- "subdir_sync/Android.bp": []byte(subdirSyncBp),
- "subdir_async/Android.bp": []byte(subdirAsyncBp),
+ "subdir_no_override/Android.bp": []byte(subdirNoOverrideBp),
+ "subdir_override_default_disable/Android.bp": []byte(subdirOverrideDefaultDisableBp),
+ "subdir_sync/Android.bp": []byte(subdirSyncBp),
+ "subdir_async/Android.bp": []byte(subdirAsyncBp),
})
}),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.MemtagHeapExcludePaths = []string{"subdir_exclude"}
- // "subdir_exclude" is covered by both include and exclude paths. Exclude wins.
- variables.MemtagHeapSyncIncludePaths = []string{"subdir_sync", "subdir_exclude"}
- variables.MemtagHeapAsyncIncludePaths = []string{"subdir_async", "subdir_exclude"}
+ variables.MemtagHeapExcludePaths = []string{"subdir_override_default_disable"}
+ // "subdir_override_default_disable" is covered by both include and override_default_disable paths. override_default_disable wins.
+ variables.MemtagHeapSyncIncludePaths = []string{"subdir_sync", "subdir_override_default_disable"}
+ variables.MemtagHeapAsyncIncludePaths = []string{"subdir_async", "subdir_override_default_disable"}
}),
)
@@ -332,53 +344,67 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ // should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ // should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
}
func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
@@ -393,53 +419,66 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ // should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
}
func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
@@ -455,51 +494,64 @@
).RunTest(t)
ctx := result.TestContext
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ // should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
}
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 7ba2363..003b7c9 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -501,13 +501,13 @@
headers = append(headers, m.SnapshotHeaders()...)
}
- if len(m.NoticeFiles()) > 0 {
+ if len(m.EffectiveLicenseFiles()) > 0 {
noticeName := ctx.ModuleName(m) + ".txt"
noticeOut := filepath.Join(noticeDir, noticeName)
// skip already copied notice file
if !installedNotices[noticeOut] {
installedNotices[noticeOut] = true
- snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.NoticeFiles(), noticeOut))
+ snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.EffectiveLicenseFiles(), noticeOut))
}
}
})
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index ebd22cf..bdf0dae 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -674,10 +674,6 @@
return nil
}
- // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
- // GenerateSingletonBuildActions method as it cannot create it for itself.
- dexpreopt.GetGlobalSoongConfig(ctx)
-
// Only generate the boot image if the configuration does not skip it.
return b.generateBootImageBuildActions(ctx, imageConfig)
}
@@ -706,7 +702,16 @@
// Build a profile for the image config and then use that to build the boot image.
profile := bootImageProfileRule(ctx, imageConfig)
- return buildBootImage(ctx, imageConfig, profile)
+
+ // Build boot image files for the host variants.
+ buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
+
+ // Build boot image files for the android variants.
+ androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
+
+ // Return the boot image files for the android variants for inclusion in an APEX and to be zipped
+ // up for the dist.
+ return androidBootImageFilesByArch
}
// Collect information for opening IDE project files in java/jdeps.go.
@@ -977,6 +982,12 @@
}
}
+ // Build the boot image files for the host variants. These are built from the dex files provided
+ // by the contents of this module as prebuilt versions of the host boot image files are not
+ // available, i.e. there is no host specific prebuilt apex containing them. This has to be built
+ // without a profile as the prebuilt modules do not provide a profile.
+ buildBootImageVariantsForBuildOs(ctx, imageConfig, nil)
+
return files
}
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
new file mode 100644
index 0000000..51d998a
--- /dev/null
+++ b/java/core-libraries/Android.bp
@@ -0,0 +1,194 @@
+// Copyright (C) 2021 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.
+
+//
+// Definitions for building the Android core libraries, i.e. ART, I18n and
+// Conscrypt.
+//
+// These are here as the definitions are used by the build itself and include
+// parts from all three of those modules.
+//
+
+// A stubs target containing the parts of the public SDK API provided by the
+// core libraries.
+//
+// Don't use this directly, use "sdk_version: core_current".
+java_library {
+ name: "core.current.stubs",
+ visibility: ["//visibility:public"],
+ static_libs: [
+ "art.module.public.api.stubs",
+ "conscrypt.module.public.api.stubs",
+ "i18n.module.public.api.stubs",
+ ],
+ sdk_version: "none",
+ system_modules: "none",
+
+ dist: {
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
+ },
+}
+
+// Distributed with the SDK for turning into system modules to compile apps
+// against.
+java_library {
+ name: "core-current-stubs-for-system-modules",
+ visibility: ["//development/sdk"],
+ static_libs: [
+ "core.current.stubs",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs-for-system-modules",
+ // This one is not on device but it's needed when javac compiles code
+ // containing @Generated annotations produced by some code generation
+ // tools.
+ // See http://b/123891440.
+ "core-generated-annotation-stubs",
+ ],
+ sdk_version: "none",
+ system_modules: "none",
+ dist: {
+ dest: "core-for-system-modules.jar",
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
+ },
+}
+
+// Used when compiling higher-level code against core.current.stubs.
+java_system_modules {
+ name: "core-current-stubs-system-modules",
+ visibility: ["//visibility:public"],
+ libs: [
+ "core-current-stubs-for-system-modules",
+ ],
+}
+
+// A stubs target containing the parts of the public SDK & @SystemApi(MODULE_LIBRARIES) API
+// provided by the core libraries.
+//
+// Don't use this directly, use "sdk_version: module_current".
+java_library {
+ name: "core.module_lib.stubs",
+ static_libs: [
+ "art.module.public.api.stubs.module_lib",
+
+ // Replace the following with the module-lib correspondence when Conscrypt or i18N module
+ // provides @SystemApi(MODULE_LIBRARIES). Currently, assume that only ART module provides
+ // @SystemApi(MODULE_LIBRARIES).
+ "conscrypt.module.public.api.stubs",
+ "i18n.module.public.api.stubs",
+ ],
+ sdk_version: "none",
+ system_modules: "none",
+ visibility: ["//visibility:private"],
+}
+
+// Used when compiling higher-level code with sdk_version "module_current"
+java_system_modules {
+ name: "core-module-lib-stubs-system-modules",
+ libs: [
+ "core.module_lib.stubs",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs-for-system-modules",
+ // This one is not on device but it's needed when javac compiles code
+ // containing @Generated annotations produced by some code generation
+ // tools.
+ // See http://b/123891440.
+ "core-generated-annotation-stubs",
+ ],
+ visibility: ["//visibility:public"],
+}
+
+// Ideally this should be a restricted allowlist but there are hundreds of modules that depend on
+// this.
+// TODO(http://b/134561230) - limit the number of dependents on this.
+core_platform_visibility = ["//visibility:public"]
+
+// Libraries containing the core platform API stubs for the core libraries.
+//
+// Although this stubs library is primarily used by the Java compiler / build to indicate
+// the core platform API surface area, compile_dex: true is used so that the Core Platform
+// API annotations are available to the dex tools that enable enforcement of runtime
+// accessibility. b/119068555
+java_library {
+ name: "legacy.core.platform.api.stubs",
+ visibility: core_platform_visibility,
+ hostdex: true,
+ compile_dex: true,
+
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: [
+ "art.module.public.api.stubs.module_lib",
+ "conscrypt.module.platform.api.stubs",
+ "legacy.i18n.module.platform.api.stubs",
+ ],
+ patch_module: "java.base",
+}
+
+java_library {
+ name: "stable.core.platform.api.stubs",
+ visibility: core_platform_visibility,
+ hostdex: true,
+ compile_dex: true,
+
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: [
+ "art.module.public.api.stubs.module_lib",
+ // conscrypt only has a stable version, so it is okay to depend on it here:
+ "conscrypt.module.platform.api.stubs",
+ "stable.i18n.module.platform.api.stubs",
+ ],
+ patch_module: "java.base",
+}
+
+// Used when compiling higher-level code against *.core.platform.api.stubs.
+java_system_modules {
+ name: "legacy-core-platform-api-stubs-system-modules",
+ visibility: core_platform_visibility,
+ libs: [
+ "legacy.core.platform.api.stubs",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs-for-system-modules",
+ // This one is not on device but it's needed when javac compiles code
+ // containing @Generated annotations produced by some code generation
+ // tools.
+ // See http://b/123891440.
+ "core-generated-annotation-stubs",
+ ],
+}
+
+java_system_modules {
+ name: "stable-core-platform-api-stubs-system-modules",
+ visibility: core_platform_visibility,
+ libs: [
+ "stable.core.platform.api.stubs",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs-for-system-modules",
+ // This one is not on device but it's needed when javac compiles code
+ // containing @Generated annotations produced by some code generation
+ // tools.
+ // See http://b/123891440.
+ "core-generated-annotation-stubs",
+ ],
+}
diff --git a/java/core-libraries/OWNERS b/java/core-libraries/OWNERS
new file mode 100644
index 0000000..bb3546a
--- /dev/null
+++ b/java/core-libraries/OWNERS
@@ -0,0 +1,3 @@
+include platform/external/icu:/OWNERS
+include platform/external/conscrypt:/OWNERS
+include platform/libcore:/OWNERS
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index cb5b6be..19c65ca 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -502,14 +502,36 @@
}
}
-// buildBootImage takes a bootImageConfig, and creates rules to build it.
+// buildBootImageVariantsForAndroidOs generates rules to build the boot image variants for the
+// android.Android OsType and returns a map from the architectures to the paths of the generated
+// boot image files.
+//
+// The paths are returned because they are needed elsewhere in Soong, e.g. for populating an APEX.
+func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageFilesByArch {
+ return buildBootImageForOsType(ctx, image, profile, android.Android)
+}
+
+// buildBootImageVariantsForBuildOs generates rules to build the boot image variants for the
+// android.BuildOs OsType, i.e. the type of OS on which the build is being running.
+//
+// The files need to be generated into their predefined location because they are used from there
+// both within Soong and outside, e.g. for ART based host side testing and also for use by some
+// cloud based tools. However, they are not needed by callers of this function and so the paths do
+// not need to be returned from this func, unlike the buildBootImageVariantsForAndroidOs func.
+func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) {
+ buildBootImageForOsType(ctx, image, profile, android.BuildOs)
+}
+
+// buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType
+// boot image files are required for and it creates rules to build the boot image
+// files for all the required architectures for them.
//
// It returns a map from android.ArchType to the predefined paths of the boot image files.
-func buildBootImage(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageFilesByArch {
+func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageFilesByArch {
filesByArch := bootImageFilesByArch{}
for _, variant := range image.variants {
- buildBootImageVariant(ctx, variant, profile)
- if variant.target.Os == android.Android {
+ if variant.target.Os == requiredOsType {
+ buildBootImageVariant(ctx, variant, profile)
filesByArch[variant.target.Arch.ArchType] = variant.imagesDeps.Paths()
}
}
@@ -545,7 +567,7 @@
// Generate boot image build rules for a specific target.
func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) {
- globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
+ globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
arch := image.target.Arch.ArchType
@@ -696,7 +718,7 @@
Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) android.WritablePath {
- globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
+ globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
if global.DisableGenerateProfile {
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 3160a27..c1e14b2 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -437,10 +437,15 @@
// Build a profile for the image config and then use that to build the boot image.
profile := bootImageProfileRule(ctx, imageConfig)
- bootImageFilesByArch := buildBootImage(ctx, imageConfig, profile)
- // Zip the boot image files up.
- buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFilesByArch)
+ // Build boot image files for the android variants.
+ androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
+
+ // Zip the android variant boot image files up.
+ buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFilesByArch)
+
+ // Build boot image files for the host variants. There are use directly by ART host side tests.
+ buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
dumpOatRules(ctx, imageConfig)
}
diff --git a/mk2rbc/android_products.go b/mk2rbc/android_products.go
new file mode 100644
index 0000000..de38391
--- /dev/null
+++ b/mk2rbc/android_products.go
@@ -0,0 +1,110 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+// Implements mkparser.Scope, to be used by mkparser.Value.Value()
+type localDirEval struct {
+ localDir string
+ hasErrors bool
+}
+
+func (l *localDirEval) Get(name string) string {
+ if name == "LOCAL_DIR" {
+ return l.localDir
+ }
+ l.hasErrors = true
+ return fmt.Sprintf("$(%s)", name)
+}
+
+func (l *localDirEval) Set(_, _ string) {
+}
+
+func (l *localDirEval) Call(_ string, _ []string) []string {
+ l.hasErrors = true
+ return []string{"$(call ...)"}
+}
+
+func (l *localDirEval) SetFunc(_ string, _ func([]string) []string) {
+}
+
+// UpdateProductConfigMap builds product configuration map.
+// The product configuration map maps a product name (i.e., the value of the
+// TARGET_PRODUCT variable) to the top-level configuration file.
+// In the Android's Make-based build machinery, the equivalent of the
+// product configuration map is $(PRODUCT_MAKEFILES), which is the list
+// of <product>:<configuration makefile> pairs (if <product>: is missing,
+// <product> is the basename of the configuration makefile).
+// UpdateProductConfigMap emulates this build logic by processing the
+// assignments to PRODUCT_MAKEFILES in the file passed to it.
+func UpdateProductConfigMap(configMap map[string]string, configMakefile string) error {
+ contents, err := ioutil.ReadFile(configMakefile)
+ if err != nil {
+ return err
+ }
+ parser := mkparser.NewParser(configMakefile, bytes.NewBuffer(contents))
+ nodes, errs := parser.Parse()
+ if len(errs) > 0 {
+ for _, e := range errs {
+ fmt.Fprintln(os.Stderr, "ERROR:", e)
+ }
+ return fmt.Errorf("cannot parse %s", configMakefile)
+ }
+
+ ldEval := &localDirEval{localDir: filepath.Dir(configMakefile)}
+
+ for _, node := range nodes {
+ // We are interested in assignments to 'PRODUCT_MAKEFILES'
+ asgn, ok := node.(*mkparser.Assignment)
+ if !ok {
+ continue
+ }
+ if !(asgn.Name.Const() && asgn.Name.Strings[0] == "PRODUCT_MAKEFILES") {
+ continue
+ }
+
+ // Resolve the references to $(LOCAL_DIR) in $(PRODUCT_MAKEFILES).
+ ldEval.hasErrors = false
+ value := asgn.Value.Value(ldEval)
+ if ldEval.hasErrors {
+ return fmt.Errorf("cannot evaluate %s", asgn.Value.Dump())
+ }
+ // Each item is either <product>:<configuration makefile>, or
+ // just <configuration makefile>
+ for _, token := range strings.Fields(value) {
+ var product, config_path string
+ if n := strings.Index(token, ":"); n >= 0 {
+ product = token[0:n]
+ config_path = token[n+1:]
+ } else {
+ config_path = token
+ product = filepath.Base(config_path)
+ product = strings.TrimSuffix(product, filepath.Ext(product))
+ }
+ configMap[product] = config_path
+ }
+ }
+ return nil
+}
diff --git a/mk2rbc/android_products_test.go b/mk2rbc/android_products_test.go
new file mode 100644
index 0000000..f8c930a
--- /dev/null
+++ b/mk2rbc/android_products_test.go
@@ -0,0 +1,38 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "path/filepath"
+ "reflect"
+ "testing"
+)
+
+func TestProductsMakefile(t *testing.T) {
+ testDir := getTestDirectory()
+ abspath := func(relPath string) string { return filepath.Join(testDir, relPath) }
+ actualProducts := make(map[string]string)
+ if err := UpdateProductConfigMap(actualProducts, abspath("android_products.mk.test")); err != nil {
+ t.Fatal(err)
+ }
+ expectedProducts := map[string]string{
+ "aosp_cf_x86_tv": abspath("vsoc_x86/tv/device.mk"),
+ "aosp_tv_arm": abspath("aosp_tv_arm.mk"),
+ "aosp_tv_arm64": abspath("aosp_tv_arm64.mk"),
+ }
+ if !reflect.DeepEqual(actualProducts, expectedProducts) {
+ t.Errorf("\nExpected: %v\n Actual: %v", expectedProducts, actualProducts)
+ }
+}
diff --git a/mk2rbc/config_variables.go b/mk2rbc/config_variables.go
new file mode 100644
index 0000000..dac509c
--- /dev/null
+++ b/mk2rbc/config_variables.go
@@ -0,0 +1,67 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+// Extracts the list of product config variables from a file, calling
+// given registrar for each variable.
+func FindConfigVariables(mkFile string, vr variableRegistrar) error {
+ mkContents, err := ioutil.ReadFile(mkFile)
+ if err != nil {
+ return err
+ }
+ parser := mkparser.NewParser(mkFile, bytes.NewBuffer(mkContents))
+ nodes, errs := parser.Parse()
+ if len(errs) > 0 {
+ for _, e := range errs {
+ fmt.Fprintln(os.Stderr, "ERROR:", e)
+ }
+ return fmt.Errorf("cannot parse %s", mkFile)
+ }
+ for _, node := range nodes {
+ asgn, ok := node.(*mkparser.Assignment)
+ if !ok {
+ continue
+ }
+ // We are looking for a variable called '_product_list_vars'
+ // or '_product_single_value_vars'.
+ if !asgn.Name.Const() {
+ continue
+ }
+ varName := asgn.Name.Strings[0]
+ var starType starlarkType
+ if varName == "_product_list_vars" {
+ starType = starlarkTypeList
+ } else if varName == "_product_single_value_vars" {
+ starType = starlarkTypeUnknown
+ } else {
+ continue
+ }
+ for _, name := range strings.Fields(asgn.Value.Dump()) {
+ vr.NewVariable(name, VarClassConfig, starType)
+ }
+
+ }
+ return nil
+}
diff --git a/mk2rbc/config_variables_test.go b/mk2rbc/config_variables_test.go
new file mode 100644
index 0000000..f5a5180
--- /dev/null
+++ b/mk2rbc/config_variables_test.go
@@ -0,0 +1,60 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "testing"
+)
+
+type testVar struct {
+ name string
+ cl varClass
+ ty starlarkType
+}
+
+type testVariables struct {
+ v []testVar
+}
+
+func (v *testVariables) NewVariable(name string, varClass varClass, valueType starlarkType) {
+ v.v = append(v.v, testVar{name, varClass, valueType})
+}
+
+// getTestDirectory returns the test directory, which should be the test/ subdirectory
+func getTestDirectory() string {
+ _, myFile, _, _ := runtime.Caller(1)
+ return filepath.Join(filepath.Dir(myFile), "test")
+}
+
+func TestConfigVariables(t *testing.T) {
+ testFile := filepath.Join(getTestDirectory(), "config_variables.mk.test")
+ var actual testVariables
+ if err := FindConfigVariables(testFile, &actual); err != nil {
+ t.Fatal(err)
+ }
+ expected := testVariables{[]testVar{
+ {"PRODUCT_NAME", VarClassConfig, starlarkTypeUnknown},
+ {"PRODUCT_MODEL", VarClassConfig, starlarkTypeUnknown},
+ {"PRODUCT_LOCALES", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_AAPT_CONFIG", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_AAPT_PREF_CONFIG", VarClassConfig, starlarkTypeUnknown},
+ }}
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("\nExpected: %v\n Actual: %v", expected, actual)
+ }
+}
diff --git a/mk2rbc/soong_variables.go b/mk2rbc/soong_variables.go
new file mode 100644
index 0000000..de46925
--- /dev/null
+++ b/mk2rbc/soong_variables.go
@@ -0,0 +1,151 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "regexp"
+ "strings"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+type context struct {
+ includeFileScope mkparser.Scope
+ registrar variableRegistrar
+}
+
+// Scans the makefile Soong uses to generate soong.variables file,
+// collecting variable names and types from the lines that look like this:
+// $(call add_json_XXX, <...>, $(VAR))
+//
+func FindSoongVariables(mkFile string, includeFileScope mkparser.Scope, registrar variableRegistrar) error {
+ ctx := context{includeFileScope, registrar}
+ return ctx.doFind(mkFile)
+}
+
+func (ctx *context) doFind(mkFile string) error {
+ mkContents, err := ioutil.ReadFile(mkFile)
+ if err != nil {
+ return err
+ }
+ parser := mkparser.NewParser(mkFile, bytes.NewBuffer(mkContents))
+ nodes, errs := parser.Parse()
+ if len(errs) > 0 {
+ for _, e := range errs {
+ fmt.Fprintln(os.Stderr, "ERROR:", e)
+ }
+ return fmt.Errorf("cannot parse %s", mkFile)
+ }
+ for _, node := range nodes {
+ switch t := node.(type) {
+ case *mkparser.Variable:
+ ctx.handleVariable(t)
+ case *mkparser.Directive:
+ ctx.handleInclude(t)
+ }
+ }
+ return nil
+}
+
+func (ctx context) NewSoongVariable(name, typeString string) {
+ var valueType starlarkType
+ switch typeString {
+ case "bool":
+ valueType = starlarkTypeBool
+ case "csv":
+ // Only PLATFORM_VERSION_ALL_CODENAMES, and it's a list
+ valueType = starlarkTypeList
+ case "list":
+ valueType = starlarkTypeList
+ case "str":
+ valueType = starlarkTypeString
+ case "val":
+ // Only PLATFORM_SDK_VERSION uses this, and it's integer
+ valueType = starlarkTypeInt
+ default:
+ panic(fmt.Errorf("unknown Soong variable type %s", typeString))
+ }
+
+ ctx.registrar.NewVariable(name, VarClassSoong, valueType)
+}
+
+func (ctx context) handleInclude(t *mkparser.Directive) {
+ if t.Name != "include" && t.Name != "-include" {
+ return
+ }
+ includedPath := t.Args.Value(ctx.includeFileScope)
+ err := ctx.doFind(includedPath)
+ if err != nil && t.Name == "include" {
+ fmt.Fprintf(os.Stderr, "cannot include %s: %s", includedPath, err)
+ }
+}
+
+var callFuncRex = regexp.MustCompile("^call +add_json_(str|val|bool|csv|list) *,")
+
+func (ctx context) handleVariable(t *mkparser.Variable) {
+ // From the variable reference looking as follows:
+ // $(call json_add_TYPE,arg1,$(VAR))
+ // we infer that the type of $(VAR) is TYPE
+ // VAR can be a simple variable name, or another call
+ // (e.g., $(call invert_bool, $(X)), from which we can infer
+ // that the type of X is bool
+ if prefix, v, ok := prefixedVariable(t.Name); ok && strings.HasPrefix(prefix, "call add_json") {
+ if match := callFuncRex.FindStringSubmatch(prefix); match != nil {
+ ctx.inferSoongVariableType(match[1], v)
+ // NOTE(asmundak): sometimes arg1 (the name of the Soong variable defined
+ // in this statement) may indicate that there is a Make counterpart. E.g, from
+ // $(call add_json_bool, DisablePreopt, $(call invert_bool,$(ENABLE_PREOPT)))
+ // it may be inferred that there is a Make boolean variable DISABLE_PREOPT.
+ // Unfortunately, Soong variable names have no 1:1 correspondence to Make variables,
+ // for instance,
+ // $(call add_json_list, PatternsOnSystemOther, $(SYSTEM_OTHER_ODEX_FILTER))
+ // does not mean that there is PATTERNS_ON_SYSTEM_OTHER
+ // Our main interest lies in finding the variables whose values are lists, and
+ // so far there are none that can be found this way, so it is not important.
+ } else {
+ panic(fmt.Errorf("cannot match the call: %s", prefix))
+ }
+ }
+}
+
+var (
+ callInvertBoolRex = regexp.MustCompile("^call +invert_bool *, *$")
+ callFilterBoolRex = regexp.MustCompile("^(filter|filter-out) +(true|false), *$")
+)
+
+func (ctx context) inferSoongVariableType(vType string, n *mkparser.MakeString) {
+ if n.Const() {
+ ctx.NewSoongVariable(n.Strings[0], vType)
+ return
+ }
+ if prefix, v, ok := prefixedVariable(n); ok {
+ if callInvertBoolRex.MatchString(prefix) || callFilterBoolRex.MatchString(prefix) {
+ // It is $(call invert_bool, $(VAR)) or $(filter[-out] [false|true],$(VAR))
+ ctx.inferSoongVariableType("bool", v)
+ }
+ }
+}
+
+// If MakeString is foo$(BAR), returns 'foo', BAR(as *MakeString) and true
+func prefixedVariable(s *mkparser.MakeString) (string, *mkparser.MakeString, bool) {
+ if len(s.Strings) != 2 || s.Strings[1] != "" {
+ return "", nil, false
+ }
+ return s.Strings[0], s.Variables[0].Name, true
+}
diff --git a/mk2rbc/soong_variables_test.go b/mk2rbc/soong_variables_test.go
new file mode 100644
index 0000000..c883882
--- /dev/null
+++ b/mk2rbc/soong_variables_test.go
@@ -0,0 +1,51 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "fmt"
+ "path/filepath"
+ "reflect"
+ "testing"
+)
+
+type dirResolverForTest struct {
+ ScopeBase
+}
+
+func (t dirResolverForTest) Get(name string) string {
+ if name != "BUILD_SYSTEM" {
+ return fmt.Sprintf("$(%s)", name)
+ }
+ return getTestDirectory()
+}
+
+func TestSoongVariables(t *testing.T) {
+ testFile := filepath.Join(getTestDirectory(), "soong_variables.mk.test")
+ var actual testVariables
+ if err := FindSoongVariables(testFile, dirResolverForTest{}, &actual); err != nil {
+ t.Fatal(err)
+ }
+ expected := testVariables{[]testVar{
+ {"BUILD_ID", VarClassSoong, starlarkTypeString},
+ {"PLATFORM_SDK_VERSION", VarClassSoong, starlarkTypeInt},
+ {"DEVICE_PACKAGE_OVERLAYS", VarClassSoong, starlarkTypeList},
+ {"ENABLE_CFI", VarClassSoong, starlarkTypeBool},
+ {"ENABLE_PREOPT", VarClassSoong, starlarkTypeBool},
+ }}
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("\nExpected: %v\n Actual: %v", expected, actual)
+ }
+}
diff --git a/mk2rbc/test/android_products.mk.test b/mk2rbc/test/android_products.mk.test
new file mode 100644
index 0000000..a2220ed
--- /dev/null
+++ b/mk2rbc/test/android_products.mk.test
@@ -0,0 +1,4 @@
+PRODUCT_MAKEFILES := \
+ $(LOCAL_DIR)/aosp_tv_arm.mk \
+ $(LOCAL_DIR)/aosp_tv_arm64.mk \
+ aosp_cf_x86_tv:$(LOCAL_DIR)/vsoc_x86/tv/device.mk
\ No newline at end of file
diff --git a/mk2rbc/test/config_variables.mk.test b/mk2rbc/test/config_variables.mk.test
new file mode 100644
index 0000000..e5cd0e9
--- /dev/null
+++ b/mk2rbc/test/config_variables.mk.test
@@ -0,0 +1,12 @@
+_product_single_value_vars :=
+
+# Variables that are lists of values.
+_product_list_vars :=
+
+_product_single_value_vars += PRODUCT_NAME
+_product_single_value_vars += PRODUCT_MODEL
+
+# The resoure configuration options to use for this product.
+_product_list_vars += PRODUCT_LOCALES
+_product_list_vars += PRODUCT_AAPT_CONFIG
+_product_single_value_vars += PRODUCT_AAPT_PREF_CONFIG
diff --git a/mk2rbc/test/soong_included.mk.test b/mk2rbc/test/soong_included.mk.test
new file mode 100644
index 0000000..255ecc5
--- /dev/null
+++ b/mk2rbc/test/soong_included.mk.test
@@ -0,0 +1 @@
+ $(call add_json_bool, DisablePreopt, $(call invert_bool,$(ENABLE_PREOPT)))
diff --git a/mk2rbc/test/soong_variables.mk.test b/mk2rbc/test/soong_variables.mk.test
new file mode 100644
index 0000000..ca60c9c
--- /dev/null
+++ b/mk2rbc/test/soong_variables.mk.test
@@ -0,0 +1,5 @@
+$(call add_json_str, BuildId, $(BUILD_ID))
+$(call add_json_val, Platform_sdk_version, $(PLATFORM_SDK_VERSION))
+$(call add_json_list, DeviceResourceOverlays, $(DEVICE_PACKAGE_OVERLAYS))
+$(call add_json_bool, EnableCFI, $(call invert_bool,$(filter false,$(ENABLE_CFI))))
+include $(BUILD_SYSTEM)/soong_included.mk.test
diff --git a/mk2rbc/types.go b/mk2rbc/types.go
new file mode 100644
index 0000000..22c8b58
--- /dev/null
+++ b/mk2rbc/types.go
@@ -0,0 +1,55 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+// Starlark expression types we use
+type starlarkType int
+
+const (
+ starlarkTypeUnknown starlarkType = iota
+ starlarkTypeList starlarkType = iota
+ starlarkTypeString starlarkType = iota
+ starlarkTypeInt starlarkType = iota
+ starlarkTypeBool starlarkType = iota
+ starlarkTypeVoid starlarkType = iota
+)
+
+type varClass int
+
+const (
+ VarClassConfig varClass = iota
+ VarClassSoong varClass = iota
+ VarClassLocal varClass = iota
+)
+
+type variableRegistrar interface {
+ NewVariable(name string, varClass varClass, valueType starlarkType)
+}
+
+// ScopeBase is a dummy implementation of the mkparser.Scope.
+// All our scopes are read-only and resolve only simple variables.
+type ScopeBase struct{}
+
+func (s ScopeBase) Set(_, _ string) {
+ panic("implement me")
+}
+
+func (s ScopeBase) Call(_ string, _ []string) []string {
+ panic("implement me")
+}
+
+func (s ScopeBase) SetFunc(_ string, _ func([]string) []string) {
+ panic("implement me")
+}
diff --git a/rust/binary.go b/rust/binary.go
index 8d0a0a7..2c3f548 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -155,7 +155,3 @@
}
return binary.baseCompiler.stdLinkage(ctx)
}
-
-func (binary *binaryDecorator) isDependencyRoot() bool {
- return true
-}
diff --git a/rust/compiler.go b/rust/compiler.go
index 1598ebf..0b28135 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -289,10 +289,6 @@
return android.OptionalPathForPath(compiler.cargoOutDir)
}
-func (compiler *baseCompiler) isDependencyRoot() bool {
- return false
-}
-
func (compiler *baseCompiler) strippedOutputFilePath() android.OptionalPath {
return compiler.strippedOutputFile
}
diff --git a/rust/rust.go b/rust/rust.go
index a11a04c..38f1742 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -172,13 +172,6 @@
return mod.sanitize != nil && mod.compiler != nil
}
-func (mod *Module) IsDependencyRoot() bool {
- if mod.compiler != nil {
- return mod.compiler.isDependencyRoot()
- }
- panic("IsDependencyRoot called on a non-compiler Rust module")
-}
-
func (mod *Module) IsPrebuilt() bool {
if _, ok := mod.compiler.(*prebuiltLibraryDecorator); ok {
return true
@@ -449,7 +442,6 @@
SetDisabled()
stdLinkage(ctx *depsContext) RustLinkage
- isDependencyRoot() bool
strippedOutputFilePath() android.OptionalPath
}
@@ -998,7 +990,9 @@
case procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, rustDep)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
- case android.SourceDepTag:
+ }
+
+ if android.IsSourceDepTagWithOutputTag(depTag, "") {
// Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
// OS/Arch variant is used.
var helper string
@@ -1128,8 +1122,7 @@
}
if srcDep, ok := dep.(android.SourceFileProducer); ok {
- switch depTag {
- case android.SourceDepTag:
+ if android.IsSourceDepTagWithOutputTag(depTag, "") {
// These are usually genrules which don't have per-target variants.
directSrcDeps = append(directSrcDeps, srcDep)
}
diff --git a/sdk/sdk.go b/sdk/sdk.go
index afc6aa4..b1c8aeb 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -93,10 +93,6 @@
// dropped. Adding a rule to members that have //visibility:private will
// cause the //visibility:private to be discarded.
Prebuilt_visibility []string
-
- // Specifying whether the generated prebuilt SDK build rule should have the
- // prefer flag set or not.
- Prebuilts_prefer *bool // default: false
}
// Contains information about the sdk properties that list sdk members, e.g.
@@ -296,10 +292,6 @@
return s.properties.Snapshot
}
-func (s *sdk) PreferPrebuilts() bool {
- return proptools.BoolDefault(s.properties.Prebuilts_prefer, false)
-}
-
func (s *sdk) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if s.snapshot() {
// We don't need to create a snapshot out of sdk_snapshot.
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 0933db2..a13b0d7 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -662,68 +662,3 @@
)
})
}
-
-// Ensure that sdk prebuilt_prefer works correctly.
-func TestSnapshot_PrebuiltPreferTrue(t *testing.T) {
- bp := `
- sdk {
- name: "mysdk",
- java_header_libs: ["myjavalib"],
- prebuilts_prefer: true,
- }
-
- java_library {
- name: "myjavalib",
- srcs: ["Test.java"],
- system_modules: "none",
- sdk_version: "none",
- compile_dex: true,
- host_supported: true,
- }
- `
- preparer := android.GroupFixturePreparers(
- prepareForSdkTestWithJava,
- android.FixtureWithRootAndroidBp(bp),
- )
-
- checkZipFile := func(t *testing.T, result *android.TestResult, expected string) {
- zipRule := result.ModuleForTests("mysdk", "common_os").Rule("SnapshotZipFiles")
- android.AssertStringEquals(t, "snapshot zip file", expected, zipRule.Output.String())
- }
-
- t.Run("prefer=true", func(t *testing.T) {
- result := android.GroupFixturePreparers(
- preparer,
- ).RunTest(t)
-
- checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
-
- CheckSnapshot(t, result, "mysdk", "",
- checkAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-java_import {
- name: "mysdk_myjavalib@current",
- sdk_member_name: "myjavalib",
- visibility: ["//visibility:public"],
- apex_available: ["//apex_available:platform"],
- jars: ["java/myjavalib.jar"],
-}
-
-java_import {
- name: "myjavalib",
- prefer: true,
- visibility: ["//visibility:public"],
- apex_available: ["//apex_available:platform"],
- jars: ["java/myjavalib.jar"],
-}
-
-sdk_snapshot {
- name: "mysdk@current",
- visibility: ["//visibility:public"],
- java_header_libs: ["mysdk_myjavalib@current"],
-}
- `),
- )
- })
-}
diff --git a/sdk/update.go b/sdk/update.go
index 2ab45d7..b146b62 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -32,9 +32,8 @@
// ========================================================
//
// SOONG_SDK_SNAPSHOT_PREFER
-// By default every unversioned module in the generated snapshot has prefer set by the
-// sdk.prebuilts_prefer property. Building it with SOONG_SDK_SNAPSHOT_PREFER=true will force
-// them to use prefer: true.
+// By default every unversioned module in the generated snapshot has prefer: false. Building it
+// with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true.
//
// SOONG_SDK_SNAPSHOT_VERSION
// This provides control over the version of the generated snapshot.
@@ -1624,11 +1623,11 @@
// Do not add the prefer property if the member snapshot module is a source module type.
if !memberType.UsesSourceModuleTypeInSnapshot() {
- // Set the prefer based on the environment variable if present, else the sdk.prefer_prebuilts
- // value.
+ // Set the prefer based on the environment variable. This is a temporary work around to allow a
+ // snapshot to be created that sets prefer: true.
// TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
// dynamically at build time not at snapshot generation time.
- prefer := ctx.sdkMemberContext.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER") || s.PreferPrebuilts()
+ prefer := ctx.sdkMemberContext.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
// Set prefer. Setting this to false is not strictly required as that is the default but it does
// provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to