[英]How to get linux ebpf assembly?
我想學習linux ebpf vm,如果我寫一個ebpf程序test.c,用過llvm:
clang -O2 -target bpf -o test.o test.c. 如何在經典bpf中獲得像tcpdump -d這樣的ebpf程序集,謝謝。
這取決於你對“學習linux ebpf vm”的意思。
如果您的意思是了解eBPF的指令,即類似匯編的語言本身,您可以查看內核中的文檔 (非常密集)或者來自bcc項目的語法匯總版本 。
如果您更喜歡看eBPF虛擬機的內部工作方式,您可以查看各種演示文稿(我推薦來自D. Borkmann的演示文稿),我在此博客文章中有一個列表; 或者您可以直接在linux/kernel/bpf
(特別是文件core.c
)下的內核源代碼中讀取。 或者,可以使用更簡單的用戶空間實現 。
現在,如果你想看到從C編譯到eBPF的代碼,這里有幾個解決方案。
就我而言,我使用tc-bpf
手冊頁中提供的命令進行編譯:
__bcc() {
clang -O2 -emit-llvm -c $1 -o - | \
llc -march=bpf -filetype=obj -o "`basename $1 .c`.o"
}
alias bcc=__bcc
代碼被翻譯成eBPF並存儲在生成的ELF文件的一個部分中。 然后我可以使用objdump
或readelf
等工具檢查我的程序。 例如,如果我的程序在classifier
部分中:
$ bcc return_zero.c
$ readelf -x classifier return_zero.o
Hex dump of section 'classifier':
0x00000000 b7000000 02000000 95000000 00000000 ................
在上面的輸出中,顯示了兩條指令(小端 - 以0x
的第一個字段是節內的偏移量)。 我們可以解析這個以形成指令並獲得:
b7 0 0 0000 00000002 // Load 0x02 in register r0
95 0 0 0000 00000000 // Exit and return value in r0
可以將內核中加載的程序(然后可能附加到其中一個可用的BPF掛鈎)的指令轉儲為eBPF匯編指令,或者如果程序已經過JIT編譯則轉儲為機器指令。 bpftool ,依賴於libbpf,是執行此類操作的首選實用程序。 例如,可以看到當前加載的程序,並記下它們的ID,包括:
# bpftool prog show
然后轉儲給定id的程序的指令就像這樣簡單:
# bpftool prog dump xlated id <id>
# bpftool prog dump jited id <id>
分別用於eBPF或JITed(如果可用)說明。 如有必要,輸出也可以格式化為JSON。
根據您用於將BPF注入內核的工具,您通常可以轉儲內核驗證程序的輸出,該驗證程序包含以人性化方式格式化的大多數指令。
使用bcc工具集 (與前一個命令沒有直接關系,與舊的16位編譯器根本沒有關系),你可以通過使用 BPF對象實例的相關標志來獲得這個,而使用tc filter add dev eth0 bpf obj … verbose
這是用verbose
關鍵字完成的。
前面提到的用戶空間實現( uBPF )有自己可能感興趣的匯編器和反匯編器:它將“人性化”( add32 r0, r1
和like)指令作為輸入並轉換為目標文件,或者其他分別是。
但可能更有趣的是,在LLVM本身中支持調試信息,以及BPF反匯編程序:截至今天它最近已合並,其作者(A. Starovoitov)已在netdev上發送了一封關於它的電子郵件郵件列表。 這意味着使用clang / LLVM 4.0+,您應該能夠使用llvm-objdump -S -no-show-raw-insn my_file.o
來獲得格式良好的輸出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.