GCC 外掛基礎設施¶
簡介¶
GCC 外掛是可載入的模組,為編譯器提供額外的功能 [1]。它們對於執行時檢測和靜態分析很有用。我們可以透過回撥 [2]、GIMPLE [3]、IPA [4] 和 RTL 傳遞 [5] 在編譯期間分析、更改和新增更多程式碼。
核心的 GCC 外掛基礎設施支援構建樹外模組、交叉編譯和在單獨的目錄中構建。外掛原始檔必須可由 C++ 編譯器編譯。
目前,GCC 外掛基礎設施僅支援某些架構。 grep “select HAVE_GCC_PLUGINS” 以找出哪些架構支援 GCC 外掛。
此基礎設施從 grsecurity [6] 和 PaX [7] 移植而來。
--
目的¶
GCC 外掛旨在提供一個場所來試驗潛在的編譯器功能,這些功能既不在 GCC 中,也不在上游 Clang 中。 一旦證明了它們的實用性,目標是將該功能上游到 GCC(和 Clang)中,然後在所有支援的 GCC 版本中都提供該功能後,最終將其從核心中刪除。
具體來說,新外掛應該只實現沒有上游編譯器支援(在 GCC 或 Clang 中)的功能。
當某個功能存在於 Clang 中但不存在於 GCC 中時,應努力將該功能引入上游 GCC(而不僅僅是作為核心特定的 GCC 外掛),以便整個生態系統都可以從中受益。
同樣,即使 GCC 外掛提供的功能在 Clang 中 *不* 存在,但該功能被證明是有用的,也應該花費精力將該功能上游到 GCC(和 Clang)。
在某個功能在上游 GCC 中可用之後,該外掛將被設定為對相應的 GCC 版本(以及更高版本)不可構建。 一旦所有核心支援的 GCC 版本都提供了該功能,該外掛將從核心中刪除。
檔案¶
$(src)/scripts/gcc-plugins
這是 GCC 外掛的目錄。
$(src)/scripts/gcc-plugins/gcc-common.h
這是 GCC 外掛的相容性標頭檔案。 它應該始終包含,而不是單獨的 gcc 標頭檔案。
$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h, $(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h
這些標頭檔案自動生成 GIMPLE、SIMPLE_IPA、IPA 和 RTL 傳遞的註冊結構。 應該優先使用它們,而不是手動建立結構。
用法¶
您必須為您的 gcc 版本安裝 gcc 外掛標頭檔案,例如,在 Ubuntu 上對於 gcc-10
apt-get install gcc-10-plugin-dev
或者在 Fedora 上
dnf install gcc-plugin-devel libmpc-devel
或者在使用包含外掛的交叉編譯器時,在 Fedora 上
dnf install libmpc-devel
啟用 GCC 外掛基礎設施和您想要在核心配置中使用的某些外掛
CONFIG_GCC_PLUGINS=y
CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
...
執行 gcc(本機或交叉編譯器)以確保檢測到外掛標頭檔案
gcc -print-file-name=plugin
CROSS_COMPILE=arm-linux-gnu- ${CROSS_COMPILE}gcc -print-file-name=plugin
單詞 “plugin” 表示未檢測到它們
plugin
完整路徑表示已檢測到它們
/usr/lib/gcc/x86_64-redhat-linux/12/plugin
要編譯包含外掛的最小工具集
make scripts
或者只執行核心 make 並使用圈複雜度 GCC 外掛編譯整個核心。
4. 如何新增新的 GCC 外掛¶
GCC 外掛位於 scripts/gcc-plugins/ 中。 您需要將外掛原始檔直接放在 scripts/gcc-plugins/ 下。 不支援建立子目錄。 必須將其新增到 scripts/gcc-plugins/Makefile、scripts/Makefile.gcc-plugins 和相關的 Kconfig 檔案中。