英語

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 檔案中。