Spazio dei nomi linker

Il linker dinamico affronta due sfide nella progettazione di Treble VNDK:

  • Librerie condivise SP-HAL e rispettive dipendenze, tra cui VNDK-SP vengono caricate nei processi framework. Dovrebbero esserci alcuni per evitare conflitti tra simboli.
  • dlopen() e android_dlopen_ext() possono presentare alcune dipendenze di runtime che non sono visibili al momento della build difficili da rilevare con l'analisi statica.

Queste due sfide possono essere risolte dallo spazio dei nomi linker meccanismo di attenzione. Questo meccanismo è fornito dal linker dinamico. it può isolare le librerie condivise in diversi spazi dei nomi del linker in modo che librerie con lo stesso nome di libreria ma con simboli diversi non saranno in conflitto.

D'altra parte, il meccanismo dello spazio dei nomi del linker offre la flessibilità in modo che alcune librerie condivise possano essere esportate da uno spazio dei nomi linker e utilizzate con un altro spazio dei nomi linker. Le librerie condivise esportate possono diventare interfacce di programmazione delle applicazioni pubbliche per altri programmi nascondendo i dettagli di implementazione negli spazi dei nomi dei linker.

Ad esempio, /system/lib[64]/libcutils.so e /system/lib[64]/vndk-sp-${VER}/libcutils.so sono due condivisi librerie. Queste due librerie possono avere simboli diversi. Sono stati caricati in diversi spazi dei nomi del linker, in modo che i moduli del framework possano dipendere Le librerie condivise di /system/lib[64]/libcutils.so e SP-HAL possono dipendono da /system/lib[64]/vndk-sp-${VER}/libcutils.so.

D'altra parte, /system/lib[64]/libc.so è un esempio una libreria pubblica esportata da uno spazio dei nomi linker e importata in molti spazi dei nomi dei linker. Le dipendenze /system/lib[64]/libc.so, ad esempio libnetd_client.so, vengono caricati nello spazio dei nomi in cui /system/lib[64]/libc.so risiedono. Gli altri spazi dei nomi non avranno accesso a queste dipendenze. Questo di incapsulamento dei dettagli dell'implementazione, fornendo al contempo al pubblico interfacce.

Come funziona

Il linker dinamico è responsabile del caricamento delle librerie condivise specificate nelle voci DT_NEEDED o nelle librerie condivise specificate dal di dlopen() o android_dlopen_ext(). In entrambi i formati, casi, il linker dinamico trova lo spazio dei nomi del linker in cui il chiamante risiede e tenta di caricare le dipendenze nello stesso spazio dei nomi del linker. Se il linker dinamico non riesce a caricare la libreria condivisa nel linker specificato Richiede lo spazio dei nomi del linker collegato per i file condivisi librerie.

Formato file di configurazione

Il formato del file di configurazione si basa sul formato file INI. Un tipico di configurazione del deployment ha questo aspetto:

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}

Il file di configurazione include:

  • Diverse proprietà di mappatura delle sezioni di directory all'inizio per linker dinamico per selezionare la sezione effettiva.
  • Diverse sezioni di configurazione degli spazi dei nomi dei linker:
    • Ogni sezione contiene diversi spazi dei nomi (vertici dei grafici) e link di fallback tra spazi dei nomi (archi di grafici).
    • Ogni spazio dei nomi ha il proprio isolamento, percorsi di ricerca, percorsi consentiti, e visibilità.

Le tabelle seguenti descrivono in dettaglio il significato di ogni proprietà.

Proprietà mappatura sezione-directory

Proprietà Descrizione Esempio

dir.name

Il percorso di una directory la cui sezione [name] a cui si applica.

Ogni proprietà mappa gli eseguibili all'interno della directory a un linker di configurazione degli spazi dei nomi. Potrebbero esserci due (o più) proprietà che hanno lo stesso name ma puntano a diversi .

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

Questo indica che la configurazione specificata La sezione [system] si applica agli eseguibili caricati da /system/bin o /system/xbin.

Si applica la configurazione specificata nella sezione [vendor] agli eseguibili caricati da /vendor/bin.

Proprietà relazione

Proprietà Descrizione Esempio
additional.namespaces

Un elenco di spazi dei nomi aggiuntivi separati da virgole (oltre al default) per la sezione.

additional.namespaces = sphal,vndk

Questo indica che sono presenti tre spazi dei nomi (default, sphal e vndk) in [system] configurazione.

namespace.name.links

Un elenco di spazi dei nomi di riserva separati da virgole.

Se non è possibile trovare una libreria condivisa nello spazio dei nomi corrente, il linker tenta di caricare la libreria condivisa dagli spazi dei nomi di riserva. La specificato all'inizio dell'elenco ha una priorità maggiore.

namespace.sphal.links = default,vndk

Se una libreria condivisa o un eseguibile richiede una libreria condivisa che impossibile caricare nello spazio dei nomi sphal, il linker dinamico prova a caricare la libreria condivisa da default nello spazio dei nomi.

Quindi, se la libreria condivisa non può essere caricata dal default, il Linker dinamico tenta di caricare lo libreria condivisa dallo spazio dei nomi vndk.

Infine, se tutti i tentativi non vanno a buon fine, il linker dinamico restituisce un errore.

namespace.name.link.other.shared_libs

Un elenco separato da due punti di librerie condivise in cui è possibile eseguire ricerche other di spazi dei nomi quando queste librerie non sono presenti nello spazio dei nomi name.

Questa proprietà non può essere utilizzata con namespace.name.link.other.allow_all_shared_libs.

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

Questo indica che il link di riserva accetta solo libc.so o libm.so come nome della libreria richiesto. Linker dinamico ignora il link di fallback da sphal a default se il nome della libreria richiesto non è libc.so o libm.so.

namespace.name.link.other.allow_all_shared_libs

Un valore booleano che indica se tutte le librerie condivise possono essere Cercato nello spazio dei nomi other quando queste librerie non possono nello spazio dei nomi name.

Questa proprietà non può essere utilizzata con namespace.name.link.other.shared_libs.

namespace.vndk.link.sphal.allow_all_shared_libs = true

Questo indica che tutti i nomi delle librerie possono passare attraverso il link di fallback da vndk a sphal.

Proprietà dello spazio dei nomi

Proprietà Descrizione Esempio
namespace.name.isolated

Un valore booleano che indica se il linker dinamico deve controllare in cui si trova la libreria condivisa.

Se isolated è true, solo le raccolte condivise che si trovano in una delle search.paths directory (escluse le sottodirectory) o sono in una delle Le directory permitted.paths (incluse le sottodirectory) possono essere caricato.

Se isolated è false (valore predefinito), lo stato il linker non controlla il percorso delle librerie condivise.

namespace.sphal.isolated = true

Questo indica che solo le librerie condivise search.paths o meno di permitted.paths possono essere caricato nello spazio dei nomi sphal.

namespace.name.search.paths

Un elenco di directory separate da due punti in cui cercare librerie.

Le directory specificate in search.paths sono anteposte al nome della libreria richiesto se la funzione chiama a dlopen() o Le voci DT_NEEDED non specificano il percorso completo. La directory specificato all'inizio dell'elenco ha una priorità maggiore.

Se il valore di isolated è true, le raccolte condivise che si trovano in una delle search.paths directory (escluse sottodirectory) possono essere caricate indipendentemente da permitted.paths proprietà.

Ad esempio, se search.paths è /system/${LIB} e permitted.paths è vuoto, /system/${LIB}/libc.so può essere caricato, ma Impossibile caricare /system/${LIB}/vndk/libutils.so.

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

Ciò indica che il Linker dinamico cerca /system/${LIB} per le raccolte condivise.

namespace.name.asan.search.paths

Un elenco di directory separate da due punti in cui cercare le librerie condivise quando AddressSanitizer (ASan) sia abilitato.

namespace.name.search.paths è ignorato quando ASan viene in un bucket con il controllo delle versioni attivo.

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

Questo indica che quando ASan sia abilitato il linker dinamico effettua prima ricerche /data/asan/system/${LIB} e poi cerca /system/${LIB}.

namespace.name.permitted.paths

Un elenco di directory (incluse le sottodirectory) separate da due punti in cui il linker dinamico può caricare le librerie condivise (oltre a search.paths) quando isolated è true.

Le librerie condivise che si trovano nelle sottodirectory È possibile caricare anche permitted.paths. Ad esempio, se permitted.paths è /system/${LIB}, sia /system/${LIB}/libc.so che È possibile caricare /system/${LIB}/vndk/libutils.so.

Se isolated è false, permitted.paths vengono ignorati e viene emesso un avviso.

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

Questo indica che le librerie condivise /system/${LIB}/hw può essere caricato nell'isolato default.

Ad esempio, senza permitted.paths, Impossibile caricare libaudiohal.so /system/${LIB}/hw/audio.a2dp.default.so nel default.

namespace.name.asan.permitted.paths

Un elenco di directory separate da due punti in cui può caricare il linker dinamico le librerie condivise quando è abilitato ASan.

namespace.name.permitted.paths è ignorato quando ASan è abilitato.

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

Questo indica che quando viene attivato ASan raccolte condivise in /data/asan/system/${LIB}/hw o È possibile caricare /system/${LIB}/hw nell'istanza dello spazio dei nomi default.

namespace.name.visible

Un valore booleano che indica se il programma (diverso da libc) può ottenere l'handle di uno spazio dei nomi linker con android_get_exported_namespace() e apri una raccolta condivisa in lo spazio dei nomi del linker passando l'handle android_dlopen_ext().

Se visible è true, android_get_exported_namespace() restituisce sempre l'handle se se lo spazio dei nomi esiste.

Se visible è false (valore predefinito), android_get_exported_namespace() restituisce sempre NULL indipendentemente dalla presenza dello spazio dei nomi. Librerie condivise possono essere caricati in questo spazio dei nomi solo se (1) sono richiesti da un altro linker che abbia un link di fallback a questo spazio dei nomi oppure (2) richiesti da altre librerie condivise o eseguibili in questo spazio dei nomi.

namespace.sphal.visible = true

Ciò indica che android_get_exported_namespace("sphal") può restituire un handle valido dello spazio dei nomi del linker.

Creazione dello spazio dei nomi del linker

In Android 11, la configurazione del linker viene creata in fase di runtime in /linkerconfig anziché utilizzare file di testo normale in ${android-src}/system/core/rootdir/etc. La configurazione viene generata all'avvio in base all'ambiente di runtime, che include i seguenti elementi:

  • Se il dispositivo supporta VNDK
  • Versione VNDK di destinazione della partizione del fornitore
  • Versione VNDK della partizione prodotto
  • Moduli APEX installati

La configurazione del linker viene creata risolvendo le dipendenze tra gli spazi dei nomi del linker. Per Ad esempio, se sono presenti aggiornamenti dei moduli APEX che includono aggiornamenti delle dipendenze, linker la configurazione generata riflettendo queste modifiche. Ulteriori dettagli per creare la configurazione del linker disponibile in ${android-src}/system/linkerconfig

Isolamento dello spazio dei nomi linker

Esistono tre tipi di configurazione. A seconda del valore PRODUCT_TREBLE_LINKER_NAMESPACES e BOARD_VNDK_VERSION a BoardConfig.mk, viene generata la configurazione corrispondente al momento dell'avvio.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Configurazione selezionata Requisito VTS
true current VNDK Obbligatorio per i dispositivi avviati con Android 9 o versioni successive
Vuoto VNDK Lite Obbligatorio per i dispositivi avviati con Android 8.x
false Vuoto Legacy Per dispositivi non alti

La configurazione VNDK Lite isola le librerie condivise SP-HAL e VNDK-SP. In Android 8.0, deve essere il file di configurazione del Linker dinamico quando PRODUCT_TREBLE_LINKER_NAMESPACES è true.

La configurazione VNDK isola anche le librerie condivise SP-HAL e VNDK-SP. Inoltre, questa configurazione fornisce l'isolamento completo del linker dinamico. Garantisce che i moduli nella partizione di sistema non dipendano nelle partizioni del fornitore e viceversa.

In Android 8.1 o versioni successive, la configurazione VNDK è quella predefinita Consigliamo inoltre di abilitare l'isolamento completo del linker dinamico impostando Da BOARD_VNDK_VERSION a current.

Configurazione VNDK

La configurazione VNDK isola le dipendenze della libreria condivisa tra la partizione di sistema e le partizioni del fornitore. Rispetto a configurazioni menzionate nella sottosezione precedente, le differenze sono descritti di seguito:

  • Processi framework

    • default, vndk, Vengono creati spazi dei nomi sphal e rs.
    • Tutti gli spazi dei nomi sono isolati.
    • Le librerie condivise di sistema vengono caricate nello spazio dei nomi default.
    • Gli SP-HAL vengono caricati nello spazio dei nomi sphal.
    • Librerie condivise VNDK-SP caricate nello spazio dei nomi vndk.
  • Processi del fornitore

    • Vengono creati gli spazi dei nomi default, vndk e system.
    • Lo spazio dei nomi default è isolato.
    • Le librerie condivise del fornitore vengono caricate nello spazio dei nomi default.
    • Le librerie condivise VNDK e VNDK-SP vengono caricate nello spazio dei nomi vndk.
    • LL-NDK e le sue dipendenze vengono caricate nello spazio dei nomi system.

La relazione tra gli spazi dei nomi del linker è illustrata di seguito.

Grafico dello spazio dei nomi del linker descritto nella configurazione VNDK

Figura 1. Isolamento dello spazio dei nomi del linker (configurazione VNDK).

Nell'immagine qui sopra, LL-NDK e VNDK-SP indicano raccolte condivise:

  • 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

Puoi trovare ulteriori dettagli in /linkerconfig/ld.config.txt dal dispositivo.

Configurazione VNDK Lite

A partire da Android 8.0, il Linker dinamico è configurato per isolare SP-HAL e Librerie condivise VNDK-SP in modo tale che i loro simboli non siano in conflitto con altri e librerie condivise di un framework. La relazione tra gli spazi dei nomi del linker come mostrato di seguito.

Grafico dello spazio dei nomi del linker descritto nella configurazione di VNDK Lite
Figura 2. Isolamento dello spazio dei nomi del linker (configurazione VNDK Lite)
di Gemini Advanced.

LL-NDK e VNDK-SP indicano le seguenti librerie condivise:

  • LL-NDK
      .
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (non presente nella configurazione)
    • libsync.so
    • libvndksupport.so
    • libz.so (spostato in VNDK-SP in la configurazione)
  • 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

La tabella seguente elenca la configurazione degli spazi dei nomi per il framework di un processo, che è un estratto dalla sezione [system] in la configurazione VNDK Lite.

Namespace Proprietà Valore
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 (per 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 (per 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 (per kernel RS compilato)
isolated true
visible true
links default,vndk
link.default.shared_libs LL-NDK

libmediandk.so libft2.so
link.vndk.shared_libs VNDK-SP

La tabella seguente illustra la configurazione degli spazi dei nomi per i processi del fornitore che è un estratto dalla sezione [vendor] in la configurazione VNDK Lite.

Namespace Proprietà Valore
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} e
/system/${LIB}/vndk-sp-${VER}
/system/${LIB} (ritirato)
/product/${LIB} (deprecato)
isolated false

Puoi trovare ulteriori dettagli in /linkerconfig/ld.config.txt del dispositivo.

Cronologia dei documenti

Modifiche ad Android 11

  • In Android 11, i file ld.config.*.txt statici vengono rimossi dal codebase e LinkerConfig li genera in runtime.

Modifiche ad Android 9

  • In Android 9, al fornitore viene aggiunto lo spazio dei nomi del linker vndk e le librerie condivise VNDK sono isolate dal linker predefinito nello spazio dei nomi.
  • Sostituisci PRODUCT_FULL_TREBLE con una più specifica PRODUCT_TREBLE_LINKER_NAMESPACES.
  • Android 9 cambia i nomi della seguente configurazione del Linker dinamico .
    Android 8.x Android 9 Descrizione
    ld.config.txt.in ld.config.txt Per i dispositivi con isolamento dello spazio dei nomi del Linker del runtime
    ld.config.txt ld.config.vndk_lite.txt Per i dispositivi con isolamento dello spazio dei nomi del linker VNDK-SP
    ld.config.legacy.txt ld.config.legacy.txt Per dispositivi legacy con Android 7.x o versioni precedenti
  • Rimuovi android.hardware.graphics.allocator@2.0.so.
  • Vengono aggiunte le partizioni product e odm.