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

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

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

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

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

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

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 המערכת מתעלמת מ- 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") יכול להחזיר נקודת אחיזה חוקית של מרחב שמות מקשר.

יצירת מרחב שמות מקשר

באנדרואיד 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 חובה למכשירים שהושקו עם אנדרואיד 9 ומעלה
ריק VNDK Lite חובה עבור מכשירים שהושקו עם אנדרואיד 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 הידור)
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 מהמכשיר.

היסטוריית מסמכים

שינויים באנדרואיד 11

  • באנדרואיד 11, הקבצים הסטטיים ld.config.*.txt מוסרים מבסיס הקוד ו-LinkerConfig יוצר אותם בזמן ריצה במקום זאת.

שינויים באנדרואיד 9

  • באנדרואיד 9, מרחב השמות vndk linker מתווסף לתהליכי ספק וספריות משותפות VNDK מבודדות ממרחב השמות המקשר המוגדר כברירת מחדל.
  • החלף PRODUCT_FULL_TREBLE ב- PRODUCT_TREBLE_LINKER_NAMESPACES ספציפי יותר.
  • אנדרואיד 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 עבור מכשירים מדור קודם עם אנדרואיד 7.x ומטה
  • הסר את android.hardware.graphics.allocator@2.0.so .
  • מתווספות מחיצות product ו- odm .