The dynamic linker tackles two challenges in Treble VNDK design:
dlopen()
and android_dlopen_ext()
may introduce
some run-time dependencies that are not visible at build-time and can be
difficult to detect using static analysis.These two challenges can be resolved by the linker namespace mechanism. The linker namespace mechanism is provided by the dynamic linker. It can isolate the shared libraries in different linker namespaces so that libraries with same library name but with different symbols won't conflict.
On the other hand, the linker namespace mechanism provides the flexibility so that some shared libraries may be exported by a linker namespace and used by another linker namespace. These exported shared libraries may become the application programming interfaces that are public to other programs while hiding their implementation details within their linker namespaces.
For example, /system/lib[64]/libcutils.so
and
/system/lib[64]/vndk-sp-${VER}/libcutils.so
are two shared
libraries. These two libraries may have different symbols. They are loaded
into different linker namespaces so that framework modules can depend on
/system/lib[64]/libcutils.so
and SP-HAL shared libraries can
depend on /system/lib[64]/vndk-sp-${VER}/libcutils.so
.
On the other hand, /system/lib[64]/libc.so
is an example of
public libraries that is exported by a linker namespace and imported into
many linker namespaces. The dependencies of
/system/lib[64]/libc.so
, such as libnetd_client.so
,
is loaded into the namespace in which /system/lib[64]/libc.so
resides. Other namespaces won't have accesses to those dependencies. This
mechanism encapsulates the implementation details while providing the public
interfaces.
The dynamic linker is responsible for loading the shared libraries specified
in DT_NEEDED
entries or the shared libraries specified by the
argument of dlopen()
or android_dlopen_ext()
. In both
cases, the dynamic linker finds the linker namespace where the caller
resides and try to load the dependencies into the same linker namespace. If
the dynamic linker cannot load the shared library into the specified linker
namespace, it asks the linked linker namespace for exported shared
libraries.
The configuration file format is based on the INI file format. A typical configuration file looks like:
dir.system = /system/bin dir.system = /system/xbin dir.vendor = /vendor/bin [system] additional.namespaces = sphal,vndk namespace.default.isolated = true namespace.default.search.paths = /system/${LIB} namespace.default.permitted.paths = /system/${LIB}/hw namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} namespace.default.asan.permitted.paths = /data/asan/system/${LIB}/hw:/system/${LIB}/hw namespace.sphal.isolated = true namespace.sphal.visible = true namespace.sphal.search.paths = /odm/${LIB}:/vendor/${LIB} namespace.sphal.permitted.paths = /odm/${LIB}:/vendor/${LIB} namespace.sphal.asan.search.paths = /data/asan/odm/${LIB}:/odm/${LIB} namespace.sphal.asan.search.paths += /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.asan.permitted.paths = /data/asan/odm/${LIB}:/odm/${LIB} namespace.sphal.asan.permitted.paths += /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.links = default,vndk namespace.sphal.link.default.shared_libs = libc.so:libm.so namespace.sphal.link.vndk.shared_libs = libbase.so:libcutils.so namespace.vndk.isolated = true namespace.vndk.search.paths = /system/${LIB}/vndk-sp-29 namespace.vndk.permitted.paths = /system/${LIB}/vndk-sp-29 namespace.vndk.links = default namespace.vndk.link.default.shared_libs = libc.so:libm.so [vendor] namespace.default.isolated = false namespace.default.search.paths = /vendor/${LIB}:/system/${LIB}
The configuration file includes:
The tables below describe the meaning of each property in detail.
Property | Description | Example |
---|---|---|
|
A path to a directory that the Each property maps the executables under the directory to a linker
namespaces configuration section. There might be two (or more) properties
with the same |
This indicates that the configuration specified in the
The configuration specified in the |
Property | Description | Example |
---|---|---|
additional. |
A comma-separated list of additional namespaces (in addition to the
|
This indicates there are three namespaces ( |
namespace. |
A comma-separated list of fallback namespaces. If a shared library cannot be found in the current namespace, the dynamic linker tries to load the shared library from the fallback namespaces. The namespace specified at the beginning of the list has higher priority. |
If a shared library or an executable requests a shared library that
cannot be loaded into the And then, if the shared library cannot be loaded from the
Finally, if all attempts fail, the dynamic linker returns an error. |
namespace. |
A colon-separated list of shared libraries that can be searched in the
This property cannot be used with
|
This indicates that the fallback link only accepts |
namespace. |
A boolean value that indicates whether all shared libraries can be
searched in the This property cannot be used with
|
This indicates all library names can walk through the fallback link
from |
Property | Description | Example |
---|---|---|
namespace. |
A boolean value that indicates whether the dynamic linker should check where the shared library resides. If If |
This indicates that only the shared libraries in
|
namespace. |
A colon-separated list of directories to search for shared libraries. The directories specified in When For example, if |
This indicates that the dynamic linker searches
|
namespace. |
A colon-separated list of directories to search for shared libraries when Address Sanitizer is enabled.
|
This indicates that when
Address Sanitizer is enabled the
dynamic linker searches |
namespace. |
A colon-separated list of directories (including sub-directories) where
the dynamic linker can load the shared libraries (in addition to
The shared libraries that are under the sub-directories of
If |
This indicates that the shared libraries under
For example, without |
namespace. |
A colon-separated list of directories where the dynamic linker can load the shared libraries when Address Sanitizer is enabled.
|
This indicates that when
Address Sanitizer is enabled shared
libraries under |
namespace. |
A boolean value that indicates whether the program (other than
If If |
This indicates that |
There are three configuration files in
${android-src}/system/core/rootdir/etc
. Depending on the value of
PRODUCT_TREBLE_LINKER_NAMESPACES
, BOARD_VNDK_VERSION
,
and BOARD_VNDK_RUNTIME_DISABLE
in BoardConfig.mk
,
different configurations are selected:
PRODUCT_TREBLE_ LINKER_NAMESPACES |
BOARD_VNDK_ VERSION |
BOARD_VNDK_ RUNTIME_DISABLE |
Selected configuration | VTS Requirement |
---|---|---|---|---|
true |
current |
empty | ld.config.txt |
Mandatory for devices launched with Android P. |
true |
ld.config.vndk_lite.txt |
Mandatory for devices launched with Android 8.x. | ||
empty | any | |||
false |
any | any | ld.config.legacy.txt |
For non-Treble devices |
${android-src}/system/core/rootdir/etc/ld.config.vndk_lite.txt
isolates SP-HAL and VNDK-SP shared libraries. In Android 8.0 and higher, this
must be the configuration file for dynamic linker when
PRODUCT_TREBLE_LINKER_NAMESPACES
is true
.
${android-src}/system/core/rootdir/etc/ld.config.txt
isolates
SP-HAL and VNDK-SP shared libraries as well. In addition,
ld.config.txt
also provides the full dynamic linker isolation.
It makes sure that modules in the system partition won't depend on the shared
libraries in the vendor partitions and vice versa.
In Android 8.1, ld.config.txt
is the default configuration file
and it is highly recommended to enable full dynamic linker isolation. However,
if there are too many dependencies to be cleaned up in Android 8.1, you may add
BOARD_VNDK_RUNTIME_DISABLE
to BoardConfig.mk
:
BOARD_VNDK_RUNTIME_DISABLE := true
If BOARD_VNDK_RUNTIME_DISABLE
is true
,
${android-src}/system/core/rootdir/etc/ld.config.vndk_lite.txt
is installed.
ld.config.txt
isolates the shared library dependencies
between the system partition and vendor partitions. Compared to
ld.config.txt
mentioned in previous subsection, the differences
are outlined as following items:
Framework Processes
default
, vndk
,
sphal
, and rs
) are created.default
namespace.sphal
namespace.vndk
namespace.Vendor Processes
default
, vndk
, and
system
) are created.default
namespace is isolated.default
namespace.vndk
namespace.system
namespace.The relationship between the linker namespaces is depicted in the figure below:
ld.config.txt
)
In the graph above, LL-NDK and VNDK-SP stand for following shared libraries:
libEGL.so
libGLESv1_CM.so
libGLESv2.so
libGLESv3.so
libandroid_net.so
libc.so
libdl.so
liblog.so
libm.so
libnativewindow.so
libneuralnetworks.so
libsync.so
libvndksupport.so
libvulkan.so
android.hardware.graphics.common@1.0.so
android.hardware.graphics.mapper@2.0.so
android.hardware.renderscript@1.0.so
android.hidl.memory@1.0.so
libRSCpuRef.so
libRSDriver.so
libRS_internal.so
libbase.so
libbcinfo.so
libc++.so
libcutils.so
libhardware.so
libhidlbase.so
libhidlmemory.so
libhidltransport.so
libhwbinder.so
libion.so
libutils.so
libz.so
The table below presents the namespaces configuration for framework
processes, which is excerpted from the [system]
section in
ld.config.txt
:
Namespace | Property | Value |
---|---|---|
default |
search.paths |
/system/${LIB} /product/${LIB}
|
permitted.paths |
/system/${LIB}/drm /system/${LIB}/extractors /system/${LIB}/hw /product/${LIB} /system/framework /system/app /system/priv-app /vendor/app /vendor/priv-app /oem/app /odm/priv-app /oem/app /product/framework /product/app /product/priv-app /data /mnt/expand
|
|
isolated |
true |
|
sphal |
search.paths |
/odm/${LIB} /vendor/${LIB}
|
permitted.paths |
/odm/${LIB} /vendor/${LIB}
|
|
isolated |
true |
|
visible |
true |
|
links |
default,vndk,rs |
|
link.default.shared_libs |
LL-NDK | |
link.vndk.shared_libs |
VNDK-SP | |
link.rs.shared_libs |
libRS_internal.so |
|
vndk (For VNDK-SP) |
search.paths |
/odm/${LIB}/vndk-sp /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-sp-${VER}
|
permitted.paths |
/odm/${LIB}/hw /odm/${LIB}/egl /vendor/${LIB}/hw /vendor/${LIB}/egl /system/${LIB}/vndk-sp-${VER}/hw
|
|
isolated |
true |
|
visible |
true |
|
links |
default , sphal |
|
link.default.shared_libs |
LL-NDK | |
link.default.allow_all_shared_libs |
true |
|
rs (For Renderscript) |
search.paths |
/odm/${LIB}/vndk-sp /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-sp-${VER} /odm/${LIB} /vendor/${LIB}
|
permitted.paths |
/odm/${LIB} /vendor/${LIB} /data (For compiled RS kernel)
|
|
isolated |
true |
|
visible |
true |
|
links |
default,vndk |
|
link.default.shared_libs |
LL-NDKlibmediandk.so libft2.so
|
|
link.vndk.shared_libs |
VNDK-SP |
The table below presents the namespaces configuration for vendor processes,
which is excerpted from the [vendor]
section in
ld.config.txt
:
Namespace | Property | Value |
---|---|---|
default |
search.paths |
/odm/${LIB} /vendor/${LIB}
|
permitted.paths |
/odm /vendor |
|
isolated |
true |
|
visible |
true |
|
links |
system , vndk |
|
link.system.shared_libs |
LL-NDK | |
link.vndk.shared_libs |
VNDK, VNDK-SP (vendor available) | |
vndk |
search.paths |
/odm/${LIB}/vndk /odm/${LIB}/vndk-sp /vendor/${LIB}/vndk /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-${VER} /system/${LIB}/vndk-sp-${VER}
|
isolated |
true |
|
links |
system , default |
|
link.system.shared_libs |
LL-NDK | |
link.default.allow_all_shared_libs |
true |
|
system |
search.paths |
/system/${LIB} |
isolated |
false |
More details can be found in
${android-src}/system/core/rootdir/etc/ld.config.txt
.
As of Android 8.0, the dynamic linker is configured to isolate SP-HAL and VNDK-SP shared libraries such that their symbols do not conflict with other framework shared libraries. The relationship between the linker namespaces is shown below:
ld.config.vndk_lite.txt
)
LL-NDK and VNDK-SP stand for following shared libraries:
libEGL.so
libGLESv1_CM.so
libGLESv2.so
libc.so
libdl.so
liblog.so
libm.so
libnativewindow.so
libstdc++.so
(Not in ld.config.txt
)libsync.so
libvndksupport.so
libz.so
(Moved to VNDK-SP in
ld.config.txt
)android.hardware.graphics.common@1.0.so
android.hardware.graphics.mapper@2.0.so
android.hardware.renderscript@1.0.so
android.hidl.memory@1.0.so
libbase.so
libc++.so
libcutils.so
libhardware.so
libhidlbase.so
libhidlmemory.so
libhidltransport.so
libhwbinder.so
libion.so
libutils.so
The table below presents the namespaces configuration for framework
processes, which is excerpted from the [system]
section in
ld.config.vndk_lite.txt
:
Namespace | Property | Value |
---|---|---|
default |
search.paths |
/system/${LIB} /odm/${LIB} /vendor/${LIB} /product/${LIB}
|
isolated |
false |
|
sphal |
search.paths |
/odm/${LIB} /vendor/${LIB}
|
permitted.paths |
/odm/${LIB} /vendor/${LIB}
|
|
isolated |
true |
|
visible |
true |
|
links |
default,vndk,rs |
|
link.default.shared_libs |
LL-NDK | |
link.vndk.shared_libs |
VNDK-SP | |
link.rs.shared_libs |
libRS_internal.so |
|
vndk (For VNDK-SP) |
search.paths |
/odm/${LIB}/vndk-sp /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-sp-${VER}
|
permitted.paths |
/odm/${LIB}/hw /odm/${LIB}/egl /vendor/${LIB}/hw /vendor/${LIB}/egl /system/${LIB}/vndk-sp-${VER}/hw |
|
isolated |
true |
|
visible |
true |
|
links |
default |
|
link.default.shared_libs |
LL-NDK | |
rs (For Renderscript) |
search.paths |
/odm/${LIB}/vndk-sp /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-sp-${VER} /odm/${LIB} /vendor/${LIB}
|
permitted.paths |
/odm/${LIB} /vendor/${LIB} /data (For compiled RS kernel)
|
|
isolated |
true |
|
visible |
true |
|
links |
default,vndk |
|
link.default.shared_libs |
LL-NDKlibmediandk.so libft2.so
|
|
link.vndk.shared_libs |
VNDK-SP |
The table below presents the namespaces configuration for vendor processes,
which is excerpted from the [vendor]
section in
ld.config.vndk_lite.txt
:
Namespace | Property | Value |
---|---|---|
default |
search.paths |
/odm/${LIB} /odm/${LIB}/vndk /odm/${LIB}/vndk-sp /vendor/${LIB} /vendor/${LIB}/vndk /vendor/${LIB}/vndk-sp /system/${LIB}/vndk-${VER} /system/${LIB}/vndk-sp-${VER} /system/${LIB} (Deprecated)/product/${LIB} (Deprecated)
|
isolated |
false |
More details can be found in
${android-src}/system/core/rootdir/etc/ld.config.vndk_lite.txt
.
In Android P, the vndk
linker namespace is added to vendor
processes and VNDK shared libraries are isolated from the default linker
namespace.
Replace PRODUCT_FULL_TREBLE
with more specific
PRODUCT_TREBLE_LINKER_NAMESPACES
.
Android P changes the names of the following dynamic linker configuration files:
Android 8.x | Android P | Description |
---|---|---|
ld.config.txt.in | ld.config.txt | For devices with runtime linker namespace isolation |
ld.config.txt | ld.config.vndk_lite.txt | For devices with VNDK-SP linker namespace isolation |
ld.config.legacy.txt | ld.config.legacy.txt | For legacy devices running Android 7.x and earlier |
Remove android.hardware.graphics.allocator@2.0.so
.
product
and odm
partitions are added.