مساحة اسم الرابط

يعالج الرابط الديناميكي تحديين في تصميم Treble VNDK:

  • يتم تحميل مكتبات SP-HAL المشتركة وتبعياتها ، بما في ذلك مكتبات VNDK-SP ، في عمليات إطار العمل. يجب أن تكون هناك بعض الآليات لمنع تعارض الرموز.
  • يمكن أن يقدم dlopen ( dlopen() و android_dlopen_ext() بعض تبعيات وقت التشغيل غير المرئية في وقت الإنشاء ويمكن أن يكون من الصعب اكتشافها باستخدام التحليل الثابت.

يمكن حل هذين التحديين من خلال آلية مساحة اسم الرابط . يتم توفير هذه الآلية بواسطة الرابط الديناميكي. يمكنه عزل المكتبات المشتركة في مساحات أسماء روابط مختلفة بحيث لا تتعارض المكتبات التي تحمل نفس اسم المكتبة ولكن برموز مختلفة.

من ناحية أخرى ، توفر آلية مساحة اسم الرابط المرونة بحيث يمكن تصدير بعض المكتبات المشتركة بواسطة مساحة اسم رابط واستخدامها بواسطة مساحة اسم رابط أخرى. يمكن أن تصبح هذه المكتبات المشتركة المصدرة واجهات برمجة تطبيقات تكون عامة للبرامج الأخرى أثناء إخفاء تفاصيل التنفيذ الخاصة بها داخل مساحات أسماء الروابط الخاصة بها.

على سبيل المثال ، /system/lib[64]/libcutils.so و /system/lib[64]/vndk-sp-${VER}/libcutils.so هما مكتبتان مشتركتان. يمكن أن يكون لهاتين المكتبتين رموز مختلفة. يتم تحميلها في مساحات أسماء مختلفة للرابط بحيث يمكن أن تعتمد وحدات إطار العمل على /system/lib[64]/libcutils.so ويمكن أن تعتمد مكتبات SP-HAL المشتركة على /system/lib[64]/vndk-sp-${VER}/libcutils.so .

من ناحية أخرى ، يعد /system/lib[64]/libc.so مثالاً على مكتبة عامة يتم تصديرها بواسطة مساحة اسم رابط ويتم استيرادها إلى العديد من مساحات أسماء الروابط. يتم تحميل تبعيات /system/lib[64]/libc.so ، مثل libnetd_client.so ، في مساحة الاسم التي يوجد /system/lib[64]/libc.so . لن تتمكن مساحات الأسماء الأخرى من الوصول إلى تلك التبعيات. تلخص هذه الآلية تفاصيل التنفيذ مع توفير الواجهات العامة.

كيف يعمل؟

الرابط الديناميكي مسؤول عن تحميل المكتبات المشتركة المحددة في إدخالات DT_NEEDED أو المكتبات المشتركة المحددة بواسطة وسيطة dlopen ( dlopen() أو android_dlopen_ext() . في كلتا الحالتين ، يجد الرابط الديناميكي مساحة اسم الرابط حيث يقيم المتصل ويحاول تحميل التبعيات في نفس مساحة اسم الرابط. إذا تعذر على الرابط الديناميكي تحميل المكتبة المشتركة في مساحة اسم الرابط المحددة ، فإنه يطلب مساحة اسم الرابط المرتبط للمكتبات المشتركة المصدرة.

تنسيق ملف التكوين

يعتمد تنسيق ملف التكوين على تنسيق ملف 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}

يتضمن ملف التكوين:

  • العديد من خصائص تعيين قسم الدليل في البداية للرابط الديناميكي لتحديد القسم الفعال.
  • عدة أقسام لتهيئة مساحات أسماء الروابط:
    • يحتوي كل قسم على العديد من مساحات الأسماء (رؤوس الرسم البياني) والعديد من الروابط الاحتياطية بين مساحات الأسماء (أقواس الرسم البياني).
    • لكل مساحة اسم عزلها ومسارات البحث والمسارات المسموح بها وإعدادات الرؤية.

توضح الجداول أدناه معنى كل عقار بالتفصيل.

خاصية تعيين قسم الدليل

ملكية وصف مثال

dir. name

مسار إلى دليل ينطبق عليه قسم [ name ] .

تقوم كل خاصية بتعيين الملفات التنفيذية الموجودة ضمن الدليل إلى قسم تكوين مساحات أسماء الروابط. قد تكون هناك خاصيتان (أو أكثر) لهما نفس name ولكنهما يشيران إلى أدلة مختلفة.

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

يشير هذا إلى أن التكوين المحدد في قسم [system] ينطبق على الملفات التنفيذية التي تم تحميلها من إما /system/bin أو /system/xbin .

ينطبق التكوين المحدد في قسم [vendor] على الملفات التنفيذية التي تم تحميلها من /vendor/bin .

خصائص العلاقة

ملكية وصف مثال
additional. namespaces

قائمة مفصولة بفواصل لمساحات الأسماء الإضافية (بالإضافة إلى مساحة الاسم default ) للقسم.

additional. namespaces = sphal, vndk

يشير هذا إلى وجود ثلاث مساحات أسماء ( default ، و sphal ، و vndk ) في تكوين [system] .

namespace. name . links

قائمة بمساحات الاسم الاحتياطية مفصولة بفواصل.

إذا تعذر العثور على مكتبة مشتركة في مساحة الاسم الحالية ، فإن الرابط الديناميكي يحاول تحميل المكتبة المشتركة من مساحات الأسماء الاحتياطية. مساحة الاسم المحددة في بداية القائمة لها أولوية أعلى.

namespace. sphal. links = default, vndk

إذا طلبت مكتبة مشتركة أو قابلة للتنفيذ مكتبة مشتركة لا يمكن تحميلها في مساحة اسم sphal ، يحاول الرابط الديناميكي تحميل المكتبة المشتركة من مساحة الاسم default .

وبعد ذلك ، إذا تعذر تحميل المكتبة المشتركة من مساحة الاسم default أيضًا ، فسيحاول الرابط الديناميكي تحميل المكتبة المشتركة من مساحة اسم vndk .

أخيرًا ، إذا فشلت جميع المحاولات ، يقوم الرابط الديناميكي بإرجاع خطأ.

namespace. name . link. other . shared_libs

قائمة مفصولة بنقطتين للمكتبات المشتركة التي يمكن البحث عنها في مساحات الأسماء other عندما لا يمكن العثور على هذه المكتبات في مساحة name .

لا يمكن استخدام هذه الخاصية مع namespace. name . link. other . allow_all_shared_libs .

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

يشير هذا إلى أن الارتباط الاحتياطي يقبل فقط libc.so أو libm.so كاسم المكتبة المطلوبة. الرابط الديناميكي يتجاهل الارتباط الاحتياطي من sphal إلى مساحة الاسم default إذا كان اسم المكتبة المطلوب ليس libc.so أو libm.so

namespace. name . link. other . allow_all_shared_libs

قيمة منطقية تشير إلى ما إذا كان يمكن البحث في جميع المكتبات المشتركة في مساحة الاسم other عندما يتعذر العثور على هذه المكتبات في مساحة name .

لا يمكن استخدام هذه الخاصية مع namespace. name . link. other . shared_libs .

namespace. vndk. link. sphal. allow_all_shared_libs = true

يشير هذا إلى أن جميع أسماء المكتبات يمكنها السير عبر الرابط الاحتياطي من vndk إلى مساحة الاسم sphal .

خصائص Namespace

ملكية وصف مثال
namespace. name . isolated

قيمة منطقية تشير إلى ما إذا كان يجب على الرابط الديناميكي التحقق من مكان تواجد المكتبة المشتركة.

إذا كان isolated true ، يمكن فقط تحميل المكتبات المشتركة الموجودة في أحد أدلة search.paths (باستثناء الدلائل الفرعية) أو الموجودة ضمن أحد أدلة المسار permitted.paths (بما في ذلك الأدلة الفرعية).

إذا كان isolated false (افتراضيًا) ، فلن يتحقق الرابط الديناميكي من مسار المكتبات المشتركة.

namespace. sphal. isolated = true

يشير هذا إلى أنه لا يمكن تحميل سوى المكتبات المشتركة في search.paths أو ضمن permitted.paths في مساحة اسم sphal .

namespace. name . search.paths

قائمة أدلة مفصولة بنقطتين للبحث عن المكتبات المشتركة.

يتم إلحاق الدلائل المحددة في search.paths إلى اسم المكتبة المطلوب إذا لم تحدد استدعاءات الوظائف لإدخالات dlopen dlopen() أو DT_NEEDED المسار الكامل. الدليل المحدد في بداية القائمة له أولوية أعلى.

عندما يكون isolated true ، يمكن تحميل المكتبات المشتركة الموجودة في أحد أدلة search.paths (باستثناء الدلائل الفرعية) بغض النظر عن خاصية permitted.paths .

على سبيل المثال ، إذا كانت search.paths هي /system/${LIB} و permitted.paths فارغة ، فيمكن تحميل /system/${LIB}/libc.so ولكن /system/${LIB}/vndk/libutils.so لا يمكن تحميلها.

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

يشير هذا إلى أن الرابط الديناميكي يبحث /system/${LIB} عن المكتبات المشتركة.

namespace. name . asan.search.paths

قائمة أدلة مفصولة بنقطتين للبحث عن المكتبات المشتركة عند تمكين AddressSanitizer (ASan) .

namespace. name . search.paths يتم تجاهل namespace. name . search.paths عند تمكين ASan .

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

يشير هذا إلى أنه عند تمكين ASan ، يتم البحث عن الرابط الديناميكي /data/asan/system/${LIB} أولاً ثم عمليات البحث /system/${LIB} .

namespace. name . permitted.paths

قائمة أدلة مفصولة بنقطتين (بما في ذلك الدلائل الفرعية) حيث يمكن للرابط الديناميكي تحميل المكتبات المشتركة (بالإضافة إلى search.paths ) عندما يكون isolated true .

يمكن أيضًا تحميل المكتبات المشتركة الموجودة ضمن الدلائل الفرعية لـ permitted.paths . على سبيل المثال ، إذا كان permitted.paths هو /system/${LIB} ، فيمكن تحميل كل من /system/${LIB}/libc.so و /system/${LIB}/vndk/libutils.so .

إذا كان isolated false ، يتم تجاهل permitted.paths ويتم إصدار تحذير.

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

يشير هذا إلى أنه يمكن تحميل المكتبات المشتركة ضمن /system/${LIB}/hw في مساحة الاسم default المعزولة.

على سبيل المثال ، بدون permitted.paths ، لا يمكن libaudiohal.so تحميل /system/${LIB}/hw/audio.a2dp.default.so في مساحة الاسم default .

namespace. name . asan.permitted.paths

قائمة أدلة مفصولة بنقطتين حيث يمكن للرابط الديناميكي تحميل المكتبات المشتركة عند تمكين ASan .

namespace. name . permitted.paths يتم تجاهل namespace. name . permitted.paths عند تمكين ASan .

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

يشير هذا إلى أنه عند تمكين ASan ، يمكن تحميل المكتبات المشتركة ضمن /data/asan/system/${LIB}/hw أو /system/${LIB}/hw إلى مساحة الاسم default المعزولة.

namespace. name . visible

قيمة منطقية تشير إلى ما إذا كان البرنامج (بخلاف libc ) يمكنه الحصول على مؤشر مساحة اسم رابط باستخدام android_get_exported_namespace() وفتح مكتبة مشتركة في مساحة اسم الرابط عن طريق تمرير المقبض إلى android_dlopen_ext() .

إذا كان visible true ، android_get_exported_namespace() يعرض دائمًا المقبض في حالة وجود مساحة الاسم.

إذا كان الخيار " visible " false (افتراضي) ، android_get_exported_namespace() دائمًا بإرجاع NULL بغض النظر عن وجود مساحة الاسم. يمكن تحميل المكتبات المشتركة في مساحة الاسم هذه فقط إذا (1) طلبت ذلك من خلال مساحة اسم رابط أخرى بها رابط احتياطي لمساحة الاسم هذه ، أو (2) طلبت المكتبات المشتركة أو الملفات التنفيذية الأخرى في مساحة الاسم هذه.

namespace. sphal. visible = true

يشير هذا إلى أن android_get_exported_namespace("sphal") يمكنه إرجاع مؤشر مساحة اسم رابط صالح.

رابط إنشاء مساحة الاسم

في Android 11 ، يتم إنشاء تكوين الرابط في وقت التشغيل ضمن /linkerconfig بدلاً من استخدام ملفات نصية عادية في ${android-src}/system/core/rootdir/etc . يتم إنشاء التكوين في وقت التمهيد بناءً على بيئة وقت التشغيل ، والتي تتضمن العناصر التالية:

  • إذا كان الجهاز يدعم VNDK
  • إصدار VNDK الهدف لقسم البائع
  • إصدار VNDK الخاص بقسم المنتج
  • وحدات APEX المثبتة

يتم تكوين تكوين الرابط عن طريق حل التبعيات بين مساحات أسماء الروابط. على سبيل المثال ، في حالة وجود أية تحديثات على وحدات APEX النمطية التي تتضمن تحديثات التبعية ، يتم إنشاء تكوين الرابط الذي يعكس هذه التغييرات. يمكن العثور على مزيد من التفاصيل حول إنشاء تهيئة الرابط في ${android-src}/system/linkerconfig .

عزل مساحة اسم الرابط

هناك ثلاثة أنواع من التكوين. اعتمادًا على قيمة PRODUCT_TREBLE_LINKER_NAMESPACES و BOARD_VNDK_VERSION في BoardConfig.mk ، يتم إنشاء التكوين المقابل في وقت التمهيد.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
التكوين المحدد متطلبات VTS
true current VNDK إلزامي للأجهزة التي تعمل بنظام Android 9 أو أعلى
فارغة VNDK Lite إلزامي للأجهزة التي تعمل بنظام Android 8.x
false فارغة Legacy للأجهزة غير الثلاثية

يعزل تكوين VNDK Lite المكتبات المشتركة SP-HAL و VNDK-SP. في Android 8.0 ، يجب أن يكون هذا ملف التكوين للرابط الديناميكي عندما يكون PRODUCT_TREBLE_LINKER_NAMESPACES true .

يعزل تكوين VNDK أيضًا مكتبات SP-HAL و VNDK-SP المشتركة. بالإضافة إلى ذلك ، يوفر هذا التكوين عزل الرابط الديناميكي الكامل. يضمن أن الوحدات النمطية في قسم النظام لن تعتمد على المكتبات المشتركة في أقسام البائع والعكس صحيح.

في Android 8.1 أو أعلى ، يعد تكوين VNDK هو التكوين الافتراضي ويوصى بشدة بتمكين عزل الرابط الديناميكي الكامل عن طريق تعيين BOARD_VNDK_VERSION على current .

تكوين VNDK

يعزل تكوين VNDK تبعيات المكتبة المشتركة بين قسم النظام وأقسام البائع. مقارنة بالتكوينات المذكورة في القسم الفرعي السابق ، تم تحديد الاختلافات على النحو التالي:

  • عمليات الإطار

    • يتم إنشاء مساحات الأسماء default ، و vndk ، و sphal ، و rs .
    • جميع مساحات الأسماء معزولة.
    • يتم تحميل مكتبات النظام المشتركة في مساحة الاسم default .
    • يتم تحميل SP-HALs في مساحة الاسم sphal .
    • مكتبات VNDK-SP المشتركة التي تم تحميلها في مساحة اسم vndk .
  • عمليات البائع

    • يتم إنشاء مساحات الأسماء default ، و vndk ، system .
    • مساحة الاسم default معزولة.
    • يتم تحميل مكتبات البائعين المشتركة في مساحة الاسم default .
    • يتم تحميل مكتبات VNDK و VNDK-SP المشتركة في مساحة اسم vndk .
    • يتم تحميل LL-NDK وتبعياتها في مساحة اسم system .

العلاقة بين مساحات الأسماء رابط موضحة أدناه.

مخطط مساحة اسم الرابط الموضح في تكوين VNDK
الشكل 1. عزل مساحة اسم الرابط (تكوين VNDK)

في الصورة أعلاه ، يقف LL-NDK و VNDK-SP للمكتبات المشتركة التالية:

  • 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

يمكنك العثور على مزيد من التفاصيل في /linkerconfig/ld.config.txt من الجهاز.

تكوين VNDK Lite

اعتبارًا من Android 8.0 ، تم تكوين الرابط الديناميكي لعزل المكتبات المشتركة SP-HAL و VNDK-SP بحيث لا تتعارض رموزها مع مكتبات الإطار المشتركة الأخرى. العلاقة بين مساحات اسم الرابط موضحة أدناه.

مخطط مساحة اسم الرابط الموضح في تكوين VNDK Lite
الشكل 2. عزل مساحة اسم الرابط (تكوين VNDK Lite)

حامل LL-NDK و VNDK-SP للمكتبات المشتركة التالية:

  • LL-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (ليس في التكوين)
    • libsync.so
    • libvndksupport.so
    • libz.so (تم نقله إلى VNDK-SP في التكوين)
  • 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

يسرد الجدول أدناه تكوين مساحات الأسماء لعمليات إطار العمل ، والمقتطف من قسم [system] في تكوين VNDK Lite.

مساحة الاسم ملكية قيمة
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) 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) 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 (لـ RS kernel المترجمة)
isolated true
visible true
links default,vndk
link.default.shared_libs LL-NDK
libmediandk.so
libft2.so
link.vndk.shared_libs VNDK-SP

يعرض الجدول أدناه تكوين مساحات الأسماء لعمليات البائع ، والذي تم اقتباسه من قسم [vendor] في تكوين VNDK Lite.

مساحة الاسم ملكية قيمة
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} (مهمل)
/product/${LIB} (مهمل)
isolated false

يمكن العثور على مزيد من التفاصيل في /linkerconfig/ld.config.txt من الجهاز.

سجل المستند

تغييرات Android 11

  • في Android 11 ، تتم إزالة ملفات ld.config.*.txt الثابتة من قاعدة التعليمات البرمجية ويقوم LinkerConfig بإنشائها في وقت التشغيل بدلاً من ذلك.

يتغير نظام Android 9

  • في Android 9 ، تتم إضافة مساحة اسم رابط vndk إلى عمليات البائعين ويتم عزل مكتبات VNDK المشتركة عن مساحة اسم الرابط الافتراضية.
  • استبدل PRODUCT_FULL_TREBLE بـ PRODUCT_TREBLE_LINKER_NAMESPACES أكثر تحديدًا.
  • يغير Android 9 أسماء ملفات تكوين الرابط الديناميكي التالية.
    أندرويد 8.x أندرويد 9 وصف
    ld.config.txt.in ld.config.txt بالنسبة للأجهزة التي تحتوي على عزل مساحة اسم رابط وقت التشغيل
    ld.config.txt ld.config.vndk_lite.txt للأجهزة مع عزل مساحة اسم رابط VNDK-SP
    ld.config.legacy.txt ld.config.legacy.txt للأجهزة القديمة التي تعمل بنظام Android 7.x أو إصدار أقل
  • إزالة android.hardware.graphics.allocator@2.0.so .
  • تمت إضافة أقسام product و odm .