Merge "To use same default for the nightly builds."
diff --git a/android/Android.bp b/android/Android.bp
index 69aa037..efa70a9 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -59,6 +59,7 @@
"sandbox.go",
"sdk.go",
"singleton.go",
+ "singleton_module.go",
"soong_config_modules.go",
"test_suites.go",
"testing.go",
@@ -95,6 +96,7 @@
"paths_test.go",
"prebuilt_test.go",
"rule_builder_test.go",
+ "singleton_module_test.go",
"soong_config_modules_test.go",
"util_test.go",
"variable_test.go",
diff --git a/android/config.go b/android/config.go
index ddb2de3..a7e0b67 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1256,6 +1256,27 @@
return HasAnyPrefix(path, c.productVariables.CFIIncludePaths)
}
+func (c *config) MemtagHeapDisabledForPath(path string) bool {
+ if len(c.productVariables.MemtagHeapExcludePaths) == 0 {
+ return false
+ }
+ return HasAnyPrefix(path, c.productVariables.MemtagHeapExcludePaths)
+}
+
+func (c *config) MemtagHeapAsyncEnabledForPath(path string) bool {
+ if len(c.productVariables.MemtagHeapAsyncIncludePaths) == 0 {
+ return false
+ }
+ return HasAnyPrefix(path, c.productVariables.MemtagHeapAsyncIncludePaths)
+}
+
+func (c *config) MemtagHeapSyncEnabledForPath(path string) bool {
+ if len(c.productVariables.MemtagHeapSyncIncludePaths) == 0 {
+ return false
+ }
+ return HasAnyPrefix(path, c.productVariables.MemtagHeapSyncIncludePaths)
+}
+
func (c *config) VendorConfig(name string) VendorConfig {
return soongconfig.Config(c.productVariables.VendorVars[name])
}
diff --git a/android/makevars.go b/android/makevars.go
index 546abcf..40c0ccd 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -134,8 +134,6 @@
// SingletonMakeVarsProvider is a Singleton with an extra method to provide extra values to be exported to Make.
type SingletonMakeVarsProvider interface {
- Singleton
-
// MakeVars uses a MakeVarsContext to provide extra values to be exported to Make.
MakeVars(ctx MakeVarsContext)
}
diff --git a/android/module.go b/android/module.go
index b0ad89b..17035bb 100644
--- a/android/module.go
+++ b/android/module.go
@@ -454,6 +454,7 @@
InstallForceOS() (*OsType, *ArchType)
HideFromMake()
IsHideFromMake() bool
+ IsSkipInstall() bool
MakeUninstallable()
ReplacedByPrebuilt()
IsReplacedByPrebuilt() bool
@@ -1398,6 +1399,12 @@
m.commonProperties.SkipInstall = true
}
+// IsSkipInstall returns true if this variant is marked to not create install
+// rules when ctx.Install* are called.
+func (m *ModuleBase) IsSkipInstall() bool {
+ return m.commonProperties.SkipInstall
+}
+
// Similar to HideFromMake, but if the AndroidMk entry would set
// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry
// rather than leaving it out altogether. That happens in cases where it would
diff --git a/android/register.go b/android/register.go
index 995be0c..ca658f5 100644
--- a/android/register.go
+++ b/android/register.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "reflect"
"github.com/google/blueprint"
)
@@ -26,6 +27,7 @@
}
var moduleTypes []moduleType
+var moduleTypesForDocs = map[string]reflect.Value{}
type singleton struct {
name string
@@ -72,6 +74,16 @@
func RegisterModuleType(name string, factory ModuleFactory) {
moduleTypes = append(moduleTypes, moduleType{name, factory})
+ RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
+}
+
+// RegisterModuleTypeForDocs associates a module type name with a reflect.Value of the factory
+// function that has documentation for the module type. It is normally called automatically
+// by RegisterModuleType, but can be called manually after RegisterModuleType in order to
+// override the factory method used for documentation, for example if the method passed to
+// RegisterModuleType was a lambda.
+func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
+ moduleTypesForDocs[name] = factory
}
func RegisterSingletonType(name string, factory SingletonFactory) {
@@ -157,12 +169,17 @@
return ret
}
+func ModuleTypeFactoriesForDocs() map[string]reflect.Value {
+ return moduleTypesForDocs
+}
+
// Interface for registering build components.
//
// Provided to allow registration of build components to be shared between the runtime
// and test environments.
type RegistrationContext interface {
RegisterModuleType(name string, factory ModuleFactory)
+ RegisterSingletonModuleType(name string, factory SingletonModuleFactory)
RegisterSingletonType(name string, factory SingletonFactory)
PreArchMutators(f RegisterMutatorFunc)
@@ -201,8 +218,9 @@
var _ RegistrationContext = (*TestContext)(nil)
type initRegistrationContext struct {
- moduleTypes map[string]ModuleFactory
- singletonTypes map[string]SingletonFactory
+ moduleTypes map[string]ModuleFactory
+ singletonTypes map[string]SingletonFactory
+ moduleTypesForDocs map[string]reflect.Value
}
func (ctx *initRegistrationContext) RegisterModuleType(name string, factory ModuleFactory) {
@@ -211,6 +229,17 @@
}
ctx.moduleTypes[name] = factory
RegisterModuleType(name, factory)
+ RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
+}
+
+func (ctx *initRegistrationContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
+ s, m := SingletonModuleFactoryAdaptor(name, factory)
+ ctx.RegisterSingletonType(name, s)
+ ctx.RegisterModuleType(name, m)
+ // Overwrite moduleTypesForDocs with the original factory instead of the lambda returned by
+ // SingletonModuleFactoryAdaptor so that docs can find the module type documentation on the
+ // factory method.
+ RegisterModuleTypeForDocs(name, reflect.ValueOf(factory))
}
func (ctx *initRegistrationContext) RegisterSingletonType(name string, factory SingletonFactory) {
diff --git a/android/singleton_module.go b/android/singleton_module.go
new file mode 100644
index 0000000..2351738
--- /dev/null
+++ b/android/singleton_module.go
@@ -0,0 +1,146 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// 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 android
+
+import (
+ "fmt"
+ "sync"
+
+ "github.com/google/blueprint"
+)
+
+// A SingletonModule is halfway between a Singleton and a Module. It has access to visiting
+// other modules via its GenerateSingletonBuildActions method, but must be defined in an Android.bp
+// file and can also be depended on like a module. It must be used zero or one times in an
+// Android.bp file, and it can only have a single variant.
+//
+// The SingletonModule's GenerateAndroidBuildActions method will be called before any normal or
+// singleton module that depends on it, but its GenerateSingletonBuildActions method will be called
+// after all modules, in registration order with other singletons and singleton modules.
+// GenerateAndroidBuildActions and GenerateSingletonBuildActions will not be called if the
+// SingletonModule was not instantiated in an Android.bp file.
+//
+// Since the SingletonModule rules likely depend on the modules visited during
+// GenerateSingletonBuildActions, the GenerateAndroidBuildActions is unlikely to produce any
+// rules directly. Instead, it will probably set some providers to paths that will later have rules
+// generated to produce them in GenerateSingletonBuildActions.
+//
+// The expected use case for a SingletonModule is a module that produces files that depend on all
+// modules in the tree and will be used by other modules. For example it could produce a text
+// file that lists all modules that meet a certain criteria, and that text file could be an input
+// to another module. Care must be taken that the ninja rules produced by the SingletonModule
+// don't produce a cycle by referencing output files of rules of modules that depend on the
+// SingletonModule.
+//
+// A SingletonModule must embed a SingletonModuleBase struct, and its factory method must be
+// registered with RegisterSingletonModuleType from an init() function.
+//
+// A SingletonModule can also implement SingletonMakeVarsProvider to export values to Make.
+type SingletonModule interface {
+ Module
+ GenerateSingletonBuildActions(SingletonContext)
+ singletonModuleBase() *SingletonModuleBase
+}
+
+// SingletonModuleBase must be embedded into implementers of the SingletonModule interface.
+type SingletonModuleBase struct {
+ ModuleBase
+
+ lock sync.Mutex
+ bp string
+ variant string
+}
+
+// GenerateBuildActions wraps the ModuleBase GenerateBuildActions method, verifying it was only
+// called once to prevent multiple variants of a SingletonModule.
+func (smb *SingletonModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
+ smb.lock.Lock()
+ if smb.variant != "" {
+ ctx.ModuleErrorf("GenerateAndroidBuildActions already called for variant %q, SingletonModules can only have one variant", smb.variant)
+ }
+ smb.variant = ctx.ModuleSubDir()
+ smb.lock.Unlock()
+
+ smb.ModuleBase.GenerateBuildActions(ctx)
+}
+
+// InitAndroidSingletonModule must be called from the SingletonModule's factory function to
+// initialize SingletonModuleBase.
+func InitAndroidSingletonModule(sm SingletonModule) {
+ InitAndroidModule(sm)
+}
+
+// singletonModuleBase retrieves the embedded SingletonModuleBase from a SingletonModule.
+func (smb *SingletonModuleBase) singletonModuleBase() *SingletonModuleBase { return smb }
+
+// SingletonModuleFactory is a factory method that returns a SingletonModule.
+type SingletonModuleFactory func() SingletonModule
+
+// SingletonModuleFactoryAdaptor converts a SingletonModuleFactory into a SingletonFactory and a
+// ModuleFactory.
+func SingletonModuleFactoryAdaptor(name string, factory SingletonModuleFactory) (SingletonFactory, ModuleFactory) {
+ // The sm variable acts as a static holder of the only SingletonModule instance. Calls to the
+ // returned SingletonFactory and ModuleFactory lambdas will always return the same sm value.
+ // The SingletonFactory is only expected to be called once, but the ModuleFactory may be
+ // called multiple times if the module is replaced with a clone of itself at the end of
+ // blueprint.ResolveDependencies.
+ var sm SingletonModule
+ s := func() Singleton {
+ sm = factory()
+ return &singletonModuleSingletonAdaptor{sm}
+ }
+ m := func() Module {
+ if sm == nil {
+ panic(fmt.Errorf("Singleton %q for SingletonModule was not instantiated", name))
+ }
+
+ // Check for multiple uses of a SingletonModule in a LoadHook. Checking directly in the
+ // factory would incorrectly flag when the factory was called again when the module is
+ // replaced with a clone of itself at the end of blueprint.ResolveDependencies.
+ AddLoadHook(sm, func(ctx LoadHookContext) {
+ smb := sm.singletonModuleBase()
+ smb.lock.Lock()
+ defer smb.lock.Unlock()
+ if smb.bp != "" {
+ ctx.ModuleErrorf("Duplicate SingletonModule %q, previously used in %s", name, smb.bp)
+ }
+ smb.bp = ctx.BlueprintsFile()
+ })
+ return sm
+ }
+ return s, m
+}
+
+// singletonModuleSingletonAdaptor makes a SingletonModule into a Singleton by translating the
+// GenerateSingletonBuildActions method to Singleton.GenerateBuildActions.
+type singletonModuleSingletonAdaptor struct {
+ sm SingletonModule
+}
+
+// GenerateBuildActions calls the SingletonModule's GenerateSingletonBuildActions method, but only
+// if the module was defined in an Android.bp file.
+func (smsa *singletonModuleSingletonAdaptor) GenerateBuildActions(ctx SingletonContext) {
+ if smsa.sm.singletonModuleBase().bp != "" {
+ smsa.sm.GenerateSingletonBuildActions(ctx)
+ }
+}
+
+func (smsa *singletonModuleSingletonAdaptor) MakeVars(ctx MakeVarsContext) {
+ if smsa.sm.singletonModuleBase().bp != "" {
+ if makeVars, ok := smsa.sm.(SingletonMakeVarsProvider); ok {
+ makeVars.MakeVars(ctx)
+ }
+ }
+}
diff --git a/android/singleton_module_test.go b/android/singleton_module_test.go
new file mode 100644
index 0000000..9232eb4
--- /dev/null
+++ b/android/singleton_module_test.go
@@ -0,0 +1,149 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// 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 android
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+)
+
+type testSingletonModule struct {
+ SingletonModuleBase
+ ops []string
+}
+
+func (tsm *testSingletonModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ tsm.ops = append(tsm.ops, "GenerateAndroidBuildActions")
+}
+
+func (tsm *testSingletonModule) GenerateSingletonBuildActions(ctx SingletonContext) {
+ tsm.ops = append(tsm.ops, "GenerateSingletonBuildActions")
+}
+
+func (tsm *testSingletonModule) MakeVars(ctx MakeVarsContext) {
+ tsm.ops = append(tsm.ops, "MakeVars")
+}
+
+func testSingletonModuleFactory() SingletonModule {
+ tsm := &testSingletonModule{}
+ InitAndroidSingletonModule(tsm)
+ return tsm
+}
+
+func runSingletonModuleTest(bp string) (*TestContext, []error) {
+ config := TestConfig(buildDir, nil, bp, nil)
+ // Enable Kati output to test SingletonModules with MakeVars.
+ config.katiEnabled = true
+ ctx := NewTestContext(config)
+ ctx.RegisterSingletonModuleType("test_singleton_module", testSingletonModuleFactory)
+ ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
+ ctx.Register()
+
+ _, errs := ctx.ParseBlueprintsFiles("Android.bp")
+ if len(errs) > 0 {
+ return ctx, errs
+ }
+
+ _, errs = ctx.PrepareBuildActions(config)
+ return ctx, errs
+}
+
+func TestSingletonModule(t *testing.T) {
+ bp := `
+ test_singleton_module {
+ name: "test_singleton_module",
+ }
+ `
+ ctx, errs := runSingletonModuleTest(bp)
+ if len(errs) > 0 {
+ t.Fatal(errs)
+ }
+
+ ops := ctx.ModuleForTests("test_singleton_module", "").Module().(*testSingletonModule).ops
+ wantOps := []string{"GenerateAndroidBuildActions", "GenerateSingletonBuildActions", "MakeVars"}
+ if !reflect.DeepEqual(ops, wantOps) {
+ t.Errorf("Expected operations %q, got %q", wantOps, ops)
+ }
+}
+
+func TestDuplicateSingletonModule(t *testing.T) {
+ bp := `
+ test_singleton_module {
+ name: "test_singleton_module",
+ }
+
+ test_singleton_module {
+ name: "test_singleton_module2",
+ }
+ `
+ _, errs := runSingletonModuleTest(bp)
+ if len(errs) == 0 {
+ t.Fatal("expected duplicate SingletonModule error")
+ }
+ if len(errs) != 1 || !strings.Contains(errs[0].Error(), `Duplicate SingletonModule "test_singleton_module", previously used in`) {
+ t.Fatalf("expected duplicate SingletonModule error, got %q", errs)
+ }
+}
+
+func TestUnusedSingletonModule(t *testing.T) {
+ bp := ``
+ ctx, errs := runSingletonModuleTest(bp)
+ if len(errs) > 0 {
+ t.Fatal(errs)
+ }
+
+ singleton := ctx.SingletonForTests("test_singleton_module").Singleton()
+ sm := singleton.(*singletonModuleSingletonAdaptor).sm
+ ops := sm.(*testSingletonModule).ops
+ if ops != nil {
+ t.Errorf("Expected no operations, got %q", ops)
+ }
+}
+
+func testVariantSingletonModuleMutator(ctx BottomUpMutatorContext) {
+ if _, ok := ctx.Module().(*testSingletonModule); ok {
+ ctx.CreateVariations("a", "b")
+ }
+}
+
+func TestVariantSingletonModule(t *testing.T) {
+ bp := `
+ test_singleton_module {
+ name: "test_singleton_module",
+ }
+ `
+
+ config := TestConfig(buildDir, nil, bp, nil)
+ ctx := NewTestContext(config)
+ ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("test_singleton_module_mutator", testVariantSingletonModuleMutator)
+ })
+ ctx.RegisterSingletonModuleType("test_singleton_module", testSingletonModuleFactory)
+ ctx.Register()
+
+ _, errs := ctx.ParseBlueprintsFiles("Android.bp")
+
+ if len(errs) == 0 {
+ _, errs = ctx.PrepareBuildActions(config)
+ }
+
+ if len(errs) == 0 {
+ t.Fatal("expected duplicate SingletonModule error")
+ }
+ if len(errs) != 1 || !strings.Contains(errs[0].Error(), `GenerateAndroidBuildActions already called for variant`) {
+ t.Fatalf("expected duplicate SingletonModule error, got %q", errs)
+ }
+}
diff --git a/android/testing.go b/android/testing.go
index 6539063..a66b1e1 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -103,6 +103,12 @@
ctx.Context.RegisterModuleType(name, ModuleFactoryAdaptor(factory))
}
+func (ctx *TestContext) RegisterSingletonModuleType(name string, factory SingletonModuleFactory) {
+ s, m := SingletonModuleFactoryAdaptor(name, factory)
+ ctx.RegisterSingletonType(name, s)
+ ctx.RegisterModuleType(name, m)
+}
+
func (ctx *TestContext) RegisterSingletonType(name string, factory SingletonFactory) {
ctx.Context.RegisterSingletonType(name, SingletonFactoryAdaptor(ctx.Context, factory))
}
diff --git a/android/variable.go b/android/variable.go
index 9786b9f..41cd337 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -260,6 +260,10 @@
DisableScudo *bool `json:",omitempty"`
+ MemtagHeapExcludePaths []string `json:",omitempty"`
+ MemtagHeapAsyncIncludePaths []string `json:",omitempty"`
+ MemtagHeapSyncIncludePaths []string `json:",omitempty"`
+
VendorPath *string `json:",omitempty"`
OdmPath *string `json:",omitempty"`
ProductPath *string `json:",omitempty"`
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index 57b18de..c11a89c 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -486,6 +486,8 @@
neuralnetworks_utils_hal_1_3(minSdkVersion:30)
neuralnetworks_utils_hal_common(minSdkVersion:30)
neuralnetworks_utils_hal_service(minSdkVersion:30)
+note_memtag_heap_async(minSdkVersion:16)
+note_memtag_heap_sync(minSdkVersion:16)
PermissionController(minSdkVersion:28)
permissioncontroller-statsd(minSdkVersion:current)
philox_random(minSdkVersion:(no version))
diff --git a/apex/apex.go b/apex/apex.go
index a18e34b..5cd18ed 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -168,6 +168,10 @@
// used in tests.
Test_only_unsigned_payload *bool
+ // Whenever apex should be compressed, regardless of product flag used. Should be only
+ // used in tests.
+ Test_only_force_compression *bool
+
IsCoverageVariant bool `blueprint:"mutated"`
// List of sanitizer names that this APEX is enabled for
@@ -1241,6 +1245,11 @@
return proptools.Bool(a.properties.Test_only_unsigned_payload)
}
+// See the test_only_force_compression property
+func (a *apexBundle) testOnlyShouldForceCompression() bool {
+ return proptools.Bool(a.properties.Test_only_force_compression)
+}
+
// These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its
// members) can be sanitized, either forcibly, or by the global configuration. For some of the
// sanitizers, extra dependencies can be forcibly added as well.
diff --git a/apex/builder.go b/apex/builder.go
index 106302b..bc1b566 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -763,9 +763,13 @@
})
a.outputFile = signedOutputFile
- // Process APEX compression if enabled
+ // Process APEX compression if enabled or forced
+ if ctx.ModuleDir() != "system/apex/apexd/apexd_testdata" && a.testOnlyShouldForceCompression() {
+ ctx.PropertyErrorf("test_only_force_compression", "not available")
+ return
+ }
compressionEnabled := ctx.Config().CompressedApex() && proptools.BoolDefault(a.properties.Compressible, true)
- if compressionEnabled && apexType == imageApex {
+ if apexType == imageApex && (compressionEnabled || a.testOnlyShouldForceCompression()) {
a.isCompressed = true
unsignedCompressedOutputFile := android.PathForModuleOut(ctx, a.Name()+".capex.unsigned")
diff --git a/cc/cc.go b/cc/cc.go
index c0c85f9..ca2bd4f 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -420,6 +420,7 @@
type ModuleContextIntf interface {
static() bool
staticBinary() bool
+ testBinary() bool
header() bool
binary() bool
object() bool
@@ -1261,6 +1262,10 @@
return ctx.mod.staticBinary()
}
+func (ctx *moduleContextImpl) testBinary() bool {
+ return ctx.mod.testBinary()
+}
+
func (ctx *moduleContextImpl) header() bool {
return ctx.mod.Header()
}
@@ -2961,6 +2966,15 @@
return false
}
+func (c *Module) testBinary() bool {
+ if test, ok := c.linker.(interface {
+ testBinary() bool
+ }); ok {
+ return test.testBinary()
+ }
+ return false
+}
+
// Header returns true if the module is a header-only variant. (See cc/library.go header()).
func (c *Module) Header() bool {
if h, ok := c.linker.(interface {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 3502d5f..3399e93 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -738,12 +738,29 @@
},
nocrt: true,
}
+
+ cc_library {
+ name: "libllndk",
+ llndk_stubs: "libllndk.llndk",
+ }
+
+ llndk_library {
+ name: "libllndk.llndk",
+ symbol_file: "",
+ export_llndk_headers: ["libllndk_headers"],
+ }
+
+ llndk_headers {
+ name: "libllndk_headers",
+ export_include_dirs: ["include"],
+ }
`)
checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
"LLNDK: libc.so",
"LLNDK: libdl.so",
"LLNDK: libft2.so",
+ "LLNDK: libllndk.so",
"LLNDK: libm.so",
"VNDK-SP: libc++.so",
"VNDK-core: libvndk-private.so",
@@ -4461,3 +4478,138 @@
t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
}
}
+
+func checkHasImplicitDep(t *testing.T, m android.TestingModule, name string) {
+ implicits := m.Rule("ld").Implicits
+ for _, lib := range implicits {
+ if strings.Contains(lib.Rel(), name) {
+ return
+ }
+ }
+
+ t.Errorf("%q is not found in implicit deps of module %q", name, m.Module().(*Module).Name())
+}
+
+func checkDoesNotHaveImplicitDep(t *testing.T, m android.TestingModule, name string) {
+ implicits := m.Rule("ld").Implicits
+ for _, lib := range implicits {
+ if strings.Contains(lib.Rel(), name) {
+ t.Errorf("%q is found in implicit deps of module %q", name, m.Module().(*Module).Name())
+ }
+ }
+}
+
+func TestSanitizeMemtagHeap(t *testing.T) {
+ rootBp := `
+ cc_library_static {
+ name: "libstatic",
+ sanitize: { memtag_heap: true },
+ }
+
+ cc_library_shared {
+ name: "libshared",
+ sanitize: { memtag_heap: true },
+ }
+
+ cc_library {
+ name: "libboth",
+ sanitize: { memtag_heap: true },
+ }
+
+ cc_binary {
+ name: "binary",
+ shared_libs: [ "libshared" ],
+ static_libs: [ "libstatic" ],
+ }
+
+ cc_binary {
+ name: "binary_true",
+ sanitize: { memtag_heap: true },
+ }
+
+ cc_binary {
+ name: "binary_true_sync",
+ sanitize: { memtag_heap: true, diag: { memtag_heap: true }, },
+ }
+
+ cc_binary {
+ name: "binary_false",
+ sanitize: { memtag_heap: false },
+ }
+
+ cc_test {
+ name: "test",
+ gtest: false,
+ }
+
+ cc_test {
+ name: "test_true",
+ gtest: false,
+ sanitize: { memtag_heap: true },
+ }
+
+ cc_test {
+ name: "test_false",
+ gtest: false,
+ sanitize: { memtag_heap: false },
+ }
+
+ cc_test {
+ name: "test_true_async",
+ gtest: false,
+ sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
+ }
+
+ `
+
+ subdirAsyncBp := `
+ cc_binary {
+ name: "binary_async",
+ }
+ `
+
+ subdirSyncBp := `
+ cc_binary {
+ name: "binary_sync",
+ }
+ `
+
+ mockFS := map[string][]byte{
+ "subdir_async/Android.bp": []byte(subdirAsyncBp),
+ "subdir_sync/Android.bp": []byte(subdirSyncBp),
+ }
+
+ config := TestConfig(buildDir, android.Android, nil, rootBp, mockFS)
+ config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+ config.TestProductVariables.MemtagHeapAsyncIncludePaths = []string{"subdir_async"}
+ config.TestProductVariables.MemtagHeapSyncIncludePaths = []string{"subdir_sync"}
+ ctx := CreateTestContext(config)
+ ctx.Register()
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp", "subdir_sync/Android.bp", "subdir_async/Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
+
+ variant := "android_arm64_armv8-a"
+ note_async := "note_memtag_heap_async"
+ note_sync := "note_memtag_heap_sync"
+ note_any := "note_memtag_"
+
+ checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared"), note_any)
+ checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared"), note_any)
+
+ checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("binary", variant), note_any)
+ checkHasImplicitDep(t, ctx.ModuleForTests("binary_true", variant), note_async)
+ checkHasImplicitDep(t, ctx.ModuleForTests("binary_true_sync", variant), note_sync)
+ checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("binary_false", variant), note_any)
+
+ checkHasImplicitDep(t, ctx.ModuleForTests("test", variant), note_sync)
+ checkHasImplicitDep(t, ctx.ModuleForTests("test_true", variant), note_async)
+ checkDoesNotHaveImplicitDep(t, ctx.ModuleForTests("test_false", variant), note_any)
+ checkHasImplicitDep(t, ctx.ModuleForTests("test_true_async", variant), note_async)
+
+ checkHasImplicitDep(t, ctx.ModuleForTests("binary_async", variant), note_async)
+ checkHasImplicitDep(t, ctx.ModuleForTests("binary_sync", variant), note_sync)
+}
diff --git a/cc/config/global.go b/cc/config/global.go
index fa8e0fb..d47e0ce 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -215,10 +215,6 @@
"frameworks/native/opengl/include",
"frameworks/av/include",
})
- // This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
- // with this, since there is no associated library.
- pctx.PrefixedExistentPathsForSourcesVariable("CommonNativehelperInclude", "-I",
- []string{"libnativehelper/include_jni"})
pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase)
pctx.VariableFunc("ClangBase", func(ctx android.PackageVarContext) string {
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index cf5674b..0aa6866 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -18,6 +18,7 @@
// For these libraries, the vendor variants must be installed even if the device
// has VndkUseCoreVariant set.
var VndkMustUseVendorVariantList = []string{
+ "android.hardware.authsecret-unstable-ndk_platform",
"android.hardware.automotive.occupant_awareness-ndk_platform",
"android.hardware.light-ndk_platform",
"android.hardware.identity-ndk_platform",
diff --git a/cc/image.go b/cc/image.go
index 13095fc..f89194f 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -264,31 +264,34 @@
productVndkVersion = platformVndkVersion
}
- if boardVndkVersion == "" {
+ _, isLLNDKLibrary := m.linker.(*llndkStubDecorator)
+ _, isLLNDKHeaders := m.linker.(*llndkHeadersDecorator)
+ lib := moduleLibraryInterface(m)
+ hasLLNDKStubs := lib != nil && lib.hasLLNDKStubs()
+
+ if isLLNDKLibrary || isLLNDKHeaders || hasLLNDKStubs {
+ // This is an LLNDK library. The implementation of the library will be on /system,
+ // and vendor and product variants will be created with LLNDK stubs.
+ // The LLNDK libraries need vendor variants even if there is no VNDK.
+ // The obsolete llndk_library and llndk_headers modules also need the vendor variants
+ // so the cc_library LLNDK stubs can depend on them.
+ if hasLLNDKStubs {
+ coreVariantNeeded = true
+ }
+ if platformVndkVersion != "" {
+ vendorVariants = append(vendorVariants, platformVndkVersion)
+ productVariants = append(productVariants, platformVndkVersion)
+ }
+ if boardVndkVersion != "" {
+ vendorVariants = append(vendorVariants, boardVndkVersion)
+ }
+ if productVndkVersion != "" {
+ productVariants = append(productVariants, productVndkVersion)
+ }
+ } else if boardVndkVersion == "" {
// If the device isn't compiling against the VNDK, we always
// use the core mode.
coreVariantNeeded = true
- } else if _, ok := m.linker.(*llndkStubDecorator); ok {
- // LL-NDK stubs only exist in the vendor and product variants,
- // since the real libraries will be used in the core variant.
- vendorVariants = append(vendorVariants,
- platformVndkVersion,
- boardVndkVersion,
- )
- productVariants = append(productVariants,
- platformVndkVersion,
- productVndkVersion,
- )
- } else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
- // ... and LL-NDK headers as well
- vendorVariants = append(vendorVariants,
- platformVndkVersion,
- boardVndkVersion,
- )
- productVariants = append(productVariants,
- platformVndkVersion,
- productVndkVersion,
- )
} else if m.isSnapshotPrebuilt() {
// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
// PRODUCT_EXTRA_VNDK_VERSIONS.
@@ -346,18 +349,6 @@
} else {
vendorVariants = append(vendorVariants, platformVndkVersion)
}
- } else if lib := moduleLibraryInterface(m); lib != nil && lib.hasLLNDKStubs() {
- // This is an LLNDK library. The implementation of the library will be on /system,
- // and vendor and product variants will be created with LLNDK stubs.
- coreVariantNeeded = true
- vendorVariants = append(vendorVariants,
- platformVndkVersion,
- boardVndkVersion,
- )
- productVariants = append(productVariants,
- platformVndkVersion,
- productVndkVersion,
- )
} else {
// This is either in /system (or similar: /data), or is a
// modules built with the NDK. Modules built with the NDK
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index bd48501..a46b31c 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -161,6 +161,13 @@
*libraryDecorator
}
+func (llndk *llndkHeadersDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
+ deps.HeaderLibs = append(deps.HeaderLibs, llndk.Properties.Llndk.Export_llndk_headers...)
+ deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders,
+ llndk.Properties.Llndk.Export_llndk_headers...)
+ return deps
+}
+
// llndk_headers contains a set of c/c++ llndk headers files which are imported
// by other soongs cc modules.
func llndkHeadersFactory() android.Module {
@@ -178,11 +185,6 @@
module.installer = nil
module.library = decorator
- module.AddProperties(
- &module.Properties,
- &library.MutatedProperties,
- &library.flagExporter.Properties)
-
module.Init()
return module
diff --git a/cc/makevars.go b/cc/makevars.go
index 8301c6b..48d5636 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -154,16 +154,6 @@
ctx.Strict("SOONG_STRIP_PATH", "${stripPath}")
ctx.Strict("XZ", "${xzCmd}")
- nativeHelperIncludeFlags, err := ctx.Eval("${config.CommonNativehelperInclude}")
- if err != nil {
- panic(err)
- }
- nativeHelperIncludes, nativeHelperSystemIncludes := splitSystemIncludes(ctx, nativeHelperIncludeFlags)
- if len(nativeHelperSystemIncludes) > 0 {
- panic("native helper may not have any system includes")
- }
- ctx.Strict("JNI_H_INCLUDE", strings.Join(nativeHelperIncludes, " "))
-
includeFlags, err := ctx.Eval("${config.CommonGlobalIncludes}")
if err != nil {
panic(err)
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 5992611..af17490 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -89,6 +89,7 @@
cfi
scs
Fuzzer
+ memtag_heap
)
// Name of the sanitizer variation for this sanitizer type
@@ -106,6 +107,8 @@
return "cfi"
case scs:
return "scs"
+ case memtag_heap:
+ return "memtag_heap"
case Fuzzer:
return "fuzzer"
default:
@@ -120,6 +123,8 @@
return "address"
case hwasan:
return "hwaddress"
+ case memtag_heap:
+ return "memtag_heap"
case tsan:
return "thread"
case intOverflow:
@@ -179,6 +184,7 @@
Integer_overflow *bool `android:"arch_variant"`
Scudo *bool `android:"arch_variant"`
Scs *bool `android:"arch_variant"`
+ Memtag_heap *bool `android:"arch_variant"`
// A modifier for ASAN and HWASAN for write only instrumentation
Writeonly *bool `android:"arch_variant"`
@@ -190,6 +196,7 @@
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"`
} `android:"arch_variant"`
@@ -330,6 +337,11 @@
}
s.Writeonly = 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)
+ }
+ }
if len(globalSanitizers) > 0 {
ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
@@ -351,6 +363,25 @@
}
}
+ // cc_test targets default to SYNC MemTag.
+ if ctx.testBinary() && s.Memtag_heap == nil {
+ if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) {
+ s.Memtag_heap = boolPtr(true)
+ s.Diag.Memtag_heap = boolPtr(true)
+ }
+ }
+
+ // Enable Memtag for all components in the include paths (for Aarch64 only)
+ if s.Memtag_heap == nil && ctx.Arch().ArchType == android.Arm64 {
+ if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
+ s.Memtag_heap = boolPtr(true)
+ s.Diag.Memtag_heap = boolPtr(true)
+ } else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) {
+ s.Memtag_heap = boolPtr(true)
+ s.Diag.Memtag_heap = boolPtr(false)
+ }
+ }
+
// 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)
@@ -381,6 +412,11 @@
s.Scs = nil
}
+ // memtag_heap is only implemented on AArch64.
+ if ctx.Arch().ArchType != android.Arm64 {
+ s.Memtag_heap = nil
+ }
+
// Also disable CFI if ASAN is enabled.
if Bool(s.Address) || Bool(s.Hwaddress) {
s.Cfi = boolPtr(false)
@@ -435,7 +471,7 @@
if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
- Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs)) {
+ Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap)) {
sanitize.Properties.SanitizerEnabled = true
}
@@ -717,6 +753,8 @@
return sanitize.Properties.Sanitize.Cfi
case scs:
return sanitize.Properties.Sanitize.Scs
+ case memtag_heap:
+ return sanitize.Properties.Sanitize.Memtag_heap
case Fuzzer:
return sanitize.Properties.Sanitize.Fuzzer
default:
@@ -731,6 +769,7 @@
!sanitize.isSanitizerEnabled(tsan) &&
!sanitize.isSanitizerEnabled(cfi) &&
!sanitize.isSanitizerEnabled(scs) &&
+ !sanitize.isSanitizerEnabled(memtag_heap) &&
!sanitize.isSanitizerEnabled(Fuzzer)
}
@@ -756,6 +795,8 @@
sanitize.Properties.Sanitize.Cfi = boolPtr(b)
case scs:
sanitize.Properties.Sanitize.Scs = boolPtr(b)
+ case memtag_heap:
+ sanitize.Properties.Sanitize.Memtag_heap = boolPtr(b)
case Fuzzer:
sanitize.Properties.Sanitize.Fuzzer = boolPtr(b)
default:
@@ -1032,6 +1073,20 @@
sanitizers = append(sanitizers, "shadow-call-stack")
}
+ if Bool(c.sanitize.Properties.Sanitize.Memtag_heap) && c.binary() {
+ noteDep := "note_memtag_heap_async"
+ if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
+ noteDep = "note_memtag_heap_sync"
+ }
+ depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true}
+ variations := append(mctx.Target().Variations(),
+ blueprint.Variation{Mutator: "link", Variation: "static"})
+ if c.Device() {
+ variations = append(variations, c.ImageVariation())
+ }
+ mctx.AddFarVariationDependencies(variations, depTag, noteDep)
+ }
+
if Bool(c.sanitize.Properties.Sanitize.Fuzzer) {
sanitizers = append(sanitizers, "fuzzer-no-link")
}
diff --git a/cc/test.go b/cc/test.go
index 4ff5bf6..f715a8d 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -236,6 +236,10 @@
return BoolDefault(test.Properties.Gtest, true)
}
+func (test *testDecorator) testBinary() bool {
+ return true
+}
+
func (test *testDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
if !test.gtest() {
return flags
diff --git a/cc/testing.go b/cc/testing.go
index 8d92ea2..903f76c 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -445,6 +445,14 @@
stl: "none",
system_shared_libs: [],
}
+
+ cc_library_static {
+ name: "note_memtag_heap_async",
+ }
+
+ cc_library_static {
+ name: "note_memtag_heap_sync",
+ }
`
supportLinuxBionic := false
diff --git a/cmd/soong_build/writedocs.go b/cmd/soong_build/writedocs.go
index 253979e..f2c2c9b 100644
--- a/cmd/soong_build/writedocs.go
+++ b/cmd/soong_build/writedocs.go
@@ -20,7 +20,6 @@
"html/template"
"io/ioutil"
"path/filepath"
- "reflect"
"sort"
"github.com/google/blueprint/bootstrap"
@@ -97,12 +96,8 @@
}
func getPackages(ctx *android.Context) ([]*bpdoc.Package, error) {
- moduleTypeFactories := android.ModuleTypeFactories()
- bpModuleTypeFactories := make(map[string]reflect.Value)
- for moduleType, factory := range moduleTypeFactories {
- bpModuleTypeFactories[moduleType] = reflect.ValueOf(factory)
- }
- return bootstrap.ModuleTypeDocs(ctx.Context, bpModuleTypeFactories)
+ moduleTypeFactories := android.ModuleTypeFactoriesForDocs()
+ return bootstrap.ModuleTypeDocs(ctx.Context, moduleTypeFactories)
}
func writeDocs(ctx *android.Context, filename string) error {
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index 6db870f..ea62af4 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -26,6 +26,7 @@
platform-mainline-test-exports
runtime-module-host-exports
runtime-module-sdk
+ tzdata-module-test-exports
)
# List of libraries installed on the platform that are needed for ART chroot