linker: allow using reserved space for multiple libraries.
Introduce a new flag ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE which
instructs the linker to use the reserved address space to load all of
the newly-loaded libraries required by a dlopen() call instead of only
the main library. They will be loaded consecutively into that region if
they fit. The RELRO sections of all the loaded libraries will also be
considered for reading/writing shared RELRO data.
This will allow the WebView implementation to potentially consist of
more than one .so file while still benefiting from the RELRO sharing
optimisation, which would otherwise only apply to the "root" .so file.
Test: bionic-unit-tests (existing and newly added)
Bug: 110790153
Change-Id: I61da775c29fd5017d9a1e2b6b3757c3d20a355b3
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index e78be39..f0b731c 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -114,6 +114,29 @@
*/
ANDROID_DLEXT_USE_NAMESPACE = 0x200,
+ /**
+ * Instructs dlopen to apply `ANDROID_DLEXT_RESERVED_ADDRESS`,
+ * `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`, `ANDROID_DLEXT_WRITE_RELRO` and
+ * `ANDROID_DLEXT_USE_RELRO` to any libraries loaded as dependencies of the
+ * main library as well.
+ *
+ * This means that if the main library depends on one or more not-already-loaded libraries, they
+ * will be loaded consecutively into the region starting at `reserved_addr`, and `reserved_size`
+ * must be large enough to contain all of the libraries. The libraries will be loaded in the
+ * deterministic order constructed from the DT_NEEDED entries, rather than the more secure random
+ * order used by default.
+ *
+ * Each library's GNU RELRO sections will be written out to `relro_fd` in the same order they were
+ * loaded. This will mean that the resulting file is dependent on which of the libraries were
+ * already loaded, as only the newly loaded libraries will be included, not any already-loaded
+ * dependencies. The caller should ensure that the set of libraries newly loaded is consistent
+ * for this to be effective.
+ *
+ * This is mainly useful for the system WebView implementation.
+ */
+ ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE = 0x400,
+
+
/** Mask of valid bits. */
ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS |
ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
@@ -122,7 +145,8 @@
ANDROID_DLEXT_USE_LIBRARY_FD |
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET |
ANDROID_DLEXT_FORCE_LOAD |
- ANDROID_DLEXT_USE_NAMESPACE,
+ ANDROID_DLEXT_USE_NAMESPACE |
+ ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE,
};
struct android_namespace_t;