Namespace do vinculador

O vinculador dinâmico enfrenta dois desafios no design do VNDK do Treble:

  • Bibliotecas compartilhadas SP-HAL e respectivas dependências, incluindo VNDK-SP são carregados nos processos de framework. Deve haver algumas para evitar conflitos de símbolos.
  • dlopen() e android_dlopen_ext() podem introduzir com algumas dependências de tempo de execução que não são visíveis no tempo de build e podem ser difíceis de detectar usando a análise estática.

Esses dois desafios podem ser resolvidos pelo namespace do vinculador. mecanismo de atenção. Esse mecanismo é fornecido pelo vinculador dinâmico. Ela pode isolar as bibliotecas compartilhadas em diferentes namespaces do vinculador para que bibliotecas com o mesmo nome, mas com símbolos diferentes, não entrarão em conflito.

Por outro lado, o mecanismo de namespace do vinculador oferece a flexibilidade de modo que algumas bibliotecas compartilhadas podem 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 do aplicativo públicas para outros programas, ocultar 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 dois compartilhados bibliotecas. 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 As bibliotecas compartilhadas /system/lib[64]/libcutils.so e SP-HAL podem dependem 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 do vinculador e importada para o vários namespaces do vinculador. As dependências /system/lib[64]/libc.so, como libnetd_client.so, são carregados no namespace em que /system/lib[64]/libc.so reside. Outros namespaces não terão acesso a essas dependências. Isso mecanismo encapsula os detalhes da implementação enquanto fornece ao público do Google Cloud.

Como funciona

O vinculador dinâmico é responsável por carregar as bibliotecas compartilhadas especificadas. nas entradas DT_NEEDED ou nas bibliotecas compartilhadas especificadas pelo de dlopen() ou android_dlopen_ext(). Em ambos 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 pode carregar a biblioteca compartilhada no vinculador especificado. namespace, ele solicita ao namespace do vinculador vinculado para bibliotecas.

Formato do arquivo de configurações

O formato do arquivo de configuração é baseado no formato de arquivo INI. Uma configuração típica de configuração é semelhante a este:

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 da seção de diretório no início do vinculador dinâmico para selecionar a seção efetiva.
  • Várias seções de configuração de namespaces do vinculador:
    • Cada seção contém diversos namespaces (vértices do gráfico) e diversos links de fallback entre namespaces (arcos do gráfico).
    • Cada namespace tem isolamento, caminhos de pesquisa e caminhos permitidos próprios, e as configurações de visibilidade.

As tabelas abaixo descrevem o significado de cada propriedade em detalhes.

Propriedade de mapeamento da seção do diretório

Propriedade Descrição Exemplo

dir.name

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

Cada propriedade mapeia os executáveis no diretório para um vinculador na seção de configuração dos namespaces. Pode haver duas (ou mais) propriedades que têm o mesmo name, mas apontam para diferentes diretórios.

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

Isso indica que a configuração especificada no A seção [system] se aplica aos executáveis carregados de /system/bin ou /system/xbin.

A configuração especificada na seção [vendor] se aplica aos executáveis carregados de /vendor/bin.

Propriedades de relação

Propriedade Descrição Exemplo
additional.namespaces

Uma lista separada por vírgulas de namespaces adicionais (além dos default) para a seção.

additional.namespaces = sphal,vndk

Isso indica que há três namespaces (default, sphal e vndk) no [system] configuração do Terraform.

namespace.name.links

Uma lista separada por vírgulas de namespaces substitutos.

Se não for possível encontrar uma biblioteca compartilhada no namespace atual, a biblioteca dinâmica o vinculador tenta carregar a biblioteca compartilhada a partir dos namespaces substitutos. A especificado no início da lista tem maior prioridade.

namespace.sphal.links = default,vndk

Se uma biblioteca compartilhada ou um executável solicita uma biblioteca compartilhada que não pode ser carregado no namespace sphal, o vinculador dinâmico. tenta carregar a biblioteca compartilhada do default .

Se não for possível carregar a biblioteca compartilhada pelo default, o vinculador dinâmico tentará carregar o biblioteca compartilhada do namespace vndk.

Por fim, 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 na other namespaces quando essas bibliotecas não podem ser encontradas nos name.

Não é possível usar esta propriedade com namespace.name.link.other.allow_all_shared_libs:

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

Isso indica que o link substituto aceita apenas libc.so. ou libm.so como o nome da biblioteca solicitada. Vinculador dinâmico ignora o link substituto de sphal para default caso o nome da biblioteca solicitada não seja 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 pesquisado no namespace other quando essas bibliotecas não podem ser encontradas no namespace name.

Não é possível usar esta propriedade com namespace.name.link.other.shared_libs:

namespace.vndk.link.sphal.allow_all_shared_libs = true

Isso indica que todos os nomes de biblioteca podem passar pelo link substituto do namespace vndk a sphal.

Propriedades de namespace

Propriedade Descrição Exemplo
namespace.name.isolated

Um valor booleano que indica se o vinculador dinâmico deve verificar onde fica a biblioteca compartilhada.

Se isolated for true, somente as bibliotecas compartilhadas que estão em um dos diretórios search.paths (excluindo subdiretórios) ou estão em um dos Diretórios permitted.paths (incluindo subdiretórios) podem ser carregado.

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

namespace.sphal.isolated = true

Isso indica que apenas as bibliotecas compartilhadas search.paths ou menos de permitted.paths podem ser carregados no namespace sphal.

namespace.name.search.paths

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

Os diretórios especificados em search.paths são anexados ao início para o nome da biblioteca solicitada se a função chamar dlopen() ou As entradas DT_NEEDED não especificam o caminho completo. O diretório especificado no início da lista tem maior prioridade.

Quando isolated for true, as bibliotecas compartilhadas que estão em um dos diretórios search.paths (exceto subdiretórios) podem ser carregados independentemente dos permitted.paths .

Por exemplo, se search.paths for /system/${LIB} e permitted.paths estão vazios, /system/${LIB}/libc.so pode ser carregado, mas Não foi possível carregar /system/${LIB}/vndk/libutils.so.

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

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

namespace.name.asan.search.paths

Uma lista de diretórios separada por dois-pontos para pesquisar bibliotecas compartilhadas quando: O AddressSanitizer (ASan) está ativado.

namespace.name.search.paths é ignorado quando o ASan é ativado.

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

Isso indica que, quando ASan está ativado o vinculador dinâmico pesquisa /data/asan/system/${LIB} primeiro e em seguida, pesquisa /system/${LIB}.

namespace.name.permitted.paths

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 search.paths) quando isolated for true

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

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

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

Isso indica que as bibliotecas compartilhadas em /system/${LIB}/hw pode ser carregado no arquivo default.

Por exemplo, sem permitted.paths, Não é possível carregar libaudiohal.so /system/${LIB}/hw/audio.a2dp.default.so no default.

namespace.name.asan.permitted.paths

Uma lista de diretórios separada por dois-pontos em que o vinculador dinâmico pode ser carregado. as bibliotecas compartilhadas quando o ASan está ativado.

namespace.name.permitted.paths é ignorado quando o ASan está ativado.

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

Isso indica que, quando o ASan está ativado bibliotecas compartilhadas em /data/asan/system/${LIB}/hw ou /system/${LIB}/hw pode ser carregado no arquivo default.

namespace.name.visible

Um valor booleano que indica se o programa (diferente de libc) pode conseguir um identificador de namespace do vinculador com android_get_exported_namespace() e abrir uma biblioteca compartilhada em o namespace do vinculador passando o identificador para android_dlopen_ext()

Se visible for true, android_get_exported_namespace() sempre retorna o identificador se o namespace existe.

Se visible for false (padrão), android_get_exported_namespace() sempre retorna. NULL, independentemente da presença do namespace. Bibliotecas compartilhadas só podem ser carregados nesse namespace se (1) forem solicitados por outro namespace do vinculador que tenha um link de fallback para esse namespace ou (2) eles são solicitados por outras bibliotecas ou executáveis compartilhados neste namespace.

namespace.sphal.visible = true

Isso indica que android_get_exported_namespace("sphal") pode retornar um identificador válido do namespace do vinculador.

Criação de namespace do vinculador

No Android 11, a configuração do vinculador é criada durante a 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 tempo com base no ambiente de execução, que inclui os seguintes itens:

  • Se o dispositivo oferecer suporte ao VNDK
  • Versão de destino do VNDK da partição do fornecedor
  • Versão do VNDK da partição de produtos
  • Módulos APEX instalados

A configuração do vinculador é criada ao resolver as dependências entre os namespaces dele. Para exemplo, se há atualizações nos módulos APEX que incluem atualizações de dependência, o vinculador configuração é gerada refletindo essas alterações. Mais detalhes para criar a configuração do vinculador podem ser encontradas em ${android-src}/system/linkerconfig

Isolamento de namespace do vinculador

Há três tipos de configuração. Dependendo do valor 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 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, 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 fornece o isolamento completo do vinculador dinâmico. Isso garante que os módulos na partição do sistema não dependam da bibliotecas nas partições do fornecedor e vice-versa.

No Android 8.1 ou versões mais recentes, a configuração do VNDK é a configuração padrão É altamente recomendável ativar o isolamento total do vinculador dinâmico configurando BOARD_VNDK_VERSION para current.

Configuração do VNDK

A configuração do VNDK isola as dependências da biblioteca compartilhada. entre as partições do sistema e do fornecedor. Comparado a mencionadas na subseção anterior, as diferenças são descritos da seguinte forma:

  • Processos do framework

    • default, vndk. os namespaces sphal e rs são criados.
    • Todos os namespaces estão isolados.
    • As bibliotecas compartilhadas do sistema são carregadas no namespace default.
    • SP-HALs são carregadas no namespace sphal.
    • Bibliotecas compartilhadas VNDK-SP carregadas no namespace vndk.
  • Processos do fornecedor

    • Os namespaces default, vndk e system são criados.
    • O namespace default está 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.

A relação entre os namespaces do vinculador é ilustrada abaixo.

Gráfico de namespace do vinculador descrito na configuração do VNDK

Figura 1. Isolamento de namespace do vinculador (configuração de VNDK).

Na imagem acima, LL-NDK e VNDK-SP significam o seguinte: bibliotecas compartilhadas:

  • LL-NDK (link em inglês)
    • 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 (link em inglês)
    • 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 a SP-HAL e Bibliotecas compartilhadas do VNDK-SP para que os símbolos não entrem em conflito com outros bibliotecas compartilhadas do framework. A relação entre os namespaces do vinculador é mostradas abaixo.

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

LL-NDK e VNDK-SP significam as seguintes bibliotecas compartilhadas:

  • LL-NDK (link em inglês)
    • 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 em a configuração)
  • VNDK-SP (link em inglês)
    • 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 o framework processos, que foi extraído da seção [system] do a 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 em inglês)
link.vndk.shared_libs VNDK-SP (link em inglês)
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 (link em inglês)
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} e
/vendor/${LIB} e
/data (para kernel de 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 (link em inglês)

A tabela abaixo apresenta a configuração de namespaces para processos do fornecedor. que foi extraído da seção [vendor] do a configuração do VNDK Lite.

Namespace Propriedade Valor
default search.paths /odm/${LIB} e
/odm/${LIB}/vndk e
/odm/${LIB}/vndk-sp e

de /vendor/${LIB} /vendor/${LIB}/vndk e
/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 ambiente de execução.

Mudanças no Android 9

  • No Android 9, o namespace do vinculador vndk é adicionado ao fornecedor Processos e bibliotecas compartilhadas do VNDK são isolados do vinculador padrão .
  • Substitua PRODUCT_FULL_TREBLE por uma opção mais específica PRODUCT_TREBLE_LINKER_NAMESPACES.
  • O Android 9 muda os nomes da seguinte 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 ambiente 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 e odm foram adicionadas.