sparse誕生於2023年,是由linux之父開發的,目的就是提供乙個靜態檢查**的工具,從而減少linux核心的隱患。起始,在sparse之前已經有了乙個不錯的**靜態檢查工具(swat),只不過這個工具不是免費軟體,使用上有一些限制。所以linus自己開發了乙個靜態檢查工具。
核心**中有乙個對sparse的簡略說明文件:documentation/sparse.txt。
sparse通過gcc的擴充套件屬性__attribute__以及自己定義的__context__來對**進行靜態檢查。
這些屬性如下:
巨集名稱巨集定義
說明__bitwise
__attribute__((bitwise))
確保變數是相同的位方式(比如 bit-endian, little-endiandeng)
__user
__attribute__((noderef, address_space(1)))
指標位址必須在使用者位址空間
__kernel
__attribute__((noderef, address_space(0)))
指標位址必須在核心位址空間
__iomem
__attribute__((noderef, address_space(2)))
指標位址必須在裝置位址空間
__safe
__attribute__((safe))
變數可以為空
__force
__attribute__((force))
變數可以進行強制轉換
__nocast
__attribute__((nocast))
引數型別與實際引數型別必須一致
__acquires(x)
__attribute__((context(x, 0, 1)))
引數x 在執行前引用計數必須是0,執行後,引用計數必須為1
__releases
__attribute__((context(x, 1, 0)))
與__acquires(x)相反
__acquire
__context__(x, 1)
引數x的引用計數+1
__release
__context__(x, 1)
與__acquire(x)相反
__cond_lock(x,c)
((c) ? () : 0)
引數c 不為0時,引用計數 + 1, 並返回1
其中__acquires(x)和__releases,__acquire和__release必須配對使用,否則sparse會發出警告
主要作用就是確保核心使用的整數是在同樣的位方式下。對於使用了這個巨集的變數,sparse會檢查這個變數是否一直在同一種位方式(big-endian,little-endian或其他)下被使用。如果此變數在多個位方式下被使用了,sparse會給出警告。
/* kernel version:4.6.2 */
/* file:include/linux/types.h line:158 */
typedef
unsigned __bitwise__ fmode_t;
如果使用了__user巨集的指標不在使用者位址空間初始化,或者指向核心位址空間、裝置位址空間等,sparse會給出警告。
/* kernel version:4.6.2 */
/* file:kernel/ldt.c line:153 */
static
int read_ldt(void __user *ptr, unsigned
long bytecount)
如果使用了__kernel巨集的指標不在核心位址空間初始化,或者指向使用者位址空間、裝置位址空間等,sparse會給出警告。
/* kernel version:4.6.2 */
/* file:drivers/s390/char/hmcdrv_ftp.h line:52 */
void __kernel *buf;
如果使用了__iomem巨集的指標不在裝置位址空間初始化,或者指向使用者位址空間、核心位址空間等,sparse會給出警告。
/* kernel version:4.6.2 */
/* file:kernel/apic/io_apic.c line:461 */
struct io_apic __iomem *io_apic;
如果使用了__safe巨集修飾的變數在使用前沒有判斷它是否為空(null),sparse會給出警告。
最新的gcc應該已經會對這種情況給出警告,所以沒有必要用sparse去檢查。
如果使用了__force修飾的變數可以進行強制型別轉換,沒有使用__force修飾的變數進行強制型別轉換時,sparse會給出警告。
/* kernel version:4.6.2 */
/* file:include/asm/io.h line:213 */
memset((void __force *)addr, val, count);
如果使用了__nocast修飾的引數必須和實際傳入的引數型別一致才可以,否則sparse會給出警告。
/* kernel version:4.6.2 */
/* file:include/asm-generic/cputime_nsecs.h line:21 */
typedef u64
__nocast cputime_t;
這4個巨集都是和鎖有關的,__acquires和__releases、__acquire和__release必須成對使用,否則sparse會警告。 Linux核心 fork 原始碼分析
核心版本 linux 4.4.18 原始碼位置 這裡 接著 呼叫copy process 它設定了程序描述符以及子程序所需的任何其他核心資料結構。ftrace graph init task 初始化ftrace,核心追蹤函式呼叫。rt mutex init task 初始化鎖。copy creds ...
linux核心原始碼目錄結構分析
注 本文是學習朱老師課程整理的筆記,基於linux2.6.35.7和九鼎x210bv3s開發板進行移植。arch。arch是architecture的縮寫。arch目錄下是好多個不同架構的cpu的子目錄,譬如arm這種cpu的所有檔案都在arch arm目錄下,x86的cpu的所有檔案都在arch ...
linux核心原始碼目錄結構分析
1 分析原始碼目錄下的單個檔案 1 kbuild,kbuild是kernel build的意思,就是核心編譯的意思。這個檔案就是linux核心特有的核心編譯體系需要用到的檔案。2 makefile,這個是linux核心的總makefile,整個核心工程用這個makefile來管理的。3 mk,是九鼎...