Namespace penaut

Linker dinamis mengatasi dua tantangan dalam desain Treble VNDK:

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

Kedua tantangan ini dapat diselesaikan oleh mekanisme namespace penaut. Mekanisme ini disediakan oleh linker dinamis. Hal ini dapat mengisolasi library bersama di namespace penaut yang berbeda sehingga library dengan nama library yang sama, tetapi dengan simbol yang berbeda, tidak akan mengalami konflik.

Di sisi lain, mekanisme namespace penaut memberikan fleksibilitas sehingga beberapa library bersama dapat diekspor oleh namespace penaut dan digunakan oleh namespace penaut lain. Library bersama yang diekspor ini dapat menjadi antarmuka pemrograman aplikasi yang bersifat publik untuk program lain sekaligus menyembunyikan detail implementasinya dalam namespace penaut.

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

Di sisi lain, /system/lib[64]/libc.so adalah contoh library publik yang diekspor oleh namespace penaut dan diimpor ke banyak namespace penaut. 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 mengenkapsulasi detail implementasi sekaligus menyediakan antarmuka publik.

Cara kerjanya

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

Format file konfigurasi

Format file konfigurasi didasarkan pada format file INI. File konfigurasi umum 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 mencakup:

  • Beberapa properti pemetaan bagian direktori di awal untuk penaut dinamis guna memilih bagian yang efektif.
  • Beberapa bagian konfigurasi namespace penaut:
    • Setiap bagian berisi beberapa namespace (vertikal grafik) dan beberapa link penggantian antar-namespace (busur grafik).
    • Setiap namespace memiliki setelan isolasi, jalur penelusuran, jalur yang diizinkan, dan setelan visibilitasnya sendiri.

Tabel di bawah menjelaskan arti setiap properti secara mendetail.

Properti pemetaan bagian direktori

Properti Deskripsi Contoh

dir.name

Jalur ke direktori tempat bagian [name] berlaku.

Setiap properti memetakan file yang dapat dieksekusi di direktori ke bagian konfigurasi namespace penaut. 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

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

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

Properti hubungan

Properti Deskripsi 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 penggantian yang dipisahkan koma.

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

namespace.sphal.links = default,vndk

Jika library bersama atau file yang dapat dieksekusi meminta library bersama yang tidak dapat dimuat ke namespace sphal, penaut dinamis akan mencoba memuat library bersama dari namespace default.

Kemudian, jika library bersama juga tidak dapat dimuat dari namespace default, dynamic linker akan mencoba memuat library bersama dari namespace vndk.

Terakhir, jika semua upaya gagal, linker dinamis akan menampilkan error.

namespace.name.link.other.shared_libs

Daftar library bersama yang dipisahkan titik dua, yang dapat ditelusuri dalam namespace other jika library tersebut tidak dapat ditemukan dalam 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 penggantian hanya menerima libc.so atau libm.so sebagai nama library yang diminta. Penaut dinamis mengabaikan link penggantian dari namespace sphal ke default jika nama library yang diminta bukan libc.so atau libm.so.

namespace.name.link.other.allow_all_shared_libs

Nilai boolean yang menunjukkan apakah semua library bersama dapat ditelusuri di namespace other jika library 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 library dapat menelusuri link penggantian dari namespace vndk ke sphal.

Properti namespace

Properti Deskripsi Contoh
namespace.name.isolated

Nilai boolean yang menunjukkan apakah penaut dinamis harus memeriksa lokasi library bersama.

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

Jika isolated adalah false (default), penaut dinamis tidak akan memeriksa jalur library bersama.

namespace.sphal.isolated = true

Hal ini menunjukkan bahwa hanya library bersama di search.paths atau di bagian permitted.paths yang dapat dimuat ke namespace sphal.

namespace.name.search.paths

Daftar direktori yang dipisahkan titik dua untuk menelusuri library bersama.

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

Jika isolated adalah true, library bersama yang ada di salah satu direktori search.paths (tidak termasuk subdirektori) dapat dimuat, apa pun 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 linker dinamis menelusuri /system/${LIB} untuk library bersama.

namespace.name.asan.search.paths

Daftar direktori yang dipisahkan titik dua untuk menelusuri library bersama saat AddressSanitizer (ASan) diaktifkan.

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

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

Ini menunjukkan bahwa ketika ASan diaktifkan, penaut 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 penaut dinamis dapat memuat library bersama (selain search.paths) saat isolated adalah true.

Library bersama yang berada di subdirektori 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 akan diabaikan dan peringatan akan muncul.

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

Hal ini menunjukkan bahwa library bersama di /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 penaut dinamis dapat memuat library bersama saat ASan diaktifkan.

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

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

Hal ini menunjukkan bahwa saat ASan diaktifkan, library bersama di /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 mendapatkan handle namespace penaut dengan android_get_exported_namespace() dan membuka library bersama di namespace penaut dengan meneruskan handle ke android_dlopen_ext().

Jika visible adalah true, android_get_exported_namespace() selalu menampilkan nama sebutan jika namespace ada.

Jika visible adalah false (default), android_get_exported_namespace() selalu menampilkan NULL terlepas dari keberadaan namespace. Library bersama hanya dapat dimuat ke dalam namespace ini jika (1) diminta oleh namespace penaut lain yang memiliki link penggantian ke namespace ini, atau (2) diminta oleh library bersama atau file yang dapat dieksekusi lainnya di namespace ini.

namespace.sphal.visible = true

Hal ini menunjukkan bahwa android_get_exported_namespace("sphal") dapat menampilkan handle namespace penaut yang valid.

Pembuatan namespace linker

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

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

Konfigurasi penaut dibuat dengan me-resolve dependensi antar-namespace penaut. Misalnya, jika ada update pada modul APEX yang menyertakan update dependensi, konfigurasi penaut akan dibuat yang mencerminkan perubahan ini. Detail selengkapnya untuk membuat konfigurasi penaut dapat ditemukan di ${android-src}/system/linkerconfig.

Isolasi namespace penaut

Ada tiga jenis konfigurasi. Bergantung pada nilai PRODUCT_TREBLE_LINKER_NAMESPACES dan BOARD_VNDK_VERSION di BoardConfig.mk, konfigurasi yang sesuai akan dibuat pada waktu booting.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Konfigurasi yang dipilih Persyaratan VTS
true current VNDK Wajib untuk perangkat yang diluncurkan dengan Android 9 atau yang 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 library bersama SP-HAL dan VNDK-SP. Pada Android 8.0, file ini harus berupa file konfigurasi untuk penaut dinamis jika PRODUCT_TREBLE_LINKER_NAMESPACES adalah true.

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

Di Android 8.1 atau yang lebih tinggi, konfigurasi VNDK adalah konfigurasi default dan sangat direkomendasikan untuk mengaktifkan isolasi penaut dinamis penuh dengan menetapkan BOARD_VNDK_VERSION ke current.

Konfigurasi VNDK

Konfigurasi VNDK mengisolasi dependensi library bersama antara partisi sistem dan partisi vendor. Dibandingkan dengan konfigurasi yang disebutkan di subbagian sebelumnya, perbedaannya diuraikan sebagai berikut:

  • Proses framework

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

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

Hubungan antara namespace penaut diilustrasikan di bawah ini.

Grafik namespace penaut yang dijelaskan dalam konfigurasi VNDK

Gambar 1. Isolasi namespace penaut (konfigurasi VNDK).

Pada gambar di atas, LL-NDK dan VNDK-SP adalah singkatan dari library 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 selengkapnya di /linkerconfig/ld.config.txt dari perangkat.

Konfigurasi VNDK Lite

Mulai Android 8.0, penaut dinamis dikonfigurasi untuk mengisolasi library bersama SP-HAL dan VNDK-SP sehingga simbolnya tidak bertentangan dengan library bersama framework lainnya. Hubungan antara namespace penaut ditampilkan di bawah.

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

LL-NDK dan VNDK-SP adalah singkatan dari library 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 framework, 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 menampilkan konfigurasi namespace untuk proses vendor, yang diambil 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 selengkapnya dapat ditemukan di /linkerconfig/ld.config.txt dari perangkat.

Histori dokumen

Perubahan Android 11

  • Di Android 11, file ld.config.*.txt statis dihapus dari codebase dan LinkerConfig akan membuatnya dalam runtime.

Perubahan Android 9

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