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

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

  • ספריות משותפות SP-HAL ותלותן, כולל ספריות VNDK-SP, נטענות בתהליכי מסגרת. צריכים להיות כמה מנגנונים למניעת התנגשויות סמלים.
  • 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() או 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

הדבר מעיד כי הקישור fallback מקבל רק 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

הדבר מעיד כי כל השמות הספרייה יכול ללכת דרך הקישור fallback מן 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 (אסאן) מופעלת.

namespace. name . search.paths מתעלם כאשר תסאנו מופעל.

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

זה מצביע על כך שכאשר תסאנו מופעלת חיפושי המקשר הדינמי /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

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

namespace. name . permitted.paths מתעלם כאשר תסאנו מופעל.

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

זה מצביע על כך שכאשר אסאן מופעלת ספריות משותפות תחת /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 למכשירים שאינם מסוג Treble

תצורת VNDK Lite מבודדת ספריות משותפות SP-HAL ו- VNDK-SP. בשנת אנדרואיד 8.0, זה חייב להיות קובץ ההגדרות מקשרות דינמי כאשר PRODUCT_TREBLE_LINKER_NAMESPACES הוא true .

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

בשנת אנדרואיד 8.1 ומעלה, תצורת VNDK תצורת ברירת המחדל ואת זה מומלץ מאוד כדי לאפשר בידוד מקשר דינמי מלא על ידי הגדרת BOARD_VNDK_VERSION כדי current .

תצורת VNDK

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

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

    • default , vndk , sphal , ו rs מרחבי שם נוצרים.
    • כל מרחבי השמות מבודדים.
    • ספריות משותפות מע' נטענות לתוך default המרחב.
    • SP-שכבות HAL נטענים לתוך sphal המרחב.
    • VNDK-SP משותף ספריות וטעון vndk מרחב.
  • תהליכי ספק

    • default , vndk , ואת system מרחבים שם נוצרים.
    • default המרחב מבודד.
    • ספריות משותפות Vendor נטענות לתוך 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

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

גרף מרחב שמות Linker המתואר בתצורת VNDK Lite
איור 2. לינקר בידוד מרחב (תצורת VNDK לייט)

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.

מרחב שמות תכונה ערך
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.

מרחב שמות תכונה ערך
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

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

שינויים ב- Android 9

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