獲取Linux核心未匯出符號的幾種方式

2021-09-29 16:16:58 字數 1446 閱讀 6510

從linux核心的2.6某個版本開始,核心引入了匯出符號的機制。只有在核心中使用export_symbol或export_symbol_gpl匯出的符號才能在核心模組中直接使用。然而,核心並沒有匯出所有的符號。例如,在3.8.0的核心中,do_page_fault就沒有被匯出。

而我的核心模組中需要使用do_page_fault,那麼有那些方法呢?這些方法分別有什麼優劣呢?

下面以do_page_fault為例,一一進行分析:

修改核心,新增export_symbol(do_page_fault)或export_symbol_gpl(do_page_fault)。

這種方法適用於可以修改核心的情形。在可以修改核心的情況下,這是最簡單的方式。

使用kallsyms_lookup_name讀取

kallsyms_lookup_name本身也是乙個核心符號,如果這個符號被匯出了,那麼就可以在核心模組中呼叫kallsyms_lookup_name("do_page_fault")來獲得do_page_fault的符號位址。

這種方法的侷限性在於kallsyms_lookup_name本身不一定被匯出。

讀取/boot/system.map-,再使用核心模組引數傳入核心模組

system.map-是編譯核心時產生的,它裡面記錄了編譯時核心符號的位址。如果能夠保證當前使用的核心與system.map-是一一對應的,那麼從system.map-中讀出的符號位址就是正確的。其中,kernel-version可以通過'uname -r'獲得。

但是這種方法也有侷限性,在模組執行的時候,system.map-檔案不一定存在,即使存在也不能保證與當前核心是正確對應的。

讀取/proc/kallsyms,再使用核心模組引數傳入核心模組

/proc/kallsyms是乙個特殊的檔案,它並不是儲存在磁碟上的檔案。這個檔案只有被讀取的時候,才會由核心產生內容。因為這些內容是核心動態生成的,所以可以保證其中讀到的位址是正確的,不會有system.map-的問題。

需要注意的是,從核心2.6.37開始,普通使用者是沒有辦法從/proc/kallsyms中讀到正確的值。在某些版本中,該檔案為空。在較新的版本中,該檔案中所有符號的位址均為0(除非/porc/sys/kernel/kptr_restrict 的值被設為0)。但是root使用者是可以從/proc/kallsyms中讀到正確的值的。好在載入模組也需要root許可權,可以在載入模組時用指令碼獲取符號的位址。命令:

#cat /proc/kallsyms | grep"\

" | awk ''

不過,根據我的實際使用經驗,/proc/kallsyms中符號的數量比systemp.map-要少一些。

kallsyms.c中: kallsyms_op->s_show()-> seq_printf(... %pk ...)->vsnprintf() -> 

pointer() =>

kptr_restrict.

linux核心中符號位址的獲取

有些核心函式或者核心變數是不匯出的,但是確實需要用,那該怎麼辦?因此尋找核心符號位址就有必要進行一下總結,更有甚,如果想找一條特定的指令,比如movl的指令位址,那更需要投入一些精力!總的來說,我總結了下面五種方式 1.通過procfs中的kallsym檔案或者system.map檔案直接查詢 這種...

libcurl鏈結庫未匯出符號的錯誤

2010 04 03 13 25 56 分類 程式設計入門 字型大小 訂閱 在使用libcurl的時候出現乙個很普遍unresolved external symbol error lnk2001 unresolved external symbol imp curl easy perform er...

未解決的外部符號!

遺忘功能體 許多新的程式設計師的乙個問題是 如果我們向前宣告乙個函式,但不定義它會發生什麼?考慮下面的程式 include int add int x,int y forward declaration of add using function prototype int main 在這個程式中,...