Bağlayıcı Ad Alanı

Dinamik bağlayıcı, Treble VNDK tasarımındaki iki zorluğun üstesinden gelir:

  • SP-HAL paylaşılan kitaplıkları ve VNDK-SP kitaplıkları dahil bunların bağımlılıkları çerçeve süreçlerine yüklenir. Sembol çatışmalarını önleyecek bazı mekanizmaların olması gerekir.
  • dlopen() ve android_dlopen_ext() derleme sırasında görünmeyen ve statik analiz kullanılarak tespit edilmesi zor olabilecek bazı çalışma zamanı bağımlılıklarını ortaya çıkarabilir.

Bu iki zorluk bağlayıcı ad alanı mekanizmasıyla çözülebilir. Bu mekanizma dinamik bağlayıcı tarafından sağlanır. Paylaşılan kitaplıkları farklı bağlayıcı ad alanlarında izole edebilir, böylece aynı kitaplık adına sahip ancak farklı sembollere sahip kitaplıklar çakışmaz.

Öte yandan, bağlayıcı ad alanı mekanizması, bazı paylaşılan kitaplıkların bir bağlayıcı ad alanı tarafından dışa aktarılabilmesi ve başka bir bağlayıcı ad alanı tarafından kullanılabilmesi için esneklik sağlar. Dışa aktarılan bu paylaşılan kitaplıklar, uygulama ayrıntılarını bağlayıcı ad alanları içinde gizlerken diğer programlara açık olan uygulama programlama arayüzleri haline gelebilir.

Örneğin, /system/lib[64]/libcutils.so ve /system/lib[64]/vndk-sp-${VER}/libcutils.so iki paylaşılan kütüphanedir. Bu iki kütüphanenin farklı sembolleri olabilir. Çerçeve modüllerinin /system/lib[64]/libcutils.so ve SP-HAL paylaşımlı kitaplıklarının /system/lib[64]/vndk-sp-${VER}/libcutils.so bağlı olabilmesi için farklı bağlayıcı ad alanlarına yüklenirler. /system/lib[64]/vndk-sp-${VER}/libcutils.so .

Öte yandan, /system/lib[64]/libc.so , bir bağlayıcı ad alanı tarafından dışa aktarılan ve birçok bağlayıcı ad alanına içe aktarılan bir genel kitaplık örneğidir. /system/lib[64]/libc.so bağımlılıkları, örneğin libnetd_client.so , /system/lib[64]/libc.so bulunduğu ad alanına yüklenir. Diğer ad alanlarının bu bağımlılıklara erişimi olmayacaktır. Bu mekanizma, genel arayüzleri sağlarken uygulama ayrıntılarını da kapsar.

O nasıl çalışır?

Dinamik bağlayıcı, DT_NEEDED girişlerinde belirtilen paylaşılan kitaplıkların veya dlopen() veya android_dlopen_ext() argümanı tarafından belirtilen paylaşılan kitaplıkların yüklenmesinden sorumludur. Her iki durumda da dinamik bağlayıcı, arayanın bulunduğu bağlayıcı ad alanını bulur ve bağımlılıkları aynı bağlayıcı ad alanına yüklemeye çalışır. Dinamik bağlayıcı, paylaşılan kitaplığı belirtilen bağlayıcı ad alanına yükleyemezse, dışa aktarılan paylaşılan kitaplıklar için bağlantılı bağlayıcı ad alanını sorar.

Yapılandırma dosyası formatı

Yapılandırma dosyası formatı INI dosya formatını temel alır. Tipik bir yapılandırma dosyası şuna benzer:

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}

Yapılandırma dosyası şunları içerir:

  • Dinamik bağlayıcının etkili bölümü seçmesi için başlangıçta çeşitli dizin bölümü eşleme özellikleri.
  • Çeşitli bağlayıcı ad alanları yapılandırma bölümleri:
    • Her bölüm birkaç ad alanı (grafik köşeleri) ve ad alanları arasında birkaç geri dönüş bağlantısı (grafik yayları) içerir.
    • Her ad alanının kendi izolasyonu, arama yolları, izin verilen yolları ve görünürlük ayarları vardır.

Aşağıdaki tablolarda her bir özelliğin anlamı ayrıntılı olarak açıklanmaktadır.

Dizin bölümü eşleme özelliği

Mülk Tanım Örnek

dir. name

[ name ] bölümünün geçerli olduğu dizinin yolu.

Her özellik, dizin altındaki yürütülebilir dosyaları bir bağlayıcı ad alanları yapılandırma bölümüyle eşler. Aynı name sahip ancak farklı dizinlere işaret eden iki (veya daha fazla) özellik olabilir.

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

Bu, [system] bölümünde belirtilen yapılandırmanın, /system/bin veya /system/xbin yüklenen yürütülebilir dosyalar için geçerli olduğunu gösterir.

[vendor] bölümünde belirtilen yapılandırma, /vendor/bin konumundan yüklenen yürütülebilir dosyalar için geçerlidir.

İlişki özellikleri

Mülk Tanım Örnek
additional. namespaces

Bölüme ilişkin ek ad alanlarının ( default ad alanına ek olarak) virgülle ayrılmış listesi.

additional. namespaces = sphal, vndk

Bu, [system] konfigürasyonunda üç ad alanının ( default , sphal ve vndk ) olduğunu gösterir.

namespace. name . links

Geri dönüş ad alanlarının virgülle ayrılmış listesi.

Geçerli ad alanında paylaşılan bir kitaplık bulunamazsa dinamik bağlayıcı, paylaşılan kitaplığı yedek ad alanlarından yüklemeye çalışır. Listenin başında belirtilen ad alanı daha yüksek önceliğe sahiptir.

namespace. sphal. links = default, vndk

Paylaşılan bir kitaplık veya yürütülebilir dosya, sphal ad alanına yüklenemeyen bir paylaşılan kitaplık talep ederse, dinamik bağlayıcı, paylaşılan kitaplığı default ad alanından yüklemeye çalışır.

Daha sonra, paylaşılan kitaplık default ad alanından da yüklenemezse, dinamik bağlayıcı, paylaşılan kitaplığı vndk ad alanından yüklemeye çalışır.

Son olarak, tüm denemeler başarısız olursa dinamik bağlayıcı bir hata döndürür.

namespace. name . link. other . shared_libs

other ad alanlarında bu kitaplıklar name alanında bulunamadığında aranabilecek paylaşılan kitaplıkların iki nokta üst üste ayrılmış listesi.

Bu özellik namespace. name . link. other . allow_all_shared_libs .

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

Bu, geri dönüş bağlantısının istenen kitaplık adı olarak yalnızca libc.so veya libm.so kabul ettiğini gösterir. İstenen kitaplık adı libc.so veya libm.so değilse, dinamik bağlayıcı sphal default ad alanına olan geri dönüş bağlantısını yok sayar.

namespace. name . link. other . allow_all_shared_libs

Bu kitaplıklar name ad alanında bulunamadığında tüm paylaşılan kitaplıkların other ad alanında aranıp aranamayacağını belirten bir boole değeri.

Bu özellik namespace. name . link. other . shared_libs .

namespace. vndk. link. sphal. allow_all_shared_libs = true

Bu, tüm kitaplık adlarının vndk sphal ad alanına geri dönüş bağlantısı üzerinden yürüyebileceğini gösterir.

Ad alanı özellikleri

Mülk Tanım Örnek
namespace. name . isolated

Dinamik bağlayıcının, paylaşılan kitaplığın nerede bulunduğunu denetlemesi gerekip gerekmediğini belirten bir boole değeri.

isolated edilmişse true , yalnızca search.paths dizinlerinden birinde (alt dizinler hariç) veya permitted.paths dizinlerinden birinin altında (alt dizinler dahil) bulunan paylaşılan kitaplıklar yüklenebilir.

isolated değeri false (varsayılan), dinamik bağlayıcı paylaşılan kitaplıkların yolunu denetlemez.

namespace. sphal. isolated = true

Bu, sphal ad alanına yalnızca search.paths veya permitted.paths altındaki paylaşılan kitaplıkların yüklenebileceğini gösterir.

namespace. name . search.paths

Paylaşılan kitaplıkları aramak için iki nokta üst üste ayrılmış dizin listesi.

search.paths belirtilen dizinler dlopen() veya DT_NEEDED girişlerine yapılan işlev çağrılarının tam yolu belirtmemesi durumunda istenen kitaplık adının başına eklenir. Listenin başında belirtilen dizin daha yüksek önceliğe sahiptir.

isolated edildiğinde true , search.paths dizinlerinden birinde (alt dizinler hariç) bulunan paylaşılan kitaplıklar, permitted.paths özelliğinden bağımsız olarak yüklenebilir.

Örneğin, search.paths /system/${LIB} ve permitted.paths boşsa, /system/${LIB}/libc.so yüklenebilir ancak /system/${LIB}/vndk/libutils.so yüklenemiyor.

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

Bu, dinamik bağlayıcının paylaşılan kitaplıkları /system/${LIB} aradığını gösterir.

namespace. name . asan.search.paths

AdresSanitizer (ASan) etkinleştirildiğinde paylaşılan kitaplıkları aramak için iki nokta üst üste ayrılmış dizin listesi.

namespace. name . search.paths ASan etkinleştirildiğinde namespace. name . search.paths göz ardı edilir.

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

Bu, ASan etkinleştirildiğinde dinamik bağlayıcının önce /data/asan/system/${LIB} aradığını ve ardından /system/${LIB} yi aradığını gösterir.

namespace. name . permitted.paths

isolated dinamik bağlayıcının paylaşılan kitaplıkları ( search.paths ek olarak) yükleyebildiği iki nokta üst üste ayrılmış dizin listesi (alt dizinler dahil) true olur.

permitted.paths alt dizinleri altındaki paylaşılan kitaplıklar da yüklenebilir. Örneğin, permitted.paths /system/${LIB} ise, hem /system/${LIB}/libc.so hem de /system/${LIB}/vndk/libutils.so yüklenebilir.

isolated edilmişse false ise permitted.paths dikkate alınmaz ve bir uyarı verilir.

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

Bu /system/${LIB}/hw altındaki paylaşılan kitaplıkların yalıtılmış default ad alanına yüklenebileceğini gösterir.

Örneğin, permitted.paths olmadan libaudiohal.so , /system/${LIB}/hw/audio.a2dp.default.so dosyasını default ad alanına yükleyemez.

namespace. name . asan.permitted.paths

ASan etkinleştirildiğinde dinamik bağlayıcının paylaşılan kitaplıkları yükleyebileceği iki nokta üst üste ayrılmış dizin listesi.

namespace. name . permitted.paths ASan etkinleştirildiğinde namespace. name . permitted.paths göz ardı edilir.

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

Bu, ASan etkinleştirildiğinde /data/asan/system/${LIB}/hw veya /system/${LIB}/hw altındaki paylaşılan kitaplıkların yalıtılmış default ad alanına yüklenebileceğini gösterir.

namespace. name . visible

Programın ( libc dışında) android_get_exported_namespace() ile bir bağlayıcı ad alanı tanıtıcısı elde edip edemeyeceğini ve tanıtıcıyı android_dlopen_ext() öğesine ileterek bağlayıcı ad alanında paylaşılan bir kitaplık açıp açamayacağını belirten bir boole değeri.

visible true ise, android_get_exported_namespace() ad alanı mevcutsa her zaman tanıtıcıyı döndürür.

visible false (varsayılan) ise, android_get_exported_namespace() ad alanının varlığına bakılmaksızın her zaman NULL değerini döndürür. Paylaşılan kitaplıklar bu ad alanına yalnızca (1) bu ad alanına geri dönüş bağlantısı olan başka bir bağlayıcı ad alanı tarafından istendiğinde veya (2) bu ad alanındaki diğer paylaşılan kitaplıklar veya yürütülebilir dosyalar tarafından istendiğinde yüklenebilir.

namespace. sphal. visible = true

Bu, android_get_exported_namespace("sphal") öğesinin geçerli bir bağlayıcı ad alanı tanıtıcısı döndürebileceğini gösterir.

Bağlayıcı ad alanı oluşturma

Android 11'de, bağlayıcı yapılandırması ${android-src}/system/core/rootdir/etc içindeki düz metin dosyalarını kullanmak yerine çalışma zamanında /linkerconfig altında oluşturulur. Yapılandırma, aşağıdaki öğeleri içeren çalışma zamanı ortamına göre önyükleme sırasında oluşturulur:

  • Cihaz VNDK'yi destekliyorsa
  • Satıcı bölümünün hedef VNDK sürümü
  • Ürün bölümünün VNDK sürümü
  • Kurulu APEX modülleri

Bağlayıcı yapılandırması, bağlayıcı ad alanları arasındaki bağımlılıklar çözülerek oluşturulur. Örneğin APEX modüllerinde bağımlılık güncellemelerini içeren güncellemeler varsa bu değişiklikleri yansıtacak şekilde linker konfigürasyonu oluşturulur. Bağlayıcı yapılandırması oluşturmaya ilişkin daha fazla ayrıntıyı ${android-src}/system/linkerconfig adresinde bulabilirsiniz.

Bağlayıcı ad alanı yalıtımı

Üç konfigürasyon türü vardır. BoardConfig.mk PRODUCT_TREBLE_LINKER_NAMESPACES ve BOARD_VNDK_VERSION değerine bağlı olarak, önyükleme sırasında ilgili konfigürasyon oluşturulur.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Seçilen konfigürasyon VTS gereksinimi
true current VNDK Android 9 veya sonraki sürümlerle başlatılan cihazlar için zorunludur
Boş VNDK Lite Android 8.x ile başlatılan cihazlar için zorunludur
false Boş Legacy Treble olmayan cihazlar için

VNDK Lite yapılandırması, SP-HAL ve VNDK-SP paylaşılan kitaplıklarını izole eder. Android 8.0'da, PRODUCT_TREBLE_LINKER_NAMESPACES true olduğunda bu, dinamik bağlayıcının yapılandırma dosyası olmalıdır.

VNDK yapılandırması ayrıca SP-HAL ve VNDK-SP paylaşılan kitaplıklarını da yalıtır. Ayrıca bu yapılandırma tam dinamik bağlayıcı izolasyonu sağlar. Sistem bölümündeki modüllerin satıcı bölümlerindeki paylaşılan kitaplıklara (ve bunun tersi) bağlı olmamasını sağlar.

Android 8.1 veya üzeri sürümlerde, VNDK yapılandırması varsayılan yapılandırmadır ve BOARD_VNDK_VERSION current geçerli olarak ayarlayarak tam dinamik bağlayıcı izolasyonunun etkinleştirilmesi önemle tavsiye edilir.

VNDK yapılandırması

VNDK yapılandırması, sistem bölümü ile satıcı bölümleri arasındaki paylaşılan kitaplık bağımlılıklarını yalıtır. Önceki alt bölümde bahsedilen konfigürasyonlarla karşılaştırıldığında farklar aşağıdaki şekilde özetlenmiştir:

  • Çerçeve süreçleri

    • default , vndk , sphal ve rs ad alanları oluşturulur.
    • Tüm ad alanları yalıtılmıştır.
    • Sistem paylaşılan kitaplıkları default ad alanına yüklenir.
    • SP-HAL'ler sphal ad alanına yüklenir.
    • VNDK-SP paylaşılan kitaplıkları vndk ad alanına yüklendi.
  • Satıcı süreçleri

    • default , vndk ve system ad alanları oluşturulur.
    • default ad alanı yalıtılmıştır.
    • Satıcının paylaştığı kitaplıklar default ad alanına yüklenir.
    • VNDK ve VNDK-SP paylaşılan kitaplıkları vndk ad alanına yüklenir.
    • LL-NDK ve bağımlılıkları system ad alanına yüklenir.

Bağlayıcı ad alanları arasındaki ilişki aşağıda gösterilmiştir.

VNDK yapılandırmasında açıklanan bağlayıcı ad alanı grafiği
Şekil 1. Bağlayıcı ad alanı yalıtımı (VNDK yapılandırması)

Yukarıdaki resimde LL-NDK ve VNDK-SP , aşağıdaki paylaşılan kitaplıkları temsil eder:

  • 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

Daha fazla ayrıntıyı cihazdaki /linkerconfig/ld.config.txt dosyasında bulabilirsiniz.

VNDK Lite yapılandırması

Android 8.0'dan itibaren dinamik bağlayıcı, SP-HAL ve VNDK-SP paylaşılan kitaplıklarını, sembolleri diğer çerçeve paylaşılan kitaplıklarıyla çakışmayacak şekilde yalıtacak şekilde yapılandırılmıştır. Bağlayıcı ad alanları arasındaki ilişki aşağıda gösterilmiştir.

VNDK Lite yapılandırmasında açıklanan bağlayıcı ad alanı grafiği
Şekil 2. Bağlayıcı ad alanı yalıtımı (VNDK Lite yapılandırması)

LL-NDK ve VNDK-SP, aşağıdaki paylaşılan kitaplıkları ifade eder:

  • LL-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (yapılandırmada değil)
    • libsync.so
    • libvndksupport.so
    • libz.so (yapılandırmada VNDK-SP'ye taşındı)
  • 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

Aşağıdaki tablo, VNDK Lite yapılandırmasındaki [system] bölümünden alıntılanan çerçeve işlemlerine yönelik ad alanları yapılandırmasını listelemektedir.

Ad alanı Mülk Değer
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 (VNDK-SP için) 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 (RenderScript için) 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 (derlenmiş RS çekirdeği için)
isolated true
visible true
links default,vndk
link.default.shared_libs LL-NDK
libmediandk.so
libft2.so
link.vndk.shared_libs VNDK-SP

Aşağıdaki tablo, VNDK Lite yapılandırmasındaki [vendor] bölümünden alıntılanan satıcı işlemlerine yönelik ad alanları yapılandırmasını sunmaktadır.

Ad alanı Mülk Değer
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} (kullanımdan kaldırıldı)
/product/${LIB} (kullanımdan kaldırıldı)
isolated false

Daha fazla ayrıntıyı cihazdaki /linkerconfig/ld.config.txt dosyasında bulabilirsiniz.

Belge geçmişi

Android 11 Değişiklikleri

  • Android 11'de statik ld.config.*.txt dosyaları kod tabanından kaldırılır ve LinkerConfig, bunları çalışma zamanında oluşturur.

Android 9 değişiklikleri

  • Android 9'da, vndk bağlayıcı ad alanı satıcı işlemlerine eklenir ve VNDK paylaşılan kitaplıkları, varsayılan bağlayıcı ad alanından yalıtılır.
  • PRODUCT_FULL_TREBLE daha spesifik PRODUCT_TREBLE_LINKER_NAMESPACES ile değiştirin.
  • Android 9, aşağıdaki dinamik bağlayıcı yapılandırma dosyalarının adlarını değiştirir.
    Android 8.x Android 9 Tanım
    ld.config.txt.in ld.config.txt Çalışma zamanı bağlayıcı ad alanı izolasyonuna sahip cihazlar için
    ld.config.txt ld.config.vndk_lite.txt VNDK-SP bağlayıcı ad alanı izolasyonuna sahip cihazlar için
    ld.config.legacy.txt ld.config.legacy.txt Android 7.x veya daha eski sürümleri çalıştıran eski cihazlar için
  • android.hardware.graphics.allocator@2.0.so kaldırın.
  • product ve odm bölümleri eklendi.