Dynamiczny linker rozwiązuje 2 problemy w architekturze VNDK w Treble:
- Biblioteki współdzielone SP-HAL i ich zależności, w tym biblioteki VNDK-SP, są ładowane do procesów platformy. Powinny istnieć mechanizmy zapobiegające konfliktom symboli.
 dlopen()iandroid_dlopen_ext()mogą wprowadzać zależności w czasie działania, które nie są widoczne w czasie kompilacji i które trudno wykryć za pomocą analizy statycznej.
Te 2 problemy można rozwiązać za pomocą mechanizmu przestrzeni nazw linkera. Ten mechanizm jest udostępniany przez dynamiczny linker. Może on izolować biblioteki współdzielone w różnych przestrzeniach nazw linkera, dzięki czemu biblioteki o tej samej nazwie, ale z różnymi symbolami nie będą ze sobą kolidować.
Z drugiej strony mechanizm przestrzeni nazw linkera zapewnia elastyczność, dzięki czemu niektóre biblioteki współdzielone mogą być eksportowane przez przestrzeń nazw linkera i używane przez inną przestrzeń nazw linkera. Wyeksportowane biblioteki współdzielone mogą stać się interfejsami programowania aplikacji, które są publiczne dla innych programów, a jednocześnie ukrywają szczegóły implementacji w przestrzeniach nazw linkera.
Na przykład /system/lib[64]/libcutils.so i /system/lib[64]/vndk-sp-${VER}/libcutils.so to 2 biblioteki udostępnione. Te 2 biblioteki mogą mieć różne symbole. Są one wczytywane do różnych przestrzeni nazw linkera, dzięki czemu moduły platformy 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 kolei /system/lib[64]/libc.so to przykład biblioteki publicznej, która jest eksportowana przez przestrzeń nazw linkera i importowana do wielu przestrzeni nazw linkera. Zależności /system/lib[64]/libc.so, takie jak libnetd_client.so, są wczytywane 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. Ten mechanizm zawiera szczegóły implementacji, a jednocześnie udostępnia interfejsy publiczne.
Jak to działa
Dynamiczny linker odpowiada za wczytywanie 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ę wywołujący, i próbuje załadować zależności do tej samej przestrzeni nazw linkera. Jeśli dynamiczny linker nie może wczytać biblioteki współdzielonej do określonej przestrzeni nazw linkera, prosi połączoną przestrzeń nazw linkera o wyeksportowane biblioteki współdzielone.
Format pliku konfiguracji
Format pliku konfiguracyjnego jest oparty na formacie pliku INI. Typowy plik konfiguracji wygląda tak:
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 konfiguracji zawiera:
- Na początku kilka właściwości mapowania sekcji katalogu, aby dynamiczny linker mógł wybrać odpowiednią sekcję.
 - 
  Kilka sekcji konfiguracji przestrzeni nazw linkera:
- Każda sekcja zawiera kilka przestrzeni nazw (wierzchołków wykresu) i kilka linków rezerwowych między przestrzeniami nazw (łuków wykresu).
 - Każda przestrzeń nazw ma własne ustawienia izolacji, ścieżek wyszukiwania, dozwolonych ścieżek i widoczności.
 
 
Tabele poniżej zawierają szczegółowe opisy poszczególnych właściwości.
Właściwość mapowania sekcji katalogu
| Właściwość | Opis | Przykład | 
|---|---|---|
  | 
  
    Ścieżka do katalogu, do którego odnosi się sekcja  Każda właściwość mapuje pliki wykonywalne w katalogu na sekcję konfiguracji przestrzeni nazw linkera. Mogą istnieć 2 (lub więcej) usług, które mają ten sam atrybut   | 
  
    
     Oznacza to, że konfiguracja określona w sekcji  Konfiguracja określona w sekcji   | 
 
Właściwości relacji
| Właściwość | Opis | Przykład | 
|---|---|---|
additional. | 
  
    Lista dodatkowych przestrzeni nazw (oprócz przestrzeni nazw   | 
  
    
 Oznacza to, że w konfiguracji   | 
 
namespace. | 
  
    Lista przestrzeni nazw rezerwowych rozdzielona przecinkami. Jeśli biblioteki udostępnionej nie można znaleźć w bieżącej przestrzeni nazw, dynamiczny linker próbuje wczytać ją z przestrzeni nazw rezerwowych. Przestrzeń nazw podana na początku listy ma wyższy priorytet.  | 
  
    
 Jeśli biblioteka współużytkowana lub plik wykonywalny zażąda biblioteki współużytkowanej, której nie można załadować do przestrzeni nazw  Jeśli nie można załadować biblioteki udostępnionej z przestrzeni nazw  Jeśli wszystkie próby zawiodą, dynamiczny linker zwróci błąd.  | 
 
namespace. | 
  
    Lista zasobów wspólnych rozdzielonych dwukropkiem, które można przeszukiwać w przestrzeniach nazw  Tej właściwości nie można używać z wartością   | 
  
    
 Oznacza to, że link rezerwowy akceptuje tylko   | 
 
namespace. | 
  
    Wartość logiczna wskazująca, czy można przeszukiwać wszystkie zasoby wspólne w przestrzeni nazw  Tej właściwości nie można używać z wartością   | 
  
    
 Oznacza to, że wszystkie nazwy bibliotek mogą przechodzić przez link rezerwowy z przestrzeni nazw   | 
 
Właściwości przestrzeni nazw
| Właściwość | Opis | Przykład | 
|---|---|---|
namespace. | 
  
    Wartość logiczna wskazująca, czy dynamiczny linker powinien sprawdzać, gdzie znajduje się biblioteka współdzielona. Jeśli  Jeśli   | 
  
    
 Oznacza to, że do przestrzeni nazw   | 
 
namespace. | 
  
    Lista katalogów rozdzielonych dwukropkiem, w których mają być wyszukiwane biblioteki udostępnione. Katalogi określone w  Gdy wartość  Jeśli na przykład wartość   | 
  
    
 Oznacza to, że dynamiczny linker wyszukuje biblioteki współdzielone w   | 
 
namespace. | 
  
    Lista katalogów oddzielonych dwukropkiem, w których należy szukać bibliotek współdzielonych, gdy włączona jest funkcja AddressSanitizer (ASan). Gdy włączona jest funkcja ASan, zasada   | 
  
    
 Oznacza to, że gdy ASan jest włączony, dynamiczny linker najpierw wyszukuje   | 
 
namespace. | 
  
    Lista katalogów (wraz z podkatalogami) oddzielonych dwukropkiem, z których dynamiczny linker może wczytywać biblioteki współdzielone (oprócz  Można też załadować biblioteki udostępnione znajdujące się w podkatalogach  Jeśli   | 
  
    
 Oznacza to, że biblioteki udostępnione w obszarze  Na przykład bez   | 
 
namespace. | 
  
    Lista katalogów oddzielonych dwukropkiem, z których dynamiczny linker może ładować biblioteki współdzielone, gdy włączona jest funkcja ASan. Gdy włączona jest funkcja ASan, zasada   | 
  
    
 Oznacza to, że gdy ASan jest włączony, biblioteki współdzielone w   | 
 
namespace. | 
  
    Wartość logiczna wskazująca, czy program (inny niż  Jeśli  Jeśli   | 
  
    
 Oznacza to, że funkcja   | 
 
Tworzenie przestrzeni nazw linkera
W Androidzie 11 konfiguracja linkera jest tworzona w czasie działania w katalogu /linkerconfig zamiast przy użyciu zwykłych plików tekstowych w katalogu ${android-src}/system/core/rootdir/etc. Konfiguracja jest generowana podczas uruchamiania na podstawie środowiska wykonawczego, które obejmuje te elementy:
- Jeśli urządzenie obsługuje VNDK
 - Docelowa wersja VNDK partycji dostawcy
 - Wersja VNDK podziału produktu
 - Zainstalowane moduły APEX
 
Konfiguracja linkera jest tworzona przez rozwiązywanie zależności między przestrzeniami nazw linkera. Jeśli na przykład w modułach APEX są dostępne aktualizacje, które obejmują aktualizacje zależności, generowana jest konfiguracja linkera odzwierciedlająca te zmiany. Więcej informacji o tworzeniu konfiguracji linkera znajdziesz w ${android-src}/system/linkerconfig.
Izolacja przestrzeni nazw linkera
Dostępne są 3 typy konfiguracji. W zależności od wartości PRODUCT_TREBLE_LINKER_NAMESPACES i BOARD_VNDK_VERSION w BoardConfig.mk odpowiednia konfiguracja jest generowana podczas uruchamiania.
PRODUCT_TREBLE_LINKER_NAMESPACES | 
  BOARD_VNDK_VERSION | 
  Wybrana konfiguracja | Wymagania dotyczące VTS | 
|---|---|---|---|
true | 
  current | 
  VNDK | 
  Obowiązkowe w przypadku urządzeń wprowadzonych na rynek z Androidem 9 lub nowszym | 
| Puste | VNDK Lite | 
  Obowiązkowe w przypadku urządzeń wprowadzonych na rynek z Androidem 8.x | |
false | 
  Puste | Legacy | 
  W przypadku urządzeń innych niż Treble | 
Konfiguracja VNDK Lite izoluje biblioteki współdzielone SP-HAL i VNDK-SP. W Androidzie 8.0 musi to być plik konfiguracji dynamicznego linkera, gdy PRODUCT_TREBLE_LINKER_NAMESPACES ma wartość true.
Konfiguracja VNDK izoluje też biblioteki współdzielone SP-HAL i VNDK-SP. Dodatkowo ta konfiguracja zapewnia pełną izolację dynamicznego linkera. Dzięki temu moduły w partycji systemowej nie będą zależeć od bibliotek współdzielonych w partycjach dostawcy i na odwrót.
W Androidzie 8.1 lub nowszym konfiguracja VNDK jest domyślna. Zdecydowanie zalecamy włączenie pełnej izolacji dynamicznego linkera przez ustawienie BOARD_VNDK_VERSION na current.
Konfiguracja VNDK
Konfiguracja VNDK izoluje zależności biblioteki udostępnionej między partycją systemową a partycjami dostawcy. W porównaniu z konfiguracjami wymienionymi w poprzedniej sekcji różnice są następujące:
- 
  
Procesy platformy
- Zostaną utworzone przestrzenie nazw 
default,vndk,sphalirs. - Wszystkie przestrzenie nazw są odizolowane.
 - Systemowe biblioteki udostępnione są wczytywane do przestrzeni nazw 
default. - SP-HAL są wczytywane do przestrzeni nazw 
sphal. - Biblioteki współdzielone VNDK-SP załadowane do przestrzeni nazw 
vndk. 
 - Zostaną utworzone przestrzenie nazw 
 - 
Procesy dostawcy
- Tworzone są przestrzenie nazw 
default,vndkisystem. - Przestrzeń nazw 
defaultjest odizolowana. - Biblioteki udostępnione dostawcy są wczytywane do przestrzeni nazw 
default. - Biblioteki współdzielone VNDK i VNDK-SP są wczytywane do przestrzeni nazw 
vndk. - LL-NDK i jego zależności są ładowane do przestrzeni nazw 
system. 
 - Tworzone są przestrzenie nazw 
 
Zależności między przestrzeniami nazw linkera zostały zilustrowane poniżej.
Rysunek 1. Izolacja przestrzeni nazw linkera (konfiguracja VNDK).
Na powyższym obrazie LL-NDK i VNDK-SP oznaczają te biblioteki współdzielone:
- 
  LL-NDK
  
libEGL.solibGLESv1_CM.solibGLESv2.solibGLESv3.solibandroid_net.solibc.solibdl.soliblog.solibm.solibnativewindow.solibneuralnetworks.solibsync.solibvndksupport.solibvulkan.so
 - 
  VNDK-SP
  
android.hardware.graphics.common@1.0.soandroid.hardware.graphics.mapper@2.0.soandroid.hardware.renderscript@1.0.soandroid.hidl.memory@1.0.solibRSCpuRef.solibRSDriver.solibRS_internal.solibbase.solibbcinfo.solibc++.solibcutils.solibhardware.solibhidlbase.solibhidlmemory.solibhidltransport.solibhwbinder.solibion.solibutils.solibz.so
 
Więcej informacji znajdziesz w /linkerconfig/ld.config.txt na urządzeniu.
Konfiguracja VNDK Lite
Od Androida 8.0 dynamiczny linker jest skonfigurowany tak, aby izolować biblioteki współdzielone SP-HAL i VNDK-SP, dzięki czemu ich symbole nie powodują konfliktów z innymi bibliotekami współdzielonymi platformy. Relacja między przestrzeniami nazw linkera jest pokazana poniżej.
LL-NDK i VNDK-SP to nazwy tych bibliotek udostępnionych:
- 
  LL-NDK
  
libEGL.solibGLESv1_CM.solibGLESv2.solibc.solibdl.soliblog.solibm.solibnativewindow.solibstdc++.so(nie ma w konfiguracji)libsync.solibvndksupport.solibz.so(przeniesiono do VNDK-SP w konfiguracji)
 - 
  VNDK-SP
  
android.hardware.graphics.common@1.0.soandroid.hardware.graphics.mapper@2.0.soandroid.hardware.renderscript@1.0.soandroid.hidl.memory@1.0.solibbase.solibc++.solibcutils.solibhardware.solibhidlbase.solibhidlmemory.solibhidltransport.solibhwbinder.solibion.solibutils.so
 
Tabela poniżej zawiera konfigurację przestrzeni nazw dla procesów frameworka, która jest wyciągiem z sekcji [system] w konfiguracji VNDK Lite.
| Przestrzeń nazw | Właściwość | 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 (w przypadku 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 (w przypadku 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 (w przypadku skompilowanego jądra RS)
   | 
 |
isolated | 
  true | 
 |
visible | 
  true | 
 |
links | 
  default,vndk | 
 |
link.default.shared_libs | 
  
   LL-NDKlibmediandk.solibft2.so
   | 
 |
link.vndk.shared_libs | 
  VNDK-SP | 
Tabela poniżej przedstawia konfigurację przestrzeni nazw dla procesów dostawcy, która została wyodrębniona z sekcji [vendor] w konfiguracji VNDK Lite.
| Przestrzeń nazw | Właściwość | 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} (wycofano)/product/${LIB} (wycofano)
   | 
 
isolated | 
  false | 
 
Więcej informacji znajdziesz w /linkerconfig/ld.config.txt na urządzeniu.
Historia dokumentu
Zmiany w Androidzie 11
- W Androidzie 11 statyczne pliki 
ld.config.*.txtzostały usunięte z bazy kodu, a zamiast nich LinkerConfig generuje je w czasie działania. 
Zmiany w Androidzie 9
- W Androidzie 9 do procesów dostawcy dodano przestrzeń nazw linkera 
vndk, a biblioteki współdzielone VNDK są odizolowane od domyślnej przestrzeni nazw linkera. - Zastąp 
PRODUCT_FULL_TREBLEbardziej szczegółowym tekstemPRODUCT_TREBLE_LINKER_NAMESPACES. - Android 9 zmienia nazwy tych plików konfiguracyjnych dynamicznego linkera:
Android 8.x Android 9 Opis ld.config.txt.inld.config.txtW przypadku urządzeń z izolacją przestrzeni nazw linkera w czasie działania ld.config.txtld.config.vndk_lite.txtW przypadku urządzeń z izolacją przestrzeni nazw linkera VNDK-SP ld.config.legacy.txtld.config.legacy.txtStarsze urządzenia z Androidem 7.x lub starszym  - Usuń 
android.hardware.graphics.allocator@2.0.so. - Dodano partycje 
productiodm.