我想学习linux,如果我编写了一个ebpf程序test.c,使用了llvm:
clang -O2 -target bpf -o test.o test.c.如何在经典bpf中获得像tcpdump -d这样的ebpf程序集,谢谢。
发布于 2016-12-01 13:51:06
这取决于您所谓的“学习linux”的确切含义。
语言本身
如果您指的是学习-- eBPF的指令,以及类似于程序集的语言本身--您可以查看内核的文档 (相当密集)或来自bcc项目的这是语法的摘要版本。
虚拟机
如果您希望看到虚拟机的内部是如何工作的,您可以查看各种演示文稿(我推荐这些演示文稿来自D.Borkmann),这里有一个在这篇博客文章中列表;或者您可以在linux/kernel/bpf下直接阅读内核源代码(特别是core.c文件)。或者,有一个可用的更简单的用户空间实现。
转储eBPF指令
现在,如果您希望看到从C编译到eBPF的代码,下面是几个解决方案。
读取对象文件
就我而言,我使用手册页中提供的命令进行编译。
__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 ................在上面的输出中,显示了两个指令(小endian --以0x开头的第一个字段是该部分中的偏移量)。我们可以解析它以形成指令,并获得:
b7 0 0 0000 00000002 // Load 0x02 in register r0
95 0 0 0000 00000000 // Exit and return value in r02019年4月编辑转储内核中加载的eBPF程序
可以转储内核中加载的程序的指令(然后可能附加到一个可用的BPF挂钩),要么作为eBPF程序集指令,要么作为机器指令(如果程序已经进行了JIT编译)。bpftool,依赖libbpf,是做这些事情的实用工具。例如,人们可以看到当前加载了哪些程序,并注意到它们的ids,其中包括:
# 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和类似的)指令作为输入,并分别转换为对象文件或相反的方式。
但可能更有趣的是,LLVM本身也支持调试信息,还附带了BPF反汇编程序:到目前为止,它已经被合并,其作者(A. Starovoitov)已经将电子邮件发送到netdev邮件列表中。这意味着使用clang/LLVM 4.0+,您应该能够使用llvm-objdump -S -no-show-raw-insn my_file.o获得格式良好的输出。
https://stackoverflow.com/questions/39998050
复制相似问题