Bağlayıcı ad alanı

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

  • SP-HAL paylaşılan kitaplıkları ve VNDK-SP kitaplıkları da dahil olmak üzere bağımlılıklarını ç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 zamanında görünmeyen ve statik analiz kullanılarak tespit edilmesi zor olabilecek bazı çalışma zamanı bağımlılıkları getirebilir.

Bu iki sorun, bağlantılayıcı ad alanı mekanizmasıyla çözülebilir. Bu mekanizma dinamik bağlayıcı tarafından sağlanır. Aynı kitaplık adına sahip ancak farklı sembollere sahip kitaplıklar ç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. Dışa aktarılan bu paylaşılan kitaplıklar, uygulama programlama arayüzleri haline gelebilir. Bu arayüzler, uygulama ayrıntılarını bağlayıcı ad alanlarında gizleyerek diğer programlar tarafından kullanılabilir.

Ö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ığın farklı sembolleri olabilir. Çerçeve modüllerinin /system/lib[64]/libcutils.so'e, SP-HAL paylaşılan kitaplıklarının ise /system/lib[64]/vndk-sp-${VER}/libcutils.so'a bağımlı olabilmesi için farklı bağlayıcı ad alanlarında yüklenir.

Diğer 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 aktarılan bir herkese açık kitaplık örneğidir. /system/lib[64]/libc.so'ün bağımlılıkları (ör. libnetd_client.so), /system/lib[64]/libc.so'ün bulunduğu ad alanına yüklenir. Diğer ad alanlarının bu bağımlılıklara erişimi olmaz. Bu mekanizma, herkese açık arayüzleri 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ğlı bağlayıcı ad alanını ister.

Yapılandırma dosyası biçimi

Yapılandırma dosyası biçimi, INI dosya biçimini temel alı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 etkili bölümü seçmesi için başlangıçta kullanılan çeşitli dizin bölümü eşleme özellikleri.
  • Birkaç bağlayıcı ad alanı yapılandırma bölümü:
    • 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 yalıtımı, 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, dizin altındaki yürütülebilir dosyaları bir bağlayıcı ad alanı yapılandırması bölümüne eşler. Aynı name değerine sahip ancak farklı dizinleri gösteren iki (veya daha fazla) mülk 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'dan yüklenen yürütülebilir dosyalara uygulanır.

İlişki özellikleri

Özellik Açıklama Örnek
additional.namespaces

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

additional.namespaces = sphal,vndk

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

namespace.name.links

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

Mevcut 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ının önceliği daha yüksektir.

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 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

name ad alanında bulunamayan paylaşılan kitaplıkların, other ad alanlarında aranabileceği iki nokta işareti ile ayrılmış liste.

Bu özellik 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'ı kabul ettiğini gösterir. İstenilen kitaplık adı libc.so veya libm.so değilse dinamik bağlayıcı, sphal ad alanından default ad alanına giden yedek bağlantıyı yoksayar.

namespace.name.link.other.allow_all_shared_libs

name ad alanında bulunamayan 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 alanından sphal ad alanına yedek bağlantıda 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ği

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

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

namespace.sphal.isolated = true

Bu, yalnızca search.paths içinde 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ğı dizinlerin iki nokta üst üste ile ayrılmış listesi.

dlopen() veya DT_NEEDED girişlerinde işlev çağrıları tam yolu belirtmiyorsa search.paths öğesinde belirtilen dizinler, 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 bulunan (alt dizinler hariç) ortak kitaplıklar, permitted.paths mülkünden bağımsız olarak yüklenebilir.

Örneğin, search.paths /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ğı dizinlerin iki nokta üst üste ile ayrılmış 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} sonradan /system/${LIB} araması yaptığını gösterir.

namespace.name.permitted.paths

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

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 bir uyarı gönderilir.

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 dizinlerin iki nokta üst üste ile ayrılmış 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, izole 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ı arabirimi alıp alamayacağı ve android_dlopen_ext()'ye ileterek android_get_exported_namespace()'yi bağlayıcı ad alanında açabileceğini belirten bir boole değeri.

visible değeri true ise android_get_exported_namespace(), ad alanı varsa her zaman herkese açık kullanıcı adını döndürür.

visible false ise (varsayılan), ad alanının varlığından bağımsız olarak android_get_exported_namespace() her zaman NULL döndürür. Paylaşılan kitaplıklar bu ad alanına yalnızca (1) bu ad alanına yedek 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 yüklenebilir.

namespace.sphal.visible = true

Bu, android_get_exported_namespace("sphal") etiketinin geçerli bir bağlayıcı ad alanı işleyici döndürebileceğini gösterir.

Bağlantı oluşturucu ad alanı oluşturma

Android 11'de, bağlayıcı yapılandırması ${android-src}/system/core/rootdir/etc altında düz metin dosyaları kullanmak yerine /linkerconfig altında çalışma zamanı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ın çözümlenmesiyle oluşturulur. Örneğin, APEX modüllerinde bağımlılık güncellemeleri içeren güncellemeler varsa bağlayıcı yapılandırması bu değişiklikleri yansıtacak şekilde oluşturulur. Bağlayıcı yapılandırması oluşturmayla ilgili daha fazla bilgiyi ${android-src}/system/linkerconfig bölümünde bulabilirsiniz.

Bağlantı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ğerlerine 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 gereksinimi
true current VNDK Android 9 veya sonraki sürümlerle kullanıma sunulan cihazlar için zorunludur
Boş VNDK Lite Android 8.x ile kullanıma sunulan 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ı ayırır. 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ı, SP-HAL ve VNDK-SP paylaşılan kitaplıkları da izole eder. Ayrıca bu yapılandırma, tam dinamik bağlayıcı izolasyonu sağlar. Sistem bölümündeki modüllerin, tedarikçi firma bölümlerindeki paylaşılan kitaplıklara bağlı olmamasını ve bunun tam tersini sağlar.

Android 8.1 veya sonraki sürümlerde varsayılan yapılandırma VNDK yapılandırmasıdır ve BOARD_VNDK_VERSION değerini current olarak ayarlayarak tam dinamik bağlayıcı izolasyonunu etkinleştirmeniz önemle tavsiye edilir.

VNDK yapılandırması

VNDK yapılandırması, paylaşılan kitaplık bağımlılıkları sistem bölümü ile tedarikçi bölümleri arasında izole eder. Önceki alt bölümde belirtilen yapılandırmalara kıyasla farklılıklar aşağıdaki gibi özetlenebilir:

  • Çerçeve süreçleri

    • default, vndk, sphal ve rs ad alanlarının oluşturulması
    • Tüm ad alanları birbirinden izole edilir.
    • Sistem paylaşılan kitaplıkları default ad alanına yüklenir.
    • SP-HAL'ler sphal ad alanına yüklenir.
    • vndk ad alanına yüklenen VNDK-SP paylaşılan kitaplıkları.
  • Tedarikçi süreçleri

    • default, vndk ve system ad alanları oluşturulur.
    • default ad alanı izole edilmiştir.
    • Tedarikçi firmanın 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ğlantı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ı 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ı, simgelerinin diğer çerçeve paylaşılan kitaplıklarıyla çakışmaması için izole edecek şekilde yapılandırılır. Bağlantı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 alanına 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, çerçeve işlemleri için ad alanı yapılandırması listelenmektedir. Bu yapılandırma, VNDK Lite yapılandırmasındaki [system] bölümünden alınmıştır.

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ında [vendor] bölümünden alınan tedarikçi firma işlemleri 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 cihazdaki /linkerconfig/ld.config.txt bölümünde bulabilirsiniz.

Doküman 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ı tedarikçi süreçlerine eklenir ve VNDK paylaşılan kitaplıkları varsayılan bağlayıcı ad alanından ayrılır.
  • PRODUCT_FULL_TREBLE yerine daha spesifik bir PRODUCT_TREBLE_LINKER_NAMESPACES ifadesi girin.
  • 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 eklendi.