diff --git a/android/apex.go b/android/apex.go index 205ec95c2..2b5072b1b 100644 --- a/android/apex.go +++ b/android/apex.go @@ -92,12 +92,10 @@ type ApexModule interface { // APEX as this module DepIsInSameApex(ctx BaseModuleContext, dep Module) bool - // Returns the highest version which is <= min_sdk_version. - // For example, with min_sdk_version is 10 and versionList is [9,11] - // it returns 9. - ChooseSdkVersion(versionList []string, useLatest bool) (string, error) - - ShouldSupportAndroid10() bool + // Returns the highest version which is <= maxSdkVersion. + // For example, with maxSdkVersion is 10 and versionList is [9,11] + // it returns 9 as string + ChooseSdkVersion(versionList []string, maxSdkVersion int) (string, error) } type ApexProperties struct { @@ -189,22 +187,14 @@ func (m *ApexModuleBase) DepIsInSameApex(ctx BaseModuleContext, dep Module) bool return true } -func (m *ApexModuleBase) ChooseSdkVersion(versionList []string, useLatest bool) (string, error) { - if useLatest { - return versionList[len(versionList)-1], nil - } - minSdkVersion := m.ApexProperties.Info.MinSdkVersion +func (m *ApexModuleBase) ChooseSdkVersion(versionList []string, maxSdkVersion int) (string, error) { for i := range versionList { ver, _ := strconv.Atoi(versionList[len(versionList)-i-1]) - if ver <= minSdkVersion { + if ver <= maxSdkVersion { return versionList[len(versionList)-i-1], nil } } - return "", fmt.Errorf("min_sdk_version is set %v, but not found in %v", minSdkVersion, versionList) -} - -func (m *ApexModuleBase) ShouldSupportAndroid10() bool { - return !m.IsForPlatform() && (m.ApexProperties.Info.MinSdkVersion <= SdkVersion_Android10) + return "", fmt.Errorf("not found a version(<=%d) in versionList: %v", maxSdkVersion, versionList) } func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) { diff --git a/apex/apex_test.go b/apex/apex_test.go index 704bad690..ba7d91639 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -856,7 +856,7 @@ func TestApexDependsOnLLNDKTransitively(t *testing.T) { shouldNotLink []string }{ { - name: "should link to test latest", + name: "should link to the latest", minSdkVersion: "current", shouldLink: "30", shouldNotLink: []string{"29"}, @@ -1196,7 +1196,7 @@ func TestPlatformUsesLatestStubsFromApexes(t *testing.T) { expectNoLink("libz", "shared", "libz", "shared") } -func TestQApexesUseLatestStubsInBundledBuilds(t *testing.T) { +func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) { ctx, _ := testApex(t, ` apex { name: "myapex", @@ -1223,16 +1223,18 @@ func TestQApexesUseLatestStubsInBundledBuilds(t *testing.T) { versions: ["29", "30"], }, } - `) + `, func(fs map[string][]byte, config android.Config) { + config.TestProductVariables.SanitizeDevice = []string{"hwaddress"} + }) expectLink := func(from, from_variant, to, to_variant string) { ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld") libFlags := ld.Args["libFlags"] ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") } - expectLink("libx", "shared_myapex", "libbar", "shared_30") + expectLink("libx", "shared_hwasan_myapex", "libbar", "shared_30") } -func TestQTargetApexUseStaticUnwinder(t *testing.T) { +func TestQTargetApexUsesStaticUnwinder(t *testing.T) { ctx, _ := testApex(t, ` apex { name: "myapex", @@ -1251,8 +1253,7 @@ func TestQTargetApexUseStaticUnwinder(t *testing.T) { name: "libx", apex_available: [ "myapex" ], } - - `, withUnbundledBuild) + `) // ensure apex variant of c++ is linked with static unwinder cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module) @@ -1263,7 +1264,7 @@ func TestQTargetApexUseStaticUnwinder(t *testing.T) { } func TestInvalidMinSdkVersion(t *testing.T) { - testApexError(t, `"libz" .*: min_sdk_version is set 29.*`, ` + testApexError(t, `"libz" .*: not found a version\(<=29\)`, ` apex { name: "myapex", key: "myapex.key", @@ -1293,9 +1294,9 @@ func TestInvalidMinSdkVersion(t *testing.T) { versions: ["30"], }, } - `, withUnbundledBuild) + `) - testApexError(t, `"myapex" .*: min_sdk_version: should be .*`, ` + testApexError(t, `"myapex" .*: min_sdk_version: should be "current" or `, ` apex { name: "myapex", key: "myapex.key", @@ -1758,7 +1759,7 @@ func TestMacro(t *testing.T) { // non-APEX variant does not have __ANDROID_APEX__ defined mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") - ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=10000") + ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__") // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"] diff --git a/cc/cc.go b/cc/cc.go index 62e861f30..930c19c8e 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -476,6 +476,9 @@ type Module struct { makeLinkType string // Kythe (source file indexer) paths for this compilation module kytheFiles android.Paths + + // For apex variants, this is set as apex.min_sdk_version + apexSdkVersion int } func (c *Module) Toc() android.OptionalPath { @@ -1197,7 +1200,7 @@ func (ctx *moduleContextImpl) apexName() string { } func (ctx *moduleContextImpl) apexSdkVersion() int { - return ctx.mod.ApexProperties.Info.MinSdkVersion + return ctx.mod.apexSdkVersion } func (ctx *moduleContextImpl) hasStubsVariants() bool { @@ -1828,7 +1831,10 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { }, depTag, lib) } - if deps.StaticUnwinderIfLegacy && ctx.Config().UnbundledBuild() { + // staticUnwinderDep is treated as staticDep for Q apexes + // so that native libraries/binaries are linked with static unwinder + // because Q libc doesn't have unwinder APIs + if deps.StaticUnwinderIfLegacy { actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, }, staticUnwinderDepTag, staticUnwinder(actx)) @@ -2212,9 +2218,22 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } } + // For the dependency from platform to apex, use the latest stubs + c.apexSdkVersion = android.FutureApiLevel + if !c.IsForPlatform() { + c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion + } + + if android.InList("hwaddress", ctx.Config().SanitizeDevice()) { + // In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000) + // so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)). + // (b/144430859) + c.apexSdkVersion = android.FutureApiLevel + } + if depTag == staticUnwinderDepTag { - // Use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859) - if c.ShouldSupportAndroid10() { + // Use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859) + if c.apexSdkVersion <= android.SdkVersion_Android10 { depTag = StaticDepTag } else { return @@ -2268,8 +2287,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // when to use (unspecified) stubs, check min_sdk_version and choose the right one if useThisDep && depIsStubs && !explicitlyVersioned { - useLatest := c.IsForPlatform() || (c.ShouldSupportAndroid10() && !ctx.Config().UnbundledBuild()) - versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), useLatest) + versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), c.apexSdkVersion) if err != nil { ctx.OtherModuleErrorf(dep, err.Error()) return @@ -2292,8 +2310,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // if this is for use_vendor apex && dep has stubsVersions // apply the same rule of apex sdk enforcement to choose right version var err error - useLatest := c.ShouldSupportAndroid10() && !ctx.Config().UnbundledBuild() - versionToUse, err = c.ChooseSdkVersion(versions, useLatest) + versionToUse, err = c.ChooseSdkVersion(versions, c.apexSdkVersion) if err != nil { ctx.OtherModuleErrorf(dep, err.Error()) return diff --git a/cc/testing.go b/cc/testing.go index 7b0305f64..e5be7da89 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -66,6 +66,20 @@ func GatherRequiredDepsForTest(os android.OsType) string { src: "", } + cc_prebuilt_library_shared { + name: "libclang_rt.hwasan-aarch64-android", + nocrt: true, + vendor_available: true, + recovery_available: true, + system_shared_libs: [], + stl: "none", + srcs: [""], + check_elf_files: false, + sanitize: { + never: true, + }, + } + toolchain_library { name: "libclang_rt.builtins-i686-android", vendor_available: true,