Dynamiczny linker stawia czoła dwóm wyzwaniom w projektowaniu Treble VNDK:
- Biblioteki współdzielone SP-HAL i ich zależności, w tym biblioteki VNDK-SP, są ładowane do procesów frameworka. Powinny istnieć pewne mechanizmy zapobiegające konfliktom symboli.
-
dlopen()
iandroid_dlopen_ext()
mogą wprowadzić pewne zależności w czasie wykonywania, które nie są widoczne w czasie kompilacji i mogą być trudne do wykrycia za pomocą analizy statycznej.
Te dwa wyzwania można rozwiązać za pomocą mechanizmu przestrzeni nazw linkera . Mechanizm ten zapewnia dynamiczny linker. Może izolować biblioteki współdzielone w różnych przestrzeniach nazw linkerów, dzięki czemu biblioteki o tej samej nazwie biblioteki, ale z różnymi symbolami, nie będą powodować konfliktów.
Z drugiej strony mechanizm przestrzeni nazw konsolidatora zapewnia elastyczność, dzięki czemu niektóre biblioteki współdzielone mogą być eksportowane przez przestrzeń nazw konsolidatora i używane przez inną przestrzeń nazw konsolidatora. Te wyeksportowane biblioteki współdzielone mogą stać się interfejsami programowania aplikacji, które są publiczne dla innych programów, ukrywając jednocześnie szczegóły ich implementacji w przestrzeniach nazw konsolidatora.
Na przykład /system/lib[64]/libcutils.so
i /system/lib[64]/vndk-sp-${VER}/libcutils.so
to dwie biblioteki współdzielone. Te dwie biblioteki mogą mieć różne symbole. Są ładowane do różnych przestrzeni nazw linkerów, więc moduły frameworku mogą zależeć od /system/lib[64]/libcutils.so
, a biblioteki współdzielone SP-HAL mogą zależeć od /system/lib[64]/vndk-sp-${VER}/libcutils.so
.
Z drugiej strony /system/lib[64]/libc.so
jest przykładem biblioteki publicznej, która jest eksportowana przez przestrzeń nazw konsolidatora i importowana do wielu przestrzeni nazw konsolidatora. Zależności pliku /system/lib[64]/libc.so
, takie jak libnetd_client.so
, są ładowane do przestrzeni nazw, w której znajduje się /system/lib[64]/libc.so
. Inne przestrzenie nazw nie będą miały dostępu do tych zależności. Mechanizm ten hermetyzuje szczegóły implementacji, zapewniając jednocześnie interfejsy publiczne.
Jak to działa?
Linker dynamiczny odpowiada za ładowanie bibliotek współdzielonych określonych we wpisach DT_NEEDED
lub bibliotek współdzielonych określonych przez argument dlopen()
lub android_dlopen_ext()
. W obu przypadkach dynamiczny linker znajduje przestrzeń nazw linkera, w której znajduje się obiekt wywołujący, i próbuje załadować zależności do tej samej przestrzeni nazw linkera. Jeśli dynamiczny linker nie może załadować biblioteki współdzielonej do określonej przestrzeni nazw konsolidatora, pyta połączoną przestrzeń nazw konsolidatora o wyeksportowane biblioteki współdzielone.
Format pliku konfiguracyjnego
Format pliku konfiguracyjnego opiera się na formacie pliku INI. Typowy plik konfiguracyjny wygląda następująco:
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}
Plik konfiguracyjny zawiera:
- Na początku kilka właściwości mapowania sekcji katalogów, aby dynamiczny linker mógł wybrać efektywną sekcję.
- Kilka sekcji konfiguracyjnych przestrzeni nazw linkera:
- Każda sekcja zawiera kilka przestrzeni nazw (wierzchołki wykresu) i kilka zastępczych łączy między przestrzeniami nazw (łuki wykresu).
- Każda przestrzeń nazw ma własną izolację, ścieżki wyszukiwania, dozwolone ścieżki i ustawienia widoczności.
Poniższe tabele szczegółowo opisują znaczenie każdej właściwości.
Właściwość mapowania sekcji katalogu
Nieruchomość | Opis | Przykład |
---|---|---|
| Ścieżka do katalogu, którego dotyczy sekcja Każda właściwość odwzorowuje pliki wykonywalne w katalogu na sekcję konfiguracji przestrzeni nazw konsolidatora. Mogą istnieć dwie (lub więcej) właściwości o tej samej | Oznacza to, że konfiguracja określona w sekcji Konfiguracja określona w sekcji |
Właściwości relacji
Nieruchomość | Opis | Przykład |
---|---|---|
additional. namespaces | Rozdzielana przecinkami lista dodatkowych przestrzeni nazw (oprócz | Oznacza to, że w konfiguracji |
namespace. name . links | Rozdzielana przecinkami lista zastępczych przestrzeni nazw. Jeśli w bieżącej przestrzeni nazw nie można znaleźć biblioteki współdzielonej, linker dynamiczny próbuje załadować bibliotekę współdzieloną z rezerwowych przestrzeni nazw. Przestrzeń nazw określona na początku listy ma wyższy priorytet. | Jeśli biblioteka współdzielona lub plik wykonywalny żąda biblioteki współdzielonej, której nie można załadować do przestrzeni nazw Następnie, jeśli nie można załadować biblioteki współdzielonej z Na koniec, jeśli wszystkie próby zawiodą, dynamiczny linker zwróci błąd. |
namespace. name . link. other . shared_libs | Rozdzielana dwukropkami lista bibliotek współdzielonych, które można przeszukiwać w Tej właściwości nie można używać z | Oznacza to, że łącze rezerwowe akceptuje tylko |
namespace. name . link. other . allow_all_shared_libs | Wartość logiczna wskazująca, czy wszystkie biblioteki współdzielone mogą być przeszukiwane w Tej właściwości nie można używać z | Oznacza to, że wszystkie nazwy bibliotek mogą przechodzić przez łącze rezerwowe z przestrzeni |
Właściwości przestrzeni nazw
Nieruchomość | Opis | Przykład |
---|---|---|
namespace. name . isolated | Wartość logiczna wskazująca, czy linker dynamiczny powinien sprawdzać, gdzie znajduje się biblioteka współdzielona. Jeśli Jeśli | Oznacza to, że do przestrzeni nazw |
namespace. name . search.paths | Rozdzielana dwukropkami lista katalogów do wyszukiwania bibliotek współdzielonych. Katalogi określone w Jeśli Na przykład, jeśli | Oznacza to, że dynamiczny linker przeszukuje |
namespace. name . asan.search.paths | Rozdzielana dwukropkami lista katalogów, w których należy wyszukiwać biblioteki współdzielone, gdy włączony jest program AddressSanitizer (ASan) . | Oznacza to, że gdy ASan jest włączony, dynamiczny linker przeszukuje najpierw |
namespace. name . permitted.paths | Rozdzielana dwukropkami lista katalogów (w tym podkatalogów), z których dynamiczny linker może załadować biblioteki współdzielone (oprócz Można także załadować biblioteki współdzielone znajdujące się w podkatalogach Jeśli | Oznacza to, że biblioteki współdzielone z Na przykład bez |
namespace. name . asan.permitted.paths | Rozdzielana dwukropkami lista katalogów, w których dynamiczny linker może załadować biblioteki współdzielone, gdy włączony jest ASan . | Oznacza to, że gdy włączony jest ASan , biblioteki współdzielone w |
namespace. name . visible | Wartość logiczna wskazująca, czy program (inny niż Jeśli Jeśli | Oznacza to, że |
Tworzenie przestrzeni nazw linkera
W Androidzie 11 konfiguracja linkera jest tworzona w czasie wykonywania w /linkerconfig
zamiast używać zwykłych plików tekstowych w ${android-src}/system/core/rootdir/etc
. Konfiguracja jest generowana podczas uruchamiania systemu na podstawie środowiska wykonawczego, które obejmuje następujące elementy:
- Jeśli urządzenie obsługuje VNDK
- Docelowa wersja VNDK partycji dostawcy
- Wersja VNDK partycji produktu
- Zainstalowane moduły APEX
Konfiguracja linkera jest tworzona poprzez rozwiązanie zależności pomiędzy przestrzeniami nazw linkera. Na przykład, jeśli istnieją jakieś aktualizacje modułów APEX, które obejmują aktualizacje zależności, generowana jest konfiguracja linkera odzwierciedlająca te zmiany. Więcej szczegółów na temat tworzenia konfiguracji linkera można znaleźć w ${android-src}/system/linkerconfig
.
Izolacja przestrzeni nazw linkera
Istnieją trzy typy konfiguracji. W zależności od wartości PRODUCT_TREBLE_LINKER_NAMESPACES
i BOARD_VNDK_VERSION
w BoardConfig.mk
, podczas rozruchu generowana jest odpowiednia konfiguracja.
PRODUCT_TREBLE_ LINKER_NAMESPACES | BOARD_VNDK_ VERSION | Wybrana konfiguracja | Wymóg VTS |
---|---|---|---|
true | current | VNDK | Obowiązkowe w przypadku urządzeń z systemem Android 9 lub nowszym |
Pusty | VNDK Lite | Obowiązkowe dla urządzeń z systemem Android 8.x | |
false | Pusty | Legacy | Dla urządzeń innych niż Treble |
Konfiguracja VNDK Lite izoluje współdzielone biblioteki SP-HAL i VNDK-SP. W systemie Android 8.0 musi to być plik konfiguracyjny dynamicznego linkera, jeśli PRODUCT_TREBLE_LINKER_NAMESPACES
ma true
.
Konfiguracja VNDK izoluje także biblioteki współdzielone SP-HAL i VNDK-SP. Dodatkowo ta konfiguracja zapewnia pełną dynamiczną izolację linkera. Zapewnia to, że moduły w partycji systemowej nie będą zależne od bibliotek współdzielonych w partycjach dostawcy i odwrotnie.
W systemie Android 8.1 lub nowszym konfiguracja VNDK jest konfiguracją domyślną i zdecydowanie zaleca się włączenie pełnej dynamicznej izolacji linkera poprzez ustawienie BOARD_VNDK_VERSION
na current
.
Konfiguracja VNDK
Konfiguracja VNDK izoluje zależności bibliotek współdzielonych pomiędzy partycją systemową a partycjami dostawcy. W porównaniu z konfiguracjami wspomnianymi w poprzednim podrozdziale różnice przedstawiono w następujący sposób:
Procesy ramowe
- tworzone są przestrzenie nazw
default
,vndk
,sphal
irs
. - Wszystkie przestrzenie nazw są izolowane.
- Systemowe biblioteki współdzielone są ładowane do
default
przestrzeni nazw. - SP-HAL są ładowane do przestrzeni nazw
sphal
. - Biblioteki współdzielone VNDK-SP załadowane do przestrzeni nazw
vndk
.
- tworzone są przestrzenie nazw
Procesy dostawców
- tworzone są
default
przestrzenie nazw,vndk
isystem
. -
default
przestrzeń nazw jest izolowana. - Biblioteki współdzielone dostawcy są ładowane do
default
przestrzeni nazw. - Biblioteki współdzielone VNDK i VNDK-SP są ładowane do przestrzeni nazw
vndk
. - LL-NDK i jego zależności są ładowane do
system
przestrzeni nazw.
- tworzone są
Poniżej zilustrowano relację pomiędzy przestrzeniami nazw linkera.

Na powyższym obrazku LL-NDK i VNDK-SP oznaczają następujące biblioteki współdzielone:
- LL-NDK
-
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
-
- VNDK-SP
-
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
-
Więcej szczegółów można znaleźć w /linkerconfig/ld.config.txt
z urządzenia.
Konfiguracja VNDK Lite
Począwszy od wersji Androida 8.0, dynamiczny linker jest skonfigurowany tak, aby izolować biblioteki współdzielone SP-HAL i VNDK-SP, tak aby ich symbole nie kolidowały z innymi bibliotekami współdzielonymi platformy. Poniżej pokazano relację pomiędzy przestrzeniami nazw linkera.

LL-NDK i VNDK-SP oznaczają następujące biblioteki współdzielone:
- LL-NDK
-
libEGL.so
-
libGLESv1_CM.so
-
libGLESv2.so
-
libc.so
-
libdl.so
-
liblog.so
-
libm.so
-
libnativewindow.so
-
libstdc++.so
(nie w konfiguracji) -
libsync.so
-
libvndksupport.so
-
libz.so
(przeniesiony do VNDK-SP w konfiguracji)
-
- VNDK-SP
-
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
-
Poniższa tabela zawiera konfigurację przestrzeni nazw dla procesów frameworkowych, która została zaczerpnięta z sekcji [system]
w konfiguracji VNDK Lite.
Przestrzeń nazw | Nieruchomość | Wartość |
---|---|---|
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 (dla 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 (dla 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 (dla skompilowanego jądra RS) | |
isolated | true | |
visible | true | |
links | default,vndk | |
link.default.shared_libs | LL-NDKlibmediandk.so libft2.so | |
link.vndk.shared_libs | VNDK-SP |
Poniższa tabela przedstawia konfigurację przestrzeni nazw dla procesów dostawców, która została zaczerpnięta z sekcji [vendor]
w konfiguracji VNDK Lite.
Przestrzeń nazw | Nieruchomość | Wartość |
---|---|---|
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} (przestarzałe)/product/${LIB} (przestarzałe) |
isolated | false |
Więcej szczegółów można znaleźć w /linkerconfig/ld.config.txt
z urządzenia.
Historia dokumentu
Zmiany w Androidzie 11
- W systemie Android 11 statyczne pliki
ld.config.*.txt
są usuwane z bazy kodu, a zamiast tego LinkerConfig generuje je w czasie wykonywania.
Zmiany w Androidzie 9
- W systemie Android 9 przestrzeń nazw konsolidatora
vndk
jest dodawana do procesów dostawcy, a biblioteki współdzielone VNDK są izolowane od domyślnej przestrzeni nazw konsolidatora. - Zastąp
PRODUCT_FULL_TREBLE
bardziej szczegółowymPRODUCT_TREBLE_LINKER_NAMESPACES
. - Android 9 zmienia nazwy następujących plików konfiguracyjnych dynamicznego linkera.
Android 8.x Androida 9 Opis ld.config.txt.in
ld.config.txt
Dla urządzeń z izolacją przestrzeni nazw konsolidatora środowiska wykonawczego ld.config.txt
ld.config.vndk_lite.txt
Dla urządzeń z izolacją przestrzeni nazw linkera VNDK-SP ld.config.legacy.txt
ld.config.legacy.txt
Dla starszych urządzeń z systemem Android 7.x lub starszym - Usuń
android.hardware.graphics.allocator@2.0.so
. - dodawane są partycje
product
iodm
.