Динамический компоновщик решает две проблемы, связанные с архитектурой VNDK в Treble:
- Общие библиотеки SP-HAL и их зависимости, в том числе библиотеки VNDK-SP, загружаются в процессы фреймворка. Необходимо предусмотреть механизмы, предотвращающие конфликты символов.
dlopen()иandroid_dlopen_ext()могут создавать зависимости времени выполнения, которые не видны во время сборки и которые сложно обнаружить с помощью статического анализа.
Эти две проблемы можно решить с помощью пространства имен связывателя. Этот механизм предоставляется динамическим компоновщиком. Она позволяет изолировать общие библиотеки в разных пространствах имен компоновщика, чтобы библиотеки с одинаковыми названиями, но разными символами не конфликтовали.
С другой стороны, механизм пространств имен компоновщика обеспечивает гибкость, позволяя экспортировать некоторые общие библиотеки с помощью одного пространства имен компоновщика и использовать их в другом. Экспортированные общие библиотеки могут стать общедоступными API, скрывающими детали реализации в своих пространствах имен компоновщика.
Например, /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}
Файл конфигурации содержит:
- Несколько свойств сопоставления разделов каталога в начале, чтобы динамический компоновщик мог выбрать эффективный раздел.
-
Несколько разделов конфигурации пространств имен компоновщика:
- Каждый раздел содержит несколько пространств имен (вершин графа) и несколько резервных ссылок между пространствами имен (дуг графа).
- У каждого пространства имен есть собственные настройки изоляции, путей поиска, разрешенных путей и видимости.
В таблицах ниже подробно описано значение каждого свойства.
Свойство сопоставления разделов каталога
| Свойство | Описание | Пример |
|---|---|---|
|
Путь к каталогу, к которому относится раздел Каждое свойство сопоставляет исполняемые файлы в каталоге с разделом конфигурации пространств имен компоновщика. Может быть два или более ресурсов с одинаковым значением |
Это означает, что конфигурация, указанная в разделе Конфигурация, указанная в разделе |
Свойства отношений
| Свойство | Описание | Пример |
|---|---|---|
additional. |
Список дополнительных пространств имен (помимо пространства имен |
Это означает, что в конфигурации |
namespace. |
Список резервных пространств имен, разделенных запятыми. Если общая библиотека не найдена в текущем пространстве имен, динамический компоновщик пытается загрузить ее из резервных пространств имен. Пространство имен, указанное в начале списка, имеет более высокий приоритет. |
Если общая библиотека или исполняемый файл запрашивает общую библиотеку, которую нельзя загрузить в пространство имен Если общую библиотеку не удается загрузить из пространства имен Если все попытки завершатся неудачей, динамический компоновщик вернет ошибку. |
namespace. |
Разделенный двоеточиями список общих библиотек, в которых можно выполнять поиск в пространствах имен Это свойство нельзя использовать с |
Это означает, что резервная ссылка принимает только |
namespace. |
Логическое значение, которое указывает, можно ли искать все общие библиотеки в пространстве имен Это свойство нельзя использовать вместе с |
Это означает, что все названия библиотек могут переходить по резервной ссылке из пространства имен |
Свойства пространства имен
| Свойство | Описание | Пример |
|---|---|---|
namespace. |
Логическое значение, указывающее, должен ли динамический компоновщик проверять, где находится общая библиотека. Если Если для переменной |
Это означает, что в пространство имен |
namespace. |
Список каталогов, разделенных двоеточием, в которых нужно искать общие библиотеки. Каталоги, указанные в правиле Если для параметра Например, если |
Это означает, что динамический компоновщик ищет общие библиотеки в каталоге |
namespace. |
Список каталогов, разделенных двоеточием, для поиска общих библиотек, когда включен AddressSanitizer (ASan).
|
Это означает, что при включенном ASan динамический компоновщик сначала ищет |
namespace. |
Разделенный двоеточиями список каталогов (включая подкаталоги), из которых динамический компоновщик может загружать общие библиотеки (в дополнение к Также можно загрузить общие библиотеки, которые находятся в подкаталогах Если |
Это означает, что общие библиотеки в пространстве имен Например, без |
namespace. |
Список каталогов, разделенных двоеточием, в которых динамический компоновщик может загружать общие библиотеки, когда включен ASan.
|
Это означает, что при включенном ASan общие библиотеки из |
namespace. |
Логическое значение, указывающее, может ли программа (кроме Если Если |
Это означает, что |
Создание пространства имен для связывания
В 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 |
Для устройств без поддержки Treble |
Конфигурация 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-HAL загружаются в пространство имен
sphal. - Общие библиотеки VNDK-SP, загруженные в пространство имен
vndk.
- создаются пространства имен
-
Процессы поставщика
- Создаются пространства имен
default,vndkиsystem. - Пространство имен
defaultизолировано. - Общие библиотеки поставщиков загружаются в пространство имен
default. - Общие библиотеки VNDK и VNDK-SP загружаются в пространство имен
vndk. - LL-NDK и его зависимости загружаются в пространство имен
system.
- Создаются пространства имен
Ниже показано, как связаны пространства имен связывателя.
Рисунок 1. Изоляция пространства имен компоновщика (конфигурация VNDK).
На изображении выше LL-NDK и VNDK-SP обозначают следующие общие библиотеки:
-
LL-NDK
libEGL.solibGLESv1_CM.solibGLESv2.solibGLESv3.solibandroid_net.solibc.solibdl.soliblog.solibm.solibnativewindow.solibneuralnetworks.solibsync.solibvndksupport.solibvulkan.so
-
VNDK-SP
android.hardware.graphics.common@1.0.soandroid.hardware.graphics.mapper@2.0.soandroid.hardware.renderscript@1.0.soandroid.hidl.memory@1.0.solibRSCpuRef.solibRSDriver.solibRS_internal.solibbase.solibbcinfo.solibc++.solibcutils.solibhardware.solibhidlbase.solibhidlmemory.solibhidltransport.solibhwbinder.solibion.solibutils.solibz.so
Подробную информацию можно найти в /linkerconfig/ld.config.txt.
Конфигурация VNDK Lite
В Android 8.0 и более поздних версий динамический компоновщик настроен так, чтобы изолировать общие библиотеки SP-HAL и VNDK-SP, чтобы их символы не конфликтовали с другими общими библиотеками фреймворка. Связь между пространствами имен компоновщика показана ниже.
LL-NDK и VNDK-SP – это следующие общие библиотеки:
-
LL-NDK
libEGL.solibGLESv1_CM.solibGLESv2.solibc.solibdl.soliblog.solibm.solibnativewindow.solibstdc++.so(не в конфигурации)libsync.solibvndksupport.solibz.so(перемещено в VNDK-SP в конфигурации)
-
VNDK-SP
android.hardware.graphics.common@1.0.soandroid.hardware.graphics.mapper@2.0.soandroid.hardware.renderscript@1.0.soandroid.hidl.memory@1.0.solibbase.solibc++.solibcutils.solibhardware.solibhidlbase.solibhidlmemory.solibhidltransport.solibhwbinder.solibion.solibutils.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 (для скомпилированного ядра RenderScript)
|
|
isolated |
true |
|
visible |
true |
|
links |
default,vndk |
|
link.default.shared_libs |
LL-NDKlibmediandk.solibft2.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 изменены названия следующих файлов конфигурации динамического компоновщика:
Android 8.x Android 9 Описание ld.config.txt.inld.config.txtДля устройств с изоляцией пространства имен динамического компоновщика ld.config.txtld.config.vndk_lite.txtДля устройств с изоляцией пространства имен компоновщика VNDK-SP ld.config.legacy.txtld.config.legacy.txtДля устаревших устройств с Android 7.x и более ранних версий - Удалить
android.hardware.graphics.allocator@2.0.so - Добавлены разделы
productиodm.