מרחב שמות של מקשר

המנגנון לקישור דינמי מתמודד עם שני אתגרים בעיצוב Treble VNDK:

  • ספריות משותפות של SP-HAL וקשרי התלות שלהן, כולל VNDK-SP של הספריות נטענות לתהליכי framework. צריכות להיות כמה מנגנונים למניעת התנגשויות בין סמלים.
  • dlopen() ו-android_dlopen_ext() יכולים להציג יחסי תלות מסוימים של סביבת זמן הריצה שלא ניתן לראות בזמן ה-build, והם עלולים שקשה לזהות באמצעות ניתוח סטטי.

אפשר לפתור את שני האתגרים האלה באמצעות מרחב השמות של המקשר על מנגנוני תשומת לב. המנגנון הזה מסופק על-ידי המקשר הדינמי. הוא הוא יכול לבודד את הספריות המשותפות במרחבי שמות של מקשרים שונים, ספריות שהשם שלהן זהה אבל עם סמלים שונים לא יתנגשו.

מצד שני, מנגנון מרחב השמות המקשר מספק את הגמישות כדי שאפשר יהיה לייצא חלק מהספריות המשותפות באמצעות מרחב שמות של מקשר ולהשתמש בהן מרחב שמות אחר של מקשר. הספריות המשותפות המיוצאות יכולות להפוך ממשקי תכנות יישומים שגלויים לכולם לתוכנות אחרות בזמן להסתיר את פרטי ההטמעה במרחבי השמות המקשרים.

לדוגמה, /system/lib[64]/libcutils.so וגם /system/lib[64]/vndk-sp-${VER}/libcutils.so הם שני סוגים משותפים של הספריות. לשתי הספריות האלה יכולים להיות סמלים שונים. הם נטענו במרחבי שמות שונים לקישור, כך שמודולים של framework יוכלו להיות תלויים ספריות משותפות של /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 גרים ב-Google. למרחבי שמות אחרים לא תהיה גישה ליחסי התלות האלה. הזה כולל את פרטי ההטמעה וגם מספק לציבור ממשקים.

איך זה עובד

המנגנון לקישור דינמי אחראי לטעון את הספריות המשותפות שצוינו ב-DT_NEEDED רשומות או בספריות המשותפות שצוינו על ידי ארגומנט dlopen() או android_dlopen_ext(). בשניהם במקרים מסוימים, המקשר הדינמי מוצא את מרחב השמות המקשר שבו מבצע הקריאה החוזרת (caller) נמצא ומנסה לטעון את יחסי התלות לאותו מרחב שמות של מקשר. אם המיקום המקשר הדינמי לא יכול לטעון את הספרייה המשותפת למנגנון לקישור שצוין הוא מציג בקשה למרחב השמות של המקשר המקושרים לייצוא הנתונים המשותפים של הספריות.

הפורמט של קובץ התצורה

הפורמט של קובץ התצורה מבוסס על פורמט הקובץ 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.name.isolated

ערך בוליאני שמציין אם על המקשר הדינמי לבדוק שבה נמצאת הספרייה המשותפת.

אם הערך של isolated הוא true, רק הספריות המשותפות שנמצאות באחת מהספריות search.paths (לא כולל ספריות משנה) או במסגרת אחת מהן ספריות permitted.paths (כולל ספריות משנה) יכולות להיות נטען.

אם הערך של isolated הוא false (ברירת המחדל), הערך הדינמי ה-linker לא בודק את הנתיב של הספריות המשותפות.

namespace.sphal.isolated = true

מציין שרק הספריות המשותפות ב- search.paths או פחות מ-permitted.paths יכולים להיות נטען למרחב השמות sphal.

namespace.name.search.paths

רשימת ספריות המופרדות בנקודתיים לחיפוש משותפות של הספריות.

הספריות שצוינו ב-search.paths מתווספות מראש לשם הספרייה המבוקש אם הפונקציה קוראת לפונקציה 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 הוא המערכת מתעלמת ממנו כאשר 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

רשימת ספריות המופרדות בנקודתיים שבהן ניתן לטעון את ה-Linker הדינמי הספריות המשותפות כאשר ASan מופעל.

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. In addition, ההגדרה הזו מספקת את הבידוד המלא של המקשר הדינמי. היא מבטיחה שהמודולים במחיצה של המערכת לא יהיו תלויים ספריות במחיצות הספקים ולהפך.

ב-Android מגרסה 8.1 ואילך, הגדרת ברירת המחדל היא VNDK ומומלץ מאוד להפעיל בידוד דינמי מלא באמצעות BOARD_VNDK_VERSION עד current.

הגדרת VNDK

הגדרת VNDK מבודדת את יחסי התלות של הספרייה המשותפת בין מחיצת המערכת למחיצות של הספק. בהשוואה ל וההגדרות האישיות שהוזכרו בקטע המשנה הקודם, מפורטות כך:

  • תהליכי מסגרת

    • default, vndk נוצרים מרחבי שמות sphal ו-rs.
    • כל מרחבי השמות מבודדים.
    • ספריות משותפות של המערכת נטענות למרחב השמות default.
    • דפי SP-HAL נטענים למרחב השמות של 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

בטבלה הבאה מפורטות ההגדרות של מרחבי השמות ל-framework. מתוך הקטע [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 שעבר הידור)
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 הסטטיים שהוסרו מ-codebase ו-LinkerConfig יוצר אותן בזמן הריצה במקום זאת.

שינויים ב-Android 9

  • ב-Android 9, מרחב השמות המקשר vndk מתווסף לספק של תהליכים וספריות משותפות של VNDK מבודדות ממנגנון הקישור המוגדר כברירת מחדל מרחב שמות.
  • החלפה של PRODUCT_FULL_TREBLE במילים ספציפיות יותר PRODUCT_TREBLE_LINKER_NAMESPACES.
  • ב-Android 9 השמות של ההגדרות האישיות לקישור דינמי מחדש השתנו .
    Android מגרסה 8.x 9 Android תיאור
    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 נוספו.