Stabilitas ABI

Stabilitas Antarmuka Biner Aplikasi (ABI) adalah prasyarat pembaruan kerangka saja karena modul vendor mungkin bergantung pada pustaka bersama Vendor Native Development Kit (VNDK) yang berada di partisi sistem. Dalam rilis Android, pustaka bersama VNDK yang baru dibuat harus kompatibel dengan ABI dengan pustaka bersama VNDK yang dirilis sebelumnya sehingga modul vendor dapat bekerja dengan pustaka tersebut tanpa kompilasi ulang dan tanpa kesalahan waktu proses. Di antara rilis Android, pustaka VNDK dapat diubah dan tidak ada jaminan ABI.

Untuk membantu memastikan kompatibilitas ABI, Android 9 menyertakan pemeriksa ABI header, seperti dijelaskan di bagian berikut.

Tentang kepatuhan VNDK dan ABI

VNDK adalah sekumpulan pustaka terbatas yang dapat ditautkan oleh modul vendor dan yang memungkinkan pembaruan kerangka kerja saja. Kepatuhan ABI mengacu pada kemampuan versi terbaru dari pustaka bersama untuk berfungsi seperti yang diharapkan dengan modul yang terhubung secara dinamis dengannya (yaitu berfungsi sebagaimana versi pustaka yang lebih lama).

Tentang simbol yang diekspor

Simbol yang diekspor (juga dikenal sebagai simbol global ) mengacu pada simbol yang memenuhi semua hal berikut:

  • Diekspor oleh header publik perpustakaan bersama.
  • Muncul di tabel .dynsym dari file .so yang sesuai dengan perpustakaan bersama.
  • Memiliki pengikatan LEMAH atau GLOBAL.
  • Visibilitas adalah DEFAULT atau DILINDUNGI.
  • Indeks bagian tidak TERDEFINISIKAN.
  • Jenisnya adalah FUNC atau OBJECT.

Header publik dari pustaka bersama didefinisikan sebagai header yang tersedia untuk pustaka/biner lain melalui atribut export_include_dirs , export_header_lib_headers , export_static_lib_headers , export_shared_lib_headers , dan export_generated_headers dalam definisi Android.bp dari modul yang terkait dengan pustaka bersama.

Tentang tipe yang dapat dijangkau

Tipe yang dapat dijangkau adalah tipe bawaan C/C++ atau yang ditentukan pengguna yang dapat dijangkau secara langsung atau tidak langsung melalui simbol yang diekspor DAN diekspor melalui header publik. Misalnya, libfoo.so memiliki fungsi Foo , yang merupakan simbol yang diekspor yang ditemukan di tabel .dynsym . Pustaka libfoo.so mencakup yang berikut ini:

foo_exported.h foo.private.h
typedef struct foo_private foo_private_t;

typedef struct foo {
  int m1;
  int *m2;
  foo_private_t *mPfoo;
} foo_t;

typedef struct bar {
  foo_t mfoo;
} bar_t;

bool Foo(int id, bar_t *bar_ptr);
typedef struct foo_private {
  int m1;
  float mbar;
} foo_private_t;
Android.bp
cc_library {
  name : libfoo,
  vendor_available: true,
  vndk {
    enabled : true,
  }
  srcs : ["src/*.cpp"],
  export_include_dirs : [
    "exported"
  ],
}
tabel .dynsym
Num Value Size Type Bind Vis Ndx Name
1 0 0 FUNC GLOB DEF UND dlerror@libc
2 1ce0 20 FUNC GLOB DEF 12 Foo

Melihat Foo , jenis yang dapat dijangkau langsung/tidak langsung meliputi:

Jenis Keterangan
bool Jenis pengembalian Foo .
int Jenis parameter Foo pertama.
bar_t * Jenis parameter Foo kedua. Melalui bar_t * , bar_t diekspor melalui foo_exported.h .

bar_t berisi anggota mfoo , bertipe foo_t , yang diekspor melalui foo_exported.h , sehingga menghasilkan lebih banyak tipe yang diekspor:
  • int : adalah tipe m1 .
  • int * : adalah tipe m2 .
  • foo_private_t * : adalah tipe mPfoo .

Namun, foo_private_t TIDAK dapat dijangkau karena tidak diekspor melalui foo_exported.h . ( foo_private_t * buram, oleh karena itu perubahan yang dilakukan pada foo_private_t diperbolehkan.)

Penjelasan serupa dapat diberikan untuk tipe yang dapat dijangkau melalui penentu kelas dasar dan parameter templat juga.

Memastikan kepatuhan ABI

Kepatuhan ABI harus dipastikan untuk pustaka yang ditandai vendor_available: true dan vndk.enabled: true di file Android.bp yang sesuai. Misalnya:

cc_library {
    name: "libvndk_example",
    vendor_available: true,
    vndk: {
        enabled: true,
    }
}

Untuk tipe data yang dapat dijangkau secara langsung atau tidak langsung oleh fungsi yang diekspor, perubahan berikut pada pustaka diklasifikasikan sebagai pemecah ABI:

Tipe data Keterangan
Struktur dan Kelas
  • Ubah ukuran tipe kelas atau tipe struct.
  • Kelas dasar
    • Menambah atau menghapus kelas dasar.
    • Menambah atau menghapus kelas dasar yang diwarisi secara virtual.
    • Ubah urutan kelas dasar.
  • Fungsi anggota
    • Hapus fungsi anggota*.
    • Menambah atau menghapus argumen dari fungsi anggota.
    • Mengubah tipe argumen atau tipe kembalian fungsi anggota*.
    • Ubah tata letak tabel virtual.
  • Anggota data
    • Hapus anggota data statis.
    • Menambah atau menghapus anggota data non-statis.
    • Ubah tipe anggota data.
    • Ubah offset menjadi anggota data non-statis**.
    • Ubah kualifikasi anggota data const , volatile , dan/atau restricted ***.
    • Turunkan versi penentu akses anggota data***.
  • Ubah argumen templat.
Serikat pekerja
  • Menambah atau menghapus anggota data.
  • Ubah ukuran tipe gabungan.
  • Ubah tipe anggota data.
Pencacahan
  • Ubah tipe yang mendasarinya.
  • Ubah nama enumerator.
  • Ubah nilai enumerator.
Simbol Global
  • Hapus simbol yang diekspor oleh header publik.
  • Untuk simbol global bertipe FUNC
    • Menambah atau menghapus argumen.
    • Ubah tipe argumen.
    • Ubah jenis pengembalian.
    • Turunkan versi penentu akses***.
  • Untuk simbol global bertipe OBJECT
    • Ubah tipe C/C++ yang sesuai.
    • Turunkan versi penentu akses***.

* Fungsi anggota publik dan privat tidak boleh diubah atau dihapus karena fungsi inline publik dapat merujuk pada fungsi anggota privat. Referensi simbol ke fungsi anggota privat dapat disimpan dalam biner pemanggil. Mengubah atau menghapus fungsi anggota pribadi dari perpustakaan bersama dapat mengakibatkan biner tidak kompatibel.

** Offset ke anggota data publik atau pribadi tidak boleh diubah karena fungsi inline dapat merujuk ke anggota data ini di isi fungsinya. Mengubah offset anggota data dapat mengakibatkan biner tidak kompatibel.

*** Meskipun hal ini tidak mengubah tata letak jenis memori, terdapat perbedaan semantik yang dapat menyebabkan perpustakaan tidak berfungsi seperti yang diharapkan.

Menggunakan alat kepatuhan ABI

Ketika perpustakaan VNDK dibangun, ABI perpustakaan dibandingkan dengan referensi ABI yang sesuai untuk versi VNDK yang sedang dibangun. Referensi dump ABI terletak di:

${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/<PLATFORM_VNDK_VERSION>/<BINDER_BITNESS>/<ARCH>/source-based

Misalnya, saat membuat libfoo untuk x86 di API level 27, ABI yang disimpulkan libfoo dibandingkan dengan referensinya di:

${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/27/64/x86/source-based/libfoo.so.lsdump

Kesalahan kerusakan ABI

Pada kerusakan ABI, log build menampilkan peringatan dengan jenis peringatan dan jalur ke laporan abi-diff. Misalnya, jika ABI libbinder memiliki perubahan yang tidak kompatibel, sistem build akan menampilkan kesalahan dengan pesan serupa berikut:

*****************************************************
error: VNDK library: libbinder.so's ABI has INCOMPATIBLE CHANGES
Please check compatibility report at:
out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm64_armv8-a_cortex-a73_vendor_shared/libbinder.so.abidiff
******************************************************
---- Please update abi references by running
platform/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l libbinder ----

Membangun pemeriksaan ABI perpustakaan VNDK

Saat perpustakaan VNDK dibangun:

  1. header-abi-dumper memproses file sumber yang dikompilasi untuk membangun perpustakaan VNDK (file sumber milik perpustakaan serta file sumber yang diwarisi melalui dependensi transitif statis), untuk menghasilkan file .sdump yang sesuai dengan setiap sumber.
    sdump creation
    Gambar 1. Membuat file .sdump
  2. header-abi-linker kemudian memproses file .sdump (menggunakan skrip versi yang disediakan atau file .so yang sesuai dengan perpustakaan bersama) untuk menghasilkan file .lsdump yang mencatat semua informasi ABI yang terkait dengan perpustakaan bersama.
    lsdump creation
    Gambar 2. Membuat file .lsdump
  3. header-abi-diff membandingkan file .lsdump dengan file .lsdump referensi untuk menghasilkan laporan perbedaan yang menguraikan perbedaan ABI kedua perpustakaan.
    abi diff creation
    Gambar 3. Membuat laporan perbedaan

header-abi-dumper

Alat header-abi-dumper mem-parsing file sumber C/C++ dan membuang kesimpulan ABI dari file sumber tersebut ke file perantara. Sistem pembangunan menjalankan header-abi-dumper pada semua file sumber yang dikompilasi sekaligus membangun perpustakaan yang menyertakan file sumber dari dependensi transitif.

masukan
  • File sumber AC/C++
  • Diekspor termasuk direktori
  • Bendera kompiler
Keluaran File yang menjelaskan ABI file sumber (misalnya, foo.sdump mewakili ABI foo.cpp ).

Saat ini file .sdump dalam format JSON, yang tidak dijamin stabil pada rilis mendatang. Oleh karena itu, pemformatan file .sdump harus dianggap sebagai detail implementasi sistem build.

Misalnya, libfoo.so memiliki file sumber berikut foo.cpp :

#include <stdio.h>
#include <foo_exported.h>

bool Foo(int id, bar_t *bar_ptr) {
    if (id > 0 && bar_ptr->mfoo.m1 > 0) {
        return true;
    }
    return false;
}

Anda dapat menggunakan header-abi-dumper untuk menghasilkan file .sdump perantara yang mewakili ABI yang disajikan oleh file sumber menggunakan:

$ header-abi-dumper foo.cpp -I exported -o foo.sdump -- -I exported -x c++

Perintah ini memberitahu header-abi-dumper untuk mengurai foo.cpp dengan flag compiler berikut -- , dan mengeluarkan informasi ABI yang diekspor oleh header publik di direktori exported . Berikut ini adalah foo.sdump yang dihasilkan oleh header-abi-dumper :

{
 "array_types" : [],
 "builtin_types" :
 [
  {
   "alignment" : 4,
   "is_integral" : true,
   "linker_set_key" : "_ZTIi",
   "name" : "int",
   "referenced_type" : "_ZTIi",
   "self_type" : "_ZTIi",
   "size" : 4
  }
 ],
 "elf_functions" : [],
 "elf_objects" : [],
 "enum_types" : [],
 "function_types" : [],
 "functions" :
 [
  {
   "function_name" : "FooBad",
   "linker_set_key" : "_Z6FooBadiP3foo",
   "parameters" :
   [
    {
     "referenced_type" : "_ZTIi"
    },
    {
     "referenced_type" : "_ZTIP3foo"
    }
   ],
   "return_type" : "_ZTI3bar",
   "source_file" : "exported/foo_exported.h"
  }
 ],
 "global_vars" : [],
 "lvalue_reference_types" : [],
 "pointer_types" :
 [
  {
   "alignment" : 8,
   "linker_set_key" : "_ZTIP11foo_private",
   "name" : "foo_private *",
   "referenced_type" : "_ZTI11foo_private",
   "self_type" : "_ZTIP11foo_private",
   "size" : 8,
   "source_file" : "exported/foo_exported.h"
  },
  {
   "alignment" : 8,
   "linker_set_key" : "_ZTIP3foo",
   "name" : "foo *",
   "referenced_type" : "_ZTI3foo",
   "self_type" : "_ZTIP3foo",
   "size" : 8,
   "source_file" : "exported/foo_exported.h"
  },
  {
   "alignment" : 8,
   "linker_set_key" : "_ZTIPi",
   "name" : "int *",
   "referenced_type" : "_ZTIi",
   "self_type" : "_ZTIPi",
   "size" : 8,
   "source_file" : "exported/foo_exported.h"
  }
 ],
 "qualified_types" : [],
 "record_types" :
 [
  {
   "alignment" : 8,
   "fields" :
   [
    {
     "field_name" : "mfoo",
     "referenced_type" : "_ZTI3foo"
    }
   ],
   "linker_set_key" : "_ZTI3bar",
   "name" : "bar",
   "referenced_type" : "_ZTI3bar",
   "self_type" : "_ZTI3bar",
   "size" : 24,
   "source_file" : "exported/foo_exported.h"
  },
  {
   "alignment" : 8,
   "fields" :
   [
    {
     "field_name" : "m1",
     "referenced_type" : "_ZTIi"
    },
    {
     "field_name" : "m2",
     "field_offset" : 64,
     "referenced_type" : "_ZTIPi"
    },
    {
     "field_name" : "mPfoo",
     "field_offset" : 128,
     "referenced_type" : "_ZTIP11foo_private"
    }
   ],
   "linker_set_key" : "_ZTI3foo",
   "name" : "foo",
   "referenced_type" : "_ZTI3foo",
   "self_type" : "_ZTI3foo",
   "size" : 24,
   "source_file" : "exported/foo_exported.h"
  }
 ],
 "rvalue_reference_types" : []
}

foo.sdump berisi informasi ABI yang diekspor oleh file sumber foo.cpp dan header publik, misalnya,

  • record_types . Merujuk pada struct, union, atau kelas yang ditentukan dalam header publik. Setiap jenis rekaman memiliki informasi tentang bidangnya, ukurannya, penentu akses, file header yang ditentukan, dan atribut lainnya.
  • pointer_types . Merujuk ke tipe penunjuk yang direferensikan secara langsung/tidak langsung oleh catatan/fungsi yang diekspor di header publik, bersama dengan tipe yang ditunjuk oleh penunjuk (melalui bidang referenced_type di type_info ). Informasi serupa dicatat dalam file .sdump untuk tipe yang memenuhi syarat, tipe C/C++ bawaan, tipe array, dan tipe referensi lvalue dan rvalue. Informasi tersebut memungkinkan diffing rekursif.
  • functions . Mewakili fungsi yang diekspor oleh header publik. Mereka juga memiliki informasi tentang nama fungsi yang rusak, tipe kembalian, tipe parameter, penentu akses, dan atribut lainnya.

header-abi-linker

Alat header-abi-linker mengambil file perantara yang dihasilkan oleh header-abi-dumper sebagai masukan lalu menautkan file-file tersebut:

masukan
  • File perantara yang dihasilkan oleh header-abi-dumper
  • Skrip versi/file Peta (opsional)
  • .so file perpustakaan bersama
  • Diekspor termasuk direktori
Keluaran File yang menjelaskan ABI perpustakaan bersama (misalnya, libfoo.so.lsdump mewakili ABI libfoo ).

Alat ini menggabungkan grafik tipe di semua file perantara yang diberikan padanya, dengan mempertimbangkan perbedaan satu definisi (tipe yang ditentukan pengguna dalam unit terjemahan berbeda dengan nama yang sepenuhnya memenuhi syarat yang sama, mungkin berbeda secara semantik) di seluruh unit terjemahan. Alat tersebut kemudian mem-parsing skrip versi atau tabel .dynsym dari perpustakaan bersama (file .so ) untuk membuat daftar simbol yang diekspor.

Misalnya, libfoo terdiri dari foo.cpp dan bar.cpp . header-abi-linker dapat dipanggil untuk membuat dump ABI libfoo tertaut lengkap sebagai berikut:

header-abi-linker -I exported foo.sdump bar.sdump \
                  -o libfoo.so.lsdump \
                  -so libfoo.so \
                  -arch arm64 -api current

Contoh keluaran perintah di libfoo.so.lsdump :

{
 "array_types" : [],
 "builtin_types" :
 [
  {
   "alignment" : 1,
   "is_integral" : true,
   "is_unsigned" : true,
   "linker_set_key" : "_ZTIb",
   "name" : "bool",
   "referenced_type" : "_ZTIb",
   "self_type" : "_ZTIb",
   "size" : 1
  },
  {
   "alignment" : 4,
   "is_integral" : true,
   "linker_set_key" : "_ZTIi",
   "name" : "int",
   "referenced_type" : "_ZTIi",
   "self_type" : "_ZTIi",
   "size" : 4
  }
 ],
 "elf_functions" :
 [
  {
   "name" : "_Z3FooiP3bar"
  },
  {
   "name" : "_Z6FooBadiP3foo"
  }
 ],
 "elf_objects" : [],
 "enum_types" : [],
 "function_types" : [],
 "functions" :
 [
  {
   "function_name" : "Foo",
   "linker_set_key" : "_Z3FooiP3bar",
   "parameters" :
   [
    {
     "referenced_type" : "_ZTIi"
    },
    {
     "referenced_type" : "_ZTIP3bar"
    }
   ],
   "return_type" : "_ZTIb",
   "source_file" : "exported/foo_exported.h"
  },
  {
   "function_name" : "FooBad",
   "linker_set_key" : "_Z6FooBadiP3foo",
   "parameters" :
   [
    {
     "referenced_type" : "_ZTIi"
    },
    {
     "referenced_type" : "_ZTIP3foo"
    }
   ],
   "return_type" : "_ZTI3bar",
   "source_file" : "exported/foo_exported.h"
  }
 ],
 "global_vars" : [],
 "lvalue_reference_types" : [],
 "pointer_types" :
 [
  {
   "alignment" : 8,
   "linker_set_key" : "_ZTIP11foo_private",
   "name" : "foo_private *",
   "referenced_type" : "_ZTI11foo_private",
   "self_type" : "_ZTIP11foo_private",
   "size" : 8,
   "source_file" : "exported/foo_exported.h"
  },
  {
   "alignment" : 8,
   "linker_set_key" : "_ZTIP3bar",
   "name" : "bar *",
   "referenced_type" : "_ZTI3bar",
   "self_type" : "_ZTIP3bar",
   "size" : 8,
   "source_file" : "exported/foo_exported.h"
  },
  {
   "alignment" : 8,
   "linker_set_key" : "_ZTIP3foo",
   "name" : "foo *",
   "referenced_type" : "_ZTI3foo",
   "self_type" : "_ZTIP3foo",
   "size" : 8,
   "source_file" : "exported/foo_exported.h"
  },
  {
   "alignment" : 8,
   "linker_set_key" : "_ZTIPi",
   "name" : "int *",
   "referenced_type" : "_ZTIi",
   "self_type" : "_ZTIPi",
   "size" : 8,
   "source_file" : "exported/foo_exported.h"
  }
 ],
 "qualified_types" : [],
 "record_types" :
 [
  {
   "alignment" : 8,
   "fields" :
   [
    {
     "field_name" : "mfoo",
     "referenced_type" : "_ZTI3foo"
    }
   ],
   "linker_set_key" : "_ZTI3bar",
   "name" : "bar",
   "referenced_type" : "_ZTI3bar",
   "self_type" : "_ZTI3bar",
   "size" : 24,
   "source_file" : "exported/foo_exported.h"
  },
  {
   "alignment" : 8,
   "fields" :
   [
    {
     "field_name" : "m1",
     "referenced_type" : "_ZTIi"
    },
    {
     "field_name" : "m2",
     "field_offset" : 64,
     "referenced_type" : "_ZTIPi"
    },
    {
     "field_name" : "mPfoo",
     "field_offset" : 128,
     "referenced_type" : "_ZTIP11foo_private"
    }
   ],
   "linker_set_key" : "_ZTI3foo",
   "name" : "foo",
   "referenced_type" : "_ZTI3foo",
   "self_type" : "_ZTI3foo",
   "size" : 24,
   "source_file" : "exported/foo_exported.h"
  }
 ],
 "rvalue_reference_types" : []
}

Alat header-abi-linker :

  • Tautkan file .sdump yang disediakan ke dalamnya ( foo.sdump dan bar.sdump ), menyaring informasi ABI yang tidak ada di header yang berada di direktori: exported .
  • Mengurai libfoo.so , dan mengumpulkan informasi tentang simbol yang diekspor oleh perpustakaan melalui tabel .dynsym -nya.
  • Menambahkan _Z3FooiP3bar dan _Z6FooBadiP3foo .

libfoo.so.lsdump adalah dump ABI terakhir yang dihasilkan dari libfoo.so .

header-abi-diff

Alat header-abi-diff membandingkan dua file .lsdump yang mewakili ABI dari dua perpustakaan dan menghasilkan laporan perbedaan yang menyatakan perbedaan antara kedua ABI.

masukan
  • File .lsdump mewakili ABI perpustakaan bersama yang lama.
  • File .lsdump mewakili ABI perpustakaan bersama yang baru.
Keluaran Laporan perbedaan yang menyatakan perbedaan ABI yang ditawarkan oleh dua perpustakaan bersama dibandingkan.

File diff ABI dalam format teks protobuf . Formatnya dapat berubah pada rilis mendatang.

Misalnya, Anda memiliki dua versi libfoo : libfoo_old.so dan libfoo_new.so . Di libfoo_new.so , di bar_t , Anda mengubah jenis mfoo dari foo_t menjadi foo_t * . Karena bar_t adalah tipe yang dapat dijangkau, ini harus ditandai sebagai perubahan yang dapat menyebabkan gangguan ABI dengan header-abi-diff .

Untuk menjalankan header-abi-diff :

header-abi-diff -old libfoo_old.so.lsdump \
                -new libfoo_new.so.lsdump \
                -arch arm64 \
                -o libfoo.so.abidiff \
                -lib libfoo

Contoh keluaran perintah di libfoo.so.abidiff :

lib_name: "libfoo"
arch: "arm64"
record_type_diffs {
  name: "bar"
  type_stack: "Foo-> bar *->bar "
  type_info_diff {
    old_type_info {
      size: 24
      alignment: 8
    }
    new_type_info {
      size: 8
      alignment: 8
    }
  }
  fields_diff {
    old_field {
      referenced_type: "foo"
      field_offset: 0
      field_name: "mfoo"
      access: public_access
    }
    new_field {
      referenced_type: "foo *"
      field_offset: 0
      field_name: "mfoo"
      access: public_access
    }
  }
}

libfoo.so.abidiff berisi laporan semua perubahan yang dapat menyebabkan gangguan ABI di libfoo . Pesan record_type_diffs menunjukkan bahwa record telah berubah dan mencantumkan perubahan yang tidak kompatibel, yang meliputi:

  • Ukuran record berubah dari 24 byte menjadi 8 byte.
  • Jenis bidang mfoo berubah dari foo menjadi foo * (semua typedef dihilangkan).

Bidang type_stack menunjukkan bagaimana header-abi-diff mencapai tipe yang diubah ( bar ). Bidang ini dapat diartikan sebagai Foo adalah fungsi yang diekspor yang menggunakan bar * sebagai parameter, yang menunjuk ke bar , yang diekspor dan diubah.

Menerapkan ABI/API

Untuk menerapkan ABI/API perpustakaan bersama VNDK, referensi ABI harus diperiksa ke ${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/ . Untuk membuat referensi ini, jalankan perintah berikut:

${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py

Setelah membuat referensi, setiap perubahan yang dilakukan pada kode sumber yang mengakibatkan perubahan ABI/API yang tidak kompatibel di pustaka VNDK kini mengakibatkan kesalahan build.

Untuk memperbarui referensi ABI untuk perpustakaan tertentu, jalankan perintah berikut:

${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l <lib1> -l <lib2>

Misalnya, untuk memperbarui referensi ABI libbinder , jalankan:

${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l libbinder