Como Validar o Alinhamento de 16KB em APKs, AABs e SOs

Published on: 2025-10-15
Post image
pt android-16kb-validator apk-alignment-check android-so-library-alignment validate-16kb-alignment android-performance-optimization apk-aab-validator-tool llvm-readelf-alignment-check android-native-libs-validator 16kb-compliance-checker android-dev

Este artigo explica como validar se um pacote Android (.apk, .aab) ou um arquivo nativo (.so) tem suporte a páginas de 16KB. A necessidade surge porque, a partir do Android 15, dispositivos podem usar páginas de 16KB em vez das tradicionais 4KB. Bibliotecas nativas desalinhadas podem causar falhas ou incompatibilidades nesses dispositivos. O texto apresenta conceitos, requisitos, uso da ferramenta e formas de correção.

A validação pode ser feita com uma ferramenta Python que analisa os segmentos LOAD dos arquivos ELF dentro do pacote. Essa análise exige o utilitário readelf para extrair o campo de alinhamento. O objetivo é confirmar que o último segmento LOAD das bibliotecas 64-bit tenha alinhamento mínimo de 16384 bytes. A seguir estão explicações detalhadas sobre instalação, execução e interpretação dos resultados.

O que é alinhamento de página e por que 16KB importa

O alinhamento de página determina a fronteira em bytes usada pelo carregador para mapear segmentos na memória. Em arquivos ELF, cada segmento LOAD contém um valor de alinhamento que deve ser uma potência de 2. Para compatibilidade com páginas de 16KB é necessário que esse valor seja pelo menos 16384 bytes. Alinhamentos incorretos podem indicar builds antigos, bibliotecas corrompidas ou ausência de flags de link apropriadas.

Arquiteturas afetadas

Somente as bibliotecas nativas de 64-bit exigem alinhamento de 16KB. Arquiteturas 32-bit continuam a usar páginas de 4KB e não precisam dessa alteração. A detecção pode ocorrer por inspeção do caminho dentro do pacote ou pela leitura do cabeçalho ELF do arquivo. A lista a seguir mostra as arquiteturas de interesse.

  • arm64-v8a — 64-bit ARM, requer 16KB.
  • x86_64 — 64-bit x86, requer 16KB.
  • armeabi-v7a / x86 — 32-bit, continuam com 4KB e não exigem 16KB.

Requisitos e ferramentas

São necessários Python 3.10 ou superior e um executável readelf (GNU ou LLVM) para extrair informações ELF. O validador em Python não requer dependências externas fora da biblioteca padrão. É preciso ter acesso ao arquivo .apk, .aab ou .so a ser analisado e permissão para executar o readelf. A lista a seguir resume os requisitos mínimos.

  • Python 3.10+ instalado no sistema.
  • readelf ou llvm-readelf disponível e executável.
  • Arquivo .apk, .aab ou .so para análise.
  • Permissões de leitura sobre os arquivos e execução do readelf.

Instalando o readelf

A instalação do readelf varia conforme o sistema operacional. Em distribuições Linux o utilitário faz parte do pacote binutils disponível nos repositórios. No macOS o binutils pode ser instalado via Homebrew, que colocará o readelf em uma pasta do usuário. No Windows é comum utilizar MSYS2 e instalar o pacote binutils para obter um readelf funcional.

macOS: brew install binutils
Linux (Debian/Ubuntu): sudo apt-get install binutils
Windows (MSYS2): pacman -S mingw-w64-x86_64-binutils

Instalando o validador em Python

O validador é um projeto Python que analisa pacotes e arquivos .so sem dependências externas. O repositório pode ser clonado e executado localmente com os comandos de controle de versão. Após clonado, o script principal aceita parâmetros para o pacote, o caminho do readelf e o arquivo CSV de saída. A execução gera um resumo no terminal e um CSV com detalhes da análise.

git clone https://github.com/paulocoutinhox/android-16kb-validator.git
cd android-16kb-validator

Uso básico e opções

O uso básico exige informar o caminho do pacote, o executável readelf e um arquivo de saída CSV. O validador aceita flags que especificam cada um desses elementos e grava um CSV com resultados detalhados. O comando retorna um resumo com o alinhamento do último segmento LOAD de cada .so 64-bit e indica conformidade. A lista a seguir mostra as opções principais aceitas pelo comando.

  • --package: caminho para .apk, .aab ou .so a ser validado.
  • --readelf: caminho para o executável readelf ou llvm-readelf.
  • --out: caminho do arquivo CSV de saída (padrão: align-readelf.csv).
python3 main.py --package --readelf --out

Interpretação dos resultados

O relatório resume o último segmento LOAD encontrado em cada .so 64-bit e classifica o alinhamento. Um valor igual a 16384 ou maior e que seja potência de 2 aparece como COMPLIANT. Um valor igual a 4096 aparece como NOT COMPLIANT, indicando que a biblioteca ainda está alinhada para 4KB. Valores que não são potência de 2 aparecem como INVALID ALIGNMENT e podem indicar arquivo corrompido ou erro de parsing.

- .../lib/arm64-v8a/libexemplo.so -> 16384 -> COMPLIANT (16384 bytes)
- .../base/lib/arm64-v8a/libantigo.so -> 4096 -> NOT COMPLIANT (4096 bytes)
- .../lib/arm64-v8a/libestranho.so -> 40912 -> INVALID ALIGNMENT (40912 bytes - não é potência de 2)

Como corrigir bibliotecas não compatíveis

A solução preferencial é atualizar ferramentas de build para versões que aplicam 16KB automaticamente. Quando a atualização não for possível, é viável forçar o tamanho de página máximo durante o link usando flags do linker. Em sistemas que usam CMake ou ndk-build, é possível adicionar o flag -Wl,-z,max-page-size=16384 para as arquiteturas 64-bit. Os exemplos abaixo mostram como aplicar essa opção em CMake e em um Android.mk.

# Ajuste do linker para arm64-v8a
if(ANDROID_ABI STREQUAL "arm64-v8a")
    # Adiciona flag para definir página máxima em 16384 bytes
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
endif()

# Ajuste do linker para x86_64
if(ANDROID_ABI STREQUAL "x86_64")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
endif()
# Android.mk: forçando alinhamento para arm64-v8a e x86_64
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
    # Força página máxima para 16384 bytes
    LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384
endif

ifeq ($(TARGET_ARCH_ABI),x86_64)
    LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384
endif

Detecção de arquitetura e limites

A detecção de bibliotecas 64-bit é feita por inspeção de caminho e por análise do cabeçalho ELF quando necessário. A verificação por caminho busca padrões como /lib/arm64-v8a/ e /lib/x86_64/ dentro do pacote. Para arquivos .so isolados, o cabeçalho ELF confirma se o binário é 64-bit. O validador combina essas duas abordagens para cobrir pacotes AAB/APK e arquivos nativos soltos.

Saída CSV e indicadores de status

Além do resumo textual, a ferramenta grava um CSV com colunas que descrevem cada análise para facilitar investigação e automação. O CSV registra o caminho do arquivo, a linha bruta do LOAD, o valor de alinhamento em texto e em inteiro e o resultado de conformidade. Os estados possíveis no CSV são '16kb', 'not-16kb', 'invalid' e 'unknown', que permitem filtragem rápida. A lista a seguir descreve as colunas presentes no CSV.

  • Filename: caminho completo para o .so.
  • LineText: linha bruta do segmento LOAD proveniente do readelf.
  • Align: valor de alinhamento em formato string (hex ou dec).
  • AlignInt: valor de alinhamento como inteiro.
  • Compliant: status da verificação ('16kb', 'not-16kb', 'invalid', 'unknown').

Solução de problemas comuns

Erros frequentes incluem apontar um caminho inválido para o executável readelf ou não encontrar bibliotecas 64-bit no pacote. Em alguns casos, trocar entre GNU readelf e llvm-readelf corrige discrepâncias de parsing. Quando surgem alinhamentos que não são potência de 2, verificar integridade do .so e reconstruir pode resolver. A lista abaixo traz ações práticas para diagnosticar problemas rapidamente.

  • Verificar se o caminho passado em --readelf é executável e corresponde à versão instalada.
  • Confirmar que o pacote contém bibliotecas em /lib/arm64-v8a/ ou /lib/x86_64/ para validação.
  • Tentar usar llvm-readelf quando valores de alinhamento parecerem inválidos.
  • Recompilar bibliotecas ou atualizar NDK/AGP se o alinhamento permanecer em 4KB.

Resumo prático

A validação garante que bibliotecas 64-bit estejam adequadamente alinhadas para dispositivos com páginas de 16KB. Ferramentas simples como o validador Python junto com readelf permitem identificar problemas antes do lançamento. Atualizar Android Gradle Plugin e NDK resolve a maioria dos casos sem necessidade de ajustes manuais. Quando necessário, flags de linker e reconstrução das bibliotecas corrigem o alinhamento e recuperam compatibilidade.