libbpf:加载 ELF 部分 .BTF 时出错:0

Mai*_*ake 4 c elf bpf ebpf

当我尝试执行sudo ./mineonlyret加载 ebpf 程序的用户空间程序时,我在 ubuntu 19.04 上收到此错误消息,稍后对此进行描述。我在 ubuntu 18.04 上尝试了相同的配置,并且没有错误。导致此错误的原因可能是什么?\n如果您需要更多详细信息,请告诉我。

\n\n
libbpf: Error loading ELF section .BTF: 0.\n
Run Code Online (Sandbox Code Playgroud)\n\n

mineonlyret_user.c

\n\n
// SPDX-License-Identifier: GPL-2.0\n#include <stdio.h>\n#include <assert.h>\n#include <linux/bpf.h>\n#include "libbpf.h"\n#include <unistd.h>\n#include <arpa/inet.h>\n#include <linux/if_ether.h>\n\nint main(int ac, char **argv)\n{\n    int sock, prog_fd;\n    struct bpf_object *obj;\n    char filename[256];\n\n    if (bpf_prog_load("mineonlyret_kern.o", BPF_PROG_TYPE_SOCKET_FILTER,\n              &obj, &prog_fd))\n        return 1;\n\n    /* open up a packet socket */\n    sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));  \n    if(sock < 0){\n        printf("socket");\n        return -1;\n    }\n\n    /* attach the filter */\n    assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,\n              sizeof(prog_fd)) == 0);\n\n    int i;\n        char buf[65535];\n    for (i = 0; i < 5; i++) {\n        printf("ci\\n");\n            int res = recvfrom(sock, buf, sizeof(buf), 0, NULL, 0);\n            printf("res=%d\\n", res);\n\n        sleep(5);\n    }\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

mineonlyret_kern.c

\n\n
#include <linux/bpf.h>\n#include <linux/if_ether.h>\n#include <linux/if_packet.h>\n#include <linux/ip.h>\n#include <linux/udp.h>\n#include <linux/in.h>\n#include "bpf_helpers.h"\n#include <stddef.h>\nSEC("socket")\nint bpf_sk_prog(struct __sk_buff *skb)\n{\n\n        return 0;\n\n}\nchar _license[] SEC("license") = "GPL";\n
Run Code Online (Sandbox Code Playgroud)\n\n

我用以下命令编译 _kern.c

\n\n
clang -S -I. -O2 -emit-llvm -c mineonlyret_kern.c -o - | llc -march=bpf -filetype=obj -o mineonlyret_kern.o\n
Run Code Online (Sandbox Code Playgroud)\n\n

和 _user.c 与

\n\n
gcc  -o mineonlyret mineonlyret_user.c -I../libbpf/src/  ../libbpf/src/libbpf.a -lelf\n
Run Code Online (Sandbox Code Playgroud)\n\n

另外,我还有另一个疑问:为什么如果我使用库的共享版本它不起作用?我的意思是如果我执行

\n\n
gcc  -o mineonlyret mineonlyret_user.c -I../libbpf/src/  -L../libbpf/src/ -lbpf\n
Run Code Online (Sandbox Code Playgroud)\n\n

目录树

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 libbpf\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 include\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 libbpf.so\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 libbpf.a\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 libbpfebpf\n    |\xe2\x94\x80\xe2\x94\x80 mineonlyret_user.c\n    |\xe2\x94\x80\xe2\x94\x80 mineonlyret_kern.c\n
Run Code Online (Sandbox Code Playgroud)\n

小智 5

您需要指定-g请求 Clang 生成 .BTF(它也会生成 DWARF 调试信息,但您可以忽略或删除它,libbpf 不使用它)。虽然 .BTF 最初是一个可选的额外信息,用于更好的调试和 BPF 程序集转储,但它已发展成为现代 BPF 应用程序(至少是那些使用 libbpf 的应用程序)非常必需的部分,因此请确保始终具有“-g”指定的。