Add double_loadable property and checks for it
double_loadable is a property that tells whether a module is capable or
being loaded with other instance (possibly an older version) of the same
module in the same process. Currently, a shared library that is a member
of VNDK can be double loaded in a vendor process if the library is also
a dependency of an LLNDK library. Such libraries now must be explicitly
marked as `double_loadable: true` by the owner, or the dependency from
the LLNDK lib should be cut if the lib is not designed to be double
loaded.
Bug: 77155589
Test: m -j
Merged-In: I3b839f860cbdc01f43b59872cd7bb84ac4a7d73e
Change-Id: I3b839f860cbdc01f43b59872cd7bb84ac4a7d73e
(cherry picked from commit 89943d8be2734ab9e63ee14afe29ba67d716ab18)
diff --git a/cc/cc.go b/cc/cc.go
index 1905990..9722cf0 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -193,6 +193,15 @@
//
// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
Vendor_available *bool
+
+ // whether this module is capable of being loaded with other instance
+ // (possibly an older version) of the same module in the same process.
+ // Currently, a shared library that is a member of VNDK (vndk: {enabled: true})
+ // can be double loaded in a vendor process if the library is also a
+ // (direct and indirect) dependency of an LLNDK library. Such libraries must be
+ // explicitly marked as `double_loadable: true` by the owner, or the dependency
+ // from the LLNDK lib should be cut if the lib is not designed to be double loaded.
+ Double_loadable *bool
}
type UnusedProperties struct {
@@ -1127,6 +1136,34 @@
}
}
+// Tests whether the dependent library is okay to be double loaded inside a single process.
+// If a library is a member of VNDK and at the same time dependencies of an LLNDK library,
+// it is subject to be double loaded. Such lib should be explicitly marked as double_loaded: true
+// or as vndk-sp (vndk: { enabled: true, support_system_process: true}).
+func checkDoubleLoadableLibries(ctx android.ModuleContext, from *Module, to *Module) {
+ if _, ok := from.linker.(*libraryDecorator); !ok {
+ return
+ }
+
+ if inList(ctx.ModuleName(), llndkLibraries) ||
+ (from.useVndk() && Bool(from.VendorProperties.Double_loadable)) {
+ _, depIsLlndk := to.linker.(*llndkStubDecorator)
+ depIsVndkSp := false
+ if to.vndkdep != nil && to.vndkdep.isVndkSp() {
+ depIsVndkSp = true
+ }
+ depIsVndk := false
+ if to.vndkdep != nil && to.vndkdep.isVndk() {
+ depIsVndk = true
+ }
+ depIsDoubleLoadable := Bool(to.VendorProperties.Double_loadable)
+ if !depIsLlndk && !depIsVndkSp && !depIsDoubleLoadable && depIsVndk {
+ ctx.ModuleErrorf("links VNDK library %q that isn't double_loadable.",
+ ctx.OtherModuleName(to))
+ }
+ }
+}
+
// Convert dependencies to paths. Returns a PathDeps containing paths
func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
@@ -1225,6 +1262,7 @@
}
checkLinkType(ctx, c, ccDep, t)
+ checkDoubleLoadableLibries(ctx, c, ccDep)
}
var ptr *android.Paths