O vinculador dinâmico enfrenta dois desafios no design do VNDK do Treble:
- As bibliotecas compartilhadas da SP-HAL e as dependências delas, incluindo bibliotecas VNDK-SP, são carregadas em processos de framework. É preciso ter alguns mecanismos para evitar conflitos de símbolos.
dlopen()
eandroid_dlopen_ext()
podem introduzir algumas dependências de tempo de execução que não ficam visíveis no momento da criação e podem ser difíceis de detectar usando a análise estática.
Esses dois desafios podem ser resolvidos pelo mecanismo de namespace do vinculador. Esse mecanismo é fornecido pelo vinculador dinâmico. Ele pode isolar as bibliotecas compartilhadas em namespaces de vinculadores diferentes para que bibliotecas com o mesmo nome, mas com símbolos diferentes, não entrem em conflito.
Por outro lado, o mecanismo de namespace do vinculador oferece a flexibilidade para que algumas bibliotecas compartilhadas possam ser exportadas por um namespace do vinculador e usadas por outro namespace do vinculador. Essas bibliotecas compartilhadas exportadas podem se tornar interfaces de programação de aplicativos públicas para outros programas, enquanto ocultam os detalhes de implementação nos namespaces do vinculador.
Por exemplo, /system/lib[64]/libcutils.so
e /system/lib[64]/vndk-sp-${VER}/libcutils.so
são duas bibliotecas compartilhadas. Essas duas bibliotecas podem ter símbolos diferentes. Eles são carregados
em namespaces de vinculadores diferentes para que os módulos de framework possam depender de
/system/lib[64]/libcutils.so
e as bibliotecas compartilhadas SP-HAL possam
depender de /system/lib[64]/vndk-sp-${VER}/libcutils.so
.
Por outro lado, /system/lib[64]/libc.so
é um exemplo de
uma biblioteca pública exportada por um namespace do vinculador e importada para
muitos namespaces do vinculador. As dependências de
/system/lib[64]/libc.so
, como libnetd_client.so
,
são carregadas no namespace em que /system/lib[64]/libc.so
está. Outros namespaces não terão acesso a essas dependências. Esse mecanismo encapsula os detalhes da implementação e fornece as interfaces públicas.
Como funciona
O vinculador dinâmico é responsável por carregar as bibliotecas compartilhadas especificadas
em entradas DT_NEEDED
ou as bibliotecas compartilhadas especificadas pelo
argumento de dlopen()
ou android_dlopen_ext()
. Em ambos os casos, o vinculador dinâmico encontra o namespace do vinculador em que o chamador reside e tenta carregar as dependências no mesmo namespace do vinculador. Se o vinculador dinâmico não conseguir carregar a biblioteca compartilhada no namespace especificado, ele vai pedir ao namespace do vinculador vinculado as bibliotecas compartilhadas exportadas.
Formato do arquivo de configurações
O formato do arquivo de configuração é baseado no formato de arquivo INI. Um arquivo de configuração típico é assim:
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}
O arquivo de configuração inclui:
- Várias propriedades de mapeamento de seção de diretório no início para o vinculador dinâmico selecionar a seção efetiva.
-
Várias seções de configuração de namespaces do vinculador:
- Cada seção contém vários namespaces (vértices do gráfico) e vários links de substituição entre namespaces (arcos do gráfico).
- Cada namespace tem isolamento, caminhos de pesquisa, caminhos permitidos e configurações de visibilidade próprios.
As tabelas abaixo descrevem o significado de cada propriedade em detalhes.
Propriedade de mapeamento de seção do diretório
Propriedade | Descrição | Exemplo |
---|---|---|
|
Um caminho para um diretório a que a seção Cada propriedade mapeia os executáveis no diretório para uma seção de configuração de namespaces do vinculador. Pode haver duas (ou mais) propriedades com o mesmo |
Isso indica que a configuração especificada na seção A configuração especificada na seção |
Propriedades de relação
Propriedade | Descrição | Exemplo |
---|---|---|
additional. |
Uma lista separada por vírgulas de namespaces adicionais (além do namespace |
Isso indica que há três namespaces ( |
namespace. |
Uma lista separada por vírgulas de namespaces de substituição. Se uma biblioteca compartilhada não for encontrada no namespace atual, o vinculador dinâmico tentará carregar a biblioteca compartilhada dos namespaces de fallback. O namespace especificado no início da lista tem maior prioridade. |
Se uma biblioteca compartilhada ou um executável solicitar uma biblioteca compartilhada que
não pode ser carregada no namespace Se a biblioteca compartilhada também não puder ser carregada do namespace
Por fim, se todas as tentativas falharem, o vinculador dinâmico vai retornar um erro. |
namespace. |
Uma lista separada por dois-pontos de bibliotecas compartilhadas que podem ser pesquisadas nos namespaces
Essa propriedade não pode ser usada com |
Isso indica que o link de substituição aceita apenas |
namespace. |
Um valor booleano que indica se todas as bibliotecas compartilhadas podem ser
pesquisadas no namespace Essa propriedade não pode ser usada com |
Isso indica que todos os nomes de biblioteca podem passar pelo link de substituição
do namespace |
Propriedades do namespace
Propriedade | Descrição | Exemplo |
---|---|---|
namespace. |
Um valor booleano que indica se o vinculador dinâmico precisa verificar onde a biblioteca compartilhada está localizada. Se Se |
Isso indica que apenas as bibliotecas compartilhadas em |
namespace. |
Uma lista separada por dois-pontos de diretórios para pesquisar bibliotecas compartilhadas. Os diretórios especificados em Quando Por exemplo, se |
Isso indica que o vinculador dinâmico pesquisa
|
namespace. |
Uma lista de diretórios separados por dois-pontos para pesquisar bibliotecas compartilhadas quando o AddressSanitizer (ASan) está ativado.
|
Isso indica que, quando o ASan está ativado, o vinculador dinâmico pesquisa primeiro |
namespace. |
Uma lista de diretórios (incluindo subdiretórios) separados por dois-pontos em que
o vinculador dinâmico pode carregar as bibliotecas compartilhadas (além de
As bibliotecas compartilhadas que estão nos subdiretórios de Se |
Isso indica que as bibliotecas compartilhadas em
Por exemplo, sem |
namespace. |
Uma lista separada por dois-pontos de diretórios em que o vinculador dinâmico pode carregar as bibliotecas compartilhadas quando o ASan está ativado.
|
Isso indica que, quando o ASan está ativado, as bibliotecas compartilhadas em |
namespace. |
Um valor booleano que indica se o programa (além de
Se Se |
Isso indica que |
Criação de namespace do vinculador
No Android 11, a configuração do vinculador é criada no tempo de execução em
/linkerconfig
em vez de usar arquivos de texto simples em
${android-src}/system/core/rootdir/etc
. A configuração é gerada na inicialização
com base no ambiente de execução, que inclui os seguintes itens:
- Se o dispositivo for compatível com VNDK
- Versão do VNDK de destino da partição do fornecedor
- Versão do VNDK da partição de produto
- Módulos APEX instalados
A configuração do vinculador é criada resolvendo dependências entre namespaces do vinculador. Por exemplo, se houver atualizações nos módulos APEX que incluem atualizações de dependência, a configuração do vinculador será gerada refletindo essas mudanças. Mais detalhes para criar uma configuração de vinculador
podem ser encontrados em
${android-src}/system/linkerconfig
.
Isolamento do namespace do vinculador
Há três tipos de configuração. Dependendo do valor de
PRODUCT_TREBLE_LINKER_NAMESPACES
e
BOARD_VNDK_VERSION
em BoardConfig.mk
, a
configuração correspondente é gerada na inicialização.
PRODUCT_TREBLE_ LINKER_NAMESPACES |
BOARD_VNDK_ VERSION |
Configuração selecionada | Requisito do VTS |
---|---|---|---|
true |
current |
VNDK |
Obrigatório para dispositivos lançados com o Android 9 ou versões mais recentes |
Vazio | VNDK Lite |
Obrigatório para dispositivos lançados com o Android 8.x | |
false |
Vazio | Legacy |
Para dispositivos que não são Treble |
A configuração do VNDK Lite isola as bibliotecas compartilhadas SP-HAL e VNDK-SP. No Android 8.0, esse
precisa ser o arquivo de configuração do vinculador dinâmico quando
PRODUCT_TREBLE_LINKER_NAMESPACES
é true
.
A configuração do VNDK também isola as bibliotecas compartilhadas SP-HAL e VNDK-SP. Além disso, essa configuração oferece isolamento completo do vinculador dinâmico. Isso garante que os módulos na partição do sistema não dependam das bibliotecas compartilhadas nas partições do fornecedor e vice-versa.
No Android 8.1 ou versões mais recentes, a configuração do VNDK é a padrão. É altamente recomendável ativar o isolamento completo do vinculador dinâmico definindo BOARD_VNDK_VERSION
como current
.
Configuração do VNDK
A configuração do VNDK isola as dependências da biblioteca compartilhada entre a partição do sistema e as partições do fornecedor. Em comparação com as configurações mencionadas na subseção anterior, as diferenças são as seguintes:
-
Processos de framework
- Os namespaces
default
,vndk
,sphal
ers
são criados. - Todos os namespaces são isolados.
- As bibliotecas compartilhadas do sistema são carregadas no namespace
default
. - As SP-HALs são carregadas no namespace
sphal
. - Bibliotecas compartilhadas do VNDK-SP carregadas no namespace
vndk
.
- Os namespaces
-
Processos de fornecedores
- Os namespaces
default
,vndk
esystem
são criados. - O namespace
default
é isolado. - As bibliotecas compartilhadas do fornecedor são carregadas no namespace
default
. - As bibliotecas compartilhadas VNDK e VNDK-SP são carregadas no namespace
vndk
. - O LL-NDK e as dependências dele são carregados no namespace
system
.
- Os namespaces
A relação entre os namespaces do vinculador é ilustrada abaixo.

Figura 1. Isolamento de namespace do vinculador (configuração do VNDK).
Na imagem acima, LL-NDK e VNDK-SP representam as seguintes bibliotecas compartilhadas:
-
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
Confira mais detalhes em /linkerconfig/ld.config.txt
do dispositivo.
Configuração do VNDK Lite
No Android 8.0, o vinculador dinâmico é configurado para isolar as bibliotecas compartilhadas SP-HAL e VNDK-SP para que os símbolos delas não entrem em conflito com outras bibliotecas compartilhadas do framework. A relação entre os namespaces do vinculador é mostrada abaixo.

LL-NDK e VNDK-SP significam as seguintes bibliotecas compartilhadas:
-
LL-NDK
libEGL.so
libGLESv1_CM.so
libGLESv2.so
libc.so
libdl.so
liblog.so
libm.so
libnativewindow.so
libstdc++.so
(não está na configuração)libsync.so
libvndksupport.so
libz.so
(movido para VNDK-SP na configuração)
-
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
A tabela abaixo lista a configuração de namespaces para processos
de framework, extraída da seção [system]
na
configuração do VNDK Lite.
Namespace | Propriedade | 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 |
A tabela abaixo apresenta a configuração de namespaces para processos do fornecedor,
que é extraída da seção [vendor]
na
configuração do VNDK Lite.
Namespace | Propriedade | 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} (descontinuado)/product/${LIB} (descontinuado)
|
isolated |
false |
Confira mais detalhes em /linkerconfig/ld.config.txt
no dispositivo.
Histórico do documento
Mudanças no Android 11
- No Android 11, os arquivos estáticos
ld.config.*.txt
são removidos da base de código, e o LinkerConfig os gera no tempo de execução.
Mudanças no Android 9
- No Android 9, o namespace do vinculador
vndk
é adicionado aos processos do fornecedor, e as bibliotecas compartilhadas do VNDK são isoladas do namespace padrão do vinculador. - Substitua
PRODUCT_FULL_TREBLE
porPRODUCT_TREBLE_LINKER_NAMESPACES
mais específico. - O Android 9 muda os nomes dos seguintes arquivos de configuração do vinculador dinâmico.
Android 8.x Android 9 Descrição ld.config.txt.in
ld.config.txt
Para dispositivos com isolamento de namespace do vinculador de tempo de execução ld.config.txt
ld.config.vndk_lite.txt
Para dispositivos com isolamento de namespace do vinculador VNDK-SP ld.config.legacy.txt
ld.config.legacy.txt
Para dispositivos legados com o Android 7.x ou versões anteriores - O
android.hardware.graphics.allocator@2.0.so
foi removido. - As partições
product
eodm
são adicionadas.