簡體   English   中英

如何獲得linux ebpf程序集?

[英]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 )下的內核源代碼中讀取。 或者,可以使用更簡單的用戶空間實現

轉儲eBPF指令

現在,如果你想看到從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文件的一個部分中。 然后我可以使用objdumpreadelf等工具檢查我的程序。 例如,如果我的程序在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

[2019年4月編輯]轉儲內核中加載的eBPF程序

可以將內核中加載的程序(然后可能附加到其中一個可用的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM