2011年4月21日 星期四

Sparse工具檢測使用的屬性定義

 下面分析一下sparse所能檢查的相關屬性。

# define __user                __attribute__((noderef, address_space(1)))
# define __kernel        /* default address space */
# define __safe                __attribute__((safe))
# define __force        __attribute__((force))
# define __nocast        __attribute__((nocast))
# define __iomem        __attribute__((noderef, address_space(2)))
# define __acquires(x)        __attribute__((context(x,0,1)))
# define __releases(x)        __attribute__((context(x,1,0)))
# define __acquire(x)        __context__(x,1)
# define __release(x)        __context__(x,-1)
# define __cond_lock(x,c)        ((c) ? ({ __acquire(x); 1; }) : 0)
extern void __chk_user_ptr(const volatile void __user *);
extern void __chk_io_ptr(const volatile void __iomem *);


__user特性用來修飾一個變數的位址,該變數必須是非解除參考(no dereference)即地址是有效的,並且變數所在的位址空間必須為1,這裡為(address_space(1)),用戶位址空間。sparse把位址空間分為3部分,0表示普通位址空間,對內核來說就是位址空間。1表示用戶位址空間。2表示設備位址映射空間,即設備寄存器的位址空間。

__kernel特性修飾變數為內核位址,為內核代碼裡面默認的位址空間。

__safe特性聲明該變數為安全變數,這是為了避免在內核函數未對傳入的參數進行校驗就使用的情況下,會導致編譯器對其報錯或輸出告警資訊。通過該特性說明該變數不可能為空。

__force特性聲明該變數是可以強制類型轉換的。

__nocast聲明該變數參數類型與實際參數類型要一致才可以。

__iomem聲明位址空間是設備位址映射空間,其他的與__user一樣。

__acquires為函數屬性定義的修飾,表示函數內,該參數的引用計數值從1變為0

__releases__acquires相反,這一對修飾符用於Sparse在靜態代碼檢測時,檢查調用的次數和匹配請求,經常用於檢測lock的獲取和釋放。

__acquire表示增加變數x的計數,增加量為1

__release表示減少變數x的計數,減少量為1。這一對與上面的那一對是一樣,只是這一對用在函數的執行過程中,都用於檢查代碼中出現不平衡的狀況。

 __cond_lock用於表示條件鎖,當c這個值不為0時,計數值加1,並返回1

__chk_user_ptr__chk_io_ptr在這裡只聲明函數,沒有函數體,目的就是在編譯過程中Sparse能夠捕捉到編譯錯誤,檢查參數的類型。

沒有留言:

張貼留言