Der dynamische Linker bewältigt zwei Herausforderungen beim Treble VNDK-Design:
- Gemeinsam genutzte SP-HAL-Bibliotheken und ihre Abhängigkeiten, einschließlich VNDK-SP-Bibliotheken, werden in Framework-Prozesse geladen. Es sollte einige Mechanismen geben, um Symbolkonflikte zu verhindern.
-
dlopen()
undandroid_dlopen_ext()
können einige Laufzeitabhängigkeiten einführen, die zur Build-Zeit nicht sichtbar sind und mit der statischen Analyse schwer zu erkennen sein können.
Diese beiden Herausforderungen können durch den Linker-Namespace- Mechanismus gelöst werden. Dieser Mechanismus wird vom dynamischen Linker bereitgestellt. Es kann die gemeinsam genutzten Bibliotheken in verschiedenen Linker-Namespaces isolieren, sodass Bibliotheken mit demselben Bibliotheksnamen, aber mit unterschiedlichen Symbolen nicht in Konflikt geraten.
Andererseits bietet der Linker-Namespace-Mechanismus die Flexibilität, dass einige gemeinsam genutzte Bibliotheken von einem Linker-Namespace exportiert und von einem anderen Linker-Namespace verwendet werden können. Diese exportierten gemeinsam genutzten Bibliotheken können zu Anwendungsprogrammierschnittstellen werden, die für andere Programme öffentlich sind, während ihre Implementierungsdetails in ihren Linker-Namespaces verborgen bleiben.
Beispielsweise sind /system/lib[64]/libcutils.so
und /system/lib[64]/vndk-sp-${VER}/libcutils.so
zwei gemeinsam genutzte Bibliotheken. Diese beiden Bibliotheken können unterschiedliche Symbole haben. Sie werden in verschiedene Linker-Namespaces geladen, sodass Framework-Module von /system/lib[64]/libcutils.so
und gemeinsam genutzte SP-HAL-Bibliotheken /system/lib[64]/vndk-sp-${VER}/libcutils.so
abhängen können /system/lib[64]/vndk-sp-${VER}/libcutils.so
.
Andererseits ist /system/lib[64]/libc.so
ein Beispiel für eine öffentliche Bibliothek, die von einem Linker-Namespace exportiert und in viele Linker-Namespaces importiert wird. Die Abhängigkeiten von /system/lib[64]/libc.so
, wie z. B. libnetd_client.so
, werden in den Namespace geladen, in dem sich /system/lib[64]/libc.so
befindet. Andere Namespaces haben keinen Zugriff auf diese Abhängigkeiten. Dieser Mechanismus kapselt die Implementierungsdetails und stellt gleichzeitig die öffentlichen Schnittstellen bereit.
Wie funktioniert es?
Der dynamische Linker ist für das Laden der in DT_NEEDED
Einträgen angegebenen gemeinsam genutzten Bibliotheken oder der durch das Argument dlopen()
oder android_dlopen_ext()
angegebenen gemeinsam genutzten Bibliotheken verantwortlich. In beiden Fällen findet der dynamische Linker den Linker-Namespace, in dem sich der Aufrufer befindet, und versucht, die Abhängigkeiten in denselben Linker-Namespace zu laden. Wenn der dynamische Linker die gemeinsam genutzte Bibliothek nicht in den angegebenen Linker-Namespace laden kann, fragt er den verknüpften Linker-Namespace nach exportierten gemeinsam genutzten Bibliotheken.
Konfigurationsdateiformat
Das Konfigurationsdateiformat basiert auf dem INI-Dateiformat. Eine typische Konfigurationsdatei sieht so aus:
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}
Die Konfigurationsdatei enthält:
- Mehrere Verzeichnisabschnittszuordnungseigenschaften am Anfang, damit der dynamische Linker den effektiven Abschnitt auswählen kann.
- Mehrere Konfigurationsabschnitte für Linker-Namespaces:
- Jeder Abschnitt enthält mehrere Namespaces (Graphscheitelpunkte) und mehrere Fallback-Links zwischen Namespaces (Graphbögen).
- Jeder Namespace verfügt über seine eigene Isolation, Suchpfade, zulässigen Pfade und Sichtbarkeitseinstellungen.
Die folgenden Tabellen beschreiben die Bedeutung der einzelnen Eigenschaften im Detail.
Eigenschaft für die Verzeichnisabschnittszuordnung
Eigentum | Beschreibung | Beispiel |
---|---|---|
| Ein Pfad zu einem Verzeichnis, für das der Abschnitt Jede Eigenschaft ordnet die ausführbaren Dateien im Verzeichnis einem Konfigurationsabschnitt für Linker-Namespaces zu. Möglicherweise gibt es zwei (oder mehr) Eigenschaften, die denselben | Dies zeigt an, dass die im Abschnitt Die im Abschnitt |
Beziehungseigenschaften
Eigentum | Beschreibung | Beispiel |
---|---|---|
additional. namespaces | Eine durch Kommas getrennte Liste zusätzlicher Namespaces (zusätzlich zum | Dies weist darauf hin, dass es in der |
namespace. name . links | Eine durch Kommas getrennte Liste von Fallback-Namespaces. Wenn eine gemeinsam genutzte Bibliothek im aktuellen Namespace nicht gefunden werden kann, versucht der dynamische Linker, die gemeinsam genutzte Bibliothek aus den Fallback-Namespaces zu laden. Der am Anfang der Liste angegebene Namespace hat eine höhere Priorität. | Wenn eine gemeinsam genutzte Bibliothek oder eine ausführbare Datei eine gemeinsam genutzte Bibliothek anfordert, die nicht in den Und wenn die gemeinsam genutzte Bibliothek dann auch nicht aus dem Wenn schließlich alle Versuche fehlschlagen, gibt der dynamische Linker einen Fehler zurück. |
namespace. name . link. other . shared_libs | Eine durch Doppelpunkte getrennte Liste gemeinsam genutzter Bibliotheken, die in den Diese Eigenschaft kann nicht mit | Dies weist darauf hin, dass der Fallback-Link nur |
namespace. name . link. other . allow_all_shared_libs | Ein boolescher Wert, der angibt, ob alle gemeinsam genutzten Bibliotheken im Diese Eigenschaft kann nicht mit | Dies zeigt an, dass alle Bibliotheksnamen über den Fallback-Link von |
Namespace-Eigenschaften
Eigentum | Beschreibung | Beispiel |
---|---|---|
namespace. name . isolated | Ein boolescher Wert, der angibt, ob der dynamische Linker prüfen soll, wo sich die gemeinsam genutzte Bibliothek befindet. Wenn Wenn | Dies weist darauf hin, dass nur die gemeinsam genutzten Bibliotheken in |
namespace. name . search.paths | Eine durch Doppelpunkte getrennte Liste von Verzeichnissen zur Suche nach gemeinsam genutzten Bibliotheken. Die in Wenn Wenn beispielsweise | Dies zeigt an, dass der dynamische Linker |
namespace. name . asan.search.paths | Eine durch Doppelpunkte getrennte Liste von Verzeichnissen zur Suche nach gemeinsam genutzten Bibliotheken, wenn AddressSanitizer (ASan) aktiviert ist. | Dies weist darauf hin, dass der dynamische Linker bei aktiviertem ASan zuerst |
namespace. name . permitted.paths | Eine durch Doppelpunkte getrennte Liste von Verzeichnissen (einschließlich Unterverzeichnissen), in die der dynamische Linker die gemeinsam genutzten Bibliotheken (zusätzlich zu Es können auch die gemeinsam genutzten Bibliotheken geladen werden, die sich in den Unterverzeichnissen von Wenn | Dies zeigt an, dass die gemeinsam genutzten Bibliotheken unter Ohne |
namespace. name . asan.permitted.paths | Eine durch Doppelpunkte getrennte Liste von Verzeichnissen, in die der dynamische Linker die gemeinsam genutzten Bibliotheken laden kann, wenn ASan aktiviert ist. | Dies zeigt an, dass bei aktiviertem ASan gemeinsam genutzte Bibliotheken unter |
namespace. name . visible | Ein boolescher Wert, der angibt, ob das Programm (außer Wenn Wenn | Dies zeigt an, dass |
Erstellung eines Linker-Namespace
In Android 11 wird die Linker-Konfiguration zur Laufzeit unter /linkerconfig
erstellt, anstatt reine Textdateien in ${android-src}/system/core/rootdir/etc
zu verwenden. Die Konfiguration wird beim Booten basierend auf der Laufzeitumgebung generiert, die folgende Elemente umfasst:
- Wenn das Gerät VNDK unterstützt
- Ziel-VNDK-Version der Herstellerpartition
- VNDK-Version der Produktpartition
- Installierte APEX-Module
Die Linker-Konfiguration wird durch das Auflösen von Abhängigkeiten zwischen Linker-Namespaces erstellt. Wenn es beispielsweise Aktualisierungen für die APEX-Module gibt, die Abhängigkeitsaktualisierungen umfassen, wird eine Linkerkonfiguration generiert, die diese Änderungen widerspiegelt. Weitere Details zum Erstellen der Linker-Konfiguration finden Sie in ${android-src}/system/linkerconfig
.
Isolierung des Linker-Namespace
Es gibt drei Konfigurationstypen. Abhängig vom Wert von PRODUCT_TREBLE_LINKER_NAMESPACES
und BOARD_VNDK_VERSION
in BoardConfig.mk
wird die entsprechende Konfiguration beim Booten generiert.
PRODUCT_TREBLE_ LINKER_NAMESPACES | BOARD_VNDK_ VERSION | Ausgewählte Konfiguration | VTS-Anforderung |
---|---|---|---|
true | current | VNDK | Obligatorisch für Geräte mit Android 9 oder höher |
Leer | VNDK Lite | Obligatorisch für Geräte mit Android 8.x | |
false | Leer | Legacy | Für Nicht-Treble-Geräte |
Die VNDK Lite-Konfiguration isoliert gemeinsam genutzte SP-HAL- und VNDK-SP-Bibliotheken. In Android 8.0 muss dies die Konfigurationsdatei für den dynamischen Linker sein, wenn PRODUCT_TREBLE_LINKER_NAMESPACES
true
ist.
Die VNDK-Konfiguration isoliert auch die gemeinsam genutzten SP-HAL- und VNDK-SP-Bibliotheken. Darüber hinaus bietet diese Konfiguration die vollständige dynamische Linker-Isolation. Dadurch wird sichergestellt, dass Module in der Systempartition nicht von den gemeinsam genutzten Bibliotheken in den Herstellerpartitionen abhängig sind und umgekehrt.
In Android 8.1 oder höher ist die VNDK-Konfiguration die Standardkonfiguration und es wird dringend empfohlen, die vollständige dynamische Linker-Isolation zu aktivieren, indem BOARD_VNDK_VERSION
auf current
gesetzt wird.
VNDK-Konfiguration
Die VNDK-Konfiguration isoliert die Abhängigkeiten der gemeinsam genutzten Bibliothek zwischen der Systempartition und den Herstellerpartitionen. Im Vergleich zu den im vorherigen Unterabschnitt erwähnten Konfigurationen werden die Unterschiede wie folgt beschrieben:
Rahmenprozesse
- Es werden die Namespaces
default
,vndk
,sphal
undrs
erstellt. - Alle Namespaces sind isoliert.
- Gemeinsam genutzte Systembibliotheken werden in den
default
Namespace geladen. - SP-HALs werden in den
sphal
Namespace geladen. - In den
vndk
Namespace geladene gemeinsam genutzte VNDK-SP-Bibliotheken.
- Es werden die Namespaces
Lieferantenprozesse
- Es werden die Namespaces
default
,vndk
undsystem
erstellt. - Der
default
Namespace ist isoliert. - Gemeinsam genutzte Bibliotheken des Anbieters werden in den
default
Namespace geladen. - Die gemeinsam genutzten Bibliotheken VNDK und VNDK-SP werden in den
vndk
Namespace geladen. - LL-NDK und seine Abhängigkeiten werden in den
system
Namespace geladen.
- Es werden die Namespaces
Die Beziehung zwischen den Linker-Namespaces wird unten dargestellt.
Im Bild oben stehen LL-NDK und VNDK-SP für die folgenden gemeinsam genutzten Bibliotheken:
- 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
-
Weitere Details finden Sie in /linkerconfig/ld.config.txt
auf dem Gerät.
VNDK Lite-Konfiguration
Ab Android 8.0 ist der dynamische Linker so konfiguriert, dass er die gemeinsam genutzten Bibliotheken SP-HAL und VNDK-SP isoliert, sodass ihre Symbole nicht mit anderen gemeinsam genutzten Framework-Bibliotheken in Konflikt geraten. Die Beziehung zwischen den Linker-Namespaces ist unten dargestellt.
LL-NDK und VNDK-SP stehen für folgende gemeinsam genutzte Bibliotheken:
- LL-NDK
-
libEGL.so
-
libGLESv1_CM.so
-
libGLESv2.so
-
libc.so
-
libdl.so
-
liblog.so
-
libm.so
-
libnativewindow.so
-
libstdc++.so
(nicht in der Konfiguration) -
libsync.so
-
libvndksupport.so
-
libz.so
(in der Konfiguration nach VNDK-SP verschoben)
-
- 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
-
Die folgende Tabelle listet die Namespace-Konfiguration für Framework-Prozesse auf, die aus dem Abschnitt [system]
in der VNDK Lite-Konfiguration entnommen ist.
Namensraum | Eigentum | Wert |
---|---|---|
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 (für 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 (für 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 (für kompilierten RS-Kernel) | |
isolated | true | |
visible | true | |
links | default,vndk | |
link.default.shared_libs | LL-NDKlibmediandk.so libft2.so | |
link.vndk.shared_libs | VNDK-SP |
Die folgende Tabelle zeigt die Namespace-Konfiguration für Anbieterprozesse, die aus dem Abschnitt [vendor]
in der VNDK Lite-Konfiguration entnommen ist.
Namensraum | Eigentum | Wert |
---|---|---|
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} (veraltet)/product/${LIB} (veraltet) |
isolated | false |
Weitere Details finden Sie in /linkerconfig/ld.config.txt
auf dem Gerät.
Dokumentenverlauf
Änderungen an Android 11
- In Android 11 werden die statischen
ld.config.*.txt
-Dateien aus der Codebasis entfernt und LinkerConfig generiert sie stattdessen zur Laufzeit.
Android 9 ändert sich
- In Android 9 wird der
vndk
Linker-Namespace zu Anbieterprozessen hinzugefügt und gemeinsam genutzte VNDK-Bibliotheken werden vom Standard-Linker-Namespace isoliert. - Ersetzen Sie
PRODUCT_FULL_TREBLE
durch spezifischerePRODUCT_TREBLE_LINKER_NAMESPACES
. - Android 9 ändert die Namen der folgenden dynamischen Linker-Konfigurationsdateien.
Android 8.x Android 9 Beschreibung ld.config.txt.in
ld.config.txt
Für Geräte mit Runtime-Linker-Namespace-Isolierung ld.config.txt
ld.config.vndk_lite.txt
Für Geräte mit VNDK-SP-Linker-Namespace-Isolierung ld.config.legacy.txt
ld.config.legacy.txt
Für ältere Geräte mit Android 7.x oder niedriger - Entfernen Sie
android.hardware.graphics.allocator@2.0.so
. -
product
undodm
Partitionen werden hinzugefügt.