问题描述
我正在尝试使用 {{3} 在新项目(内核树之外)中编译和运行 sockex3
示例(来自 v5.10 的 sockex3_user.c 和 sockex3_kern.c) v0.3 作为我的存储库的子模块。我已经使用以下标志编译了代码:
内核(ebpf 程序)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -target bpf")
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g")
叮当声
$ clang -v
clang version 11.0.0
$ sudo ./build/samples/sockex3
[sudo] password for navarro:
libbpf: loading ./build/samples/bpf/CMakeFiles/sockex3_kern.dir/sockex3_kern.c.o
libbpf: elf: section(3) socket/3,size 1264,link 0,flags 6,type=1
libbpf: sec 'socket/3': found program 'bpf_func_PARSE_IP' at insn offset 0 (0 bytes),code size 158 insns (1264 bytes)
libbpf: elf: section(4) .relsocket/3,size 128,link 31,flags 0,type=9
libbpf: elf: section(5) socket/4,size 1360,type=1
libbpf: sec 'socket/4': found program 'bpf_func_PARSE_IPV6' at insn offset 0 (0 bytes),code size 170 insns (1360 bytes)
libbpf: elf: section(6) .relsocket/4,size 112,type=9
libbpf: elf: section(7) socket/1,size 256,type=1
libbpf: sec 'socket/1': found program 'bpf_func_PARSE_VLAN' at insn offset 0 (0 bytes),code size 32 insns (256 bytes)
libbpf: elf: section(8) .relsocket/1,size 16,type=9
libbpf: elf: section(9) socket/2,size 120,type=1
libbpf: sec 'socket/2': found program 'bpf_func_PARSE_MPLS' at insn offset 0 (0 bytes),code size 15 insns (120 bytes)
libbpf: elf: section(10) .relsocket/2,type=9
libbpf: elf: section(11) socket/0,size 32,type=1
libbpf: sec 'socket/0': found program 'main_prog' at insn offset 0 (0 bytes),code size 4 insns (32 bytes)
libbpf: elf: section(12) license,size 4,flags 3,type=1
libbpf: license of ./build/samples/bpf/CMakeFiles/sockex3_kern.dir/sockex3_kern.c.o is GPL
libbpf: elf: section(13) .maps,size 96,type=1
libbpf: elf: section(22) .BTF,size 4807,type=1
libbpf: elf: section(24) .BTF.ext,size 2704,type=1
libbpf: elf: section(31) .symtab,size 5904,link 1,type=2
libbpf: looking for externs among 246 symbols...
libbpf: Failed to find BTF for extern 'unlikely': -2
ERROR: opening BPF object file Failed
我想了解这个符号是如何/何时定义的。我找到了符号 libbpf。
为什么 libbpf 找不到它?我错过了什么吗?仅供参考,我从内核文件 (here) 中删除了 uapi
并将依赖项(即 sockex3_kern.c)复制到我的存储库中。
我无法理解的另一件事是为什么目标文件(内核树之外)的部分(下方)不同
31 .llvm_addrsig 00000012 0000000000000000 <--- Available in the object out of the tree
树外
$ llvm-objdump -h build/samples/bpf/CMakeFiles/sockex3_kern.dir/sockex3_kern.c.o
build/samples/bpf/CMakeFiles/sockex3_kern.dir/sockex3_kern.c.o: file format elf64-bpf
Sections:
Idx Name Size VMA Type
0 00000000 0000000000000000
1 .strtab 000002c2 0000000000000000
2 .text 00000000 0000000000000000 TEXT
3 socket/3 000004d0 0000000000000000 TEXT
4 .relsocket/3 00000070 0000000000000000
5 socket/4 00000550 0000000000000000 TEXT
6 .relsocket/4 00000070 0000000000000000
7 socket/1 00000100 0000000000000000 TEXT
8 .relsocket/1 00000010 0000000000000000
9 socket/2 00000078 0000000000000000 TEXT
10 .relsocket/2 00000010 0000000000000000
11 socket/0 000000e8 0000000000000000 TEXT
12 .relsocket/0 00000010 0000000000000000
13 license 00000004 0000000000000000 DATA
14 .maps 00000060 0000000000000000 DATA
15 .debug_loc 00000ef1 0000000000000000
16 .rel.debug_loc 00000370 0000000000000000
17 .debug_abbrev 000002b9 0000000000000000
18 .debug_info 00000f1b 0000000000000000
19 .rel.debug_info 000013c0 0000000000000000
20 .debug_ranges 000002e0 0000000000000000
21 .rel.debug_ranges 00000420 0000000000000000
22 .debug_str 000007c2 0000000000000000
23 .BTF 000012e1 0000000000000000
24 .rel.BTF 00000040 0000000000000000
25 .BTF.ext 00000ac0 0000000000000000
26 .rel.BTF.ext 00000a70 0000000000000000
27 .debug_frame 00000088 0000000000000000
28 .rel.debug_frame 000000a0 0000000000000000
29 .debug_line 0000049e 0000000000000000
30 .rel.debug_line 00000050 0000000000000000
31 .llvm_addrsig 00000012 0000000000000000
32 .symtab 00001788 0000000000000000
内核树
$ llvm-objdump -h sockex3_kern.o
sockex3_kern.o: file format elf64-bpf
Sections:
Idx Name Size VMA Type
0 00000000 0000000000000000
1 .strtab 000002b1 0000000000000000
2 .text 00000000 0000000000000000 TEXT
3 socket/3 000004d8 0000000000000000 TEXT
4 .relsocket/3 00000070 0000000000000000
5 socket/4 00000558 0000000000000000 TEXT
6 .relsocket/4 00000070 0000000000000000
7 socket/1 00000100 0000000000000000 TEXT
8 .relsocket/1 00000010 0000000000000000
9 socket/2 00000078 0000000000000000 TEXT
10 .relsocket/2 00000010 0000000000000000
11 socket/0 000000e8 0000000000000000 TEXT
12 .relsocket/0 00000010 0000000000000000
13 license 00000004 0000000000000000 DATA
14 .maps 00000060 0000000000000000 DATA
15 .debug_loc 00000ef1 0000000000000000
16 .rel.debug_loc 00000370 0000000000000000
17 .debug_abbrev 0000029f 0000000000000000
18 .debug_info 00000d4b 0000000000000000
19 .rel.debug_info 000011b0 0000000000000000
20 .debug_ranges 000002e0 0000000000000000
21 .rel.debug_ranges 00000420 0000000000000000
22 .debug_str 0000067d 0000000000000000
23 .BTF 000012c2 0000000000000000
24 .rel.BTF 00000040 0000000000000000
25 .BTF.ext 00000ac0 0000000000000000
26 .rel.BTF.ext 00000a70 0000000000000000
27 .eh_frame 000000b0 0000000000000000 DATA
28 .rel.eh_frame 00000050 0000000000000000
29 .debug_line 0000046b 0000000000000000
30 .rel.debug_line 00000050 0000000000000000
31 .symtab 00001500 0000000000000000
先谢谢你!
解决方法
我创建了:https://github.com/rafaeldtinoco/portablebpf/
出于类似原因基于上游 libbpf 文档:因此您可以使用静态 (libbpf) 方法创建/编译基于可移植 libbpf 的代码。
另外:确保您使用以下方法从 BTF 生成 vmlinux.h 包含文件:
bpftool btf dump file /sys/kernel/btf/vmlinux format c
在新内核中或通过检查:
https://lore.kernel.org/bpf/20210303181457.172434-1-rafaeldtinoco@ubuntu.com/
了解如何在较旧的内核中执行此操作。