On Thu, Aug 15, 2024 at 1:56 PM Eduard Zingerman <eddyz87@xxxxxxxxx> wrote: > > This commit adds a utility function to get disassembled text for jited > representation of a BPF program designated by file descriptor. > Function prototype looks as follows: > > int get_jited_program_text(int fd, char *text, size_t text_sz) > > Where 'fd' is a file descriptor for the program, 'text' and 'text_sz' > refer to a destination buffer for disassembled text. > > The code and makefile changes are inspired by jit_disasm.c from bpftool. > Use llvm libraries to disassemble BPF program instead of libbfd to avoid > issues with disassembly output stability pointed out in [1]. > > Selftests makefile uses Makefile.feature to detect if LLVM libraries > are available. If that is not the case selftests build proceeds but > the function returns -ENOTSUP at runtime. > > [1] commit eb9d1acf634b ("bpftool: Add LLVM as default library for disassembling JIT-ed programs") > > Acked-by: Yonghong Song <yonghong.song@xxxxxxxxx> > Signed-off-by: Eduard Zingerman <eddyz87@xxxxxxxxx> > --- > tools/testing/selftests/bpf/.gitignore | 1 + > tools/testing/selftests/bpf/Makefile | 51 +++- > .../selftests/bpf/jit_disasm_helpers.c | 234 ++++++++++++++++++ > .../selftests/bpf/jit_disasm_helpers.h | 10 + > 4 files changed, 294 insertions(+), 2 deletions(-) > create mode 100644 tools/testing/selftests/bpf/jit_disasm_helpers.c > create mode 100644 tools/testing/selftests/bpf/jit_disasm_helpers.h > > diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore > index 8f14d8faeb0b..7de4108771a0 100644 > --- a/tools/testing/selftests/bpf/.gitignore > +++ b/tools/testing/selftests/bpf/.gitignore > @@ -8,6 +8,7 @@ test_lru_map > test_lpm_map > test_tag > FEATURE-DUMP.libbpf > +FEATURE-DUMP.selftests > fixdep > /test_progs > /test_progs-no_alu32 > diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile > index f54185e96a95..b1a52739d9e7 100644 > --- a/tools/testing/selftests/bpf/Makefile > +++ b/tools/testing/selftests/bpf/Makefile > @@ -33,6 +33,13 @@ OPT_FLAGS ?= $(if $(RELEASE),-O2,-O0) > LIBELF_CFLAGS := $(shell $(PKG_CONFIG) libelf --cflags 2>/dev/null) > LIBELF_LIBS := $(shell $(PKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf) > > +ifeq ($(srctree),) > +srctree := $(patsubst %/,%,$(dir $(CURDIR))) > +srctree := $(patsubst %/,%,$(dir $(srctree))) > +srctree := $(patsubst %/,%,$(dir $(srctree))) > +srctree := $(patsubst %/,%,$(dir $(srctree))) > +endif > + > CFLAGS += -g $(OPT_FLAGS) -rdynamic \ > -Wall -Werror -fno-omit-frame-pointer \ > $(GENFLAGS) $(SAN_CFLAGS) $(LIBELF_CFLAGS) \ > @@ -55,6 +62,11 @@ progs/test_sk_lookup.c-CFLAGS := -fno-strict-aliasing > progs/timer_crash.c-CFLAGS := -fno-strict-aliasing > progs/test_global_func9.c-CFLAGS := -fno-strict-aliasing > > +# Some utility functions use LLVM libraries > +jit_disasm_helpers.c-CFLAGS = $(LLVM_CFLAGS) > +test_progs-LDLIBS = $(LLVM_LDLIBS) > +test_progs-LDFLAGS = $(LLVM_LDFLAGS) > + > ifneq ($(LLVM),) > # Silence some warnings when compiled with clang > CFLAGS += -Wno-unused-command-line-argument > @@ -164,6 +176,31 @@ endef > > include ../lib.mk > > +NON_CHECK_FEAT_TARGETS := clean docs-clean > +CHECK_FEAT := $(filter-out $(NON_CHECK_FEAT_TARGETS),$(or $(MAKECMDGOALS), "none")) > +ifneq ($(CHECK_FEAT),) > +FEATURE_USER := .selftests > +FEATURE_TESTS := llvm > +FEATURE_DISPLAY := $(FEATURE_TESTS) > + > +# Makefile.feature expects OUTPUT to end with a slash > +$(let OUTPUT,$(OUTPUT)/,\ > + $(eval include ../../../build/Makefile.feature)) > +endif > + > +ifeq ($(feature-llvm),1) > + LLVM_CFLAGS += -DHAVE_LLVM_SUPPORT > + LLVM_CONFIG_LIB_COMPONENTS := mcdisassembler all-targets > + # both llvm-config and lib.mk add -D_GNU_SOURCE, which ends up as conflict > + LLVM_CFLAGS += $(filter-out -D_GNU_SOURCE,$(shell $(LLVM_CONFIG) --cflags)) > + LLVM_LDLIBS += $(shell $(LLVM_CONFIG) --libs $(LLVM_CONFIG_LIB_COMPONENTS)) > + ifeq ($(shell $(LLVM_CONFIG) --shared-mode),static) > + LLVM_LDLIBS += $(shell $(LLVM_CONFIG) --system-libs $(LLVM_CONFIG_LIB_COMPONENTS)) > + LLVM_LDLIBS += -lstdc++ > + endif > + LLVM_LDFLAGS += $(shell $(LLVM_CONFIG) --ldflags) > +endif > + Seems like we raced between me commenting on v1 and you posting v2 :( But I just noticed that formatting seems off here. Can you please check space vs tabs issues? > SCRATCH_DIR := $(OUTPUT)/tools > BUILD_DIR := $(SCRATCH_DIR)/build > INCLUDE_DIR := $(SCRATCH_DIR)/include > @@ -488,6 +525,7 @@ define DEFINE_TEST_RUNNER > > TRUNNER_OUTPUT := $(OUTPUT)$(if $2,/)$2 > TRUNNER_BINARY := $1$(if $2,-)$2 > +TRUNNER_BASE_NAME := $1 [...]