Bağlayıcı ad alanı

Dinamik bağlayıcı, Treble VNDK tasarımında iki zorlukla mücadele eder:

  • VNDK-SP kitaplıkları da dahil olmak üzere SP-HAL paylaşılan kitaplıkları ve bağımlılıkları, çerçeve süreçlerine yüklenir. Sembol çakışmalarını önlemek için bazı mekanizmalar olmalıdır.
  • dlopen() ve android_dlopen_ext(), derleme sırasında görünmeyen ve statik analiz kullanılarak tespit edilmesi zor olabilen bazı çalışma zamanı bağımlılıkları oluşturabilir.

Bu iki sorun, bağlayıcı ad alanı mekanizmasıyla çözülebilir. Bu mekanizma, dinamik bağlayıcı tarafından sağlanır. Aynı kitaplık adına ancak farklı sembollere sahip kitaplıkların çakışmaması için paylaşılan kitaplıkları farklı bağlayıcı ad alanlarında izole edebilir.

Ö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. Bu dışa aktarılan paylaşılan kitaplıklar, bağlayıcı ad alanlarında uygulama ayrıntılarını 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 kitaplıktır. Bu iki kitaplıkta farklı semboller olabilir. Çerçeve modüllerinin /system/lib[64]/libcutils.so'ya, SP-HAL paylaşılan kitaplıklarının ise /system/lib[64]/vndk-sp-${VER}/libcutils.so'ye bağlı olabilmesi için farklı bağlayıcı ad alanlarına yüklenirler.

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

İşleyiş şekli

Dinamik bağlayıcı, DT_NEEDED girişlerinde belirtilen paylaşılan kitaplıkları veya dlopen() ya da android_dlopen_ext() bağımsız değişkeni tarafından belirtilen paylaşılan kitaplıkları yüklemekten 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ına sorar.

Yapılandırma dosyası biçimi

Yapılandırma dosyası biçimi, INI dosya biçimine dayanır. Tipik bir yapılandırma dosyası şu şekilde görünür:

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 etkin bölümü seçmesi için başlangıçta birkaç dizin bölümü eşleme özelliği.
  • Çeşitli bağlayıcı ad alanı yapılandırma bölümleri:
    • Her bölüm birkaç ad alanı (grafik köşeleri) ve ad alanları arasında birkaç yedek bağlantı (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

Özellik Açıklama Örnek

dir.name

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

Her özellik, dizindeki yürütülebilir dosyaları bir bağlayıcı ad alanları yapılandırma bölümüyle eşler. Aynı name özelliğine sahip ancak farklı dizinlere yönlendiren 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'den 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 dosyalara uygulanır.

İlişki özellikleri

Özellik Açıklama Örnek
additional.namespaces

Bölüm için default ad alanına ek olarak virgülle ayrılmış ek ad alanları listesi.

additional.namespaces = sphal,vndk

Bu, [system] yapılandırmasında üç ad alanı (default, sphal ve vndk) olduğunu gösterir.

namespace.name.links

Yedek ad alanlarının virgülle ayrılmış listesi.

Paylaşılan kitaplık geçerli ad alanında 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

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

Ardından, 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

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

Bu mülk namespace.name.link.other.allow_all_shared_libs ile kullanılamaz.

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

Bu, yedek bağlantının istenen kitaplık adı olarak yalnızca libc.so veya libm.so değerini kabul ettiğini gösterir. Dinamik bağlayıcı, istenen kitaplık adı libc.so veya libm.so değilse sphal ad alanından default ad alanına geri dönüş bağlantısını yoksayar.

namespace.name.link.other.allow_all_shared_libs

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 mülk namespace.name.link.other.shared_libs ile kullanılamaz.

namespace.vndk.link.sphal.allow_all_shared_libs = true

Bu, tüm kitaplık adlarının vndk ad alanından sphal ad alanına yedek bağlantı üzerinden geçebileceğini gösterir.

Ad alanı özellikleri

Özellik Açıklama Örnek
namespace.name.isolated

Dinamik bağlayıcının, paylaşılan kitaplığın bulunduğu yeri kontrol edip etmeyeceğini belirten bir boole değeri.

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

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

namespace.sphal.isolated = true

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

namespace.name.search.paths

Paylaşılan kitaplıkların aranacağı iki nokta üst üste ile ayrılmış dizin listesi.

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

isolated true olduğunda, 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 değeri /system/${LIB} ise ve permitted.paths boşsa /system/${LIB}/libc.so yüklenebilir ancak /system/${LIB}/vndk/libutils.so yüklenemez.

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

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

namespace.name.asan.search.paths

AddressSanitizer (ASan) etkinleştirildiğinde paylaşılan kitaplıkların aranacağı iki nokta üst üste ile ayrılmış dizin listesi.

ASan etkinleştirildiğinde namespace.name.search.paths yoksayılır.

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}, ardından /system/${LIB} araması yaptığını gösterir.

namespace.name.permitted.paths

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

permitted.paths alt dizinlerindeki 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 değeri false ise permitted.paths yoksayılır ve 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 öğesini 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 ile ayrılmış dizin listesi.

ASan etkinleştirildiğinde namespace.name.permitted.paths yoksayılır.

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

libc dışındaki programın, android_get_exported_namespace() ile bağlayıcı ad alanı tutacını alıp tutamayacağını ve tutacı android_dlopen_ext()'ye 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: Ad alanı varsa android_get_exported_namespace() her zaman tutma yerini döndürür.

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

namespace.sphal.visible = true

Bu, android_get_exported_namespace("sphal") geçerli bir bağlayıcı ad alanı işleyicisi 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çinde düz metin dosyaları 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 başlatma sırasında oluşturulur:

  • Cihaz VNDK'yı destekliyorsa
  • Tedarikçi bölümünün hedef VNDK sürümü
  • Ürün bölümünün VNDK sürümü
  • Yüklü 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, bağımlılık güncellemelerini içeren APEX modüllerinde herhangi bir güncelleme varsa bu değişiklikleri yansıtan bağlayıcı yapılandırması oluşturulur. Bağlayıcı yapılandırması oluşturmayla ilgili daha fazla bilgiyi ${android-src}/system/linkerconfig bölümünde bulabilirsiniz.

Bağlayıcı ad alanı izolasyonu

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

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Seçili yapılandırma VTS şartı
true current VNDK Android 9 veya sonraki sürümlerle kullanıma sunulan cihazlarda zorunludur.
Boş VNDK Lite Android 8.x ile kullanıma sunulan cihazlarda zorunludur.
false Boş Legacy Treble destekli olmayan cihazlar için

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

VNDK yapılandırması, 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. Bu, sistem bölümündeki modüllerin tedarikçi bölümlerindeki paylaşılan kitaplıklara ve bunun tersi yönde bağımlı olmamasını sağlar.

Android 8.1 veya sonraki sürümlerde VNDK yapılandırması varsayılan yapılandırmadır. BOARD_VNDK_VERSION değerini current olarak ayarlayarak tam dinamik bağlayıcı yalıtımını etkinleştirmeniz ö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 belirtilen yapılandırmalara kıyasla farklılıklar aşağıdaki gibi özetlenmiştir:

  • Çerçeve süreçleri

    • default, vndk, sphal ve rs ad alanları oluşturulur.
    • Tüm ad alanları izole edilir.
    • Sistem tarafından 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üklenir.
  • Tedarikçi süreçleri

    • default, vndk ve system ad alanları oluşturulur.
    • default ad alanı yalıtılmıştır.
    • Tedarikçi tarafından paylaşılan 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

1. şekil. Bağlayıcı ad alanı izolasyonu (VNDK yapılandırması).

Yukarıdaki resimde LL-NDK ve VNDK-SP, aşağıdaki paylaşılan kitaplıkları ifade 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 bilgiyi cihazdaki /linkerconfig/ld.config.txt bölümünde 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ı, sembollerinin diğer çerçeve paylaşılan kitaplıklarıyla çakışmayacak şekilde izole etmek üzere yapılandırılı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ı izolasyonu (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 tabloda, VNDK Lite yapılandırmasındaki [system] bölümünden alıntılanan, çerçeve süreçleri için ad alanı yapılandırması listelenmiştir.

Ad alanı Özellik 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 tabloda, VNDK Lite yapılandırmasındaki [vendor] bölümünden alınmış olan, satıcı süreçleri için ad alanı yapılandırması sunulmaktadır.

Ad alanı Özellik 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 bilgiyi /linkerconfig/ld.config.txt bölümünde bulabilirsiniz.

Belge geçmişi

Android 11'deki Değişiklikler

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

Android 9'daki değişiklikler

  • 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 yerine daha spesifik bir PRODUCT_TREBLE_LINKER_NAMESPACES kullanın.
  • 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 Açıklama
    ld.config.txt.in ld.config.txt Çalışma zamanı bağlayıcı ad alanı izolasyonu olan cihazlar için
    ld.config.txt ld.config.vndk_lite.txt VNDK-SP bağlayıcı ad alanı izolasyonu olan 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 öğesini kaldırın.
  • product ve odm bölümleri eklenir.