Динамический компоновщик решает две проблемы при разработке Treble 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}
Файл конфигурации включает в себя:
- Несколько свойств сопоставления разделов каталога в начале, позволяющие динамическому компоновщику выбрать эффективный раздел.
- Несколько разделов конфигурации пространств имен компоновщика:
- Каждый раздел содержит несколько пространств имен (вершины графа) и несколько резервных связей между пространствами имен (дуги графа).
- Каждое пространство имен имеет свою собственную изоляцию, пути поиска, разрешенные пути и настройки видимости.
В таблицах ниже подробно описано значение каждого свойства.
Свойство сопоставления разделов каталога
Свойство | Описание | Пример |
---|---|---|
| Путь к каталогу, к которому относится раздел Каждое свойство сопоставляет исполняемые файлы в каталоге с разделом конфигурации пространств имен компоновщика. Могут существовать два (или более) свойства с одинаковым | Это указывает на то, что конфигурация, указанная в разделе Конфигурация, указанная в разделе |
Свойства отношения
Свойство | Описание | Пример |
---|---|---|
additional. namespaces | Разделенный запятыми список дополнительных пространств имен (помимо пространства имен | Это указывает на то, что в конфигурации |
namespace. name . links | Список резервных пространств имен, разделенный запятыми. Если общая библиотека не может быть найдена в текущем пространстве имен, динамический компоновщик пытается загрузить общую библиотеку из резервных пространств имен. Пространство имен, указанное в начале списка, имеет более высокий приоритет. | Если общая библиотека или исполняемый файл запрашивает общую библиотеку, которую невозможно загрузить в пространство имен А затем, если общую библиотеку также невозможно загрузить из пространства имен Наконец, если все попытки завершаются неудачей, динамический компоновщик возвращает ошибку. |
namespace. name . link. other . shared_libs | Список общих библиотек, разделенных двоеточиями, которые можно искать в Это свойство нельзя использовать с | Это означает, что резервная ссылка принимает в качестве запрошенного имени библиотеки только |
namespace. name . link. other . allow_all_shared_libs | Логическое значение, указывающее, можно ли искать все общие библиотеки в Это свойство нельзя использовать с | Это указывает на то, что все имена библиотек могут проходить через резервную ссылку из |
Свойства пространства имен
Свойство | Описание | Пример |
---|---|---|
namespace. name . isolated | Логическое значение, указывающее, должен ли динамический компоновщик проверять, где находится общая библиотека. Если Если | Это означает, что в пространство имен |
namespace. name . search.paths | Список каталогов, разделенных двоеточиями, для поиска общих библиотек. Каталоги, указанные в Если Например, если | Это означает, что динамический компоновщик ищет |
namespace. name . asan.search.paths | Список каталогов, разделенных двоеточиями, для поиска общих библиотек, когда включен AddressSanitizer (ASan) . | Это означает, что когда ASan включен, динамический компоновщик сначала ищет |
namespace. name . permitted.paths | Список каталогов (включая подкаталоги), разделенных двоеточиями, в которые динамический компоновщик может загружать общие библиотеки (в дополнение к Также можно загрузить общие библиотеки, находящиеся в подкаталогах Если | Это означает, что общие библиотеки в Например, без |
namespace. name . asan.permitted.paths | Список каталогов, разделенных двоеточиями, в которые динамический компоновщик может загружать общие библиотеки при включенном ASan . | Это означает, что когда ASan включен, общие библиотеки в |
namespace. name . visible | Логическое значение, указывающее, может ли программа (кроме Если Если | Это указывает на то, что |
Создание пространства имен компоновщика
В 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 | Выбранная конфигурация | Требование СДС |
---|---|---|---|
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 изолирует зависимости общей библиотеки между системным разделом и разделами поставщика. По сравнению с конфигурациями, упомянутыми в предыдущем подразделе, различия заключаются в следующем:
Рамочные процессы
- создаются пространства имен
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 обозначают следующие общие библиотеки:
- ЛЛ-НДК
-
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
-
- ВНДК-СП
-
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
устройства.
Конфигурация ВНДК Lite
Начиная с Android 8.0, динамический компоновщик настроен на изоляцию общих библиотек SP-HAL и VNDK-SP, чтобы их символы не конфликтовали с другими общими библиотеками платформы. Взаимосвязь между пространствами имен компоновщика показана ниже.
LL-NDK и VNDK-SP обозначают следующие общие библиотеки:
- ЛЛ-НДК
-
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 )
-
- ВНДК-СП
-
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 | ЛЛ-НДК | |
link.vndk.shared_libs | ВНДК-СП | |
link.rs.shared_libs | libRS_internal.so | |
vndk (для ВНДК-СП) | 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 | ЛЛ-НДК | |
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 | ЛЛ-НДКlibmediandk.so libft2.so | |
link.vndk.shared_libs | ВНДК-СП |
В таблице ниже представлена конфигурация пространств имен для процессов поставщика, взятая из раздела [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.х Андроид 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
.