Orion Hodson | 9b16e34 | 2019-10-09 13:29:16 +0100 | [diff] [blame] | 1 | libnativeloader |
| 2 | =============================================================================== |
| 3 | |
| 4 | Overview |
| 5 | ------------------------------------------------------------------------------- |
| 6 | libnativeloader is responsible for loading native shared libraries (`*.so` |
| 7 | files) inside the Android Runtime (ART). The native shared libraries could be |
| 8 | app-provided JNI libraries or public native libraries like `libc.so` provided |
| 9 | by the platform. |
| 10 | |
| 11 | The most typical use case of this library is calling `System.loadLibrary(name)`. |
| 12 | When the method is called, the ART runtime delegates the call to this library |
| 13 | along with the reference to the classloader where the call was made. Then this |
| 14 | library finds the linker namespace (named `classloader-namespace`) that is |
| 15 | associated with the given classloader, and tries to load the requested library |
| 16 | from the namespace. The actual searching, loading, and linking of the library |
| 17 | is performed by the dynamic linker. |
| 18 | |
| 19 | The linker namespace is created when an APK is loaded into the process, and is |
| 20 | associated with the classloader that loaded the APK. The linker namespace is |
| 21 | configured so that only the JNI libraries embedded in the APK is accessible |
| 22 | from the namespace, thus preventing an APK from loading JNI libraries of other |
| 23 | APKs. |
| 24 | |
| 25 | The linker namespace is also configured differently depending on other |
| 26 | characteristics of the APK such as whether or not the APK is bundled with the |
| 27 | platform. In case of the unbundled, i.e., downloaded or updated APK, only the |
| 28 | public native libraries that is listed in `/system/etc/public.libraries.txt` |
| 29 | are available from the platform, whereas in case of the bundled, all libraries |
| 30 | under `/system/lib` are available (i.e. shared). In case when the unbundled |
| 31 | app is from `/vendor` or `/product` partition, the app is additionally provided |
| 32 | with the [VNDK-SP](https://source.android.com/devices/architecture/vndk#sp-hal) |
| 33 | libraries. As the platform is getting modularized with |
| 34 | [APEX](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/docs/README.md), |
| 35 | some libraries are no longer provided from platform, but from the APEXes which |
| 36 | have their own linker namespaces. For example, ICU libraries `libicuuc.so` and |
| 37 | `libicui18n.so` are from the runtime APEX. |
| 38 | |
| 39 | The list of public native libraries is not static. The default set of libraries |
| 40 | are defined in AOSP, but partners can extend it to include their own libraries. |
| 41 | Currently, following extensions are available: |
| 42 | |
| 43 | - `/vendor/etc/public.libraries.txt`: libraries in `/vendor/lib` that are |
| 44 | specific to the underlying SoC, e.g. GPU, DSP, etc. |
| 45 | - `/{system|product}/etc/public.libraries-<companyname>.txt`: libraries in |
| 46 | `/{system|product}/lib` that a device manufacturer has newly added. The |
| 47 | libraries should be named as `lib<name>.<companyname>.so` as in |
| 48 | `libFoo.acme.so`. |
| 49 | |
| 50 | Note that, due to the naming constraint requiring `.<companyname>.so` suffix, it |
| 51 | is prohibited for a device manufacturer to expose an AOSP-defined private |
| 52 | library, e.g. libgui.so, libart.so, etc., to APKs. |
| 53 | |
| 54 | Lastly, libnativeloader is responsible for abstracting the two types of the |
| 55 | dynamic linker interface: `libdl.so` and `libnativebridge.so`. The former is |
| 56 | for non-translated, e.g. ARM-on-ARM, libraries, while the latter is for |
| 57 | loading libraries in a translated environment such as ARM-on-x86. |
| 58 | |
| 59 | Implementation |
| 60 | ------------------------------------------------------------------------------- |
| 61 | Implementation wise, libnativeloader consists of four parts: |
| 62 | |
| 63 | - `native_loader.cpp` |
| 64 | - `library_namespaces.cpp` |
| 65 | - `native_loader_namespace.cpp` |
| 66 | - `public_libraries.cpp` |
| 67 | |
| 68 | `native_loader.cpp` implements the public interface of this library. It is just |
| 69 | a thin wrapper around `library_namespaces.cpp` and `native_loader_namespace.cpp`. |
| 70 | |
| 71 | `library_namespaces.cpp` implements the singleton class `LibraryNamespaces` which |
| 72 | is a manager-like entity that is responsible for creating and configuring |
| 73 | linker namespaces and finding an already created linker namespace for a given |
| 74 | classloader. |
| 75 | |
| 76 | `native_loader_namespace.cpp` implements the class `NativeLoaderNamespace` that |
| 77 | models a linker namespace. Its main job is to abstract the two types of the |
| 78 | dynamic linker interface so that other parts of this library do not have to know |
| 79 | the differences of the interfaces. |
| 80 | |
| 81 | `public_libraries.cpp` is responsible for reading `*.txt` files for the public |
| 82 | native libraries from the various partitions. It can be considered as a part of |
| 83 | `LibraryNamespaces` but is separated from it to hide the details of the parsing |
| 84 | routines. |