ビルド済み ABI 使用状況チェッカー

Android 共有ライブラリは、随時進化しています。ビルド済みのバイナリを最新の状態に保つにはかなりの労力が必要です。Android 9 以前では、削除されたライブラリや ABI のみに依存するビルド済みのバイナリは実行時にリンクできませんでした。デベロッパーは、古いビルド済みのバイナリを検出するためにログをトレースする必要がありました。Android 10 では、シンボルベースの ABI 使用状況チェッカーが導入されます。チェッカーは、ビルド時に古いビルド済みのバイナリを検出できるので、共有ライブラリのデベロッパーは、変更により無効となった可能性のあるビルド済みのバイナリとビルドし直す必要のあるバイナリを判断できます。

シンボルベースの ABI 使用状況チェッカー

シンボルベースの ABI 使用状況チェッカーは、ホスト上の Android ダイナミック リンカーをエミュレートします。チェッカーは、ビルド済みのバイナリをビルド済みのバイナリの依存関係とリンクし、すべての未定義のシンボルが解決したかどうかを確認します。

まずはじめに、チェッカーはビルド済みバイナリのターゲット アーキテクチャを確認します。ビルド済みのバイナリが、ARM、AArch64、x86、x86-64 アーキテクチャを対象としていない場合、チェッカーはそのビルド済みのバイナリをスキップします。

2 番目に、ビルド済みのバイナリの依存関係は、LOCAL_SHARED_LIBRARIES または shared_libs にリストされる必要があります。ビルドシステムは、モジュール名を共有ライブラリの一致するバリアント(例: corevendor か)に解決します。

3 番目に、チェッカーは、DT_NEEDED エントリを LOCAL_SHARED_LIBRARIES または shared_libs と比較します。具体的には、チェッカーは DT_SONAME エントリを各共有ライブラリから抽出し、これらの DT_SONAME をビルド済みのバイナリに記録された DT_NEEDED エントリと比較します。不一致がある場合は、エラー メッセージが出ます。

4 番目に、チェッカーは、ビルド済みのバイナリの未定義シンボルを解決します。これらの未定義のシンボルは、依存関係のいずれか 1 つに定義される必要があり、シンボル バインディングは GLOBAL または WEAK である必要があります。未定義のシンボルを解決できない場合は、エラー メッセージが出ます。

モジュールのプロパティを事前にビルドする

ビルド済みのバイナリの依存関係は、次のいずれか 1 つに指定する必要があります。

  • Android.bp: shared_libs: ["libc", "libdl", "libm"],
  • Android.mk: LOCAL_SHARED_LIBRARIES := libc libdl libm

ビルド済みのバイナリが未解決の未定義シンボルを持つように設計されている場合は、次のいずれか 1 つを指定します。

  • Android.bp: allow_undefined_symbols: true,
  • Android.mk: LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

ビルド済みのバイナリの ELF ファイル チェックをスキップさせるには、次のいずれか 1 つを指定します。

  • Android.bp: check_elf_files: false,
  • Android.mk: LOCAL_CHECK_ELF_FILES := false

チェッカーを実行する

チェッカーを実行するには、環境変数 CHECK_ELF_FILEStrue に設定してから make check-elf-files を実行します。

CHECK_ELF_FILES=true make check-elf-files
    

デフォルトでチェッカーを有効にするには、PRODUCT_CHECK_ELF_FILESBoardConfig.mk に追加します。

PRODUCT_CHECK_ELF_FILES := true
    

事前にビルドされたものは、Android のビルドプロセス中に自動的に確認されます。

make