O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Namespace do linker

O vinculador dinâmico enfrenta dois desafios no projeto 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() e android_dlopen_ext() pode introduzir algumas dependências de tempo de execução que não são visíveis em tempo de compilação e pode ser difícil de detectar usando análise estática.

Estes dois desafios podem ser resolvidos pelo mecanismo vinculador namespace. Esse mecanismo é fornecido pelo vinculador dinâmico. Ele pode isolar as bibliotecas compartilhadas em diferentes namespaces de 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 de vinculador fornece flexibilidade para que algumas bibliotecas compartilhadas possam ser exportadas por um namespace de vinculador e usadas por outro namespace de 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 de 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 vinculador para que os módulos de enquadramento pode depender de /system/lib[64]/libcutils.so e SP-HAL bibliotecas compartilhadas pode 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 é exportado por um namespace vinculador e importados para muitos namespaces vinculador. As dependências de /system/lib[64]/libc.so , tais como libnetd_client.so , são carregados no espaço de nomes na qual /system/lib[64]/libc.so reside. Outros namespaces não terão acesso a essas dependências. Este mecanismo encapsula os detalhes de implementação enquanto fornece as interfaces públicas.

Como funciona?

O ligante dinâmico é responsável para o carregamento das bibliotecas compartilhadas especificados em DT_NEEDED entradas ou as bibliotecas compartilhadas especificados 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 pode carregar a biblioteca compartilhada para o namespace ligador especificado, ele pede ao namespace ligador ligado para bibliotecas compartilhadas exportados.

Formato do arquivo de configuração

O formato do arquivo de configuração é baseado no formato de arquivo INI. Um arquivo de configuração típico se parece com isto:

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 de vinculador:
    • Cada seção contém vários namespaces (vértices de gráfico) e vários links de fallback entre namespaces (arcos de gráfico).
    • 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

dir. name

Um caminho para um diretório que o [ name ] seção se aplica.

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 name mas apontam para diretórios diferentes.

dir.system = /system/bin
dir.system = /system/xbin
dir.vendor = /vendor/bin

Isto indica que a configuração especificada no [system] secção aplica-se para os executáveis que são carregados a partir de qualquer /system/bin ou /system/xbin .

A configuração especificada no [vendor] secção aplica-se para os executáveis que são carregados a partir de /vendor/bin .

Propriedades de relação

Propriedade Descrição Exemplo
additional. namespaces

Uma lista separada por vírgulas de espaços de nomes suplementares (para além do default de espaço de nomes) para a secção.

additional. namespaces = sphal, vndk

Isto indica que existem três espaços de nomes ( default , sphal , e vndk ) na [system] configuração.

namespace. name . links

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 de fallback. O namespace especificado no início da lista tem prioridade mais alta.

namespace. sphal. links = default, vndk

Se uma biblioteca compartilhada ou um pedidos executáveis uma biblioteca compartilhada que não pode ser carregado no sphal namespace, as tentativas vinculador dinâmico para carregar a biblioteca compartilhada do default namespace.

E então, se a biblioteca compartilhada não pode ser carregado a partir do default namespace seja, as tentativas vinculador dinâmico para carregar a biblioteca compartilhada do vndk 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 pesquisados nas other namespaces quando essas bibliotecas não podem ser encontradas no name namespace.

Esta propriedade não pode ser usado com namespace. name . link. other . allow_all_shared_libs .

namespace. sphal. link. default. shared_libs = libc.so: libm.so

Isso indica que o link fallback aceita apenas libc.so ou libm.so como o nome da biblioteca solicitado. O vinculador dinâmico ignora o link fallback de sphal ao default namespace se o nome da biblioteca solicitado não está libc.so ou libm.so .

namespace. name . link. other . allow_all_shared_libs

Um valor booleano que indica se todas as bibliotecas compartilhadas podem ser pesquisados no other namespace quando essas bibliotecas não podem ser encontradas no name namespace.

Esta propriedade não pode ser usado com namespace. name . link. other . shared_libs .

namespace. vndk. link. sphal. allow_all_shared_libs = true

Isso indica que todos os nomes de biblioteca pode andar através do link de fallback de vndk para sphal namespace.

Propriedades de 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 isolated é true , apenas as bibliotecas compartilhadas que estão em uma das search.paths directórios (excluindo subdirectórios) ou estão sob uma das permitted.paths directórios (incluindo pastas) pode ser carregado.

Se isolated é false (padrão), o vinculador dinâmico não verifica o caminho de bibliotecas compartilhadas.

namespace. sphal. isolated = true

Isto indica que apenas as bibliotecas compartilhadas em search.paths ou sob permitted.paths pode ser carregado no sphal espaço de nomes.

namespace. name . search.paths

Uma lista de diretórios separados por dois pontos para pesquisar bibliotecas compartilhadas.

Os diretórios especificados na search.paths está anexado ao nome da biblioteca solicitada se as chamadas de função para dlopen() ou DT_NEEDED entradas não especificar o caminho completo. O diretório especificado no início da lista tem prioridade mais alta.

Quando isolated é true bibliotecas, partilhadas que estão em um dos search.paths diretórios (excluindo subdiretórios) pode ser carregado independentemente do permitted.paths propriedade.

Por exemplo, se search.paths é /system/${LIB} e permitted.paths está vazia, /system/${LIB}/libc.so pode ser carregado, mas /system/${LIB}/vndk/libutils.so não pode ser carregado.

namespace. default. search.paths = /system/${LIB}

Isso indica que as pesquisas vinculador dinâmico /system/${LIB} para bibliotecas compartilhadas.

namespace. name . asan.search.paths

Uma lista separada por dois pontos de diretórios de pesquisa para bibliotecas compartilhadas quando AddressSanitizer (Asan) está habilitado.

namespace. name . search.paths é ignorado quando Asan está habilitado.

namespace. default. asan.search.paths = /data/asan/system/${LIB}: /system/${LIB}

Isso indica que, quando Asan está habilitado as pesquisas vinculador dinâmico /data/asan/system/${LIB} primeiro e depois pesquisas /system/${LIB} .

namespace. name . permitted.paths

Uma lista separada por dois pontos de directórios (incluindo pastas) onde o ligante dinâmico pode carregar as bibliotecas compartilhadas (em adição a search.paths ) quando isolated é true .

As bibliotecas compartilhadas que estão sob as subdirectórios de permitted.paths também pode ser carregado. Por exemplo, se permitted.paths é /system/${LIB} , ambos /system/${LIB}/libc.so e /system/${LIB}/vndk/libutils.so pode ser carregado.

Se isolated é false , permitted.paths são ignorados e um aviso é emitido.

namespace. default. permitted.paths = /system/${LIB}/hw

Isso indica que as bibliotecas compartilhadas sob /system/${LIB}/hw pode ser carregado para o isolado default namespace.

Por exemplo, sem permitted.paths , libaudiohal.so pode não carregar /system/${LIB}/hw/audio.a2dp.default.so para o default namespace.

namespace. name . asan.permitted.paths

Uma lista separada por dois pontos de diretórios onde o vinculador dinâmico pode carregar as bibliotecas compartilhadas quando Asan está habilitado.

namespace. name . permitted.paths é ignorado quando Asan está habilitado.

namespace. default. asan.permitted.paths = /data/asan/system/${LIB}/hw: /system/${LIB}/hw

Isso indica que, quando Asan está habilitado bibliotecas compartilhadas sob /data/asan/system/${LIB}/hw ou /system/${LIB}/hw pode ser carregado para o isolado default namespace.

namespace. name . visible

Um valor booleano que indica se o programa (que não libc ) pode obter um identificador vinculador namespace com android_get_exported_namespace() e abrir uma biblioteca compartilhada no espaço de nomes de ligação, passando a alça para android_dlopen_ext() .

Se visible é true , android_get_exported_namespace() sempre retorna a alça se existe a namespace.

Se visible é false (padrão), android_get_exported_namespace() sempre retorna NULL independentemente da presença do namespace. Bibliotecas compartilhadas podem ser carregadas neste namespace apenas se (1) forem solicitadas por outro namespace de vinculador que tenha um link de fallback para este namespace ou (2) forem solicitadas por outras bibliotecas compartilhadas ou executáveis ​​neste namespace.

namespace. sphal. visible = true

Isso indica que android_get_exported_namespace("sphal") pode retornar uma alça de ligação namespace válido.

Criação de namespace de linker

Em Android 11, configuração do ligador é criado em tempo de execução sob /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 for compatível com VNDK
  • Versão de VNDK de destino da partição do fornecedor
  • Versão 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 alguma atualização nos módulos APEX que incluem atualizações de dependência, a configuração do vinculador é gerada refletindo essas mudanças. Mais detalhes para criar configuração do ligador pode ser encontrado em ${android-src}/system/linkerconfig .

Isolamento de namespace do linker

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 do arranque.

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 Treble

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 para vinculador dinâmico quando PRODUCT_TREBLE_LINKER_NAMESPACES é true .

A configuração VNDK também isola as bibliotecas compartilhadas SP-HAL e VNDK-SP. Além disso, essa configuração fornece o isolamento de linker dinâmico completo. 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 superior, configuração VNDK é a configuração padrão e é altamente recomendável para permitir a plena dinâmica isolamento vinculador, definindo BOARD_VNDK_VERSION a current .

Configuração VNDK

A configuração 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 da seguinte forma:

  • Processos de framework

    • default , vndk , sphal e rs namespaces são criados.
    • Todos os namespaces são isolados.
    • Bibliotecas do sistema compartilhada são carregados para o default namespace.
    • SP-HAL são carregados no sphal espaço de nomes.
    • VNDK-SP bibliotecas compartilhadas carregados no vndk namespace.
  • Processos de fornecedores

    • default , vndk e system namespaces são criados.
    • O default namespace é isolado.
    • Bibliotecas de terceiros compartilhada são carregados para o default namespace.
    • VNDK e VNDK-SP bibliotecas compartilhadas são carregados no vndk namespace.
    • LL-NDK e suas dependências são carregados no system espaço de nomes.

O relacionamento entre os namespaces do vinculador é ilustrado a seguir.

Gráfico de namespace do vinculador descrito na configuração VNDK
Figura 1. Ligador isolamento espaço de nomes (configuração VNDK)

Na imagem acima, LL-NDK e estande VNDK-SP para seguir 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 no /linkerconfig/ld.config.txt do dispositivo.

Configuração VNDK Lite

A partir do Android 8.0, o vinculador dinâmico é configurado para isolar as bibliotecas compartilhadas SP-HAL e VNDK-SP de forma que seus símbolos não entrem em conflito com outras bibliotecas compartilhadas da estrutura. O relacionamento entre os namespaces do vinculador é mostrado abaixo.

Gráfico de namespace do vinculador descrito na configuração VNDK Lite
Figura 2. Ligador isolamento espaço de nomes (VNDK Lite configuração)

LL-NDK e VNDK-SP representam seguinte 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 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 os namespaces configuração para processos de enquadramento, que foi extraído do [system] seção na configuração 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 (por 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 (por 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 do RS compilado)
isolated true
visible true
links default,vndk
link.default.shared_libs LL-NDK
libmediandk.so
libft2.so
link.vndk.shared_libs VNDK-SP

A tabela abaixo apresenta os namespaces de configuração para os processos do fornecedor, que foi extraído do [vendor] seção na configuração 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} (reprovado)
/product/${LIB} (reprovado)
isolated false

Mais detalhes podem ser encontrados em /linkerconfig/ld.config.txt do dispositivo.

Documento histórico

Alterações do Android 11

  • Em Android 11, a estática ld.config.*.txt Arquivos são removidos da base de código e LinkerConfig gera-los em tempo de execução em seu lugar.

Android 9 changes

  • Em Android 9, o vndk vinculador namespace é adicionado aos processos de fornecedores e VNDK bibliotecas compartilhadas estão isolados do namespace vinculador padrão.
  • Substitua PRODUCT_FULL_TREBLE com mais específicos PRODUCT_TREBLE_LINKER_NAMESPACES .
  • 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 em 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
  • Remover android.hardware.graphics.allocator@2.0.so .
  • product e odm partições são adicionadas.