从内核树中编译 eBPF C 代码时出错
Error compiling eBPF C code out of kernel tree
我正在尝试将用 C 编写的 BPF 程序构建到加载它所需的 bpf 字节码中。我用这个 post 来尝试让我开始:https://blogs.oracle.com/linux/notes-on-bpf-4
由于依赖库,我不想使用 BCC。我正在使用 ubuntu 18.04 (Linux bpf-ubuntu 4.15.0-1036-gcp #38-Ubuntu SMP Mon Jun 24 13:49:05 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux)
目前我的文件非常简单(并且可能不正确),因为我仍在努力编译工作:
#include <linux/version.h>
#include <uapi/linux/bpf.h>
#include "bpf_helpers.h"
#include <net/sock.h>
SEC("kprobe/tcp_connect")
int bpf_prog1(struct pt_regs *ctx) {
struct sock *sk;
sk = (struct sock*) PT_REGS_PARM1(ctx);
bpf_trace_printk("%s\n","Got tcp_connect");
}
char _license[] SEC("license") = "GPL";
u32 _version SEC("version") = LINUX_VERSION_CODE;
用于构建和结果的命令是:
clang -nostdinc -isystem `clang -print-file-name=include` \
-D__KERNEL__ -D__ASM_SYSREG_H \
-Wno-unused-value -Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Wno-gnu-variable-sized-type-not-at-end \
-Wno-address-of-packed-member -Wno-tautological-compare \
-Wno-unknown-warning-option \
-I../include -I/usr/src/linux-headers-`uname -r`/include -I/usr/src/linux-headers-`uname -r`/arch/x86/include -I/usr/src/linux-headers-`uname -r`/arch/x86/include/uapi -I/usr/src/linux-headers-`uname -r`/arch/x86/include/generated/uapi -I/usr/src/linux-headers-`uname -r`/include/generated/uapi -I/usr/src/linux-headers-`uname -r`/include/uapi \
-O2 -emit-llvm -c net_mon_kern.c -o -| llc -march=bpf -filetype=obj -o net_mon_kern.o
In file included from net_mon_kern.c:7:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/net/sock.h:43:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/hardirq.h:5:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/preempt.h:11:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/list.h:9:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/kernel.h:11:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/bitops.h:18:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/bitops.h:514:
/usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/arch_hweight.h:55:42: error: expected ')'
asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
^
/usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/arch_hweight.h:55:6: note: to match this '('
asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
^
In file included from net_mon_kern.c:7:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/net/sock.h:43:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/hardirq.h:5:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/preempt.h:81:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/preempt.h:7:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/thread_info.h:38:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/thread_info.h:12:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/page.h:14:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/page_32.h:35:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/string.h:19:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/string.h:5:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/string_64.h:6:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/jump_label.h:188:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/atomic.h:5:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/atomic.h:276:
/usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/atomic64_64.h:20:40: error: unknown type name
'atomic64_t'; did you mean 'atomic_t'?
static inline long atomic64_read(const atomic64_t *v)
^~~~~~~~~~
atomic_t
/usr/src/linux-headers-4.15.0-1036-gcp/include/linux/types.h:178:3: note: 'atomic_t' declared here
} atomic_t;
^
18 more errors relating to atomic64_t...
我不太确定如何解决这个问题。我只能假设我包含 headers 的方式不正确。
TL;DR:尝试在其他包含之前包含 linux/kconfig.h
。
在我看来,您的命令行是从内核示例(在 samples/bpf/
下)中得到启发的,但是您尝试从树中编译出来,并且修剪了 non-relevant 位。
当您尝试编译代码时,clang 会在您使用 -I
选项传递的路径中获取所有相关内核 headers。但是,其中一些 headers 包含条件定义或包含,具体取决于要构建的内核所请求的配置。例如,最终通过 <net/sock.h>
包含的 include/linux/types.h
具有以下代码:
#ifdef CONFIG_64BIT
typedef struct {
long counter;
} atomic64_t;
#endif
但是当你编译的时候,CONFIG_64BIT
从来没有被定义过...我让你联系你得到的错误信息:)。
内核示例实际上包括 kconfig.h
到 LINUXINCLUDE
and USERINCLUDE
,因此我们必须想办法以某种方式添加它。这显然足以正确设置配置变量并修复编译问题。
我发现以下可能性可以将文件包含在您的案例中:
- 将
#include <linux/kconfig.h>
添加到您的文件,在 包括其他内核 headers 之前(例如在第一行)。
- 或者通过命令行添加它:
-include linux/kconfig.h
,就像内核样本一样(这似乎是最干净的方式)。
我正在尝试将用 C 编写的 BPF 程序构建到加载它所需的 bpf 字节码中。我用这个 post 来尝试让我开始:https://blogs.oracle.com/linux/notes-on-bpf-4
由于依赖库,我不想使用 BCC。我正在使用 ubuntu 18.04 (Linux bpf-ubuntu 4.15.0-1036-gcp #38-Ubuntu SMP Mon Jun 24 13:49:05 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux)
目前我的文件非常简单(并且可能不正确),因为我仍在努力编译工作:
#include <linux/version.h>
#include <uapi/linux/bpf.h>
#include "bpf_helpers.h"
#include <net/sock.h>
SEC("kprobe/tcp_connect")
int bpf_prog1(struct pt_regs *ctx) {
struct sock *sk;
sk = (struct sock*) PT_REGS_PARM1(ctx);
bpf_trace_printk("%s\n","Got tcp_connect");
}
char _license[] SEC("license") = "GPL";
u32 _version SEC("version") = LINUX_VERSION_CODE;
用于构建和结果的命令是:
clang -nostdinc -isystem `clang -print-file-name=include` \
-D__KERNEL__ -D__ASM_SYSREG_H \
-Wno-unused-value -Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Wno-gnu-variable-sized-type-not-at-end \
-Wno-address-of-packed-member -Wno-tautological-compare \
-Wno-unknown-warning-option \
-I../include -I/usr/src/linux-headers-`uname -r`/include -I/usr/src/linux-headers-`uname -r`/arch/x86/include -I/usr/src/linux-headers-`uname -r`/arch/x86/include/uapi -I/usr/src/linux-headers-`uname -r`/arch/x86/include/generated/uapi -I/usr/src/linux-headers-`uname -r`/include/generated/uapi -I/usr/src/linux-headers-`uname -r`/include/uapi \
-O2 -emit-llvm -c net_mon_kern.c -o -| llc -march=bpf -filetype=obj -o net_mon_kern.o
In file included from net_mon_kern.c:7:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/net/sock.h:43:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/hardirq.h:5:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/preempt.h:11:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/list.h:9:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/kernel.h:11:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/bitops.h:18:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/bitops.h:514:
/usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/arch_hweight.h:55:42: error: expected ')'
asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
^
/usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/arch_hweight.h:55:6: note: to match this '('
asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
^
In file included from net_mon_kern.c:7:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/net/sock.h:43:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/hardirq.h:5:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/preempt.h:81:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/preempt.h:7:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/thread_info.h:38:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/thread_info.h:12:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/page.h:14:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/page_32.h:35:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/string.h:19:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/string.h:5:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/string_64.h:6:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/jump_label.h:188:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/include/linux/atomic.h:5:
In file included from /usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/atomic.h:276:
/usr/src/linux-headers-4.15.0-1036-gcp/arch/x86/include/asm/atomic64_64.h:20:40: error: unknown type name
'atomic64_t'; did you mean 'atomic_t'?
static inline long atomic64_read(const atomic64_t *v)
^~~~~~~~~~
atomic_t
/usr/src/linux-headers-4.15.0-1036-gcp/include/linux/types.h:178:3: note: 'atomic_t' declared here
} atomic_t;
^
18 more errors relating to atomic64_t...
我不太确定如何解决这个问题。我只能假设我包含 headers 的方式不正确。
TL;DR:尝试在其他包含之前包含 linux/kconfig.h
。
在我看来,您的命令行是从内核示例(在 samples/bpf/
下)中得到启发的,但是您尝试从树中编译出来,并且修剪了 non-relevant 位。
当您尝试编译代码时,clang 会在您使用 -I
选项传递的路径中获取所有相关内核 headers。但是,其中一些 headers 包含条件定义或包含,具体取决于要构建的内核所请求的配置。例如,最终通过 <net/sock.h>
包含的 include/linux/types.h
具有以下代码:
#ifdef CONFIG_64BIT
typedef struct {
long counter;
} atomic64_t;
#endif
但是当你编译的时候,CONFIG_64BIT
从来没有被定义过...我让你联系你得到的错误信息:)。
内核示例实际上包括 kconfig.h
到 LINUXINCLUDE
and USERINCLUDE
,因此我们必须想办法以某种方式添加它。这显然足以正确设置配置变量并修复编译问题。
我发现以下可能性可以将文件包含在您的案例中:
- 将
#include <linux/kconfig.h>
添加到您的文件,在 包括其他内核 headers 之前(例如在第一行)。 - 或者通过命令行添加它:
-include linux/kconfig.h
,就像内核样本一样(这似乎是最干净的方式)。