Linker-Namespace

Der dynamische Linker bewältigt zwei Herausforderungen im 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() und android_dlopen_ext() kann einige Laufzeitabhängigkeiten einführen , die nicht sichtbar bei der Erstellung und kann schwierig sein , statische Analyse zu erfassen , verwenden.

Diese beiden Herausforderungen können durch den Linker - Namespace - Mechanismus gelöst werden. Dieser Mechanismus wird durch den 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, so 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 sie ihre Implementierungsdetails in ihren Linker-Namespaces verbergen.

Zum Beispiel /system/lib[64]/libcutils.so und /system/lib[64]/vndk-sp-${VER}/libcutils.so sind zwei gemeinsam genutzte Bibliotheken. Diese beiden Bibliotheken können unterschiedliche Symbole haben. Sie sind in verschiedenen Linker Namensraum geladen , so dass Rahmenmodule verlassen kann auf /system/lib[64]/libcutils.so und SP-HAL gemeinsam genutzte Bibliotheken können auf abhängen /system/lib[64]/vndk-sp-${VER}/libcutils.so .

Auf der anderen Seite, /system/lib[64]/libc.so ist ein Beispiel für eine öffentliche Bibliothek , die durch einen Linker Namensraum exportiert wird und importiert in vielen Linker - Namensraum. Die Abhängigkeiten von /system/lib[64]/libc.so wie libnetd_client.so , werden in den Namensraum geladen , in dem /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 verantwortlich für die gemeinsam benutzten Bibliotheken in spezifizierten Laden DT_NEEDED Einträge oder der gemeinsam benutzten Bibliotheken durch das Argument spezifizierten dlopen() oder android_dlopen_ext() . 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 nicht die gemeinsam genutzte Bibliothek in den angegebenen Linker Namensraum laden kann, fragt es die verknüpften Linker - Namespace für exportierten gemeinsam genutzte 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 Eigenschaften für die Verzeichnisabschnittszuordnung am Anfang, damit der dynamische Linker den effektiven Abschnitt auswählen kann.
  • Mehrere Konfigurationsabschnitte für Linker-Namespaces:
    • Jeder Abschnitt enthält mehrere Namespaces (Graph-Scheitelpunkte) und mehrere Fallback-Links zwischen Namespaces (Graph Arcs).
    • Jeder Namespace hat seine eigene Isolation, Suchpfade, zulässige Pfade und Sichtbarkeitseinstellungen.

Die folgenden Tabellen beschreiben die Bedeutung der einzelnen Eigenschaften im Detail.

Zuordnungseigenschaft für Verzeichnisabschnitte

Eigentum Beschreibung Beispiel

dir. name

Ein Pfad zu einem Verzeichnis , dass die [ name ] Abschnitt bezieht sich auf.

Jede Eigenschaft ordnet die ausführbaren Dateien unter dem Verzeichnis einem Konfigurationsabschnitt für Linker-Namespaces zu. Es könnten zwei (oder mehr) Eigenschaften sein, die denselben haben name , aber Punkt auf verschiedene Verzeichnisse.

dir.system = /system/bin
dir.system = /system/xbin
dir.vendor = /vendor/bin

Dies zeigt an, dass die Konfiguration in der angegebenen [system] Abschnitt bezieht sich auf die ausführbaren Dateien , die von entweder geladen /system/bin oder /system/xbin .

Die Konfiguration spezifiziert in dem [vendor] Abschnitt bezieht sich auf die ausführbaren Dateien , die von geladenen /vendor/bin .

Beziehungseigenschaften

Eigentum Beschreibung Beispiel
additional. namespaces

Eine durch Kommata getrennte Liste von zusätzlichen Namensräumen (zusätzlich zu dem default - Namensraum) für den Abschnitt.

additional. namespaces = sphal, vndk

Dies zeigt an, dass es drei Namensräume ( default , sphal und vndk ) in der [system] Konfiguration.

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 Namensraum hat eine höhere Priorität.

namespace. sphal. links = default, vndk

Wenn eine gemeinsam genutzte Bibliothek oder eine ausführbare Anfragen eine gemeinsam genutzte Bibliothek , die nicht in die geladen werden können sphal Namespace, die dynamischen Linker versucht , die gemeinsam genutzte Bibliothek aus dem laden default - Namespace.

Und dann, wenn die gemeinsam genutzte Bibliothek kann nicht aus den geladen werden default entweder die dynamischen Linker versucht , die gemeinsam genutzte Bibliothek aus dem laden vndk Namespace.

Wenn alle Versuche fehlschlagen, gibt der dynamische Linker schließlich einen Fehler zurück.

namespace. name . link. other . shared_libs

Ein Doppelpunkt getrennte Liste von gemeinsam genutzten Bibliotheken , die in den durchsucht werden können other Namespaces , wenn diese Bibliotheken nicht in der gefunden werden name Namespace.

Diese Eigenschaft kann nicht verwendet werden mit namespace. name . link. other . allow_all_shared_libs .

namespace. sphal. link. default. shared_libs = libc.so: libm.so

Dies zeigt an, dass der Ausweich Link nur akzeptiert libc.so oder libm.so als die gewünschten Bibliotheksnamen. Der dynamische Linker ignoriert die Ausweichverbindung von sphal auf default - Namespace , wenn der angeforderte Bibliotheksname nicht ist libc.so oder libm.so .

namespace. name . link. other . allow_all_shared_libs

Ein boolescher Wert, der angibt , ob alle gemeinsam genutzten Bibliotheken in der gesucht werden other Namespace , wenn diese Bibliotheken nicht in dem gefunden werden kann name Namespace.

Diese Eigenschaft kann nicht verwendet werden mit namespace. name . link. other . shared_libs .

namespace. vndk. link. sphal. allow_all_shared_libs = true

Dies weist darauf hin , dass alle Bibliotheksnamen durch die Ausweichverbindung von zu Fuß vndk zu sphal Namespace.

Namespace-Eigenschaften

Eigentum Beschreibung Beispiel
namespace. name . isolated

Ein boolescher Wert, der angibt, ob der dynamische Linker überprüfen soll, wo sich die gemeinsam genutzte Bibliothek befindet.

Wenn isolated ist true , nur die gemeinsam genutzten Bibliotheken , die in einer der sind search.paths Verzeichnisse (ohne Unterverzeichnisse) oder unter einer der permitted.paths Verzeichnisse (inklusive Unterverzeichnisse) können geladen werden.

Wenn isolated ist false (Standard), wird der dynamische Linker nicht den Pfad der gemeinsam genutzten Bibliotheken überprüfen.

namespace. sphal. isolated = true

Dies zeigt , dass nur die gemeinsam genutzten Bibliotheken in search.paths oder unter permitted.paths in die geladen werden sphal Namespace.

namespace. name . search.paths

Eine durch Doppelpunkte getrennte Liste von Verzeichnissen, um nach gemeinsam genutzten Bibliotheken zu suchen.

Die Verzeichnisse in bestimmten search.paths werden auf die gewünschten Bibliotheksnamen vorangestellt , wenn Funktionsaufrufe dlopen() oder DT_NEEDED Einträge nicht den vollständigen Pfad angeben. Das am Anfang der Liste angegebene Verzeichnis hat höhere Priorität.

Wenn isolated ist true , gemeinsam genutzte Bibliotheken , die in einer der sind search.paths Verzeichnisse (ohne Unterverzeichnisse) können unabhängig von der geladen werden permitted.paths Eigenschaft.

Wenn zum Beispiel search.paths ist /system/${LIB} und permitted.paths leer ist, /system/${LIB}/libc.so geladen werden aber /system/${LIB}/vndk/libutils.so kann nicht geladen werden.

namespace. default. search.paths = /system/${LIB}

Dies zeigt an, dass die dynamischen Linker sucht /system/${LIB} für gemeinsam genutzte Bibliotheken.

namespace. name . asan.search.paths

Ein Doppelpunkt getrennte Liste von Verzeichnissen für gemeinsam genutzte Bibliotheken zu suchen , wenn AddressSanitizer (Asan) aktiviert ist.

namespace. name . search.paths wird ignoriert , wenn Asan aktiviert ist.

namespace. default. asan.search.paths = /data/asan/system/${LIB}: /system/${LIB}

Dies zeigt , dass , wenn Asan ist der dynamische Linker sucht aktiviert /data/asan/system/${LIB} und dann sucht /system/${LIB} .

namespace. name . permitted.paths

Ein Doppelpunkt getrennte Liste von Verzeichnissen (einschließlich Unterverzeichnisse) , wo der dynamische Linker der gemeinsamen Bibliotheken (zusätzlich laden search.paths ) , wenn isolated ist true .

Die gemeinsam genutzten Bibliotheken , die unter den Unterverzeichnissen sind permitted.paths können auch geladen werden. Wenn zum Beispiel permitted.paths ist /system/${LIB} , beide /system/${LIB}/libc.so und /system/${LIB}/vndk/libutils.so geladen werden.

Wenn isolated ist false , permitted.paths werden ignoriert und eine Warnung ausgegeben wird.

namespace. default. permitted.paths = /system/${LIB}/hw

Dies zeigt , dass die gemeinsam genutzten Bibliotheken unter /system/${LIB}/hw kann in das isolierte geladen werden default

Zum Beispiel, ohne permitted.paths , libaudiohal.so kann nicht geladen werden /system/${LIB}/hw/audio.a2dp.default.so in den default - Namespace.

namespace. name . asan.permitted.paths

Ein Doppelpunkt getrennte Liste von Verzeichnissen , in denen der dynamischen Linker die gemeinsam genutzten Bibliotheken laden kann , wenn Asan aktiviert ist.

namespace. name . permitted.paths wird ignoriert , wenn Asan aktiviert ist.

namespace. default. asan.permitted.paths = /data/asan/system/${LIB}/hw: /system/${LIB}/hw

Dies zeigt , dass , wenn Asan gemeinsam genutzte Bibliotheken unter aktiviert ist /data/asan/system/${LIB}/hw oder /system/${LIB}/hw den isolierten geladen werden kann default - Namespace.

namespace. name . visible

Ein Boolescher Wert, der das Programm (außer der angibt , ob libc mit einem Linker - Namensraum Griff bekommen kann) android_get_exported_namespace() und Öffnen eine gemeinsam benutzte Bibliothek in dem Linker - Namensraum , indem den Griff zu android_dlopen_ext() .

Wenn visible ist true , android_get_exported_namespace() liefert immer den Griff , wenn der Namensraum vorhanden ist .

Wenn visible ist false (Standard), android_get_exported_namespace() gibt immer NULL , unabhängig von der Anwesenheit des Namespace. Freigegebene Bibliotheken können nur in diesen Namespace geladen werden, wenn (1) sie von einem anderen Linker-Namespace angefordert werden, der einen Fallback-Link zu diesem Namespace hat, oder (2) sie von anderen freigegebenen Bibliotheken oder ausführbaren Dateien in diesem Namespace angefordert werden.

namespace. sphal. visible = true

Dies zeigt , dass android_get_exported_namespace("sphal") kann einen gültigen Linker Namespace Handle zurück.

Linker-Namespace-Erstellung

In Android 11 wird Linker Konfiguration zur Laufzeit erstellt unter /linkerconfig anstelle der Verwendung von Textdateien in ${android-src}/system/core/rootdir/etc . 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 erstellt, indem Abhängigkeiten zwischen Linker-Namespaces aufgelöst werden. Wenn es beispielsweise Updates für die APEX-Module gibt, die Abhängigkeitsupdates enthalten, wird eine Linkerkonfiguration generiert, die diese Änderungen widerspiegelt. Weitere Details Linker - Konfiguration erstellen finden Sie in ${android-src}/system/linkerconfig .

Isolation des Linker-Namespace

Es gibt drei Konfigurationstypen. Je nach dem Wert von PRODUCT_TREBLE_LINKER_NAMESPACES und BOARD_VNDK_VERSION in BoardConfig.mk , wird die entsprechende Konfiguration beim Booten erzeugt.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Ausgewählte Konfiguration VTS-Anforderung
true current VNDK Obligatorisch für Geräte, die mit Android 9 oder höher gestartet wurden
Leer VNDK Lite Obligatorisch für Geräte, die mit Android 8.x gestartet wurden
false Leer Legacy Für Nicht-Treble-Geräte

Die VNDK Lite-Konfiguration isoliert die gemeinsam genutzten SP-HAL- und VNDK-SP-Bibliotheken. In Android 8.0, dies muss die Konfigurationsdatei für dynamische Linker sein , wenn PRODUCT_TREBLE_LINKER_NAMESPACES ist true .

Die VNDK-Konfiguration isoliert auch gemeinsam genutzte SP-HAL- und VNDK-SP-Bibliotheken. Darüber hinaus bietet diese Konfiguration die vollständige dynamische Linker-Isolation. Es stellt sicher, dass Module in der Systempartition nicht von den gemeinsam genutzten Bibliotheken in den Herstellerpartitionen abhängen und umgekehrt.

In Android 8.1 oder höher, ist VNDK Konfiguration der Standardkonfiguration und es ist sehr voll dynamischen Linker Isolation zu ermöglichen , indem empfohlen, BOARD_VNDK_VERSION zu current .

VNDK-Konfiguration

Die VNDK-Konfiguration isoliert die Abhängigkeiten von gemeinsam genutzten Bibliotheken zwischen der Systempartition und den Herstellerpartitionen. Im Vergleich zu den im vorherigen Unterabschnitt erwähnten Konfigurationen werden die Unterschiede wie folgt skizziert:

  • Rahmenprozesse

    • default , vndk , sphal und rs Namensräume geschaffen werden .
    • Alle Namensräume sind isoliert.
    • System gemeinsam genutzte Bibliotheken werden in den geladenen default - Namespace.
    • SP-HALs in die geladen sphal Namespace.
    • VNDK-SP - Bibliotheken geteilt in die geladen vndk Namespace.
  • Lieferantenprozesse

    • default , vndk und system - Namensräume geschaffen werden .
    • Das default - Namespace isoliert.
    • Der Anbieter gemeinsam genutzte Bibliotheken werden in den geladenen default - Namespace.
    • VNDK und VNDK-SP gemeinsam genutzte Bibliotheken in die geladen werden vndk Namespace.
    • LL-NDK und ihre Abhängigkeiten werden in den geladenen system - Namensraum.

Die Beziehung zwischen den Linker-Namespaces wird unten veranschaulicht.

Linker-Namespace-Diagramm in VNDK-Konfiguration beschrieben
Abbildung 1. Linker Namensraum Isolation (VNDK Konfiguration)

Im Bild oben, LL-NDK und VNDK-SP steht für gemeinsam genutzte Bibliotheken folgenden:

  • 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

Sie können weitere Informationen in finden /linkerconfig/ld.config.txt aus dem Gerät.

VNDK Lite-Konfiguration

Ab Android 8.0 ist der dynamische Linker so konfiguriert, dass die gemeinsam genutzten Bibliotheken SP-HAL und VNDK-SP so isoliert werden, dass ihre Symbole nicht mit anderen gemeinsam genutzten Framework-Bibliotheken in Konflikt geraten. Die Beziehung zwischen den Linker-Namespaces wird unten gezeigt.

Linker-Namespace-Diagramm in VNDK Lite-Konfiguration beschrieben
Abbildung 2. Linker Namespace Isolation (VNDK Lite - Konfiguration)

LL-NDK und VNDK-SP stehen für gemeinsam genutzte Bibliotheken folgenden:

  • LL-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (in der Konfiguration)
    • libsync.so
    • libvndksupport.so
    • libz.so (bewegt VNDK-SP in der Konfiguration)
  • 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 Namespaces - Konfiguration für Rahmen Prozesse, die von der exzerpiert wird [system] Abschnitt in der VNDK Lite - Konfiguration.

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 render) 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 kompilierte Kernel RS)
isolated true
visible true
links default,vndk
link.default.shared_libs LL-NDK
libmediandk.so
libft2.so
link.vndk.shared_libs VNDK-SP

Die folgende Tabelle zeigt die Namespaces - Konfiguration für Verkäufer Prozesse, die von der exzerpiert wird [vendor] Abschnitt in der VNDK Lite - Konfiguration.

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 sich in /linkerconfig/ld.config.txt aus dem Gerät.

Dokumentenverlauf

Android 11-Änderungen

  • In Android 11, die statischen ld.config.*.txt - Dateien werden von der Code - Basis entfernt und LinkerConfig erzeugt sich im laufenden Betrieb statt.

Android 9-Änderungen

  • In Android 9, die vndk wird Linker - Namespace - Anbieter Prozesse hinzugefügt und VNDK gemeinsam genutzte Bibliotheken aus dem Standard - Linker - Namensraum isoliert sind.
  • Ersetzen PRODUCT_FULL_TREBLE mit präziser PRODUCT_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 Laufzeit-Linker-Namespace-Isolation
    ld.config.txt ld.config.vndk_lite.txt Für Geräte mit VNDK-SP-Linker-Namespace-Isolation
    ld.config.legacy.txt ld.config.legacy.txt Für ältere Geräte mit Android 7.x oder niedriger
  • Entfernen android.hardware.graphics.allocator@2.0.so .
  • product und odm - Partitionen hinzugefügt werden .