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()i- android_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.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 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.so
- libGLESv1_CM.so
- libGLESv2.so
- libc.so
- libdl.so
- liblog.so
- libm.so
- libnativewindow.so
- libstdc++.so(nie ma w konfiguracji)
- libsync.so
- libvndksupport.so
- libz.so(przeniesiono 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
 
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-NDK libmediandk.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.
