O vinculador dinâmico aborda dois desafios no design do Treble VNDK:
- Bibliotecas compartilhadas SP-HAL e suas dependências, incluindo bibliotecas VNDK-SP, são carregadas em processos de estrutura. Deve haver 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 são visíveis em tempo de compilação e podem ser difíceis de detectar usando 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 do vinculador para que as bibliotecas com o mesmo nome de biblioteca, mas com símbolos diferentes, não entrem em conflito.
Por outro lado, o mecanismo de namespace do vinculador fornece 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 enquanto ocultam seus detalhes de implementação em seus 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 do vinculador para que os módulos do 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 que é exportada por um namespace de vinculador e importada para muitos namespaces de vinculador. As dependências de /system/lib[64]/libc.so
, como libnetd_client.so
, são carregadas no namespace no qual /system/lib[64]/libc.so
reside. Outros namespaces não terão acesso a essas dependências. Esse mecanismo encapsula os detalhes da implementação enquanto 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 onde o chamador reside e tenta carregar as dependências no mesmo namespace do vinculador. Se o vinculador dinâmico não puder carregar a biblioteca compartilhada no namespace do vinculador especificado, ele solicitará ao namespace do vinculador vinculado as bibliotecas compartilhadas exportadas.
Formato do arquivo de configuração
O formato do arquivo de configuração é baseado no formato do arquivo INI. Um arquivo de configuração típico se parece com isso:
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 de grafos) e vários links de fallback entre namespaces (arcos de grafos).
- Cada namespace tem seu 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 de 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 tenham o mesmo | Isso indica que a configuração especificada na seção A configuração especificada na seção |
Propriedades da relação
Propriedade | Descrição | Exemplo |
---|---|---|
additional. namespaces | Uma lista separada por vírgulas de namespaces adicionais (além do namespace | Isso indica que há três namespaces ( |
namespace. name . links | Uma lista separada por vírgulas de namespaces de fallback. Se uma biblioteca compartilhada não puder ser 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 prioridade mais alta. | Se uma biblioteca compartilhada ou um executável solicitar uma biblioteca compartilhada que não possa ser carregada no namespace E então, se a biblioteca compartilhada também não puder ser carregada do namespace Finalmente, se todas as tentativas falharem, o vinculador dinâmico retornará um erro. |
namespace. name . link. other . shared_libs | Uma lista separada por dois pontos de bibliotecas compartilhadas que podem ser pesquisadas em Esta propriedade não pode ser usada com | Isso indica que o link de fallback aceita apenas |
namespace. name . link. other . allow_all_shared_libs | Um valor booleano que indica se todas as bibliotecas compartilhadas podem ser pesquisadas no Esta propriedade não pode ser usada com | Isso indica que todos os nomes de biblioteca podem percorrer o link de fallback do |
Propriedades do namespace
Propriedade | Descrição | Exemplo |
---|---|---|
namespace. name . isolated | Um valor booleano que indica se o vinculador dinâmico deve verificar onde reside a biblioteca compartilhada. Se Se | Isso indica que apenas as bibliotecas compartilhadas em |
namespace. name . search.paths | Uma lista de diretórios separados por dois pontos para pesquisar bibliotecas compartilhadas. Os diretórios especificados em Quando Por exemplo, se | Isso indica que o vinculador dinâmico pesquisa |
namespace. name . asan.search.paths | Uma lista de diretórios separados por dois pontos para pesquisar bibliotecas compartilhadas quando AddressSanitizer (ASan) está habilitado. | Isso indica que quando o ASan está ativado, o vinculador dinâmico pesquisa |
namespace. name . permitted.paths | Uma lista de diretórios separados por dois pontos (incluindo subdiretórios) onde 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. name . asan.permitted.paths | Uma lista de diretórios separados por dois pontos onde o vinculador dinâmico pode carregar as bibliotecas compartilhadas quando o ASan está habilitado. | Isso indica que quando o ASan está habilitado, as bibliotecas compartilhadas em |
namespace. name . visible | 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 em 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 no momento da inicialização com base no ambiente de tempo de execução, que inclui os seguintes itens:
- Se o dispositivo suportar VNDK
- Versão do VNDK de destino da partição do fornecedor
- Versão do VNDK da partição do produto
- Módulos APEX instalados
A configuração do vinculador é criada resolvendo dependências entre os namespaces do vinculador. Por exemplo, se houver atualizações nos módulos APEX que incluam atualizações de dependência, a configuração do vinculador será gerada refletindo essas alterações. Mais detalhes para criar a configuração do vinculador podem ser encontrados em ${android-src}/system/linkerconfig
.
Isolamento de namespace do vinculador
Existem 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 no momento da inicialização.
PRODUCT_TREBLE_ LINKER_NAMESPACES | BOARD_VNDK_ VERSION | Configuração selecionada | Requisito VTS |
---|---|---|---|
true | current | VNDK | Obrigatório para dispositivos lançados com Android 9 ou superior |
Vazio | VNDK Lite | Obrigatório para dispositivos lançados com 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, este deve 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 superior, a configuração do VNDK é a configuração padrão e é altamente recomendável habilitar 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 descritas a seguir:
Processos de estrutura
-
default
,vndk
,sphal
ers
namespaces são criados. - Todos os namespaces são isolados.
- As bibliotecas compartilhadas do sistema são carregadas no namespace
default
. - SP-HALs são carregados no namespace
sphal
. - Bibliotecas compartilhadas VNDK-SP carregadas no namespace
vndk
.
-
Processos do fornecedor
-
default
,vndk
e namespacessystem
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 suas dependências são carregados no namespace do
system
.
-
A relação entre os namespaces do vinculador é ilustrada abaixo.
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
-
Você pode encontrar mais detalhes em /linkerconfig/ld.config.txt
do 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 seus símbolos não entrem em conflito com outras bibliotecas compartilhadas de estrutura. A relação entre os namespaces do vinculador é mostrada abaixo.
LL-NDK e VNDK-SP representam 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 estrutura, 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 de fornecedor, 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} (obsoleto)/product/${LIB} (obsoleto) |
isolated | false |
Mais detalhes podem ser encontrados em /linkerconfig/ld.config.txt
do dispositivo.
Documento histórico
Alterações do 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 em 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 do vinculador padrão. - Substitua
PRODUCT_FULL_TREBLE
porPRODUCT_TREBLE_LINKER_NAMESPACES
mais específico. - O Android 9 altera 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 Android 7.x ou inferior - Remova
android.hardware.graphics.allocator@2.0.so
. - partições
product
eodm
são adicionadas.