diff --git a/libnativeloader/README.md b/libnativeloader/README.md new file mode 100644 index 000000000..46f6fdd7c --- /dev/null +++ b/libnativeloader/README.md @@ -0,0 +1,84 @@ +libnativeloader +=============================================================================== + +Overview +------------------------------------------------------------------------------- +libnativeloader is responsible for loading native shared libraries (`*.so` +files) inside the Android Runtime (ART). The native shared libraries could be +app-provided JNI libraries or public native libraries like `libc.so` provided +by the platform. + +The most typical use case of this library is calling `System.loadLibrary(name)`. +When the method is called, the ART runtime delegates the call to this library +along with the reference to the classloader where the call was made. Then this +library finds the linker namespace (named `classloader-namespace`) that is +associated with the given classloader, and tries to load the requested library +from the namespace. The actual searching, loading, and linking of the library +is performed by the dynamic linker. + +The linker namespace is created when an APK is loaded into the process, and is +associated with the classloader that loaded the APK. The linker namespace is +configured so that only the JNI libraries embedded in the APK is accessible +from the namespace, thus preventing an APK from loading JNI libraries of other +APKs. + +The linker namespace is also configured differently depending on other +characteristics of the APK such as whether or not the APK is bundled with the +platform. In case of the unbundled, i.e., downloaded or updated APK, only the +public native libraries that is listed in `/system/etc/public.libraries.txt` +are available from the platform, whereas in case of the bundled, all libraries +under `/system/lib` are available (i.e. shared). In case when the unbundled +app is from `/vendor` or `/product` partition, the app is additionally provided +with the [VNDK-SP](https://source.android.com/devices/architecture/vndk#sp-hal) +libraries. As the platform is getting modularized with +[APEX](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/docs/README.md), +some libraries are no longer provided from platform, but from the APEXes which +have their own linker namespaces. For example, ICU libraries `libicuuc.so` and +`libicui18n.so` are from the runtime APEX. + +The list of public native libraries is not static. The default set of libraries +are defined in AOSP, but partners can extend it to include their own libraries. +Currently, following extensions are available: + +- `/vendor/etc/public.libraries.txt`: libraries in `/vendor/lib` that are +specific to the underlying SoC, e.g. GPU, DSP, etc. +- `/{system|product}/etc/public.libraries-.txt`: libraries in +`/{system|system}/lib` that a device manufacturer has newly added. The +libraries should be named as `lib..so` as in +`libFoo.acme.so`. + +Note that, due to the naming constraint requiring `..so` suffix, it +is prohibited for a device manufacturer to expose an AOSP-defined private +library, e.g. libgui.so, libart.so, etc., to APKs. + +Lastly, libnativeloader is responsible for abstracting the two types of the +dynamic linker interface: `libdl.so` and `libnativebridge.so`. The former is +for non-translated, e.g. ARM-on-ARM, libraries, while the latter is for +loading libraries in a translated environment such as ARM-on-x86. + +Implementation +------------------------------------------------------------------------------- +Implementation wise, libnativeloader consists of four parts: + +- `native_loader.cpp` +- `library_namespaces.cpp` +- `native_loader_namespace.cpp` +- `public_libraries.cpp` + +`native_loader.cpp` implements the public interface of this library. It is just +a thin wrapper around `library_namespaces.cpp` and `native_loader_namespace.cpp`. + +`library_namespaces.cpp` implements the singleton class `LibraryNamespaces` which +is a manager-like entity that is responsible for creating and configuring +linker namespaces and finding an already created linker namespace for a given +classloader. + +`native_loader_namesapces.cpp` implements the class `NativeLoaderNamespace` that +models a linker namespace. It's main job is to abstract the two types of the +dynamic linker interface so that other parts of this library do not have to know +the differences of the interfaces. + +`public_libraries.cpp` is responsible for reading `*.txt` files for the public +native libraries from the various partitions. It can be considered as a part of +`LibraryNamespaces` but is separated from it to hide the details of the parsing +routines. diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp index 1900d5d71..f7f972ffc 100644 --- a/libnativeloader/library_namespaces.cpp +++ b/libnativeloader/library_namespaces.cpp @@ -22,12 +22,13 @@ #include #include -#include "android-base/file.h" -#include "android-base/logging.h" -#include "android-base/macros.h" -#include "android-base/properties.h" -#include "android-base/strings.h" -#include "nativehelper/ScopedUtfChars.h" +#include +#include +#include +#include +#include +#include + #include "nativeloader/dlext_namespaces.h" #include "public_libraries.h" #include "utils.h" diff --git a/libnativeloader/library_namespaces.h b/libnativeloader/library_namespaces.h index 103cfacbc..fd46cdce3 100644 --- a/libnativeloader/library_namespaces.h +++ b/libnativeloader/library_namespaces.h @@ -25,8 +25,7 @@ #include #include -#include "jni.h" -#include "utils.h" +#include namespace android::nativeloader { diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index d6304a916..0c29324e6 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -14,9 +14,10 @@ * limitations under the License. */ -#include "nativeloader/native_loader.h" #define LOG_TAG "nativeloader" +#include "nativeloader/native_loader.h" + #include #include @@ -25,16 +26,17 @@ #include #include -#include "android-base/file.h" -#include "android-base/macros.h" -#include "android-base/strings.h" +#include +#include +#include +#include +#include + #ifdef __ANDROID__ +#include #include "library_namespaces.h" -#include "log/log.h" #include "nativeloader/dlext_namespaces.h" #endif -#include "nativebridge/native_bridge.h" -#include "nativehelper/ScopedUtfChars.h" namespace android { diff --git a/libnativeloader/native_loader_namespace.cpp b/libnativeloader/native_loader_namespace.cpp index e0d4697ca..90f730c9b 100644 --- a/libnativeloader/native_loader_namespace.cpp +++ b/libnativeloader/native_loader_namespace.cpp @@ -15,15 +15,17 @@ */ #define LOG_TAG "nativeloader" + #include "native_loader_namespace.h" #include #include -#include "android-base/strings.h" -#include "log/log.h" -#include "nativebridge/native_bridge.h" +#include +#include +#include + #include "nativeloader/dlext_namespaces.h" namespace android { diff --git a/libnativeloader/native_loader_namespace.h b/libnativeloader/native_loader_namespace.h index 26c62cf09..1575f8ccb 100644 --- a/libnativeloader/native_loader_namespace.h +++ b/libnativeloader/native_loader_namespace.h @@ -20,10 +20,10 @@ #include #include -#include "android-base/logging.h" -#include "android/dlext.h" -#include "log/log.h" -#include "nativebridge/native_bridge.h" +#include +#include +#include +#include namespace android { diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp index 64fedaead..c205eb133 100644 --- a/libnativeloader/public_libraries.cpp +++ b/libnativeloader/public_libraries.cpp @@ -14,19 +14,21 @@ * limitations under the License. */ -#include "public_libraries.h" #define LOG_TAG "nativeloader" +#include "public_libraries.h" + #include #include #include -#include "android-base/file.h" -#include "android-base/logging.h" -#include "android-base/properties.h" -#include "android-base/strings.h" -#include "log/log.h" +#include +#include +#include +#include +#include + #include "utils.h" namespace android::nativeloader {