libbpf:未能找到外部“不太可能”的 BTF:-2

问题描述

我正在尝试使用 {{3} 在新项目(内核树之外)中编译和运行 sockex3 示例(来自 v5.10 的 sockex3_user.csockex3_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/

了解如何在较旧的内核中执行此操作。