[DTrace-devel] [PATCH] Add support to compile BPF functions from C source code

Kris Van Hees kris.van.hees at oracle.com
Wed Mar 4 07:49:07 PST 2020


The DTrace v2 implementation depends on being able to make use of BPF
functions (at runtime) that have been precompiled at build time.  The
build system provides a very flexible system to add templates and rules
to accompish this.

This commit provides the basic infrastructure for the compilation of
BPF code.  Appropriate packages must have been installed to provude
bpf-unknown-none-gcc and bpf-unknown-none-ld.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 GNUmakefile   | 14 +++++++++++---
 Makefunctions | 23 +++++++++++++++++++++++
 Makerules     |  7 +++++--
 3 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/GNUmakefile b/GNUmakefile
index 79e016c5..287ed762 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -16,7 +16,9 @@ VERSION := 2.0.0
 
 # Verify supported hardware.
 
-$(if $(subst sparc64,,$(subst aarch64,,$(subst x86_64,,$(shell uname -m)))), \
+ARCH := $(shell uname -m)
+
+$(if $(subst sparc64,,$(subst aarch64,,$(subst x86_64,,$(ARCH)))), \
     $(error "Error: DTrace for Linux only supports x86_64, ARM64 and sparc64"),)
 $(if $(subst Linux,,$(shell uname -s)), \
     $(error "Error: DTrace only supports Linux"),)
@@ -25,12 +27,18 @@ CFLAGS ?= -O2 -Wall -pedantic -Wno-unknown-pragmas
 LDFLAGS ?=
 BITNESS := 64
 NATIVE_BITNESS_ONLY := $(shell echo 'int main (void) { }' | gcc -x c -o /dev/null -m32 - 2>/dev/null || echo t)
-ARCHINC := $(subst sparc64,sparc,$(subst aarch64,arm64,$(subst x86_64,i386,$(shell uname -m))))
+ARCHINC := $(subst sparc64,sparc,$(subst aarch64,arm64,$(subst x86_64,i386,$(ARCH))))
 INVARIANT_CFLAGS := -std=gnu99 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 $(if $(NATIVE_BITNESS_ONLY),-DNATIVE_BITNESS_ONLY) -D_DT_VERSION=\"$(VERSION)\"
 CPPFLAGS += -Iinclude -Iuts/common -Iinclude/$(ARCHINC) -I$(objdir)
+
 export CC = gcc
 override CFLAGS += $(INVARIANT_CFLAGS)
 PREPROCESS = $(CC) -E
+export BPFC = bpf-unknown-none-gcc
+
+BPFCPPFLAGS += -D$(subst sparc64,__sparc,$(subst aarch64,__aarch64__,$(subst x86_64,__amd64,$(ARCH))))
+BPFCFLAGS ?= -O2 -Wall -pedantic -Wno-unknown-pragmas
+export BPFLD = bpf-unknown-none-ld
 
 # The first non-system uid on this system.
 USER_UID=$(shell grep '^UID_MIN' /etc/login.defs | awk '{print $$2;}')
@@ -61,7 +69,7 @@ KERNELODIR=
 # This allows you to build using a locally installed kernel built with O= by
 # just specifying KERNELODIR=relative/path/to/your/kernel/o/dir.
 KERNELDIRSUFFIX=$(if $(KERNELODIR),/source,/build)
-KERNELARCH := $(subst sparc64,sparc,$(subst aarch64,arm64,$(subst x86_64,x86,$(shell uname -m))))
+KERNELARCH := $(subst sparc64,sparc,$(subst aarch64,arm64,$(subst x86_64,x86,$(ARCH))))
 
 # Paths.
 
diff --git a/Makefunctions b/Makefunctions
index 667445ce..7c5627ea 100644
--- a/Makefunctions
+++ b/Makefunctions
@@ -60,6 +60,15 @@ $(obj-name): $(src-name) $(foreach dep,$($(1)_SRCDEPS),$(call src-name,$(1),$(de
 	$(CC) $(CPPFLAGS) $($(1)_CPPFLAGS) $(filter-out $($(1)_NOCFLAGS) $($(2)_NOCFLAGS),$(CFLAGS) $($(1)_CFLAGS) $($(2)_CFLAGS) $(3)) $(cc-dependencies) -c -o $(obj-name) $(src-name)
 endef
 
+# Rule to build a BPF C source file.
+# Syntax: $(call bpf-template,primary,filename-without-dir,optional flags)
+
+define bpf-template
+$(obj-name): $(src-name) $(foreach dep,$($(1)_SRCDEPS),$(call src-name,$(1),$(dep))) $(CONFIG_H)
+	$(call describe-target,BPF-CC,$(src-name))
+	$(BPFC) $(BPFCPPFLAGS) $($(1)_CPPFLAGS) $(filter-out $($(1)_NOCFLAGS) $($(2)_NOCFLAGS),$(BPFCFLAGS) $($(1)_CFLAGS) $($(2)_CFLAGS) $(3)) $(cc-dependencies) -c -o $(obj-name) $(src-name)
+endef
+
 # Rule to build a DTrace USDT header file.
 # Syntax: $(call hdr-template,primary,filename-without-dir)
 
@@ -128,6 +137,20 @@ $(objdir)/$($(1)_TARGET).so $(if $($(1)_VERSION),$(objdir)/$($(1)_TARGET).so.$($
 	$(foreach post,$($(1)_POST),$(call $(post),$(objdir)/$($(1)_TARGET).so$(if $($(1)_VERSION),.$($(1)_VERSION))))
 endef
 
+# Rule to build a BPF library, and all its sources.
+# Syntax: $(call bpflib-template,primary)
+
+define bpflib-template
+$(objdir)/$($(1)_TARGET).o: $(foreach source,$($(1)_SOURCES),$(call obj-name,$(1),$(source))) \
+                                  $(foreach dep,$(filter-out %.o,$($(1)_DEPS)),$(addprefix $(objdir)/,$(dep))) \
+                                  $(foreach dep,$(filter %.o,$($(1)_DEPS)),$(call obj-name,$(1),$(dep)))
+	$(call describe-target,BPF-LD,$($(1)_TARGET).o)
+	$(BPFLD) -o $(objdir)/$($(1)_TARGET).o -r $(foreach source,$($(1)_SOURCES),$(call obj-name,$(1),$(source)))
+	$(foreach post,$($(1)_POST),$(call $(post),$(objdir)/build-$($(1)_TARGET).o))
+
+$(foreach file,$(filter-out $($(1)_EXPLICIT),$($(1)_SOURCES)),$(eval $(call bpf-template,$(1),$(file))))
+endef
+
 # Rule to build a binary, and all its sources.
 # Syntax: $(call cmd-template,primary)
 
diff --git a/Makerules b/Makerules
index aab0ec6e..7615ca29 100644
--- a/Makerules
+++ b/Makerules
@@ -7,8 +7,8 @@
 
 # Trigger the library-building rules.
 
-PHONIES += build-libs libs shlibs
-TARGETS += build-libs libs shlibs
+PHONIES += build-libs libs shlibs bpflibs
+TARGETS += build-libs libs shlibs bpflibs
 
 $(foreach lib,$(BUILDLIBS),$(eval $(call build-lib-template,$(lib))))
 build-libs: $(foreach lib,$(BUILDLIBS),$(objdir)/build-$($(lib)_TARGET).a)
@@ -19,6 +19,9 @@ libs: build-libs $(foreach lib,$(LIBS),$(objdir)/$($(lib)_TARGET).a)
 $(foreach lib,$(SHLIBS),$(eval $(call shlib-template,$(lib))))
 shlibs: build-libs $(foreach lib,$(SHLIBS),$(objdir)/$($(lib)_TARGET).so)
 
+$(foreach lib,$(BPFLIBS),$(eval $(call bpflib-template,$(lib))))
+bpflibs: $(foreach lib,$(BPFLIBS),$(objdir)/$($(lib)_TARGET).o)
+
 # Trigger the command-building rule.
 
 PHONIES += cmds
-- 
2.25.0




More information about the DTrace-devel mailing list