O vinculador dinâmico enfrenta dois desafios no design do Treble VNDK:
- As bibliotecas compartilhadas do SP-HAL e as dependências, incluindo as bibliotecas do VNDK-SP, são carregadas nos processos do framework. Deve haver alguns mecanismos para evitar conflitos de símbolos.
dlopen()
eandroid_dlopen_ext()
podem introduzir algumas dependências de execução que não estão 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 diferentes namespaces de vinculador 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 que são públicas para outros programas, 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 diferentes namespaces de vinculador para que os módulos do framework possam depender de
/system/lib[64]/libcutils.so
e as bibliotecas compartilhadas do 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 de vinculador e importada em
vários namespaces de 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
reside. Outros namespaces não terão acesso a essas dependências. Esse
mecanismo encapsula os detalhes de implementação e fornece as interfaces
públicas.
Como funciona
O vinculador dinâmico é responsável por carregar as bibliotecas compartilhadas especificadas
nas 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 autor da chamada
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 de vinculador 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 INI. Um arquivo de configuração típico tem esta aparência:
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 que o vinculador dinâmico selecione 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 substitutos entre namespaces (arcos do gráfico).
- Cada namespace tem o próprio isolamento, caminhos de pesquisa, caminhos permitidos e configurações de visibilidade.
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 ao qual 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
que têm 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 substitutos. Se uma biblioteca compartilhada não puder ser encontrada no namespace atual, o vinculador dinâmico tentará carregar a biblioteca compartilhada dos namespaces substitutos. O namespace especificado no início da lista tem prioridade maior. |
Se uma biblioteca compartilhada ou um executável solicitar uma biblioteca compartilhada que
não possa ser carregada no namespace Se a biblioteca compartilhada 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 alternativo 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 usar o link substituto
do namespace |
Propriedades de namespace
Propriedade | Descrição | Exemplo |
---|---|---|
namespace. |
Um valor booleano que indica se o vinculador dinâmico precisa verificar onde a biblioteca compartilhada está. Se Se |
Isso indica que apenas as bibliotecas compartilhadas em |
namespace. |
Uma lista de diretórios separada por dois-pontos para pesquisar bibliotecas compartilhadas. Os diretórios especificados em Quando Por exemplo, se |
Isso indica que o vinculador dinâmico procura
|
namespace. |
Uma lista de diretórios separada por dois-pontos para pesquisar bibliotecas compartilhadas quando o AddressSanitizer (ASan) está ativado.
|
Isso indica que, quando
a ASan está ativada, o
vinculador dinâmico pesquisa |
namespace. |
Uma lista de diretórios separada por dois pontos (incluindo subdiretórios) 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 de diretórios separados por dois-pontos 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 (diferente de
Se Se |
Isso indica que |
Criação de namespace do vinculador
No Android 11, a configuração do vinculador é criada no momento da execução em
/linkerconfig
em vez de usar arquivos de texto simples em
${android-src}/system/core/rootdir/etc
. A configuração é gerada no momento da inicialização com base no ambiente de execução, que inclui os seguintes itens:
- Se o dispositivo oferece suporte ao 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 ao resolver as dependências entre os namespaces dele. Por
exemplo, se houver atualizações nos módulos APEX que incluem atualizações de dependência, a configuração
do linker será gerada para refletir essas mudanças. Mais detalhes sobre como criar a configuração do linker
podem ser encontrados em
${android-src}/system/linkerconfig
.
Isolamento de 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 será gerada no momento da inicialização.
PRODUCT_TREBLE_ LINKER_NAMESPACES |
BOARD_VNDK_ VERSION |
Configuração selecionada | Requisito de 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 não agudos |
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
for true
.
A configuração do VNDK também isola as bibliotecas compartilhadas SP-HAL e VNDK-SP. Além disso, essa configuração fornece o isolamento completo do vinculador dinâmico. Ele 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 mais recente, a configuração do VNDK é a configuração padrão
e é 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 do fornecedor. Em comparação com as configurações mencionadas na subseção anterior, as diferenças são descritas da seguinte maneira:
-
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 do fornecedor
- Os namespaces
default
,vndk
esystem
são criados. - O namespace
default
está isolado. - As bibliotecas compartilhadas do fornecedor são carregadas no namespace
default
. - As bibliotecas compartilhadas do VNDK e do 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 linker (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
no dispositivo.
Configuração do VNDK Lite
A partir do Android 8.0, o vinculador dinâmico é configurado para isolar as bibliotecas compartilhadas SP-HAL e VNDK-SP para que os símbolos 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 são 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, que foi extraído 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 o 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 (link em inglês) |
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 |
Mais detalhes podem ser encontrados em /linkerconfig/ld.config.txt
no dispositivo.
Histórico do documento
Mudanças no Android 11
- No Android 11, os arquivos
ld.config.*.txt
estáticos são removidos da base de código, e o LinkerConfig os gera no momento de execução.
Mudanças no Android 9
- No Android 9, o namespace do vinculador
vndk
foi adicionado aos processos do fornecedor, e as bibliotecas compartilhadas do VNDK são isoladas do namespace do vinculador padrão. - Substitua
PRODUCT_FULL_TREBLE
por umPRODUCT_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 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 Android 7.x ou anterior - O
android.hardware.graphics.allocator@2.0.so
foi removido. - As partições
product
eodm
foram adicionadas.