Ошибка компиляции кода eBPF C из дерева ядра - PullRequest
0 голосов
/ 10 июля 2019

Я пытаюсь встроить программу BPF, написанную на C, в байт-код bpf, необходимый для ее загрузки.Я использовал этот пост, чтобы попытаться начать меня: 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 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...

IЯ не совсем уверен, как это устранить.Я могу только предполагать, что я включаю заголовки неправильно.

1 Ответ

2 голосов
/ 11 июля 2019

TL; DR: попробуйте включить linux/kconfig.h до того, как другие включат.

Мне кажется, что ваша командная строка основана на примерах ядра (ниже samples/bpf/), но вы пытаетесь скомпилироватьвне дерева, и вы обрезали нерелевантные биты.

Что происходит, когда вы пытаетесь скомпилировать код, так это то, что clang получает все соответствующие заголовки ядра по путям, которые вы передали с параметрами -I.Тем не менее, некоторые из этих заголовков содержат условные определения или включения, в зависимости от запрашиваемой конфигурации для сборки ядра.Например, include/linux/types.h, который в конечном итоге включается через <net/sock.h>, имеет следующий код:

#ifdef CONFIG_64BIT
typedef struct {
    long counter;
} atomic64_t;
#endif

Но когда вы компилируете, CONFIG_64BIT никогда не определялся ... Я позволю вам связать сполученное сообщение об ошибке:).

Образцы ядра на самом деле включают kconfig.h - LINUXINCLUDE и USERINCLUDE, поэтому мы должны найти способ добавитьэто как-то.По-видимому, этого достаточно для правильной установки переменных конфигурации и устранения проблем компиляции.

Я нашел следующие возможности для включения файла в ваш случай:

  • Добавить #include <linux/kconfig.h>к вашему файлу, до , включая другие заголовки ядра (например, в первой строке).
  • Или добавьте его через командную строку: -include linux/kconfig.h, как это делают примеры ядра (что кажетсясамый чистый путь).
...