由於您對事物的理解不是很好,因此您需要一段時間才能對linux-arm-kernel列表中的任何人做出響應。請閱讀kprobes.txt並詳細研究ARM體系結構。
如果kprobe處理了未定義的指令異常(bcos kprobe只創建),那麼爲什麼__und_svc()
被調用。 __und_svc()
處理程序對於kprobes有什麼作用?
在ARM,模式0b11011
是未定義指令模式。一個未定義指令發生當流量,是undef指令的
- lr_und = PC + 4
- SPSR_und = CPSR的發生指令,其中模式。
- 將模式更改爲禁用中斷的ARM。
- PC =矢量基地+ 4
步驟4位於__vectors_start
的主要矢量表和這只是分支到 vector_und
。該代碼是一個名爲vector_stub
的宏,它可以調用__und_svc
或__und_usr
。堆棧是每個進程保留的4/8k頁面。它是包含任務結構和內核堆棧的內核頁面。
kprobe作品放置在代碼的地址,你想探測未定義指令。也就是說,它涉及未定義的指令處理程序。這應該是非常明顯的。它調用兩個例程,call_fpe
或do_undefinstr()
。您對第二種情況感興趣,它獲取操作碼並調用call_undef_hook()
。用register_undef_hook()添加一個鉤子;你可以看到arch_init_kprobes()
。主回調kprobe_handler
被稱爲struct pt_regs *regs
,這恰好是在__und_svc
中保留的額外內存。請注意,例如kretprobe_trampoline()
,它正在使用當前正在執行的堆棧玩弄技巧。
如果64字節的內存是強制性的,那麼如何在不編譯內核的情況下進行分配。即如何動態地做到這一點。?
不,它不是。您可以使用不同的機制,但您可能需要修改代碼kprobes。很可能你將不得不限制功能。也可以完全重寫堆棧幀並在事實之後保留額外的64字節。它是而不是如kmalloc()
中的分配。它只是從管理員堆棧指針中添加/減去一個數字。我猜測代碼會重新寫入來自未定義處理程序的返回地址,以便在地址的上下文(ISR,下半部分/線程IRQ,work_queue,內核任務)中執行。但可能還有其他問題尚未遇到。如果arch_init_kprobes()
從未被調用,那麼您可以始終在__und_svc
中進行預訂;它只吃了64字節的堆棧,這將使得內核堆棧更可能溢出。即,變更,
__und_svc:
@ Always reserve 64 bytes, even if kprobe is not active.
svc_entry 64
arch_init_kprobes()
是實際安裝該功能。
雖然我喜歡SO的精確問題,但恐怕這個問題太具體了。你是否嘗試過與內核相關的郵件列表? –
是的。我在systemtap郵件列表以及linux-arm郵件列表上發佈了這個問題。運氣不好在linux-arm中尚未公佈。 – Jeyaram