Espacio de nombres del vinculador

El vinculador dinámico aborda dos desafíos en el diseño del VNDK de Treble:

  • Bibliotecas compartidas de SP-HAL y sus dependencias, incluido VNDK-SP bibliotecas se cargan en procesos del framework. Debería haber mecanismos para evitar conflictos de símbolos.
  • dlopen() y android_dlopen_ext() pueden introducir algunas dependencias del entorno de ejecución que no son visibles en el tiempo de compilación y se pueden difíciles de detectar con el análisis estático.

Estos dos desafíos se pueden resolver con el espacio de nombres del vinculador. de atención. El vinculador dinámico proporciona este mecanismo. Integra pueden aislar las bibliotecas compartidas en diferentes espacios de nombres del vinculador para que las bibliotecas con el mismo nombre, pero con diferentes símbolos, no entrará en conflicto.

Por otro lado, el mecanismo de espacio de nombres del vinculador proporciona la flexibilidad de modo que un espacio de nombres de vinculador pueda exportar algunas bibliotecas compartidas y usarlas de otro espacio de nombres del vinculador. Estas bibliotecas compartidas exportadas pueden interfaces de programación de aplicaciones que son públicas para otros programas, mientras que ocultar sus detalles de implementación en los espacios de nombres del vinculador.

Por ejemplo, /system/lib[64]/libcutils.so y Se comparten /system/lib[64]/vndk-sp-${VER}/libcutils.so bibliotecas. Estas dos bibliotecas pueden tener símbolos diferentes. Se cargaron en diferentes espacios de nombres del vinculador para que los módulos del framework puedan depender Las bibliotecas compartidas /system/lib[64]/libcutils.so y SP-HAL pueden dependen de /system/lib[64]/vndk-sp-${VER}/libcutils.so.

Por otro lado, /system/lib[64]/libc.so es un ejemplo de una biblioteca pública exportada por un espacio de nombres del vinculador y que se importa muchos espacios de nombres del vinculador. Las dependencias de /system/lib[64]/libc.so, como libnetd_client.so, se cargan en el espacio de nombres en el que /system/lib[64]/libc.so su lugar de residencia. Otros espacios de nombres no tendrán acceso a esas dependencias. Esta encapsula los detalles de la implementación, a la vez que proporciona interfaces.

Cómo funciona

El vinculador dinámico es responsable de cargar las bibliotecas compartidas especificadas. en las entradas DT_NEEDED o en las bibliotecas compartidas especificadas por el argumento de dlopen() o android_dlopen_ext(). En ambos casos, el vinculador dinámico encuentra el espacio de nombres del vinculador donde el emisor reside y, luego, intenta cargar las dependencias en el mismo espacio de nombres del vinculador. Si el vinculador dinámico no puede cargar la biblioteca compartida en el vinculador especificado , este solicita el espacio de nombres del vinculador vinculado para los archivos compartidos bibliotecas.

Formato del archivo de configuración

El formato del archivo de configuración se basa en el formato de archivo INI. Un de configuración se ve así:

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}

El archivo de configuración incluye lo siguiente:

  • Varias propiedades de asignación de secciones del directorio al comienzo de la para seleccionar la sección eficaz.
  • Varias secciones de configuración de espacios de nombres del vinculador:
    • Cada sección contiene varios espacios de nombres (vértices de gráficos) y varias vínculos de resguardo entre espacios de nombres (arcos de grafos).
    • Cada espacio de nombres tiene su propio aislamiento, rutas de búsqueda, rutas de acceso permitidas, y la configuración de visibilidad.

En las siguientes tablas, se describe el significado de cada propiedad en detalle.

Propiedad de asignación de sección de directorio

Propiedad Descripción Ejemplo

dir.name

Una ruta de acceso a un directorio que la sección [name] se aplica.

Cada propiedad asigna los archivos ejecutables del directorio a un vinculador. de la configuración de los espacios de nombres. Puede haber dos (o más) propiedades que tienen el mismo name, pero apuntan a diferentes directorios.

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

Esto indica que la configuración especificada en el La sección [system] se aplica a los archivos ejecutables que se cargan desde /system/bin o /system/xbin.

Se aplica la configuración especificada en la sección [vendor]. a los ejecutables que se cargan desde /vendor/bin.

Propiedades de la relación

Propiedad Descripción Ejemplo
additional.namespaces

Una lista separada por comas de los espacios de nombres adicionales (además del default) para la sección.

additional.namespaces = sphal,vndk

Esto indica que hay tres espacios de nombres (default, sphal y vndk) en [system] configuración.

namespace.name.links

Una lista separada por comas de los espacios de nombres de resguardo.

Si no se encuentra una biblioteca compartida en el espacio de nombres actual, la biblioteca el vinculador intenta cargar la biblioteca compartida desde los espacios de nombres de resguardo. El el espacio de nombres especificado al principio de la lista tiene mayor prioridad.

namespace.sphal.links = default,vndk

Si una biblioteca compartida o un ejecutable solicita una biblioteca compartida que no se pueden cargar en el espacio de nombres sphal, el vinculador dinámico intenta cargar la biblioteca compartida desde el archivo default espacio de nombres.

Y luego, si la biblioteca compartida no se puede cargar desde el default, el vinculador dinámico intentará cargar el biblioteca compartida del espacio de nombres vndk.

Por último, si todos los intentos fallan, el vinculador dinámico muestra un error.

namespace.name.link.other.shared_libs

Lista de bibliotecas compartidas, separadas por dos puntos, que se pueden buscar en el other cuando no se puedan encontrar esas bibliotecas en el Espacio de nombres name.

No se puede usar esta propiedad con namespace.name.link.other.allow_all_shared_libs

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

Esto indica que el vínculo de resguardo solo acepta libc.so o libm.so como el nombre de la biblioteca solicitado. El vinculador dinámico ignora el vínculo de resguardo de sphal a Espacio de nombres default si el nombre de la biblioteca solicitado no es libc.so o libm.so.

namespace.name.link.other.allow_all_shared_libs

Un valor booleano que indica si todas las bibliotecas compartidas pueden en el espacio de nombres other cuando esas bibliotecas no pueden se encuentra en el espacio de nombres name.

No se puede usar esta propiedad con namespace.name.link.other.shared_libs

namespace.vndk.link.sphal.allow_all_shared_libs = true

Esto indica que todos los nombres de la biblioteca pueden revisar el vínculo de resguardo. del espacio de nombres vndk al sphal.

Propiedades del espacio de nombres

Propiedad Descripción Ejemplo
namespace.name.isolated

Un valor booleano que indica si el vinculador dinámico debe verificar en la que se encuentra la biblioteca compartida.

Si isolated es true, solo las bibliotecas compartidas que se encuentren en uno de los directorios search.paths (sin incluir subdirectorios) o que se encuentren en uno de los permitted.paths directorios (incluidos los subdirectorios) pueden cargado.

Si isolated es false (predeterminado), el valor dinámico no verifica la ruta de acceso de las bibliotecas compartidas.

namespace.sphal.isolated = true

Esto indica que solo las bibliotecas compartidas Puedes tener search.paths o menos de permitted.paths se cargan en el espacio de nombres sphal.

namespace.name.search.paths

Una lista de directorios separados por dos puntos para buscar directorios bibliotecas.

Los directorios especificados en search.paths se anteponen. al nombre de la biblioteca solicitada si la función llama a dlopen() Las entradas DT_NEEDED no especifican la ruta de acceso completa. El directorio especificada al principio de la lista tiene mayor prioridad.

Cuando isolated sea true, las bibliotecas compartidas que están en uno de los directorios search.paths (excepto en subdirectorios) se pueden cargar independientemente de la permitted.paths propiedad.

Por ejemplo, si search.paths es /system/${LIB} y permitted.paths están vacíos, /system/${LIB}/libc.so puede cargarse, pero No se puede cargar /system/${LIB}/vndk/libutils.so.

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

Esto indica que el vinculador dinámico busca /system/${LIB} para bibliotecas compartidas.

namespace.name.asan.search.paths

Una lista de directorios separados por dos puntos para buscar bibliotecas compartidas cuando AddressSanitizer (ASan) está habilitado.

namespace.name.search.paths es se ignora cuando ASan es habilitado.

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

Esto indica que cuando ASan está habilitado el el vinculador dinámico busca /data/asan/system/${LIB} primero y luego busca /system/${LIB}.

namespace.name.permitted.paths

Una lista de directorios (incluidos los subdirectorios) separados por dos puntos donde el vinculador dinámico puede cargar las bibliotecas compartidas (además del search.paths) cuando isolated es true

Las bibliotecas compartidas que se encuentran en los subdirectorios También se puede cargar permitted.paths. Por ejemplo, permitted.paths es /system/${LIB}, tanto /system/${LIB}/libc.so como Se puede cargar /system/${LIB}/vndk/libutils.so.

Si isolated es false, permitted.paths se ignoran y se emite una advertencia.

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

Esto indica que las bibliotecas compartidas /system/${LIB}/hw puede cargarse en la biblioteca Espacio de nombres default.

Por ejemplo, sin permitted.paths, No se puede cargar libaudiohal.so /system/${LIB}/hw/audio.a2dp.default.so hacia la Espacio de nombres default.

namespace.name.asan.permitted.paths

Una lista de directorios separados por dos puntos donde se puede cargar el vinculador dinámico las bibliotecas compartidas cuando ASan está habilitado.

namespace.name.permitted.paths es Se ignora cuando ASan está habilitado.

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

Esto indica que cuando ASan está habilitado las bibliotecas compartidas en /data/asan/system/${LIB}/hw o /system/${LIB}/hw se puede cargar en la capa Espacio de nombres default.

namespace.name.visible

Un valor booleano que indica si el programa (distinto del libc) puede obtener un controlador de espacio de nombres del vinculador con android_get_exported_namespace() y abre una biblioteca compartida en espacio de nombres del vinculador pasando el controlador a android_dlopen_ext()

Si visible es true, android_get_exported_namespace() siempre muestra el controlador si que exista el espacio de nombres.

Si visible es false (valor predeterminado), android_get_exported_namespace() siempre muestra resultados NULL, sin importar la presencia del espacio de nombres. Bibliotecas compartidas solo se pueden cargar en este espacio de nombres si (1) lo solicita otro del vinculador que tenga un vínculo de resguardo a este espacio de nombres, o solicitado por otras bibliotecas compartidas o ejecutables en este espacio de nombres.

namespace.sphal.visible = true

Esto indica que android_get_exported_namespace("sphal") puede mostrar un controlador de espacio de nombres del vinculador válido.

Creación de espacios de nombres del vinculador

En Android 11, la configuración del vinculador se crea durante el tiempo de ejecución en /linkerconfig en lugar de usar archivos de texto sin formato en ${android-src}/system/core/rootdir/etc La configuración se genera durante el inicio tiempo en función del entorno de ejecución, que incluye los siguientes elementos:

  • Si el dispositivo es compatible con VNDK
  • Versión de VNDK de destino de la partición del proveedor
  • Versión del VNDK de la partición de producto
  • Módulos APEX instalados

La configuración del vinculador se crea resolviendo las dependencias entre los espacios de nombres del vinculador. Para por ejemplo, si hay actualizaciones en los módulos APEX que incluyan actualizaciones de dependencias, de Terraform se genera con estos cambios. Más detalles para crear una configuración del vinculador se pueden encontrar en ${android-src}/system/linkerconfig

Aislamiento del espacio de nombres del vinculador

Existen tres tipos de configuración. Según el valor de PRODUCT_TREBLE_LINKER_NAMESPACES y BOARD_VNDK_VERSION en BoardConfig.mk, el la configuración correspondiente se genera en el momento del inicio.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Configuración seleccionada Requisito de VTS
true current VNDK Obligatoria para los dispositivos que se lanzaron con Android 9 o versiones posteriores
Vacío VNDK Lite Obligatoria para dispositivos que se lanzan con Android 8.x
false Vacío Legacy Para dispositivos que no son de Treble

La configuración de VNDK Lite aísla las bibliotecas compartidas SP-HAL y VNDK-SP. En Android 8.0, esto debe ser el archivo de configuración del vinculador dinámico cuando PRODUCT_TREBLE_LINKER_NAMESPACES es true.

La configuración del VNDK también aísla las bibliotecas compartidas SP-HAL y VNDK-SP. Además, esta configuración proporciona el aislamiento completo del vinculador dinámico. Garantiza que los módulos en la partición del sistema no dependan de la red bibliotecas en las particiones de proveedor, y viceversa.

En Android 8.1 o versiones posteriores, la configuración del VNDK es la predeterminada. y se recomienda habilitar el aislamiento completo del vinculador dinámico estableciendo De BOARD_VNDK_VERSION a current.

Configuración del VNDK

La configuración del VNDK aísla las dependencias de la biblioteca compartida. entre la partición del sistema y las particiones del proveedor. Comparado con de configuración mencionadas en la subsección anterior, las diferencias se describen de la siguiente manera:

  • Procesos del marco

    • default, vndk, Se crean los espacios de nombres sphal y rs.
    • Todos los espacios de nombres están aislados.
    • Las bibliotecas compartidas del sistema se cargan en el espacio de nombres default.
    • Las SP-HAL se cargan en el espacio de nombres sphal.
    • Se cargaron bibliotecas compartidas VNDK-SP en el espacio de nombres vndk.
  • Procesos del proveedor

    • Se crean los espacios de nombres default, vndk y system.
    • El espacio de nombres default está aislado.
    • Las bibliotecas compartidas de proveedores se cargan en el espacio de nombres default.
    • Las bibliotecas compartidas VNDK y VNDK-SP se cargan en el espacio de nombres vndk.
    • LL-NDK y sus dependencias se cargan en el espacio de nombres system.

La relación entre los espacios de nombres del vinculador se ilustra a continuación.

Gráfico del espacio de nombres del vinculador descrito en la configuración del VNDK

Figura 1: Aislamiento del espacio de nombres del vinculador (configuración del VNDK).

En la imagen anterior, LL-NDK y VNDK-SP significan lo siguiente: Bibliotecas compartidas:

  • LLC-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

Puedes ver más detalles en /linkerconfig/ld.config.txt desde el dispositivo.

Configuración del VNDK Lite

A partir de Android 8.0, el vinculador dinámico está configurado para aislar la SP-HAL y bibliotecas compartidas VNDK-SP de modo que sus símbolos no entren en conflicto con otras en las bibliotecas compartidas del framework. La relación entre los espacios de nombres del vinculador es que se muestra a continuación.

Gráfico de espacio de nombres del vinculador descrito en la configuración de VNDK Lite
Figura 2: Aislamiento del espacio de nombres del vinculador (configuración de VNDK Lite)

LL-NDK y VNDK-SP significan las siguientes bibliotecas compartidas:

  • LLC-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (no está en la configuración)
    • libsync.so
    • libvndksupport.so
    • libz.so (se movió a VNDK-SP en la configuración)
  • 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

En la siguiente tabla, se muestra la configuración de los espacios de nombres para el framework extraídos de la sección [system] en la configuración de VNDK Lite.

Espacio de nombres Propiedad Valor
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 LLC-NDK
link.vndk.shared_libs VNDK‐SP
link.rs.shared_libs libRS_internal.so
vndk (para 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 LLC-NDK
rs (para RenderScript) search.paths /odm/${LIB}/vndk-sp
/vendor/${LIB}/vndk-sp
/system/${LIB}/vndk-sp-${VER}
/odm/${LIB}
/vendor/${LIB}
permitted.paths /odm/${LIB} de
/vendor/${LIB}
/data (para el kernel RS compilado)
isolated true
visible true
links default,vndk
link.default.shared_libs LLC-NDK
libmediandk.so
libft2.so
link.vndk.shared_libs VNDK‐SP

En la siguiente tabla, se muestra la configuración de los espacios de nombres para los procesos del proveedor, que está extraído de la sección [vendor] en la configuración de VNDK Lite.

Espacio de nombres Propiedad Valor
default search.paths /odm/${LIB} de
/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} (obsoleto)
/product/${LIB} (obsoleto)
isolated false

Puedes encontrar más detalles en /linkerconfig/ld.config.txt desde el dispositivo.

Historial del documento

Cambios en Android 11

  • En Android 11, los archivos ld.config.*.txt estáticos se de la base de código, y LinkerConfig los genera en el entorno de ejecución.

Cambios en Android 9

  • En Android 9, el espacio de nombres del vinculador vndk se agrega al proveedor. los procesos y las bibliotecas compartidas VNDK están aisladas del vinculador predeterminado. espacio de nombres.
  • Reemplaza PRODUCT_FULL_TREBLE por uno más específico PRODUCT_TREBLE_LINKER_NAMESPACES
  • Android 9 cambia los nombres de la siguiente configuración del vinculador dinámico archivos.
    Android 8.x Android 9 Descripción
    ld.config.txt.in ld.config.txt Para dispositivos con aislamiento de espacio de nombres del vinculador de entorno de ejecución
    ld.config.txt ld.config.vndk_lite.txt Para dispositivos con aislamiento de espacio de nombres del vinculador VNDK-SP
    ld.config.legacy.txt ld.config.legacy.txt Para dispositivos heredados con Android 7.x o versiones anteriores
  • Se quita android.hardware.graphics.allocator@2.0.so.
  • Se agregaron las particiones product y odm.