Ruang Nama Tautan

Tautan dinamis mengatasi dua tantangan dalam desain Treble VNDK:

  • Pustaka bersama SP-HAL dan dependensinya, termasuk pustaka VNDK-SP, dimuat ke dalam proses kerangka kerja. Harus ada mekanisme untuk mencegah konflik simbol.
  • dlopen() dan android_dlopen_ext() dapat menimbulkan beberapa dependensi runtime yang tidak terlihat pada waktu build dan mungkin sulit dideteksi menggunakan analisis statis.

Kedua tantangan ini dapat diselesaikan dengan mekanisme namespace linker . Mekanisme ini disediakan oleh linker dinamis. Itu dapat mengisolasi perpustakaan bersama di ruang nama linker yang berbeda sehingga perpustakaan dengan nama perpustakaan yang sama tetapi dengan simbol yang berbeda tidak akan konflik.

Di sisi lain, mekanisme namespace linker memberikan fleksibilitas sehingga beberapa perpustakaan bersama dapat diekspor oleh namespace linker dan digunakan oleh namespace linker lain. Pustaka bersama yang diekspor ini dapat menjadi antarmuka pemrograman aplikasi yang bersifat publik bagi program lain sambil menyembunyikan detail implementasinya di dalam namespace linkernya.

Misalnya, /system/lib[64]/libcutils.so dan /system/lib[64]/vndk-sp-${VER}/libcutils.so adalah dua perpustakaan bersama. Kedua perpustakaan ini dapat memiliki simbol yang berbeda. Mereka dimuat ke dalam namespace linker yang berbeda sehingga modul kerangka kerja dapat bergantung pada /system/lib[64]/libcutils.so dan pustaka bersama SP-HAL dapat bergantung pada /system/lib[64]/vndk-sp-${VER}/libcutils.so .

Di sisi lain, /system/lib[64]/libc.so adalah contoh perpustakaan umum yang diekspor oleh namespace linker dan diimpor ke banyak namespace linker. Dependensi /system/lib[64]/libc.so , seperti libnetd_client.so , dimuat ke dalam namespace tempat /system/lib[64]/libc.so berada. Namespace lain tidak akan memiliki akses ke dependensi tersebut. Mekanisme ini merangkum rincian implementasi sambil menyediakan antarmuka publik.

Bagaimana cara kerjanya?

Linker dinamis bertanggung jawab untuk memuat pustaka bersama yang ditentukan dalam entri DT_NEEDED atau pustaka bersama yang ditentukan oleh argumen dlopen() atau android_dlopen_ext() . Dalam kedua kasus tersebut, linker dinamis menemukan namespace linker tempat pemanggil berada dan mencoba memuat dependensi ke dalam namespace linker yang sama. Jika penaut dinamis tidak dapat memuat pustaka bersama ke dalam namespace linker yang ditentukan, ia akan meminta namespace linker tertaut untuk mengekspor pustaka bersama.

Format file konfigurasi

Format file konfigurasi didasarkan pada format file INI. File konfigurasi tipikal terlihat seperti ini:

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}

File konfigurasi meliputi:

  • Beberapa properti pemetaan bagian direktori di awal untuk linker dinamis untuk memilih bagian yang efektif.
  • Beberapa bagian konfigurasi namespace linker:
    • Setiap bagian berisi beberapa ruang nama (simpul grafik) dan beberapa link cadangan antar ruang nama (busur grafik).
    • Setiap namespace memiliki isolasi, jalur pencarian, jalur yang diizinkan, dan pengaturan visibilitasnya sendiri.

Tabel di bawah ini menjelaskan arti masing-masing properti secara rinci.

Properti pemetaan bagian direktori

Properti Keterangan Contoh

dir. name

Jalur ke direktori tempat bagian [ name ] diterapkan.

Setiap properti memetakan executable di bawah direktori ke bagian konfigurasi namespace linker. Mungkin ada dua (atau lebih) properti yang memiliki name yang sama tetapi mengarah ke direktori berbeda.

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

Hal ini menunjukkan bahwa konfigurasi yang ditentukan di bagian [system] berlaku untuk executable yang dimuat dari /system/bin atau /system/xbin .

Konfigurasi yang ditentukan di bagian [vendor] berlaku untuk file executable yang dimuat dari /vendor/bin .

Properti relasi

Properti Keterangan Contoh
additional. namespaces

Daftar namespace tambahan yang dipisahkan koma (selain namespace default ) untuk bagian tersebut.

additional. namespaces = sphal, vndk

Hal ini menunjukkan bahwa ada tiga namespace ( default , sphal , dan vndk ) dalam konfigurasi [system] .

namespace. name . links

Daftar namespace cadangan yang dipisahkan koma.

Jika perpustakaan bersama tidak dapat ditemukan di namespace saat ini, linker dinamis akan mencoba memuat perpustakaan bersama dari namespace fallback. Namespace yang ditentukan di awal daftar memiliki prioritas lebih tinggi.

namespace. sphal. links = default, vndk

Jika pustaka bersama atau yang dapat dieksekusi meminta pustaka bersama yang tidak dapat dimuat ke dalam namespace sphal , linker dinamis akan mencoba memuat pustaka bersama dari namespace default .

Lalu, jika pustaka bersama juga tidak dapat dimuat dari namespace default , linker dinamis akan mencoba memuat pustaka bersama dari namespace vndk .

Terakhir, jika semua upaya gagal, penaut dinamis akan mengembalikan kesalahan.

namespace. name . link. other . shared_libs

Daftar perpustakaan bersama yang dipisahkan titik dua yang dapat dicari di namespace other ketika perpustakaan tersebut tidak dapat ditemukan di namespace name .

Properti ini tidak dapat digunakan dengan namespace. name . link. other . allow_all_shared_libs .

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

Hal ini menunjukkan bahwa link fallback hanya menerima libc.so atau libm.so sebagai nama perpustakaan yang diminta. Tautan dinamis mengabaikan tautan cadangan dari sphal ke namespace default jika nama perpustakaan yang diminta bukan libc.so atau libm.so .

namespace. name . link. other . allow_all_shared_libs

Nilai boolean yang menunjukkan apakah semua perpustakaan bersama dapat dicari di namespace other ketika perpustakaan tersebut tidak dapat ditemukan di namespace name .

Properti ini tidak dapat digunakan dengan namespace. name . link. other . shared_libs .

namespace. vndk. link. sphal. allow_all_shared_libs = true

Hal ini menunjukkan bahwa semua nama perpustakaan dapat berjalan melalui link fallback dari vndk ke namespace sphal .

Properti ruang nama

Properti Keterangan Contoh
namespace. name . isolated

Nilai boolean yang menunjukkan apakah linker dinamis harus memeriksa lokasi perpustakaan bersama.

Jika isolated adalah true , hanya perpustakaan bersama yang berada di salah satu direktori search.paths (tidak termasuk subdirektori) atau berada di bawah salah satu direktori permitted.paths (termasuk subdirektori) yang dapat dimuat.

Jika isolated false (default), tautan dinamis tidak memeriksa jalur perpustakaan bersama.

namespace. sphal. isolated = true

Hal ini menunjukkan bahwa hanya perpustakaan bersama di search.paths atau di bawah permitted.paths yang dapat dimuat ke dalam namespace sphal .

namespace. name . search.paths

Daftar direktori yang dipisahkan titik dua untuk mencari perpustakaan bersama.

Direktori yang ditentukan dalam search.paths ditambahkan ke nama perpustakaan yang diminta jika pemanggilan fungsi ke entri dlopen() atau DT_NEEDED tidak menentukan path lengkap. Direktori yang ditentukan di awal daftar memiliki prioritas lebih tinggi.

Ketika isolated adalah true , perpustakaan bersama yang berada di salah satu direktori search.paths (tidak termasuk subdirektori) dapat dimuat terlepas dari properti permitted.paths .

Misalnya, jika search.paths adalah /system/${LIB} dan permitted.paths kosong, /system/${LIB}/libc.so dapat dimuat tetapi /system/${LIB}/vndk/libutils.so tidak dapat dimuat.

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

Hal ini menunjukkan bahwa tautan dinamis mencari /system/${LIB} untuk perpustakaan bersama.

namespace. name . asan.search.paths

Daftar direktori yang dipisahkan titik dua untuk mencari perpustakaan bersama ketika AddressSanitizer (ASan) diaktifkan.

namespace. name . search.paths diabaikan ketika ASan diaktifkan.

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

Hal ini menunjukkan bahwa ketika ASan diaktifkan, tautan dinamis akan menelusuri /data/asan/system/${LIB} terlebih dahulu, lalu menelusuri /system/${LIB} .

namespace. name . permitted.paths

Daftar direktori yang dipisahkan titik dua (termasuk subdirektori) tempat linker dinamis dapat memuat perpustakaan bersama (selain search.paths ) ketika isolated adalah true .

Pustaka bersama yang berada di bawah subdirektori yang permitted.paths juga dapat dimuat. Misalnya, jika permitted.paths adalah /system/${LIB} , /system/${LIB}/libc.so dan /system/${LIB}/vndk/libutils.so dapat dimuat.

Jika isolated adalah false , permitted.paths diabaikan dan peringatan dikeluarkan.

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

Hal ini menunjukkan bahwa perpustakaan bersama di bawah /system/${LIB}/hw dapat dimuat ke namespace default yang terisolasi.

Misalnya, tanpa permitted.paths , libaudiohal.so tidak dapat memuat /system/${LIB}/hw/audio.a2dp.default.so ke dalam namespace default .

namespace. name . asan.permitted.paths

Daftar direktori yang dipisahkan titik dua tempat tautan dinamis dapat memuat perpustakaan bersama ketika ASan diaktifkan.

namespace. name . permitted.paths diabaikan ketika ASan diaktifkan.

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

Hal ini menunjukkan bahwa ketika ASan diaktifkan, perpustakaan bersama di bawah /data/asan/system/${LIB}/hw atau /system/${LIB}/hw dapat dimuat ke namespace default yang terisolasi.

namespace. name . visible

Nilai boolean yang menunjukkan apakah program (selain libc ) bisa mendapatkan pegangan namespace linker dengan android_get_exported_namespace() dan membuka pustaka bersama di namespace linker dengan meneruskan pegangan ke android_dlopen_ext() .

Jika visible adalah true , android_get_exported_namespace() selalu mengembalikan pegangan jika namespace tersebut ada.

Jika visible false (default), android_get_exported_namespace() selalu mengembalikan NULL terlepas dari keberadaan namespace. Pustaka bersama dapat dimuat ke dalam namespace ini hanya jika (1) pustaka tersebut diminta oleh namespace linker lain yang memiliki link cadangan ke namespace ini, atau (2) pustaka tersebut diminta oleh pustaka bersama atau executable lain di namespace ini.

namespace. sphal. visible = true

Hal ini menunjukkan bahwa android_get_exported_namespace("sphal") dapat mengembalikan pegangan namespace linker yang valid.

Pembuatan namespace linker

Di Android 11, konfigurasi linker dibuat saat runtime di bawah /linkerconfig alih-alih menggunakan file teks biasa di ${android-src}/system/core/rootdir/etc . Konfigurasi dihasilkan pada waktu boot berdasarkan lingkungan runtime, yang mencakup item berikut:

  • Jika perangkat mendukung VNDK
  • Versi VNDK target partisi vendor
  • Versi VNDK partisi produk
  • Modul APEX yang terpasang

Konfigurasi linker dibuat dengan menyelesaikan ketergantungan antar namespace linker. Misalnya, jika ada pembaruan apa pun pada modul APEX yang menyertakan pembaruan ketergantungan, konfigurasi linker akan dibuat untuk mencerminkan perubahan ini. Detail lebih lanjut untuk membuat konfigurasi linker dapat ditemukan di ${android-src}/system/linkerconfig .

Isolasi namespace linker

Ada tiga jenis konfigurasi. Bergantung pada nilai PRODUCT_TREBLE_LINKER_NAMESPACES dan BOARD_VNDK_VERSION di BoardConfig.mk , konfigurasi terkait dibuat saat boot.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Konfigurasi yang dipilih Persyaratan VTS
true current VNDK Wajib untuk perangkat yang diluncurkan dengan Android 9 atau lebih tinggi
Kosong VNDK Lite Wajib untuk perangkat yang diluncurkan dengan Android 8.x
false Kosong Legacy Untuk perangkat non-Treble

Konfigurasi VNDK Lite mengisolasi perpustakaan bersama SP-HAL dan VNDK-SP. Di Android 8.0, ini harus berupa file konfigurasi untuk penaut dinamis jika PRODUCT_TREBLE_LINKER_NAMESPACES bernilai true .

Konfigurasi VNDK juga mengisolasi perpustakaan bersama SP-HAL dan VNDK-SP. Selain itu, konfigurasi ini menyediakan isolasi linker dinamis penuh. Ini memastikan bahwa modul di partisi sistem tidak akan bergantung pada perpustakaan bersama di partisi vendor dan sebaliknya.

Di Android 8.1 atau lebih tinggi, konfigurasi VNDK adalah konfigurasi default dan sangat disarankan untuk mengaktifkan isolasi linker dinamis penuh dengan menyetel BOARD_VNDK_VERSION ke current .

Konfigurasi VNDK

Konfigurasi VNDK mengisolasi ketergantungan perpustakaan bersama antara partisi sistem dan partisi vendor. Dibandingkan dengan konfigurasi yang disebutkan pada subbagian sebelumnya, perbedaannya diuraikan sebagai berikut:

  • Proses kerangka

    • namespace default , vndk , sphal , dan rs dibuat.
    • Semua namespace diisolasi.
    • Pustaka bersama sistem dimuat ke dalam namespace default .
    • SP-HAL dimuat ke dalam namespace sphal .
    • Pustaka bersama VNDK-SP dimuat ke namespace vndk .
  • Proses vendor

    • default , vndk , dan namespace system dibuat.
    • Namespace default diisolasi.
    • Pustaka bersama vendor dimuat ke dalam namespace default .
    • Pustaka bersama VNDK dan VNDK-SP dimuat ke namespace vndk .
    • LL-NDK dan dependensinya dimuat ke dalam namespace system .

Hubungan antara namespace linker diilustrasikan di bawah ini.

Grafik namespace linker dijelaskan dalam konfigurasi VNDK
Gambar 1. Isolasi namespace linker (konfigurasi VNDK)

Pada gambar di atas, LL-NDK dan VNDK-SP adalah singkatan dari perpustakaan bersama berikut:

  • 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

Anda dapat menemukan detail lebih lanjut di /linkerconfig/ld.config.txt dari perangkat.

Konfigurasi VNDK Lite

Mulai Android 8.0, linker dinamis dikonfigurasi untuk mengisolasi pustaka bersama SP-HAL dan VNDK-SP sehingga simbolnya tidak bertentangan dengan pustaka bersama framework lainnya. Hubungan antara namespace linker ditunjukkan di bawah ini.

Grafik namespace linker dijelaskan dalam konfigurasi VNDK Lite
Gambar 2. Isolasi namespace linker (konfigurasi VNDK Lite)

LL-NDK dan VNDK-SP adalah singkatan dari perpustakaan bersama berikut:

  • LL-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (tidak ada dalam konfigurasi)
    • libsync.so
    • libvndksupport.so
    • libz.so (dipindahkan ke VNDK-SP dalam konfigurasi)
  • 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

Tabel di bawah mencantumkan konfigurasi namespace untuk proses kerangka kerja, yang dikutip dari bagian [system] dalam konfigurasi VNDK Lite.

Ruang nama Properti Nilai
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 (untuk 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 (untuk 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 (untuk kernel RS yang dikompilasi)
isolated true
visible true
links default,vndk
link.default.shared_libs LL-NDK
libmediandk.so
libft2.so
link.vndk.shared_libs VNDK-SP

Tabel di bawah menyajikan konfigurasi namespace untuk proses vendor, yang dikutip dari bagian [vendor] dalam konfigurasi VNDK Lite.

Ruang nama Properti Nilai
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} (tidak digunakan lagi)
/product/${LIB} (tidak digunakan lagi)
isolated false

Detail lebih lanjut dapat ditemukan di /linkerconfig/ld.config.txt dari perangkat.

Sejarah dokumen

Perubahan Android 11

  • Di Android 11, file ld.config.*.txt statis dihapus dari basis kode dan LinkerConfig menghasilkannya saat runtime.

Android 9 berubah

  • Di Android 9, namespace linker vndk ditambahkan ke proses vendor dan pustaka bersama VNDK diisolasi dari namespace linker default.
  • Ganti PRODUCT_FULL_TREBLE dengan PRODUCT_TREBLE_LINKER_NAMESPACES yang lebih spesifik.
  • Android 9 mengubah nama file konfigurasi linker dinamis berikut.
    Android 8.x Android 9 Keterangan
    ld.config.txt.in ld.config.txt Untuk perangkat dengan isolasi namespace linker runtime
    ld.config.txt ld.config.vndk_lite.txt Untuk perangkat dengan isolasi namespace linker VNDK-SP
    ld.config.legacy.txt ld.config.legacy.txt Untuk perangkat lama yang menjalankan Android 7.x atau lebih rendah
  • Hapus android.hardware.graphics.allocator@2.0.so .
  • partisi product dan odm ditambahkan.