Ruang Nama Penghubung

Linker dinamis menangani dua tantangan dalam desain Treble VNDK:

  • Pustaka bersama SP-HAL dan dependensinya, termasuk pustaka VNDK-SP, dimuat ke dalam proses kerangka kerja. Harus ada beberapa mekanisme untuk mencegah konflik simbol.
  • dlopen() dan android_dlopen_ext() dapat memperkenalkan 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 tautan yang berbeda sehingga perpustakaan dengan nama perpustakaan yang sama tetapi dengan simbol yang berbeda tidak akan bentrok.

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 untuk program lain sambil menyembunyikan detail implementasinya di dalam ruang nama tautannya.

Misalnya, /system/lib[64]/libcutils.so dan /system/lib[64]/vndk-sp-${VER}/libcutils.so adalah dua pustaka bersama. Kedua perpustakaan ini dapat memiliki simbol yang berbeda. Mereka dimuat ke ruang nama penghubung yang berbeda sehingga modul kerangka kerja dapat bergantung pada /system/lib[64]/libcutils.so dan perpustakaan 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. Ruang nama lain tidak akan memiliki akses ke dependensi tersebut. Mekanisme ini merangkum detail implementasi sambil menyediakan antarmuka publik.

Bagaimana cara kerjanya?

Penaut 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, dynamic linker 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 ruang nama penaut yang ditentukan, penaut akan meminta ruang nama penaut tertaut untuk pustaka bersama yang diekspor.

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 direktori-bagian di awal untuk linker dinamis untuk memilih bagian yang efektif.
  • Beberapa bagian konfigurasi ruang nama tautan:
    • Setiap bagian berisi beberapa ruang nama (simpul grafik) dan beberapa tautan mundur antara ruang nama (busur grafik).
    • Setiap namespace memiliki isolasi, jalur pencarian, jalur yang diizinkan, dan pengaturan visibilitasnya sendiri.

Tabel di bawah ini menjelaskan arti dari setiap properti secara rinci.

Properti pemetaan bagian direktori

Properti Keterangan Contoh

dir. name

Jalur ke direktori tempat bagian [ name ] berlaku.

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 yang berbeda.

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

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 executable yang dimuat dari /vendor/bin .

Sifat relasi

Properti Keterangan Contoh
additional. namespaces

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

additional. namespaces = sphal, vndk

Ini menunjukkan bahwa ada tiga ruang nama ( default , sphal , dan vndk ) dalam konfigurasi [system] .

namespace. name . links

Daftar ruang nama cadangan yang dipisahkan koma.

Jika pustaka bersama tidak dapat ditemukan di ruang nama saat ini, penaut dinamis mencoba memuat pustaka bersama dari ruang nama cadangan. 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 ruang nama sphal , penaut dinamis mencoba memuat pustaka bersama dari ruang nama default .

Dan kemudian, jika pustaka bersama tidak dapat dimuat dari namespace default , penaut dinamis mencoba memuat pustaka bersama dari namespace vndk .

Terakhir, jika semua upaya gagal, tautan dinamis mengembalikan kesalahan.

namespace. name . link. other . shared_libs

Daftar pustaka bersama yang dipisahkan titik dua yang dapat dicari di ruang nama other ketika pustaka tersebut tidak dapat ditemukan di ruang name nama.

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

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

Ini menunjukkan bahwa tautan mundur hanya menerima libc.so atau libm.so sebagai nama pustaka yang diminta. Penaut dinamis mengabaikan tautan mundur dari sphal ke namespace default jika nama pustaka yang diminta bukan libc.so atau libm.so .

namespace. name . link. other . allow_all_shared_libs

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

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

namespace. vndk. link. sphal. allow_all_shared_libs = true

Ini menunjukkan bahwa semua nama perpustakaan dapat berjalan melalui tautan mundur dari vndk ke ruang nama sphal .

Properti ruang nama

Properti Keterangan Contoh
namespace. name . isolated

Nilai boolean yang menunjukkan apakah penaut dinamis harus memeriksa di mana perpustakaan bersama berada.

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

Jika isolated false (default), penaut dinamis tidak memeriksa jalur pustaka bersama.

namespace. sphal. isolated = true

Ini menunjukkan bahwa hanya perpustakaan bersama di search.paths atau di bawah permitted.paths yang dapat dimuat ke dalam ruang nama sphal .

namespace. name . search.paths

Daftar direktori yang dipisahkan titik dua untuk mencari pustaka bersama.

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

Saat isolated adalah true , pustaka 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}

Ini menunjukkan bahwa penaut dinamis mencari /system/${LIB} untuk pustaka bersama.

namespace. name . asan.search.paths

Daftar direktori yang dipisahkan titik dua untuk mencari pustaka bersama saat AddressSanitizer (ASan) diaktifkan.

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

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

Ini menunjukkan bahwa ketika ASan diaktifkan, penaut dinamis mencari /data/asan/system/${LIB} terlebih dahulu dan kemudian mencari /system/${LIB} .

namespace. name . permitted.paths

Daftar direktori yang dipisahkan titik dua (termasuk subdirektori) tempat tautan dinamis dapat memuat pustaka bersama (selain search.paths ) saat isolated adalah true .

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

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

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

Ini menunjukkan bahwa pustaka bersama di bawah /system/${LIB}/hw dapat dimuat ke dalam 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 pustaka bersama saat ASan diaktifkan.

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

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

Ini menunjukkan bahwa ketika ASan diaktifkan, pustaka 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 ) dapat memperoleh pegangan namespace penaut dengan android_get_exported_namespace() dan membuka pustaka bersama di ruang nama penaut dengan meneruskan pegangan ke android_dlopen_ext() .

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

Jika visible false (default), android_get_exported_namespace() selalu mengembalikan NULL terlepas dari keberadaan namespace. Pustaka bersama dapat dimuat ke ruang nama ini hanya jika (1) diminta oleh ruang nama penaut lain yang memiliki tautan mundur ke ruang nama ini, atau (2) diminta oleh pustaka bersama lain atau yang dapat dieksekusi di ruang nama ini.

namespace. sphal. visible = true

Ini menunjukkan bahwa android_get_exported_namespace("sphal") dapat mengembalikan pegangan namespace penaut yang valid.

Pembuatan namespace penautan

Di Android 11, konfigurasi penaut dibuat saat runtime di bawah /linkerconfig alih-alih menggunakan file teks biasa di ${android-src}/system/core/rootdir/etc . Konfigurasi dibuat saat 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 dependensi antara ruang nama linker. Misalnya, jika ada pembaruan pada modul APEX yang menyertakan pembaruan ketergantungan, konfigurasi penaut dihasilkan yang mencerminkan perubahan ini. Detail lebih lanjut untuk membuat konfigurasi tautan 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 yang sesuai 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 pustaka 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 pustaka 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 pustaka 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 dependensi pustaka bersama antara partisi sistem dan partisi vendor. Dibandingkan dengan konfigurasi yang disebutkan pada subbagian sebelumnya, perbedaannya diuraikan sebagai berikut:

  • Proses kerangka

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

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

Hubungan antara ruang nama penghubung diilustrasikan di bawah ini.

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

Pada gambar di atas, LL-NDK dan VNDK-SP adalah singkatan dari shared library 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, penaut dinamis dikonfigurasi untuk mengisolasi pustaka bersama SP-HAL dan VNDK-SP sehingga simbolnya tidak bertentangan dengan pustaka bersama kerangka kerja lainnya. Hubungan antara ruang nama linker ditunjukkan di bawah ini.

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

LL-NDK dan VNDK-SP adalah singkatan dari shared library berikut:

  • LL-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (tidak 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 ini mencantumkan konfigurasi ruang nama 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 ini menyajikan konfigurasi ruang nama 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

Rincian 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 membuatnya dalam waktu proses.

Android 9 perubahan

  • Di Android 9, ruang nama penaut vndk ditambahkan ke proses vendor dan pustaka bersama VNDK diisolasi dari ruang nama penaut default.
  • Ganti PRODUCT_FULL_TREBLE dengan PRODUCT_TREBLE_LINKER_NAMESPACES yang lebih spesifik.
  • Android 9 mengubah nama file konfigurasi dynamic linker 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 .
  • product dan partisi odm ditambahkan.