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 los procesos del marco. Debe haber algunos mecanismos para prevenir conflictos de símbolos.
-
dlopen()
yandroid_dlopen_ext()
pueden introducir algunas dependencias de 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 se pueden resolver mediante el mecanismo de espacio de nombres del enlazador . Este mecanismo lo proporciona el enlazador dinámico. Puede aislar las bibliotecas compartidas en diferentes espacios de nombres del enlazador para que las bibliotecas con el mismo nombre de biblioteca pero con diferentes símbolos no entren en conflicto.
Por otro lado, el mecanismo del espacio de nombres del enlazador proporciona la flexibilidad para que un espacio de nombres del enlazador pueda exportar algunas bibliotecas compartidas y usarlas otro espacio de nombres del enlazador. Estas bibliotecas compartidas exportadas pueden convertirse en interfaces de programación de aplicaciones que son públicas para otros programas mientras ocultan sus detalles de implementación dentro de los espacios de nombres de sus enlazadores.
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 del enlazador para que los módulos del marco puedan depender de /system/lib[64]/libcutils.so
y las bibliotecas compartidas SP-HAL pueden 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 exportada por un espacio de nombres del enlazador e importada en muchos espacios de nombres del enlazador. 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 mientras proporciona las interfaces públicas.
¿Como funciona?
El enlazador 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 de 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 mapeo de sección de directorio al principio para que el enlazador dinámico seleccione la sección efectiva.
- Varias secciones de configuración de espacios de nombres del enlazador:
- 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 propia configuración de aislamiento, rutas de búsqueda, rutas permitidas y visibilidad.
Las siguientes tablas describen el significado de cada propiedad en detalle.
Propiedad de mapeo 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 enlazador. 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 enlazador 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 los Esta propiedad no se puede usar con el espacio de | Esto indica que el enlace alternativo solo acepta |
namespace. name . link. other . allow_all_shared_libs | Un valor booleano que indica si todas las bibliotecas compartidas se pueden buscar en el Esta propiedad no se puede usar con el espacio de | Esto indica que todos los nombres de biblioteca pueden pasar por el enlace alternativo de |
Propiedades del espacio de nombres
Propiedad | Descripción | Ejemplo |
---|---|---|
namespace. name . isolated | Un valor booleano que indica si el enlazador dinámico debe comprobar dónde reside la biblioteca compartida. Si Si | Esto indica que solo las bibliotecas compartidas en search.paths o 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 enlazador 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 enlazador dinámico busca |
namespace. name . permitted.paths | Una lista de directorios separados por dos puntos (incluidos los subdirectorios) donde el enlazador 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 las rutas |
namespace. name . asan.permitted.paths | Una lista de directorios separados por dos puntos donde el enlazador 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 del espacio de nombres del enlazador
En Android 11, la configuración del enlazador 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 en función del entorno de tiempo 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 de VNDK de la partición del producto
- Módulos APEX instalados
La configuración del vinculador se crea resolviendo las dependencias entre los espacios de nombres del vinculador. Por ejemplo, si hay actualizaciones en los módulos APEX que incluyen actualizaciones de dependencia, la configuración del enlazador se genera reflejando estos cambios. Se pueden encontrar más detalles para crear la configuración del enlazador en ${android-src}/system/linkerconfig
.
Aislamiento del espacio de nombres del enlazador
Hay tres tipos de configuración. Según el 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 de agudos |
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 enlazador 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 completo del enlazador dinámico. 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 de VNDK es la configuración predeterminada y se recomienda habilitar el aislamiento completo del enlazador dinámico configurando BOARD_VNDK_VERSION
en current
.
Configuración de 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 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 espacios de nombres
Procesos de proveedores
- Se crean 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 del
system
.
- Se crean espacios de nombres
La relación entre los espacios de nombres del enlazador se ilustra a continuación.
![Gráfico de espacio de nombres del vinculador descrito en la configuración de VNDK](https://source.android.com/static/devices/architecture/images/treble_vndk_linker_namespace3.png?authuser=5&hl=es)
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
desde el dispositivo.
Configuración de 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.
![Gráfico de espacio de nombres del vinculador descrito en la configuración de VNDK Lite](https://source.android.com/static/devices/architecture/images/treble_vndk_linker_namespace1.png?authuser=5&hl=es)
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 los espacios de nombres para los procesos del marco, que se extrajo 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 se extrae 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
desde el 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, en su lugar, 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 se aíslan 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 de 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 de vinculador VNDK-SP ld.config.legacy.txt
ld.config.legacy.txt
Para dispositivos heredados con Android 7.x o inferior - Quite
android.hardware.graphics.allocator@2.0.so
. - Se agregan las particiones
product
yodm
.