platform_system_core/libnativeloader
Jiyong Park c5e85bf9ba Don't fail if default namespace isn't found
This fixes a regression caused by 8f4afc8298
that libnativeloader can't no longer handle the case that it has failed
to find the default namespace. Previously before the change,
libnativeloader continued to use nullptr as the parent namespace which
is reconized as the default namespace inside the linker.

This change recovers the previous behavior. When the default namespace
is not found, NativeLoaderNamespace object is constructed from nullptr.

Bug: 138607234
Test: run app-compat/app-startup-gce on cf_x86_phone using forrest
Change-Id: If518fbc055399b73e7d3a6b45ace0f71e9c25dae
(cherry picked from commit db825ceba6)
Merged-In: If518fbc055399b73e7d3a6b45ace0f71e9c25dae
2019-08-01 09:30:01 +09:00
..
include/nativeloader Add product apk support from libnativeloader 2019-03-07 15:01:52 +09:00
test shim libraries for libnativeloader and libnativebridge 2019-02-12 19:35:45 +09:00
.clang-format Set libnativeloader style to clang-format-2 2017-03-29 17:33:12 -07:00
Android.bp Add TEST_MAPPING for libnativeloader 2019-07-23 11:14:48 +09:00
libnativeloader.map.txt Move to C API of libnativeloader. 2019-01-16 13:40:28 +00:00
library_namespaces.cpp Use android::base::Result in libnativeloader 2019-07-26 08:06:46 +09:00
library_namespaces.h Use android::base::Result in libnativeloader 2019-07-26 08:06:46 +09:00
native_loader.cpp Use android::base::Result in libnativeloader 2019-07-26 08:06:46 +09:00
native_loader_lazy.cpp Add product apk support from libnativeloader 2019-03-07 15:01:52 +09:00
native_loader_namespace.cpp Don't fail if default namespace isn't found 2019-08-01 09:30:01 +09:00
native_loader_namespace.h Use android::base::Result in libnativeloader 2019-07-26 08:06:46 +09:00
native_loader_test.cpp Merge "Don't fail catastrophically on non-existing namespace" 2019-07-26 14:50:33 +00:00
OWNERS Add runtime module members to owners. 2019-01-16 22:00:48 +00:00
public_libraries.cpp Use android::base::Result in libnativeloader 2019-07-26 08:06:46 +09:00
public_libraries.h ld.config for com.android.neuralnetworks APEX. 2019-07-22 11:28:42 +01:00
README.md Add README file for libnativeloader 2019-05-16 08:55:11 +09:00
TEST_MAPPING Add TEST_MAPPING for libnativeloader 2019-07-23 11:14:48 +09:00
utils.h Introduce utils.h 2019-05-08 13:49:49 +09:00

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 libraries. As the platform is getting modularized with APEX, 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-<companyname>.txt: libraries in /{system|system}/lib that a device manufacturer has newly added. The libraries should be named as lib<name>.<companyname>.so as in libFoo.acme.so.

Note that, due to the naming constraint requiring .<companyname>.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.