El enlazador dinámico aborda dos desafíos en el diseño de Treble VNDK:
- Las bibliotecas compartidas SP-HAL y sus dependencias, incluidas las bibliotecas VNDK-SP, se cargan en procesos de marco. Debería haber algunos mecanismos para evitar conflictos de símbolos.
-
dlopen()
yandroid_dlopen_ext()
pueden introducir algunas dependencias en tiempo de ejecución que no son visibles en el momento de la compilación y pueden ser difíciles de detectar mediante el análisis estático.
Estos dos desafíos pueden resolverse mediante el mecanismo del espacio de nombres del vinculador . Este mecanismo lo proporciona el enlazador dinámico. Puede 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 entren en conflicto.
Por otro lado, el mecanismo del espacio de nombres del vinculador proporciona la flexibilidad para que algunas bibliotecas compartidas puedan ser exportadas por un espacio de nombres del vinculador y utilizadas por otro espacio de nombres del vinculador. Estas bibliotecas compartidas exportadas pueden convertirse en interfaces de programación de aplicaciones que son públicas para otros programas y al mismo tiempo ocultan sus detalles de implementación dentro de los espacios de nombres de sus vinculadores.
Por ejemplo, /system/lib[64]/libcutils.so
y /system/lib[64]/vndk-sp-${VER}/libcutils.so
son dos bibliotecas compartidas. Estas dos bibliotecas pueden tener símbolos diferentes. Se cargan en diferentes espacios de nombres de enlazadores para que los módulos del marco puedan depender de /system/lib[64]/libcutils.so
y las bibliotecas compartidas SP-HAL puedan depender 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 que se exporta mediante un espacio de nombres del vinculador y se importa a 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 reside /system/lib[64]/libc.so
. Otros espacios de nombres no tendrán acceso a esas dependencias. Este mecanismo encapsula los detalles de implementación al tiempo que proporciona las interfaces públicas.
¿Como funciona?
El vinculador dinámico es responsable de cargar las bibliotecas compartidas especificadas en las entradas DT_NEEDED
o 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 reside la persona que llama e 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 espacio de nombres del vinculador especificado, solicita al espacio de nombres del vinculador vinculado las bibliotecas compartidas exportadas.
Formato del archivo de configuración
El formato del archivo de configuración se basa en el formato de archivo INI. Un archivo de configuración típico 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:
- Varias propiedades de asignación de sección de directorio al principio para que el vinculador dinámico seleccione la sección efectiva.
- 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 varios enlaces alternativos entre espacios de nombres (arcos de gráficos).
- Cada espacio de nombres tiene su propio aislamiento, rutas de búsqueda, rutas permitidas y configuración de visibilidad.
Las tablas siguientes describen en detalle el significado de cada propiedad.
Propiedad de asignación de sección de directorio
Propiedad | Descripción | Ejemplo |
---|---|---|
| Una ruta a un directorio al que se aplica la sección Cada propiedad asigna los ejecutables del directorio a una sección de configuración de espacios de nombres del vinculador. Puede haber dos (o más) propiedades que tengan el mismo | Esto indica que la configuración especificada en la sección La configuración especificada en la sección |
Propiedades de relación
Propiedad | Descripción | Ejemplo |
---|---|---|
additional. namespaces | Una lista separada por comas de espacios de nombres adicionales (además del espacio de nombres | Esto indica que hay tres espacios de nombres ( |
namespace. name . links | Una lista separada por comas de espacios de nombres alternativos. Si no se puede encontrar una biblioteca compartida en el espacio de nombres actual, el vinculador dinámico intenta cargar la biblioteca compartida desde los espacios de nombres alternativos. El espacio de nombres especificado al principio de la lista tiene mayor prioridad. | Si una biblioteca compartida o un ejecutable solicita una biblioteca compartida que no se puede cargar en el espacio de nombres Y luego, si la biblioteca compartida tampoco se puede cargar desde el espacio de nombres Finalmente, si todos los intentos fallan, el vinculador dinámico devuelve un error. |
namespace. name . link. other . shared_libs | Una lista separada por dos puntos de bibliotecas compartidas que se pueden buscar en Esta propiedad no se puede utilizar con | Esto indica que el enlace alternativo acepta solo |
namespace. name . link. other . allow_all_shared_libs | Un valor booleano que indica si se pueden buscar todas las bibliotecas compartidas en el Esta propiedad no se puede utilizar con | Esto indica que todos los nombres de bibliotecas pueden pasar por el enlace alternativo desde |
Propiedades del espacio de nombres
Propiedad | Descripción | Ejemplo |
---|---|---|
namespace. name . isolated | Un valor booleano que indica si el vinculador dinámico debe comprobar dónde reside la biblioteca compartida. Si Si | Esto indica que solo las bibliotecas compartidas en |
namespace. name . search.paths | Una lista de directorios separados por dos puntos para buscar bibliotecas compartidas. Los directorios especificados en Cuando Por ejemplo, si | Esto indica que el vinculador dinámico busca |
namespace. name . asan.search.paths | Una lista de directorios separados por dos puntos para buscar bibliotecas compartidas cuando AddressSanitizer (ASan) está habilitado. | Esto indica que cuando ASan está habilitado, el vinculador dinámico busca |
namespace. name . permitted.paths | Una lista de directorios (incluidos subdirectorios) separados por dos puntos donde el vinculador dinámico puede cargar las bibliotecas compartidas (además de También se pueden cargar las bibliotecas compartidas que se encuentran en los subdirectorios de Si | Esto indica que las bibliotecas compartidas en Por ejemplo, sin |
namespace. name . asan.permitted.paths | Una lista de directorios separados por dos puntos donde el vinculador dinámico puede cargar las bibliotecas compartidas cuando ASan está habilitado. | Esto indica que cuando ASan está habilitado, las bibliotecas compartidas en |
namespace. name . visible | Un valor booleano que indica si el programa (que no sea Si Si | Esto indica que |
Creación de espacio de nombres del vinculador
En Android 11, la configuración del vinculador se crea en 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 en el momento del arranque según el entorno de ejecución, que incluye los siguientes elementos:
- Si el dispositivo es compatible con VNDK
- Versión VNDK de destino de la partición del proveedor
- Versión VNDK de la partición del producto
- Módulos APEX instalados
La configuración del vinculador se crea resolviendo dependencias entre espacios de nombres del vinculador. Por ejemplo, si hay actualizaciones en los módulos APEX que incluyen actualizaciones de dependencia, se genera la configuración del vinculador que refleja estos cambios. Se pueden encontrar más detalles para crear la configuración del vinculador en ${android-src}/system/linkerconfig
.
Aislamiento del espacio de nombres del vinculador
Hay tres tipos de configuración. Dependiendo del valor de PRODUCT_TREBLE_LINKER_NAMESPACES
y BOARD_VNDK_VERSION
en BoardConfig.mk
, la configuración correspondiente se genera en el momento del arranque.
PRODUCT_TREBLE_ LINKER_NAMESPACES | BOARD_VNDK_ VERSION | Configuración seleccionada | Requisito VTS |
---|---|---|---|
true | current | VNDK | Obligatorio para dispositivos lanzados con Android 9 o superior |
Vacío | VNDK Lite | Obligatorio para dispositivos lanzados con Android 8.x | |
false | Vacío | Legacy | Para dispositivos que no son Treble |
La configuración de VNDK Lite aísla las bibliotecas compartidas SP-HAL y VNDK-SP. En Android 8.0, este debe ser el archivo de configuración para el vinculador dinámico cuando PRODUCT_TREBLE_LINKER_NAMESPACES
es true
.
La configuración de VNDK también aísla las bibliotecas compartidas SP-HAL y VNDK-SP. Además, esta configuración proporciona el aislamiento dinámico completo del vinculador. Garantiza que los módulos en la partición del sistema no dependan de las bibliotecas compartidas en las particiones del proveedor y viceversa.
En Android 8.1 o superior, la configuración VNDK es la configuración predeterminada y se recomienda encarecidamente habilitar el aislamiento dinámico completo del vinculador configurando BOARD_VNDK_VERSION
en current
.
Configuración VNDK
La configuración de VNDK aísla las dependencias de la biblioteca compartida entre la partición del sistema y las particiones del proveedor. En comparación con las configuraciones mencionadas en la subsección anterior, las diferencias se describen a continuación:
Procesos marco
- Se crean los espacios de nombres
default
,vndk
,sphal
yrs
. - Todos los espacios de nombres están aislados.
- Las bibliotecas compartidas del sistema se cargan en el espacio de nombres
default
. - Los SP-HAL se cargan en el espacio de nombres
sphal
. - Bibliotecas compartidas VNDK-SP cargadas en el espacio de nombres
vndk
.
- Se crean los espacios de nombres
Procesos de proveedores
- Se crean los espacios de nombres
default
,vndk
ysystem
. - El espacio de nombres
default
está aislado. - Las bibliotecas compartidas del proveedor 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
.
- Se crean los espacios de nombres
La relación entre los espacios de nombres del enlazador se ilustra a continuación.
En la imagen de arriba, LL-NDK y VNDK-SP representan las siguientes bibliotecas compartidas:
- 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
-
Puede encontrar más detalles en /linkerconfig/ld.config.txt
del dispositivo.
Configuración VNDK Lite
A partir de Android 8.0, el vinculador dinámico está configurado para aislar las bibliotecas compartidas SP-HAL y VNDK-SP de modo que sus símbolos no entren en conflicto con otras bibliotecas compartidas del marco. La relación entre los espacios de nombres del enlazador se muestra a continuación.
LL-NDK y VNDK-SP representan las siguientes bibliotecas compartidas:
- LL-NDK
-
libEGL.so
-
libGLESv1_CM.so
-
libGLESv2.so
-
libc.so
-
libdl.so
-
liblog.so
-
libm.so
-
libnativewindow.so
-
libstdc++.so
(no en la configuración) -
libsync.so
-
libvndksupport.so
-
libz.so
(movido 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
-
La siguiente tabla enumera la configuración de espacios de nombres para procesos de marco, que está extraída 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 | LL-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 | LL-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} /vendor/${LIB} /data (para kernel RS compilado) | |
isolated | true | |
visible | true | |
links | default,vndk | |
link.default.shared_libs | LL-NDKlibmediandk.so libft2.so | |
link.vndk.shared_libs | VNDK-SP |
La siguiente tabla presenta la configuración de espacios de nombres para procesos de proveedores, que está extraída de la sección [vendor]
en la configuración de VNDK Lite.
Espacio de nombres | Propiedad | Valor |
---|---|---|
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} (obsoleto)/product/${LIB} (obsoleto) |
isolated | false |
Se pueden encontrar más detalles en /linkerconfig/ld.config.txt
del dispositivo.
Historia del documento
Cambios en Android 11
- En Android 11, los archivos estáticos
ld.config.*.txt
se eliminan del código base y LinkerConfig los genera en tiempo de ejecución.
Cambios en Android 9
- En Android 9, el espacio de nombres del vinculador
vndk
se agrega a los procesos del proveedor y las bibliotecas compartidas de VNDK están aisladas del espacio de nombres del vinculador predeterminado. - Reemplace
PRODUCT_FULL_TREBLE
conPRODUCT_TREBLE_LINKER_NAMESPACES
más específicos. - Android 9 cambia los nombres de los siguientes archivos de configuración del vinculador dinámico.
Android 8.x androide 9 Descripción ld.config.txt.in
ld.config.txt
Para dispositivos con aislamiento del espacio de nombres del vinculador en tiempo 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 inferior - Elimine
android.hardware.graphics.allocator@2.0.so
. - Se agregan particiones
product
yodm
.