|
| 1 | +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) |
| 2 | + |
| 3 | +LINUX_SRC_PATH ?= /usr/src/linux |
| 4 | +BPF_SAMPLES_PATH := $(LINUX_SRC_PATH)/samples/bpf |
| 5 | +TOOLS_PATH := $(BPF_SAMPLES_PATH)/../../tools |
| 6 | +L3AF_SRC_PATH := $(CURDIR) |
| 7 | + |
| 8 | +# Libbpf dependencies |
| 9 | +LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a |
| 10 | + |
| 11 | +# Tell kbuild to always build the programs |
| 12 | +always-y := $(tprogs-y) |
| 13 | +always-y += uprobe.bpf.o |
| 14 | + |
| 15 | + |
| 16 | +ifeq ($(ARCH), arm) |
| 17 | +# Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux |
| 18 | +# headers when arm instruction set identification is requested. |
| 19 | +ARM_ARCH_SELECTOR := $(filter -D__LINUX_ARM_ARCH__%, $(KBUILD_CFLAGS)) |
| 20 | +BPF_EXTRA_CFLAGS := $(ARM_ARCH_SELECTOR) |
| 21 | +TPROGS_CFLAGS += $(ARM_ARCH_SELECTOR) |
| 22 | +endif |
| 23 | + |
| 24 | +ifeq ($(ARCH), mips) |
| 25 | +TPROGS_CFLAGS += -D__SANE_USERSPACE_TYPES__ |
| 26 | +ifdef CONFIG_MACH_LOONGSON64 |
| 27 | +BPF_EXTRA_CFLAGS += -I$(srctree)/arch/mips/include/asm/mach-loongson64 |
| 28 | +BPF_EXTRA_CFLAGS += -I$(srctree)/arch/mips/include/asm/mach-generic |
| 29 | +endif |
| 30 | +endif |
| 31 | + |
| 32 | +TPROGS_CFLAGS += -Wall -O2 |
| 33 | +TPROGS_CFLAGS += -Wmissing-prototypes |
| 34 | +TPROGS_CFLAGS += -Wstrict-prototypes |
| 35 | + |
| 36 | +TPROGS_CFLAGS += -I$(objtree)/usr/include |
| 37 | +TPROGS_CFLAGS += -I$(srctree)/tools/testing/selftests/bpf/ |
| 38 | +TPROGS_CFLAGS += -I$(srctree)/tools/lib/ |
| 39 | +TPROGS_CFLAGS += -I$(srctree)/tools/include |
| 40 | +TPROGS_CFLAGS += -I$(srctree)/tools/perf |
| 41 | +TPROGS_CFLAGS += -DHAVE_ATTR_TEST=0 |
| 42 | + |
| 43 | +ifdef SYSROOT |
| 44 | +TPROGS_CFLAGS += --sysroot=$(SYSROOT) |
| 45 | +TPROGS_LDFLAGS := -L$(SYSROOT)/usr/lib |
| 46 | +endif |
| 47 | + |
| 48 | +TPROGS_LDLIBS += $(LIBBPF) -lelf -lz -lcrypto |
| 49 | + |
| 50 | +# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: |
| 51 | +# make M=samples/bpf LLC=~/git/llvm-project/llvm/build/bin/llc CLANG=~/git/llvm-project/llvm/build/bin/clang |
| 52 | +LLC ?= llc |
| 53 | +CLANG ?= clang |
| 54 | +OPT ?= opt |
| 55 | +LLVM_DIS ?= llvm-dis |
| 56 | +LLVM_OBJCOPY ?= llvm-objcopy |
| 57 | +BTF_PAHOLE ?= pahole |
| 58 | + |
| 59 | +# Detect that we're cross compiling and use the cross compiler |
| 60 | +ifdef CROSS_COMPILE |
| 61 | +CLANG_ARCH_ARGS = --target=$(notdir $(CROSS_COMPILE:%-=%)) |
| 62 | +endif |
| 63 | + |
| 64 | +# Don't evaluate probes and warnings if we need to run make recursively |
| 65 | +ifneq ($(src),) |
| 66 | +HDR_PROBE := $(shell printf "\#include <linux/types.h>\n struct list_head { int a; }; int main() { return 0; }" | \ |
| 67 | + $(CC) $(TPROGS_CFLAGS) $(TPROGS_LDFLAGS) -x c - \ |
| 68 | + -o /dev/null 2>/dev/null && echo okay) |
| 69 | + |
| 70 | +ifeq ($(HDR_PROBE),) |
| 71 | +$(warning WARNING: Detected possible issues with include path.) |
| 72 | +$(warning WARNING: Please install kernel headers locally (make headers_install).) |
| 73 | +endif |
| 74 | + |
| 75 | +BTF_LLC_PROBE := $(shell $(LLC) -march=bpf -mattr=help 2>&1 | grep dwarfris) |
| 76 | +BTF_PAHOLE_PROBE := $(shell $(BTF_PAHOLE) --help 2>&1 | grep BTF) |
| 77 | +BTF_OBJCOPY_PROBE := $(shell $(LLVM_OBJCOPY) --help 2>&1 | grep -i 'usage.*llvm') |
| 78 | +BTF_LLVM_PROBE := $(shell echo "int main() { return 0; }" | \ |
| 79 | + $(CLANG) -target bpf -O2 -g -c -x c - -o ./llvm_btf_verify.o; \ |
| 80 | + readelf -S ./llvm_btf_verify.o | grep BTF; \ |
| 81 | + /bin/rm -f ./llvm_btf_verify.o) |
| 82 | + |
| 83 | +BPF_EXTRA_CFLAGS += -fno-stack-protector |
| 84 | +ifneq ($(BTF_LLVM_PROBE),) |
| 85 | + BPF_EXTRA_CFLAGS += -g |
| 86 | +else |
| 87 | +ifneq ($(and $(BTF_LLC_PROBE),$(BTF_PAHOLE_PROBE),$(BTF_OBJCOPY_PROBE)),) |
| 88 | + BPF_EXTRA_CFLAGS += -g |
| 89 | + LLC_FLAGS += -mattr=dwarfris |
| 90 | + DWARF2BTF = y |
| 91 | +endif |
| 92 | +endif |
| 93 | +endif |
| 94 | + |
| 95 | +# Trick to allow make to be run from this directory |
| 96 | +all:build tar.zip |
| 97 | +build: |
| 98 | + if [ ! -f $(L3AF_SRC_PATH)/vmlinux.h ]; then \ |
| 99 | + bpftool btf dump file /sys/kernel/btf/vmlinux format c > $(L3AF_SRC_PATH)/vmlinux.h; \ |
| 100 | + fi |
| 101 | + $(MAKE) -C $(LINUX_SRC_PATH) M=$(L3AF_SRC_PATH) |
| 102 | + |
| 103 | +tar.zip: |
| 104 | + @rm -rf l3af_uprobe |
| 105 | + @rm -f l3af_uprobe.tar.gz |
| 106 | + @mkdir l3af_uprobe |
| 107 | + @cp $(L3AF_SRC_PATH)/uprobe.bpf.o ./l3af_uprobe |
| 108 | + @tar -cvf l3af_uprobe.tar ./l3af_uprobe |
| 109 | + @gzip l3af_uprobe.tar |
| 110 | + |
| 111 | +clean: |
| 112 | + $(MAKE) -C $(LINUX_SRC_PATH) M=$(L3AF_SRC_PATH) clean |
| 113 | + @find $(CURDIR) -type f -name '*~' -delete |
| 114 | + @rm -f ./*.o |
| 115 | + @rm -f *~ |
| 116 | + |
| 117 | +$(LIBBPF): FORCE |
| 118 | +# Fix up variables inherited from Kbuild that tools/ build system won't like |
| 119 | + $(MAKE) -C $(dir $@) RM='rm -rf' EXTRA_CFLAGS="$(TPROGS_CFLAGS)" \ |
| 120 | + LDFLAGS=$(TPROGS_LDFLAGS) srctree=$(BPF_SAMPLES_PATH)/../../ O= |
| 121 | + |
| 122 | +BPFTOOLDIR := $(TOOLS_PATH)/bpf/bpftool |
| 123 | +BPFTOOL := $(BPFTOOLDIR)/bpftool |
| 124 | +$(BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) |
| 125 | + $(MAKE) -C $(BPFTOOLDIR) srctree=$(BPF_SAMPLES_PATH)/../../ |
| 126 | + |
| 127 | +$(obj)/syscall_nrs.h: $(obj)/syscall_nrs.s FORCE |
| 128 | + $(call filechk,offsets,__SYSCALL_NRS_H__) |
| 129 | + |
| 130 | +targets += syscall_nrs.s |
| 131 | +clean-files += syscall_nrs.h |
| 132 | + |
| 133 | +FORCE: |
| 134 | + |
| 135 | + |
| 136 | +# Verify LLVM compiler tools are available and bpf target is supported by llc |
| 137 | +.PHONY: verify_cmds verify_target_bpf $(CLANG) $(LLC) |
| 138 | + |
| 139 | +verify_cmds: $(CLANG) $(LLC) |
| 140 | + @for TOOL in $^ ; do \ |
| 141 | + if ! (which -- "$${TOOL}" > /dev/null 2>&1); then \ |
| 142 | + echo "*** ERROR: Cannot find LLVM tool $${TOOL}" ;\ |
| 143 | + exit 1; \ |
| 144 | + else true; fi; \ |
| 145 | + done |
| 146 | + |
| 147 | +verify_target_bpf: verify_cmds |
| 148 | + @if ! (${LLC} -march=bpf -mattr=help > /dev/null 2>&1); then \ |
| 149 | + echo "*** ERROR: LLVM (${LLC}) does not support 'bpf' target" ;\ |
| 150 | + echo " NOTICE: LLVM version >= 3.7.1 required" ;\ |
| 151 | + exit 2; \ |
| 152 | + else true; fi |
| 153 | + |
| 154 | +$(BPF_SAMPLES_PATH)/*.c: verify_target_bpf $(LIBBPF) |
| 155 | +$(src)/*.c: verify_target_bpf $(LIBBPF) |
| 156 | + |
| 157 | + |
| 158 | +-include $(BPF_SAMPLES_PATH)/Makefile.target |
| 159 | + |
| 160 | +VMLINUX_BTF_PATHS ?= $(abspath $(if $(O),$(O)/vmlinux)) \ |
| 161 | + $(abspath $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)) \ |
| 162 | + $(abspath ./vmlinux) |
| 163 | +VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) |
| 164 | + |
| 165 | +clean-files += vmlinux.h |
| 166 | + |
| 167 | +# Get Clang's default includes on this system, as opposed to those seen by |
| 168 | +# '-target bpf'. This fixes "missing" files on some architectures/distros, |
| 169 | +# such as asm/byteorder.h, asm/socket.h, asm/sockios.h, sys/cdefs.h etc. |
| 170 | +# |
| 171 | +# Use '-idirafter': Don't interfere with include mechanics except where the |
| 172 | +# build would have failed anyways. |
| 173 | +define get_sys_includes |
| 174 | +$(shell $(1) -v -E - </dev/null 2>&1 \ |
| 175 | + | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \ |
| 176 | +$(shell $(1) -dM -E - </dev/null | grep '#define __riscv_xlen ' | sed 's/#define /-D/' | sed 's/ /=/') |
| 177 | +endef |
| 178 | + |
| 179 | +CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG)) |
| 180 | + |
| 181 | + |
| 182 | +$(obj)/%.bpf.o: $(src)/%.bpf.c $(BPF_SAMPLES_PATH)/xdp_sample.bpf.h $(BPF_SAMPLES_PATH)/xdp_sample_shared.h |
| 183 | + @echo " CLANG-BPF " $@ |
| 184 | + $(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(SRCARCH) \ |
| 185 | + -Wno-compare-distinct-pointer-types -I$(srctree)/include \ |
| 186 | + -I$(srctree)/samples/bpf -I$(srctree)/tools/include \ |
| 187 | + -I$(srctree)/tools/lib -I$(srctree)/tools/lib/bpf $(CLANG_SYS_INCLUDES) \ |
| 188 | + -c $(filter %.bpf.c,$^) -o $@ |
| 189 | + |
| 190 | +# asm/sysreg.h - inline assembly used by it is incompatible with llvm. |
| 191 | +# But, there is no easy way to fix it, so just exclude it since it is |
| 192 | +# useless for BPF samples. |
| 193 | +# below we use long chain of commands, clang | opt | llvm-dis | llc, |
| 194 | +# to generate final object file. 'clang' compiles the source into IR |
| 195 | +# with native target, e.g., x64, arm64, etc. 'opt' does bpf CORE IR builtin |
| 196 | +# processing (llvm12) and IR optimizations. 'llvm-dis' converts |
| 197 | +# 'opt' output to IR, and finally 'llc' generates bpf byte code. |
| 198 | +$(obj)/%.o: $(src)/%.c |
| 199 | + @echo " CLANG-bpf " $@ |
| 200 | + $(Q)$(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(BPF_EXTRA_CFLAGS) \ |
| 201 | + -I$(obj) -I$(srctree)/tools/testing/selftests/bpf/ \ |
| 202 | + -I$(srctree)/tools/lib/ -I$(srctree)/tools/lib/bpf \ |
| 203 | + -D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \ |
| 204 | + -D__TARGET_ARCH_$(SRCARCH) -Wno-compare-distinct-pointer-types \ |
| 205 | + -Wno-gnu-variable-sized-type-not-at-end \ |
| 206 | + -Wno-address-of-packed-member -Wno-tautological-compare \ |
| 207 | + -Wno-unknown-warning-option $(CLANG_ARCH_ARGS) \ |
| 208 | + -fno-asynchronous-unwind-tables \ |
| 209 | + -I$(srctree)/samples/bpf/ -include asm_goto_workaround.h \ |
| 210 | + -O2 -emit-llvm -Xclang -disable-llvm-passes -c $< -o - | \ |
| 211 | + $(OPT) -O2 -mtriple=bpf-pc-linux | $(LLVM_DIS) | \ |
| 212 | + $(LLC) -march=bpf $(LLC_FLAGS) -filetype=obj -o $@ |
0 commit comments