連接器命名空間

這個動態連結程式克服了 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 是 是由連結器命名空間匯出的公開程式庫 許多連接器命名空間Kubernetes 的依附元件 /system/lib[64]/libc.so,例如 libnetd_client.so 會載入至命名空間 /system/lib[64]/libc.so 的命名空間 存放。其他命名空間將無法存取這些依附元件。這個 機制會封裝實作詳細資料,並將 存取 API

運作方式

動態連結器負責載入指定的共用資料庫 在 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

這表示有三個命名空間 (defaultsphalvndk) 中的 [system] 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定

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.solibm.so 做為要求的程式庫名稱。動態連結器 會忽略 sphaldefault 命名空間 (如果要求的程式庫名稱並非) libc.solibm.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

這表示所有程式庫名稱都可以穿越備用連結 從 vndksphal 命名空間。

命名空間屬性

資源 說明 範例
namespace.name.isolated

指出動態連結器是否應檢查的布林值 存取資料庫

如果 isolatedtrue,則只有共用程式庫 位於其中一個 search.paths 目錄中 (不包括子目錄),或位於 permitted.paths 目錄 (包括子目錄) 可 就會引發這個事件。

如果 isolatedfalse (預設值),則動態參數的值 連結器不會檢查共用程式庫的路徑。

namespace.sphal.isolated = true

這表示只有 search.pathspermitted.paths 以下可為 已載入 sphal 命名空間

namespace.name.search.paths

要搜尋共用的目錄清單 (以冒號分隔) 程式庫

search.paths 中指定的目錄會前置 如果函式呼叫 dlopen()DT_NEEDED 項目未指定完整路徑。目錄 已在清單開頭處指定的 Pod 有較高的優先順序

isolatedtrue 時,具有以下性質的共用程式庫: 位於以下 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} 並搜尋 /system/${LIB}

namespace.name.permitted.paths

以冒號分隔的目錄 (包括子目錄) 清單,其中 除了伺服器以外,動態連結器還可以載入共用程式庫 search.paths) 在isolatedtrue

位於以下子目錄的共用程式庫 系統也可以載入 permitted.paths。舉例來說 permitted.paths/system/${LIB}/system/${LIB}/libc.so 和 可載入 /system/${LIB}/vndk/libutils.so

如果 isolatedfalse, 系統會忽略 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 是 啟用時會忽略 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()

如果 visibletrue, 如果發生以下情況,android_get_exported_namespace() 一律會傳回控制代碼。 命名空間存在

如果 visiblefalse (預設值), 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」和 BoardConfig.mk中的 BOARD_VNDK_VERSION, 相應的設定會在開機時產生

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_NAMESPACEStrue

VNDK 設定也會隔離 SP-HAL 和 VNDK-SP 共用程式庫。此外, 這項設定可提供完整的動態連接器隔離。 確保系統分區中的模組不會依附於共用項目數量 就無法在供應商分區中使用程式庫,反之亦然。

在 Android 8.1 以上版本中,VNDK 設定是預設設定。 因此強烈建議你透過 BOARD_VNDK_VERSIONcurrent

VNDK 設定

VNDK 設定會隔離共用程式庫依附元件 與廠商分區之間進行負載平衡相較於 先前子章節提到的設定 概述:

  • 架構程序

    • defaultvndk、 已建立「sphal」和「rs」命名空間。
    • 隔離所有命名空間。
    • 系統共用程式庫會載入至 default 命名空間。
    • SP-HAL 會載入 sphal 命名空間。
    • VNDK-SP 共用程式庫已載入至 vndk 命名空間。
  • 供應商流程

    • 已建立 defaultvndksystem 命名空間。
    • default 命名空間是隔離的。
    • 供應商共用程式庫會載入至 default 命名空間。
    • VNDK 和 VNDK-SP 共用程式庫會載入至 vndk 命名空間。
    • LL-NDK 及其依附元件會載入至 system 命名空間。

連結器命名空間之間的關係說明如下。

VNDK 設定說明的連結器命名空間圖表

圖 1. 連接器命名空間隔離 (VNDK 設定)。

在上圖中,LL-NDKVNDK-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-NDKVNDK-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

文件記錄

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
  • 已新增 productodm 個分區。