動態連結器可解決 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. |
以半形逗號分隔的清單,列出該區段的其他命名空間 (除了 |
這表示 |
namespace. |
以半形逗號分隔的備用命名空間清單。 如果在目前命名空間中找不到共用程式庫,動態連結器會嘗試從備用命名空間載入共用程式庫。清單開頭指定的命名空間優先順序較高。 |
如果共用程式庫或執行檔要求無法載入至 接著,如果共用程式庫無法從 最後,如果所有嘗試都失敗,動態連結器會傳回錯誤。 |
namespace. |
以冒號分隔的共用程式庫清單。如果無法在 這項屬性無法與 |
這表示備用連結只接受 |
namespace. |
布林值,指出在 這項屬性無法與 |
這表示所有程式庫名稱都可以透過從 |
命名空間屬性
資源 | 說明 | 範例 |
---|---|---|
namespace. |
布林值,表示動態連結器是否應檢查共用程式庫所在位置。 如果 如果 |
這表示只有 |
namespace. |
以冒號分隔的資料夾清單,用於搜尋共用資料庫。 如果函式呼叫 當 舉例來說,如果 |
這表示動態連結器會在 |
namespace. |
以冒號分隔的目錄清單,用於在啟用 AddressSanitizer (ASan) 時搜尋共用程式庫。 啟用 ASan 時,系統會忽略 |
這表示啟用 ASan 時,動態連結器會先搜尋 |
namespace. |
以冒號分隔的目錄 (包括子目錄) 清單,當 您也可以載入 如果 |
這表示 舉例來說,如果沒有 |
namespace. |
以冒號分隔的目錄清單,當啟用 ASan 時,動態連結器可在其中載入共用程式庫。 啟用 ASan 時,系統會忽略 |
這表示啟用 ASan 時, |
namespace. |
布林值,指出程式 ( 如果 如果 |
這表示 |
連結器命名空間建立
在 Android 11 中,連結器設定會在 /linkerconfig
的執行階段中建立,而不是使用 ${android-src}/system/core/rootdir/etc
中的純文字檔案。系統會在啟動期間根據執行階段環境產生設定,其中包含下列項目:
- 如果裝置支援 VNDK
- 供應商分區的目標 VNDK 版本
- 產品分區的 VNDK 版本
- 已安裝的 APEX 模組
連結器設定會透過解析連結器命名空間之間的依附元件來建立。舉例來說,如果 APEX 模組有任何更新 (包括依附元件更新),系統就會產生連結器設定,反映這些變更。如需建立連結器設定的更多詳細資訊,請參閱 ${android-src}/system/linkerconfig
。
連結器命名空間隔離
設定類型有三種。系統會根據 BoardConfig.mk
中的 PRODUCT_TREBLE_LINKER_NAMESPACES
和 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_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
命名空間的 VNDK-SP 共用程式庫。
- 建立
-
供應商程序
- 建立
default
、vndk
和system
命名空間。 default
命名空間已隔離。- 供應商共用程式庫會載入至
default
命名空間。 - VNDK 和 VNDK-SP 共用程式庫會載入至
vndk
命名空間。 - LL-NDK 及其依附元件會載入至
system
命名空間。
- 建立
下圖說明連結器命名空間之間的關係。

圖 1. Linker 命名空間隔離 (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 設定
自 Android 8.0 起,動態連結器會設為隔離 SP-HAL 和 VNDK-SP 共用程式庫,以免其符號與其他架構共用程式庫發生衝突。下方顯示連結器命名空間之間的關係。

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
下表列出架構程序的命名空間設定,這些內容節錄自 VNDK Lite 設定中的 [system]
部分。
命名空間 | 資源 | 值 |
---|---|---|
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-NDKlibmediandk.so libft2.so
|
|
link.vndk.shared_libs |
VNDK-SP |
下表列出供應商程序的命名空間設定,摘錄自 VNDK Lite 設定中的 [vendor]
部分。
命名空間 | 資源 | 值 |
---|---|---|
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
分區。