Google is committed to advancing racial equity for Black communities. See how.
Эта страница переведена с помощью Cloud Translation API.
Switch to English

Пространство имен компоновщика

Динамический компоновщик решает две проблемы в дизайне 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}

Файл конфигурации включает:

  • Несколько свойств сопоставления раздела каталога в начале для динамического компоновщика, чтобы выбрать эффективный раздел.
  • Несколько разделов конфигурации пространств имен компоновщика:
    • Каждый раздел содержит несколько пространств имен (вершины графа) и несколько резервных ссылок между пространствами имен (дуги графа).
    • Каждое пространство имен имеет собственную изоляцию, пути поиска, разрешенные пути и параметры видимости.

В таблицах ниже подробно описывается значение каждого свойства.

Свойство отображения раздела каталога

Свойство Описание пример

dir. name

Путь к каталогу, к которому относится раздел [ name ] .

Каждое свойство сопоставляет исполняемые файлы в каталоге с разделом конфигурации пространств имен компоновщика. Могут быть два (или более) свойства с одинаковым name но указывающие на разные каталоги.

dir.system = /system/bin
dir.system = /system/xbin
dir.vendor = /vendor/bin

Это означает, что конфигурация, указанная в разделе [system] применяется к исполняемым /system/xbin , которые загружаются из /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 ссылка принимает только libc.so или libm.so качестве имени запрошенной библиотеки. Динамический компоновщик игнорирует sphal ссылку из 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 каталогов .paths (включая подкаталоги).

Если isolated false (по умолчанию), динамический компоновщик не проверяет путь к разделяемым библиотекам.

namespace. sphal. isolated = true

Это означает, что только общие библиотеки в search.paths или в permitted.paths sphal могут быть загружены в пространство имен sphal .

namespace. name . search.paths

Список каталогов, разделенных двоеточиями, для поиска разделяемых библиотек.

DT_NEEDED указанные в search.paths , добавляются к имени запрошенной библиотеки, если вызовы функций для записей DT_NEEDED 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} ищет /data/asan/system/${LIB} а затем ищет /system/${LIB} .

namespace. name . permitted.paths

Список каталогов (включая подкаталоги), разделенных двоеточиями, в которых динамический компоновщик может загружать разделяемые библиотеки (в дополнение к search.paths ), если isolated имеет значение true .

Совместно используемые библиотеки , которые находятся под подкаталогами permitted.paths также могут быть загружены. Например, если permitted.paths /system/${LIB}/libc.so равно /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. 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
Выбранная конфигурация Требование СУДС
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

Конфигурация VNDK изолирует зависимости разделяемых библиотек между системным разделом и разделами поставщика. По сравнению с конфигурациями, упомянутыми в предыдущем подразделе, различия изложены следующим образом:

  • Рамочные процессы

    • vndk пространства имен default , vndk , sphal и rs .
    • Все пространства имен изолированы.
    • Общие системные библиотеки загружаются в пространство имен по default .
    • SP-HAL загружаются в пространство имен sphal .
    • Совместно используемые библиотеки VNDK-SP загружены в пространство имен vndk .
  • Вендорные процессы

    • 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
  • ВНДК-СП
    • 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 в конфигурации)
  • ВНДК-СП
    • 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 ВНДК-СП
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 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 ВНДК-СП

В таблице ниже представлена ​​конфигурация пространств имен для процессов поставщика, которая взята из раздела [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.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 .