diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 1478068ad5dd..0b4e79dbd3f6 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -125,9 +125,6 @@ Given a $HOME/.perfconfig like this:
 		group = true
 		skip-empty = true
 
-	[llvm]
-		dump-obj = true
-		clang-opt = -g
 
 You can hide source code of annotate feature setting the config to false with
 
@@ -657,36 +654,6 @@ ftrace.*::
 		-F option is not specified. Possible values are 'function' and
 		'function_graph'.
 
-llvm.*::
-	llvm.clang-path::
-		Path to clang. If omit, search it from $PATH.
-
-	llvm.clang-bpf-cmd-template::
-		Cmdline template. Below lines show its default value. Environment
-		variable is used to pass options.
-		"$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
-		"-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE "	\
-		"$CLANG_OPTIONS $PERF_BPF_INC_OPTIONS $KERNEL_INC_OPTIONS " \
-		"-Wno-unused-value -Wno-pointer-sign "		\
-		"-working-directory $WORKING_DIR "		\
-		"-c \"$CLANG_SOURCE\" --target=bpf $CLANG_EMIT_LLVM -O2 -o - $LLVM_OPTIONS_PIPE"
-
-	llvm.clang-opt::
-		Options passed to clang.
-
-	llvm.kbuild-dir::
-		kbuild directory. If not set, use /lib/modules/`uname -r`/build.
-		If set to "" deliberately, skip kernel header auto-detector.
-
-	llvm.kbuild-opts::
-		Options passed to 'make' when detecting kernel header options.
-
-	llvm.dump-obj::
-		Enable perf dump BPF object files compiled by LLVM.
-
-	llvm.opts::
-		Options passed to llc.
-
 samples.*::
 
 	samples.context::
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 680396c56bd1..7d362407fb39 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -99,20 +99,6 @@ OPTIONS
           If you want to profile write accesses in [0x1000~1008), just set
           'mem:0x1000/8:w'.
 
-        - a BPF source file (ending in .c) or a precompiled object file (ending
-          in .o) selects one or more BPF events.
-          The BPF program can attach to various perf events based on the ELF section
-          names.
-
-          When processing a '.c' file, perf searches an installed LLVM to compile it
-          into an object file first. Optional clang options can be passed via the
-          '--clang-opt' command line option, e.g.:
-
-            perf record --clang-opt "-DLINUX_VERSION_CODE=0x50000" \
-                        -e tests/bpf-script-example.c
-
-          Note: '--clang-opt' must be placed before '--event/-e'.
-
 	- a group of events surrounded by a pair of brace ("{event1,event2,...}").
 	  Each event is separated by commas and the group should be quoted to
 	  prevent the shell interpretation.  You also need to use --group on
@@ -547,14 +533,6 @@ PERF_RECORD_SWITCH_CPU_WIDE. In some cases (e.g. Intel PT, CoreSight or Arm SPE)
 switch events will be enabled automatically, which can be suppressed by
 by the option --no-switch-events.
 
---clang-path=PATH::
-Path to clang binary to use for compiling BPF scriptlets.
-(enabled when BPF support is on)
-
---clang-opt=OPTIONS::
-Options passed to clang when compiling BPF scriptlets.
-(enabled when BPF support is on)
-
 --vmlinux=PATH::
 Specify vmlinux path which has debuginfo.
 (enabled when BPF prologue is on)
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 1bf8dc53641f..d66b52407e19 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -589,18 +589,6 @@ ifndef NO_LIBELF
 	LIBBPF_STATIC := 1
       endif
     endif
-
-    ifndef NO_DWARF
-      ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
-        CFLAGS += -DHAVE_BPF_PROLOGUE
-        $(call detected,CONFIG_BPF_PROLOGUE)
-      else
-        msg := $(warning BPF prologue is not supported by architecture $(SRCARCH), missing regs_query_register_offset());
-      endif
-    else
-      msg := $(warning DWARF support is off, BPF prologue is disabled);
-    endif
-
   endif # NO_LIBBPF
 endif # NO_LIBELF
 
@@ -1127,37 +1115,6 @@ ifndef NO_JVMTI
   endif
 endif
 
-USE_CXX = 0
-USE_CLANGLLVM = 0
-ifdef LIBCLANGLLVM
-  $(call feature_check,cxx)
-  ifneq ($(feature-cxx), 1)
-    msg := $(warning No g++ found, disable clang and llvm support. Please install g++)
-  else
-    $(call feature_check,llvm)
-    $(call feature_check,llvm-version)
-    ifneq ($(feature-llvm), 1)
-      msg := $(warning No suitable libLLVM found, disabling builtin clang and LLVM support. Please install llvm-dev(el) (>= 3.9.0))
-    else
-      $(call feature_check,clang)
-      ifneq ($(feature-clang), 1)
-        msg := $(warning No suitable libclang found, disabling builtin clang and LLVM support. Please install libclang-dev(el) (>= 3.9.0))
-      else
-        CFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT
-        CXXFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT -I$(shell $(LLVM_CONFIG) --includedir)
-        $(call detected,CONFIG_CXX)
-        $(call detected,CONFIG_CLANGLLVM)
-	USE_CXX = 1
-	USE_LLVM = 1
-	USE_CLANG = 1
-        ifneq ($(feature-llvm-version),1)
-          msg := $(warning This version of LLVM is not tested. May cause build errors)
-        endif
-      endif
-    endif
-  endif
-endif
-
 ifndef NO_LIBPFM4
   $(call feature_check,libpfm4)
   ifeq ($(feature-libpfm4), 1)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 0ed7ee0c1665..6ec5079fd697 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -425,19 +425,6 @@ endif
 EXTLIBS := $(call filter-out,$(EXCLUDE_EXTLIBS),$(EXTLIBS))
 LIBS = -Wl,--whole-archive $(PERFLIBS) $(EXTRA_PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
 
-ifeq ($(USE_CLANG), 1)
-  LIBS += -L$(shell $(LLVM_CONFIG) --libdir) -lclang-cpp
-endif
-
-ifeq ($(USE_LLVM), 1)
-  LIBLLVM = $(shell $(LLVM_CONFIG) --libs all) $(shell $(LLVM_CONFIG) --system-libs)
-  LIBS += -L$(shell $(LLVM_CONFIG) --libdir) $(LIBLLVM)
-endif
-
-ifeq ($(USE_CXX), 1)
-  LIBS += -lstdc++
-endif
-
 export INSTALL SHELL_PATH
 
 ### Build rules
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index aec18db7ff23..34bb31f08bb5 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -37,8 +37,6 @@
 #include "util/parse-branch-options.h"
 #include "util/parse-regs-options.h"
 #include "util/perf_api_probe.h"
-#include "util/llvm-utils.h"
-#include "util/bpf-loader.h"
 #include "util/trigger.h"
 #include "util/perf-hooks.h"
 #include "util/cpu-set-sched.h"
@@ -2465,16 +2463,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 		}
 	}
 
-	err = bpf__apply_obj_config();
-	if (err) {
-		char errbuf[BUFSIZ];
-
-		bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
-		pr_err("ERROR: Apply config to BPF failed: %s\n",
-			 errbuf);
-		goto out_free_threads;
-	}
-
 	/*
 	 * Normally perf_session__new would do this, but it doesn't have the
 	 * evlist.
@@ -3486,10 +3474,6 @@ static struct option __record_options[] = {
 		    "collect kernel callchains"),
 	OPT_BOOLEAN(0, "user-callchains", &record.opts.user_callchains,
 		    "collect user callchains"),
-	OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
-		   "clang binary to use for compiling BPF scriptlets"),
-	OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
-		   "options passed to clang when compiling BPF scriptlets"),
 	OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
 		   "file", "vmlinux pathname"),
 	OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
@@ -3967,27 +3951,6 @@ int cmd_record(int argc, const char **argv)
 
 	setlocale(LC_ALL, "");
 
-#ifndef HAVE_LIBBPF_SUPPORT
-# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
-	set_nobuild('\0', "clang-path", true);
-	set_nobuild('\0', "clang-opt", true);
-# undef set_nobuild
-#endif
-
-#ifndef HAVE_BPF_PROLOGUE
-# if !defined (HAVE_DWARF_SUPPORT)
-#  define REASON  "NO_DWARF=1"
-# elif !defined (HAVE_LIBBPF_SUPPORT)
-#  define REASON  "NO_LIBBPF=1"
-# else
-#  define REASON  "this architecture doesn't support BPF prologue"
-# endif
-# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
-	set_nobuild('\0', "vmlinux", true);
-# undef set_nobuild
-# undef REASON
-#endif
-
 #ifndef HAVE_BPF_SKEL
 # define set_nobuild(s, l, m, c) set_option_nobuild(record_options, s, l, m, c)
 	set_nobuild('\0', "off-cpu", "no BUILD_BPF_SKEL=1", true);
@@ -4116,14 +4079,6 @@ int cmd_record(int argc, const char **argv)
 	if (dry_run)
 		goto out;
 
-	err = bpf__setup_stdout(rec->evlist);
-	if (err) {
-		bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
-		pr_err("ERROR: Setup BPF stdout failed: %s\n",
-			 errbuf);
-		goto out;
-	}
-
 	err = -ENOMEM;
 
 	if (rec->no_buildid_cache || rec->no_buildid) {
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7ece2521efb6..59862467e781 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -18,6 +18,7 @@
 #include <api/fs/tracing_path.h>
 #ifdef HAVE_LIBBPF_SUPPORT
 #include <bpf/bpf.h>
+#include <bpf/libbpf.h>
 #endif
 #include "util/bpf_map.h"
 #include "util/rlimit.h"
@@ -53,7 +54,6 @@
 #include "trace/beauty/beauty.h"
 #include "trace-event.h"
 #include "util/parse-events.h"
-#include "util/bpf-loader.h"
 #include "util/tracepoint.h"
 #include "callchain.h"
 #include "print_binary.h"
@@ -3287,17 +3287,6 @@ static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace, const ch
 	return bpf_object__find_map_by_name(trace->bpf_obj, name);
 }
 
-static void trace__set_bpf_map_filtered_pids(struct trace *trace)
-{
-	trace->filter_pids.map = trace__find_bpf_map_by_name(trace, "pids_filtered");
-}
-
-static void trace__set_bpf_map_syscalls(struct trace *trace)
-{
-	trace->syscalls.prog_array.sys_enter = trace__find_bpf_map_by_name(trace, "syscalls_sys_enter");
-	trace->syscalls.prog_array.sys_exit  = trace__find_bpf_map_by_name(trace, "syscalls_sys_exit");
-}
-
 static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace, const char *name)
 {
 	struct bpf_program *pos, *prog = NULL;
@@ -3553,25 +3542,6 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace)
 	return err;
 }
 
-static void trace__delete_augmented_syscalls(struct trace *trace)
-{
-	struct evsel *evsel, *tmp;
-
-	evlist__remove(trace->evlist, trace->syscalls.events.augmented);
-	evsel__delete(trace->syscalls.events.augmented);
-	trace->syscalls.events.augmented = NULL;
-
-	evlist__for_each_entry_safe(trace->evlist, tmp, evsel) {
-		if (evsel->bpf_obj == trace->bpf_obj) {
-			evlist__remove(trace->evlist, evsel);
-			evsel__delete(evsel);
-		}
-
-	}
-
-	bpf_object__close(trace->bpf_obj);
-	trace->bpf_obj = NULL;
-}
 #else // HAVE_LIBBPF_SUPPORT
 static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace __maybe_unused,
 						   const char *name __maybe_unused)
@@ -3579,45 +3549,12 @@ static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace __maybe_u
 	return NULL;
 }
 
-static void trace__set_bpf_map_filtered_pids(struct trace *trace __maybe_unused)
-{
-}
-
-static void trace__set_bpf_map_syscalls(struct trace *trace __maybe_unused)
-{
-}
-
-static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace __maybe_unused,
-							    const char *name __maybe_unused)
-{
-	return NULL;
-}
-
 static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace __maybe_unused)
 {
 	return 0;
 }
-
-static void trace__delete_augmented_syscalls(struct trace *trace __maybe_unused)
-{
-}
 #endif // HAVE_LIBBPF_SUPPORT
 
-static bool trace__only_augmented_syscalls_evsels(struct trace *trace)
-{
-	struct evsel *evsel;
-
-	evlist__for_each_entry(trace->evlist, evsel) {
-		if (evsel == trace->syscalls.events.augmented ||
-		    evsel->bpf_obj == trace->bpf_obj)
-			continue;
-
-		return false;
-	}
-
-	return true;
-}
-
 static int trace__set_ev_qualifier_filter(struct trace *trace)
 {
 	if (trace->syscalls.events.sys_enter)
@@ -3981,16 +3918,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 	if (err < 0)
 		goto out_error_open;
 
-	err = bpf__apply_obj_config();
-	if (err) {
-		char errbuf[BUFSIZ];
-
-		bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf));
-		pr_err("ERROR: Apply config to BPF failed: %s\n",
-			 errbuf);
-		goto out_error_open;
-	}
-
 	err = trace__set_filter_pids(trace);
 	if (err < 0)
 		goto out_error_mem;
@@ -4922,77 +4849,6 @@ int cmd_trace(int argc, const char **argv)
 				       "cgroup monitoring only available in system-wide mode");
 	}
 
-	evsel = bpf__setup_output_event(trace.evlist, "__augmented_syscalls__");
-	if (IS_ERR(evsel)) {
-		bpf__strerror_setup_output_event(trace.evlist, PTR_ERR(evsel), bf, sizeof(bf));
-		pr_err("ERROR: Setup trace syscalls enter failed: %s\n", bf);
-		goto out;
-	}
-
-	if (evsel) {
-		trace.syscalls.events.augmented = evsel;
-
-		evsel = evlist__find_tracepoint_by_name(trace.evlist, "raw_syscalls:sys_enter");
-		if (evsel == NULL) {
-			pr_err("ERROR: raw_syscalls:sys_enter not found in the augmented BPF object\n");
-			goto out;
-		}
-
-		if (evsel->bpf_obj == NULL) {
-			pr_err("ERROR: raw_syscalls:sys_enter not associated to a BPF object\n");
-			goto out;
-		}
-
-		trace.bpf_obj = evsel->bpf_obj;
-
-		/*
-		 * If we have _just_ the augmenter event but don't have a
-		 * explicit --syscalls, then assume we want all strace-like
-		 * syscalls:
-		 */
-		if (!trace.trace_syscalls && trace__only_augmented_syscalls_evsels(&trace))
-			trace.trace_syscalls = true;
-		/*
-		 * So, if we have a syscall augmenter, but trace_syscalls, aka
-		 * strace-like syscall tracing is not set, then we need to trow
-		 * away the augmenter, i.e. all the events that were created
-		 * from that BPF object file.
-		 *
-		 * This is more to fix the current .perfconfig trace.add_events
-		 * style of setting up the strace-like eBPF based syscall point
-		 * payload augmenter.
-		 *
-		 * All this complexity will be avoided by adding an alternative
-		 * to trace.add_events in the form of
-		 * trace.bpf_augmented_syscalls, that will be only parsed if we
-		 * need it.
-		 *
-		 * .perfconfig trace.add_events is still useful if we want, for
-		 * instance, have msr_write.msr in some .perfconfig profile based
-		 * 'perf trace --config determinism.profile' mode, where for some
-		 * particular goal/workload type we want a set of events and
-		 * output mode (with timings, etc) instead of having to add
-		 * all via the command line.
-		 *
-		 * Also --config to specify an alternate .perfconfig file needs
-		 * to be implemented.
-		 */
-		if (!trace.trace_syscalls) {
-			trace__delete_augmented_syscalls(&trace);
-		} else {
-			trace__set_bpf_map_filtered_pids(&trace);
-			trace__set_bpf_map_syscalls(&trace);
-			trace.syscalls.unaugmented_prog = trace__find_bpf_program_by_title(&trace, "!raw_syscalls:unaugmented");
-		}
-	}
-
-	err = bpf__setup_stdout(trace.evlist);
-	if (err) {
-		bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf));
-		pr_err("ERROR: Setup BPF stdout failed: %s\n", bf);
-		goto out;
-	}
-
 	err = -1;
 
 	if (map_dump_str) {
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 38cae4721583..d3fc8090413c 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -18,7 +18,6 @@
 #include <subcmd/run-command.h>
 #include "util/parse-events.h"
 #include <subcmd/parse-options.h>
-#include "util/bpf-loader.h"
 #include "util/debug.h"
 #include "util/event.h"
 #include "util/util.h" // usage()
@@ -324,7 +323,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 	perf_config__exit();
 	exit_browser(status);
 	perf_env__exit(&perf_env);
-	bpf__clear();
 
 	if (status)
 		return status & 0xff;
diff --git a/tools/perf/tests/.gitignore b/tools/perf/tests/.gitignore
deleted file mode 100644
index d053b325f728..000000000000
--- a/tools/perf/tests/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-llvm-src-base.c
-llvm-src-kbuild.c
-llvm-src-prologue.c
-llvm-src-relocation.c
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index fb9ac5dc4079..63d5e6d5f165 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -37,8 +37,6 @@ perf-y += sample-parsing.o
 perf-y += parse-no-sample-id-all.o
 perf-y += kmod-path.o
 perf-y += thread-map.o
-perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o llvm-src-relocation.o
-perf-y += bpf.o
 perf-y += topology.o
 perf-y += mem.o
 perf-y += cpumap.o
@@ -51,7 +49,6 @@ perf-y += sdt.o
 perf-y += is_printable_array.o
 perf-y += bitmap.o
 perf-y += perf-hooks.o
-perf-y += clang.o
 perf-y += unit_number__scnprintf.o
 perf-y += mem2node.o
 perf-y += maps.o
@@ -70,34 +67,6 @@ perf-y += sigtrap.o
 perf-y += event_groups.o
 perf-y += symbols.o
 
-$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
-	$(call rule_mkdir)
-	$(Q)echo '#include <tests/llvm.h>' > $@
-	$(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@
-	$(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
-	$(Q)echo ';' >> $@
-
-$(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c tests/Build
-	$(call rule_mkdir)
-	$(Q)echo '#include <tests/llvm.h>' > $@
-	$(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@
-	$(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
-	$(Q)echo ';' >> $@
-
-$(OUTPUT)tests/llvm-src-prologue.c: tests/bpf-script-test-prologue.c tests/Build
-	$(call rule_mkdir)
-	$(Q)echo '#include <tests/llvm.h>' > $@
-	$(Q)echo 'const char test_llvm__bpf_test_prologue_prog[] =' >> $@
-	$(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
-	$(Q)echo ';' >> $@
-
-$(OUTPUT)tests/llvm-src-relocation.c: tests/bpf-script-test-relocation.c tests/Build
-	$(call rule_mkdir)
-	$(Q)echo '#include <tests/llvm.h>' > $@
-	$(Q)echo 'const char test_llvm__bpf_test_relocation[] =' >> $@
-	$(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
-	$(Q)echo ';' >> $@
-
 ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc))
 perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
 endif
diff --git a/tools/perf/tests/bpf-script-example.c b/tools/perf/tests/bpf-script-example.c
deleted file mode 100644
index b638cc99d5ae..000000000000
--- a/tools/perf/tests/bpf-script-example.c
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * bpf-script-example.c
- * Test basic LLVM building
- */
-#ifndef LINUX_VERSION_CODE
-# error Need LINUX_VERSION_CODE
-# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
-#endif
-#define BPF_ANY 0
-#define BPF_MAP_TYPE_ARRAY 2
-#define BPF_FUNC_map_lookup_elem 1
-#define BPF_FUNC_map_update_elem 2
-
-static void *(*bpf_map_lookup_elem)(void *map, void *key) =
-	(void *) BPF_FUNC_map_lookup_elem;
-static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) =
-	(void *) BPF_FUNC_map_update_elem;
-
-/*
- * Following macros are taken from tools/lib/bpf/bpf_helpers.h,
- * and are used to create BTF defined maps. It is easier to take
- * 2 simple macros, than being able to include above header in
- * runtime.
- *
- * __uint - defines integer attribute of BTF map definition,
- * Such attributes are represented using a pointer to an array,
- * in which dimensionality of array encodes specified integer
- * value.
- *
- * __type - defines pointer variable with typeof(val) type for
- * attributes like key or value, which will be defined by the
- * size of the type.
- */
-#define __uint(name, val) int (*name)[val]
-#define __type(name, val) typeof(val) *name
-
-#define SEC(NAME) __attribute__((section(NAME), used))
-struct {
-	__uint(type, BPF_MAP_TYPE_ARRAY);
-	__uint(max_entries, 1);
-	__type(key, int);
-	__type(value, int);
-} flip_table SEC(".maps");
-
-SEC("syscalls:sys_enter_epoll_pwait")
-int bpf_func__SyS_epoll_pwait(void *ctx)
-{
-	int ind =0;
-	int *flag = bpf_map_lookup_elem(&flip_table, &ind);
-	int new_flag;
-	if (!flag)
-		return 0;
-	/* flip flag and store back */
-	new_flag = !*flag;
-	bpf_map_update_elem(&flip_table, &ind, &new_flag, BPF_ANY);
-	return new_flag;
-}
-char _license[] SEC("license") = "GPL";
-int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/tools/perf/tests/bpf-script-test-kbuild.c b/tools/perf/tests/bpf-script-test-kbuild.c
deleted file mode 100644
index 219673aa278f..000000000000
--- a/tools/perf/tests/bpf-script-test-kbuild.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * bpf-script-test-kbuild.c
- * Test include from kernel header
- */
-#ifndef LINUX_VERSION_CODE
-# error Need LINUX_VERSION_CODE
-# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
-#endif
-#define SEC(NAME) __attribute__((section(NAME), used))
-
-#include <uapi/linux/fs.h>
-
-SEC("func=vfs_llseek")
-int bpf_func__vfs_llseek(void *ctx)
-{
-	return 0;
-}
-
-char _license[] SEC("license") = "GPL";
-int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c
deleted file mode 100644
index 91778b5c6125..000000000000
--- a/tools/perf/tests/bpf-script-test-prologue.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * bpf-script-test-prologue.c
- * Test BPF prologue
- */
-#ifndef LINUX_VERSION_CODE
-# error Need LINUX_VERSION_CODE
-# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
-#endif
-#define SEC(NAME) __attribute__((section(NAME), used))
-
-#include <uapi/linux/fs.h>
-
-/*
- * If CONFIG_PROFILE_ALL_BRANCHES is selected,
- * 'if' is redefined after include kernel header.
- * Recover 'if' for BPF object code.
- */
-#ifdef if
-# undef if
-#endif
-
-typedef unsigned int __bitwise fmode_t;
-
-#define FMODE_READ		0x1
-#define FMODE_WRITE		0x2
-
-static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =
-	(void *) 6;
-
-SEC("func=null_lseek file->f_mode offset orig")
-int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode,
-			 unsigned long offset, unsigned long orig)
-{
-	fmode_t f_mode = (fmode_t)_f_mode;
-
-	if (err)
-		return 0;
-	if (f_mode & FMODE_WRITE)
-		return 0;
-	if (offset & 1)
-		return 0;
-	if (orig == SEEK_CUR)
-		return 0;
-	return 1;
-}
-
-char _license[] SEC("license") = "GPL";
-int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/tools/perf/tests/bpf-script-test-relocation.c b/tools/perf/tests/bpf-script-test-relocation.c
deleted file mode 100644
index 74006e4b2d24..000000000000
--- a/tools/perf/tests/bpf-script-test-relocation.c
+++ /dev/null
@@ -1,51 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * bpf-script-test-relocation.c
- * Test BPF loader checking relocation
- */
-#ifndef LINUX_VERSION_CODE
-# error Need LINUX_VERSION_CODE
-# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig'
-#endif
-#define BPF_ANY 0
-#define BPF_MAP_TYPE_ARRAY 2
-#define BPF_FUNC_map_lookup_elem 1
-#define BPF_FUNC_map_update_elem 2
-
-static void *(*bpf_map_lookup_elem)(void *map, void *key) =
-	(void *) BPF_FUNC_map_lookup_elem;
-static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) =
-	(void *) BPF_FUNC_map_update_elem;
-
-struct bpf_map_def {
-	unsigned int type;
-	unsigned int key_size;
-	unsigned int value_size;
-	unsigned int max_entries;
-};
-
-#define SEC(NAME) __attribute__((section(NAME), used))
-struct bpf_map_def SEC("maps") my_table = {
-	.type = BPF_MAP_TYPE_ARRAY,
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.max_entries = 1,
-};
-
-int this_is_a_global_val;
-
-SEC("func=sys_write")
-int bpf_func__sys_write(void *ctx)
-{
-	int key = 0;
-	int value = 0;
-
-	/*
-	 * Incorrect relocation. Should not allow this program be
-	 * loaded into kernel.
-	 */
-	bpf_map_update_elem(&this_is_a_global_val, &key, &value, 0);
-	return 0;
-}
-char _license[] SEC("license") = "GPL";
-int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
deleted file mode 100644
index 9ccecd873ecd..000000000000
--- a/tools/perf/tests/bpf.c
+++ /dev/null
@@ -1,390 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/epoll.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <util/record.h>
-#include <util/util.h>
-#include <util/bpf-loader.h>
-#include <util/evlist.h>
-#include <linux/filter.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <api/fs/fs.h>
-#include <perf/mmap.h>
-#include "tests.h"
-#include "llvm.h"
-#include "debug.h"
-#include "parse-events.h"
-#include "util/mmap.h"
-#define NR_ITERS       111
-#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
-
-#if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
-#include <linux/bpf.h>
-#include <bpf/bpf.h>
-
-static int epoll_pwait_loop(void)
-{
-	struct epoll_event events;
-	int i;
-
-	/* Should fail NR_ITERS times */
-	for (i = 0; i < NR_ITERS; i++)
-		epoll_pwait(-(i + 1), &events, 0, 0, NULL);
-	return 0;
-}
-
-#ifdef HAVE_BPF_PROLOGUE
-
-static int llseek_loop(void)
-{
-	int fds[2], i;
-
-	fds[0] = open("/dev/null", O_RDONLY);
-	fds[1] = open("/dev/null", O_RDWR);
-
-	if (fds[0] < 0 || fds[1] < 0)
-		return -1;
-
-	for (i = 0; i < NR_ITERS; i++) {
-		lseek(fds[i % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
-		lseek(fds[(i + 1) % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
-	}
-	close(fds[0]);
-	close(fds[1]);
-	return 0;
-}
-
-#endif
-
-static struct {
-	enum test_llvm__testcase prog_id;
-	const char *name;
-	const char *msg_compile_fail;
-	const char *msg_load_fail;
-	int (*target_func)(void);
-	int expect_result;
-	bool	pin;
-} bpf_testcase_table[] = {
-	{
-		.prog_id	  = LLVM_TESTCASE_BASE,
-		.name		  = "[basic_bpf_test]",
-		.msg_compile_fail = "fix 'perf test LLVM' first",
-		.msg_load_fail	  = "load bpf object failed",
-		.target_func	  = &epoll_pwait_loop,
-		.expect_result	  = (NR_ITERS + 1) / 2,
-	},
-	{
-		.prog_id	  = LLVM_TESTCASE_BASE,
-		.name		  = "[bpf_pinning]",
-		.msg_compile_fail = "fix kbuild first",
-		.msg_load_fail	  = "check your vmlinux setting?",
-		.target_func	  = &epoll_pwait_loop,
-		.expect_result	  = (NR_ITERS + 1) / 2,
-		.pin		  = true,
-	},
-#ifdef HAVE_BPF_PROLOGUE
-	{
-		.prog_id	  = LLVM_TESTCASE_BPF_PROLOGUE,
-		.name		  = "[bpf_prologue_test]",
-		.msg_compile_fail = "fix kbuild first",
-		.msg_load_fail	  = "check your vmlinux setting?",
-		.target_func	  = &llseek_loop,
-		.expect_result	  = (NR_ITERS + 1) / 4,
-	},
-#endif
-};
-
-static int do_test(struct bpf_object *obj, int (*func)(void),
-		   int expect)
-{
-	struct record_opts opts = {
-		.target = {
-			.uid = UINT_MAX,
-			.uses_mmap = true,
-		},
-		.freq	      = 0,
-		.mmap_pages   = 256,
-		.default_interval = 1,
-	};
-
-	char pid[16];
-	char sbuf[STRERR_BUFSIZE];
-	struct evlist *evlist;
-	int i, ret = TEST_FAIL, err = 0, count = 0;
-
-	struct parse_events_state parse_state;
-	struct parse_events_error parse_error;
-
-	parse_events_error__init(&parse_error);
-	bzero(&parse_state, sizeof(parse_state));
-	parse_state.error = &parse_error;
-	INIT_LIST_HEAD(&parse_state.list);
-
-	err = parse_events_load_bpf_obj(&parse_state, &parse_state.list, obj, NULL, NULL);
-	parse_events_error__exit(&parse_error);
-	if (err == -ENODATA) {
-		pr_debug("Failed to add events selected by BPF, debuginfo package not installed\n");
-		return TEST_SKIP;
-	}
-	if (err || list_empty(&parse_state.list)) {
-		pr_debug("Failed to add events selected by BPF\n");
-		return TEST_FAIL;
-	}
-
-	snprintf(pid, sizeof(pid), "%d", getpid());
-	pid[sizeof(pid) - 1] = '\0';
-	opts.target.tid = opts.target.pid = pid;
-
-	/* Instead of evlist__new_default, don't add default events */
-	evlist = evlist__new();
-	if (!evlist) {
-		pr_debug("Not enough memory to create evlist\n");
-		return TEST_FAIL;
-	}
-
-	err = evlist__create_maps(evlist, &opts.target);
-	if (err < 0) {
-		pr_debug("Not enough memory to create thread/cpu maps\n");
-		goto out_delete_evlist;
-	}
-
-	evlist__splice_list_tail(evlist, &parse_state.list);
-
-	evlist__config(evlist, &opts, NULL);
-
-	err = evlist__open(evlist);
-	if (err < 0) {
-		pr_debug("perf_evlist__open: %s\n",
-			 str_error_r(errno, sbuf, sizeof(sbuf)));
-		goto out_delete_evlist;
-	}
-
-	err = evlist__mmap(evlist, opts.mmap_pages);
-	if (err < 0) {
-		pr_debug("evlist__mmap: %s\n",
-			 str_error_r(errno, sbuf, sizeof(sbuf)));
-		goto out_delete_evlist;
-	}
-
-	evlist__enable(evlist);
-	(*func)();
-	evlist__disable(evlist);
-
-	for (i = 0; i < evlist->core.nr_mmaps; i++) {
-		union perf_event *event;
-		struct mmap *md;
-
-		md = &evlist->mmap[i];
-		if (perf_mmap__read_init(&md->core) < 0)
-			continue;
-
-		while ((event = perf_mmap__read_event(&md->core)) != NULL) {
-			const u32 type = event->header.type;
-
-			if (type == PERF_RECORD_SAMPLE)
-				count ++;
-		}
-		perf_mmap__read_done(&md->core);
-	}
-
-	if (count != expect * evlist->core.nr_entries) {
-		pr_debug("BPF filter result incorrect, expected %d, got %d samples\n", expect * evlist->core.nr_entries, count);
-		goto out_delete_evlist;
-	}
-
-	ret = TEST_OK;
-
-out_delete_evlist:
-	evlist__delete(evlist);
-	return ret;
-}
-
-static struct bpf_object *
-prepare_bpf(void *obj_buf, size_t obj_buf_sz, const char *name)
-{
-	struct bpf_object *obj;
-
-	obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, name);
-	if (IS_ERR(obj)) {
-		pr_debug("Compile BPF program failed.\n");
-		return NULL;
-	}
-	return obj;
-}
-
-static int __test__bpf(int idx)
-{
-	int ret;
-	void *obj_buf;
-	size_t obj_buf_sz;
-	struct bpf_object *obj;
-
-	ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
-				       bpf_testcase_table[idx].prog_id,
-				       false, NULL);
-	if (ret != TEST_OK || !obj_buf || !obj_buf_sz) {
-		pr_debug("Unable to get BPF object, %s\n",
-			 bpf_testcase_table[idx].msg_compile_fail);
-		if ((idx == 0) || (ret == TEST_SKIP))
-			return TEST_SKIP;
-		else
-			return TEST_FAIL;
-	}
-
-	obj = prepare_bpf(obj_buf, obj_buf_sz,
-			  bpf_testcase_table[idx].name);
-	if ((!!bpf_testcase_table[idx].target_func) != (!!obj)) {
-		if (!obj)
-			pr_debug("Fail to load BPF object: %s\n",
-				 bpf_testcase_table[idx].msg_load_fail);
-		else
-			pr_debug("Success unexpectedly: %s\n",
-				 bpf_testcase_table[idx].msg_load_fail);
-		ret = TEST_FAIL;
-		goto out;
-	}
-
-	if (obj) {
-		ret = do_test(obj,
-			      bpf_testcase_table[idx].target_func,
-			      bpf_testcase_table[idx].expect_result);
-		if (ret != TEST_OK)
-			goto out;
-		if (bpf_testcase_table[idx].pin) {
-			int err;
-
-			if (!bpf_fs__mount()) {
-				pr_debug("BPF filesystem not mounted\n");
-				ret = TEST_FAIL;
-				goto out;
-			}
-			err = mkdir(PERF_TEST_BPF_PATH, 0777);
-			if (err && errno != EEXIST) {
-				pr_debug("Failed to make perf_test dir: %s\n",
-					 strerror(errno));
-				ret = TEST_FAIL;
-				goto out;
-			}
-			if (bpf_object__pin(obj, PERF_TEST_BPF_PATH))
-				ret = TEST_FAIL;
-			if (rm_rf(PERF_TEST_BPF_PATH))
-				ret = TEST_FAIL;
-		}
-	}
-
-out:
-	free(obj_buf);
-	bpf__clear();
-	return ret;
-}
-
-static int check_env(void)
-{
-	LIBBPF_OPTS(bpf_prog_load_opts, opts);
-	int err;
-	char license[] = "GPL";
-
-	struct bpf_insn insns[] = {
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	};
-
-	err = fetch_kernel_version(&opts.kern_version, NULL, 0);
-	if (err) {
-		pr_debug("Unable to get kernel version\n");
-		return err;
-	}
-	err = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, license, insns,
-			    ARRAY_SIZE(insns), &opts);
-	if (err < 0) {
-		pr_err("Missing basic BPF support, skip this test: %s\n",
-		       strerror(errno));
-		return err;
-	}
-	close(err);
-
-	return 0;
-}
-
-static int test__bpf(int i)
-{
-	int err;
-
-	if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table))
-		return TEST_FAIL;
-
-	if (geteuid() != 0) {
-		pr_debug("Only root can run BPF test\n");
-		return TEST_SKIP;
-	}
-
-	if (check_env())
-		return TEST_SKIP;
-
-	err = __test__bpf(i);
-	return err;
-}
-#endif
-
-static int test__basic_bpf_test(struct test_suite *test __maybe_unused,
-				int subtest __maybe_unused)
-{
-#if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
-	return test__bpf(0);
-#else
-	pr_debug("Skip BPF test because BPF or libtraceevent support is not compiled\n");
-	return TEST_SKIP;
-#endif
-}
-
-static int test__bpf_pinning(struct test_suite *test __maybe_unused,
-			     int subtest __maybe_unused)
-{
-#if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
-	return test__bpf(1);
-#else
-	pr_debug("Skip BPF test because BPF or libtraceevent support is not compiled\n");
-	return TEST_SKIP;
-#endif
-}
-
-static int test__bpf_prologue_test(struct test_suite *test __maybe_unused,
-				   int subtest __maybe_unused)
-{
-#if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_BPF_PROLOGUE) && defined(HAVE_LIBTRACEEVENT)
-	return test__bpf(2);
-#else
-	pr_debug("Skip BPF test because BPF or libtraceevent support is not compiled\n");
-	return TEST_SKIP;
-#endif
-}
-
-
-static struct test_case bpf_tests[] = {
-#if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
-	TEST_CASE("Basic BPF filtering", basic_bpf_test),
-	TEST_CASE_REASON("BPF pinning", bpf_pinning,
-			"clang isn't installed or environment missing BPF support"),
-#ifdef HAVE_BPF_PROLOGUE
-	TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test,
-			"clang/debuginfo isn't installed or environment missing BPF support"),
-#else
-	TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test, "not compiled in"),
-#endif
-#else
-	TEST_CASE_REASON("Basic BPF filtering", basic_bpf_test, "not compiled in or missing libtraceevent support"),
-	TEST_CASE_REASON("BPF pinning", bpf_pinning, "not compiled in or missing libtraceevent support"),
-	TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test, "not compiled in or missing libtraceevent support"),
-#endif
-	{ .name = NULL, }
-};
-
-struct test_suite suite__bpf = {
-	.desc = "BPF filter",
-	.test_cases = bpf_tests,
-};
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 6accb5442a73..0ad18cf6dd22 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -92,9 +92,7 @@ static struct test_suite *generic_tests[] = {
 	&suite__fdarray__add,
 	&suite__kmod_path__parse,
 	&suite__thread_map,
-	&suite__llvm,
 	&suite__session_topology,
-	&suite__bpf,
 	&suite__thread_map_synthesize,
 	&suite__thread_map_remove,
 	&suite__cpu_map,
@@ -108,7 +106,6 @@ static struct test_suite *generic_tests[] = {
 	&suite__is_printable_array,
 	&suite__bitmap_print,
 	&suite__perf_hooks,
-	&suite__clang,
 	&suite__unit_number__scnprint,
 	&suite__mem2node,
 	&suite__time_utils,
diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c
deleted file mode 100644
index a7111005d5b9..000000000000
--- a/tools/perf/tests/clang.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "tests.h"
-#include "c++/clang-c.h"
-#include <linux/kernel.h>
-
-#ifndef HAVE_LIBCLANGLLVM_SUPPORT
-static int test__clang_to_IR(struct test_suite *test __maybe_unused,
-			     int subtest __maybe_unused)
-{
-	return TEST_SKIP;
-}
-
-static int test__clang_to_obj(struct test_suite *test __maybe_unused,
-			      int subtest __maybe_unused)
-{
-	return TEST_SKIP;
-}
-#endif
-
-static struct test_case clang_tests[] = {
-	TEST_CASE_REASON("builtin clang compile C source to IR", clang_to_IR,
-			 "not compiled in"),
-	TEST_CASE_REASON("builtin clang compile C source to ELF object",
-			 clang_to_obj,
-			 "not compiled in"),
-	{ .name = NULL, }
-};
-
-struct test_suite suite__clang = {
-	.desc = "builtin clang support",
-	.test_cases = clang_tests,
-};
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
deleted file mode 100644
index 0bc25a56cfef..000000000000
--- a/tools/perf/tests/llvm.c
+++ /dev/null
@@ -1,219 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "tests.h"
-#include "debug.h"
-
-#ifdef HAVE_LIBBPF_SUPPORT
-#include <bpf/libbpf.h>
-#include <util/llvm-utils.h>
-#include "llvm.h"
-static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz)
-{
-	struct bpf_object *obj;
-
-	obj = bpf_object__open_mem(obj_buf, obj_buf_sz, NULL);
-	if (libbpf_get_error(obj))
-		return TEST_FAIL;
-	bpf_object__close(obj);
-	return TEST_OK;
-}
-
-static struct {
-	const char *source;
-	const char *desc;
-	bool should_load_fail;
-} bpf_source_table[__LLVM_TESTCASE_MAX] = {
-	[LLVM_TESTCASE_BASE] = {
-		.source = test_llvm__bpf_base_prog,
-		.desc = "Basic BPF llvm compile",
-	},
-	[LLVM_TESTCASE_KBUILD] = {
-		.source = test_llvm__bpf_test_kbuild_prog,
-		.desc = "kbuild searching",
-	},
-	[LLVM_TESTCASE_BPF_PROLOGUE] = {
-		.source = test_llvm__bpf_test_prologue_prog,
-		.desc = "Compile source for BPF prologue generation",
-	},
-	[LLVM_TESTCASE_BPF_RELOCATION] = {
-		.source = test_llvm__bpf_test_relocation,
-		.desc = "Compile source for BPF relocation",
-		.should_load_fail = true,
-	},
-};
-
-int
-test_llvm__fetch_bpf_obj(void **p_obj_buf,
-			 size_t *p_obj_buf_sz,
-			 enum test_llvm__testcase idx,
-			 bool force,
-			 bool *should_load_fail)
-{
-	const char *source;
-	const char *desc;
-	const char *tmpl_old, *clang_opt_old;
-	char *tmpl_new = NULL, *clang_opt_new = NULL;
-	int err, old_verbose, ret = TEST_FAIL;
-
-	if (idx >= __LLVM_TESTCASE_MAX)
-		return TEST_FAIL;
-
-	source = bpf_source_table[idx].source;
-	desc = bpf_source_table[idx].desc;
-	if (should_load_fail)
-		*should_load_fail = bpf_source_table[idx].should_load_fail;
-
-	/*
-	 * Skip this test if user's .perfconfig doesn't set [llvm] section
-	 * and clang is not found in $PATH
-	 */
-	if (!force && (!llvm_param.user_set_param &&
-		       llvm__search_clang())) {
-		pr_debug("No clang, skip this test\n");
-		return TEST_SKIP;
-	}
-
-	/*
-	 * llvm is verbosity when error. Suppress all error output if
-	 * not 'perf test -v'.
-	 */
-	old_verbose = verbose;
-	if (verbose == 0)
-		verbose = -1;
-
-	*p_obj_buf = NULL;
-	*p_obj_buf_sz = 0;
-
-	if (!llvm_param.clang_bpf_cmd_template)
-		goto out;
-
-	if (!llvm_param.clang_opt)
-		llvm_param.clang_opt = strdup("");
-
-	err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
-		       llvm_param.clang_bpf_cmd_template,
-		       old_verbose ? "" : " 2>/dev/null");
-	if (err < 0)
-		goto out;
-	err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
-	if (err < 0)
-		goto out;
-
-	tmpl_old = llvm_param.clang_bpf_cmd_template;
-	llvm_param.clang_bpf_cmd_template = tmpl_new;
-	clang_opt_old = llvm_param.clang_opt;
-	llvm_param.clang_opt = clang_opt_new;
-
-	err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz);
-
-	llvm_param.clang_bpf_cmd_template = tmpl_old;
-	llvm_param.clang_opt = clang_opt_old;
-
-	verbose = old_verbose;
-	if (err)
-		goto out;
-
-	ret = TEST_OK;
-out:
-	free(tmpl_new);
-	free(clang_opt_new);
-	if (ret != TEST_OK)
-		pr_debug("Failed to compile test case: '%s'\n", desc);
-	return ret;
-}
-
-static int test__llvm(int subtest)
-{
-	int ret;
-	void *obj_buf = NULL;
-	size_t obj_buf_sz = 0;
-	bool should_load_fail = false;
-
-	if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
-		return TEST_FAIL;
-
-	ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
-				       subtest, false, &should_load_fail);
-
-	if (ret == TEST_OK && !should_load_fail) {
-		ret = test__bpf_parsing(obj_buf, obj_buf_sz);
-		if (ret != TEST_OK) {
-			pr_debug("Failed to parse test case '%s'\n",
-				 bpf_source_table[subtest].desc);
-		}
-	}
-	free(obj_buf);
-
-	return ret;
-}
-#endif //HAVE_LIBBPF_SUPPORT
-
-static int test__llvm__bpf_base_prog(struct test_suite *test __maybe_unused,
-				     int subtest __maybe_unused)
-{
-#ifdef HAVE_LIBBPF_SUPPORT
-	return test__llvm(LLVM_TESTCASE_BASE);
-#else
-	pr_debug("Skip LLVM test because BPF support is not compiled\n");
-	return TEST_SKIP;
-#endif
-}
-
-static int test__llvm__bpf_test_kbuild_prog(struct test_suite *test __maybe_unused,
-					    int subtest __maybe_unused)
-{
-#ifdef HAVE_LIBBPF_SUPPORT
-	return test__llvm(LLVM_TESTCASE_KBUILD);
-#else
-	pr_debug("Skip LLVM test because BPF support is not compiled\n");
-	return TEST_SKIP;
-#endif
-}
-
-static int test__llvm__bpf_test_prologue_prog(struct test_suite *test __maybe_unused,
-					      int subtest __maybe_unused)
-{
-#ifdef HAVE_LIBBPF_SUPPORT
-	return test__llvm(LLVM_TESTCASE_BPF_PROLOGUE);
-#else
-	pr_debug("Skip LLVM test because BPF support is not compiled\n");
-	return TEST_SKIP;
-#endif
-}
-
-static int test__llvm__bpf_test_relocation(struct test_suite *test __maybe_unused,
-					   int subtest __maybe_unused)
-{
-#ifdef HAVE_LIBBPF_SUPPORT
-	return test__llvm(LLVM_TESTCASE_BPF_RELOCATION);
-#else
-	pr_debug("Skip LLVM test because BPF support is not compiled\n");
-	return TEST_SKIP;
-#endif
-}
-
-
-static struct test_case llvm_tests[] = {
-#ifdef HAVE_LIBBPF_SUPPORT
-	TEST_CASE("Basic BPF llvm compile", llvm__bpf_base_prog),
-	TEST_CASE("kbuild searching", llvm__bpf_test_kbuild_prog),
-	TEST_CASE("Compile source for BPF prologue generation",
-		  llvm__bpf_test_prologue_prog),
-	TEST_CASE("Compile source for BPF relocation", llvm__bpf_test_relocation),
-#else
-	TEST_CASE_REASON("Basic BPF llvm compile", llvm__bpf_base_prog, "not compiled in"),
-	TEST_CASE_REASON("kbuild searching", llvm__bpf_test_kbuild_prog, "not compiled in"),
-	TEST_CASE_REASON("Compile source for BPF prologue generation",
-			llvm__bpf_test_prologue_prog, "not compiled in"),
-	TEST_CASE_REASON("Compile source for BPF relocation",
-			llvm__bpf_test_relocation, "not compiled in"),
-#endif
-	{ .name = NULL, }
-};
-
-struct test_suite suite__llvm = {
-	.desc = "LLVM search and compile",
-	.test_cases = llvm_tests,
-};
diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h
deleted file mode 100644
index f68b0d9b8ae2..000000000000
--- a/tools/perf/tests/llvm.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef PERF_TEST_LLVM_H
-#define PERF_TEST_LLVM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h> /* for size_t */
-#include <stdbool.h> /* for bool */
-
-extern const char test_llvm__bpf_base_prog[];
-extern const char test_llvm__bpf_test_kbuild_prog[];
-extern const char test_llvm__bpf_test_prologue_prog[];
-extern const char test_llvm__bpf_test_relocation[];
-
-enum test_llvm__testcase {
-	LLVM_TESTCASE_BASE,
-	LLVM_TESTCASE_KBUILD,
-	LLVM_TESTCASE_BPF_PROLOGUE,
-	LLVM_TESTCASE_BPF_RELOCATION,
-	__LLVM_TESTCASE_MAX,
-};
-
-int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz,
-			     enum test_llvm__testcase index, bool force,
-			     bool *should_load_fail);
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 58cf96d762d0..220dd08c0560 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -95,7 +95,6 @@ make_with_babeltrace:= LIBBABELTRACE=1
 make_with_coresight := CORESIGHT=1
 make_no_sdt	    := NO_SDT=1
 make_no_syscall_tbl := NO_SYSCALL_TABLE=1
-make_with_clangllvm := LIBCLANGLLVM=1
 make_no_libpfm4     := NO_LIBPFM4=1
 make_with_gtk2      := GTK2=1
 make_refcnt_check   := EXTRA_CFLAGS="-DREFCNT_CHECKING=1"
@@ -163,7 +162,6 @@ run += make_no_sdt
 run += make_no_syscall_tbl
 run += make_with_babeltrace
 run += make_with_coresight
-run += make_with_clangllvm
 run += make_no_libpfm4
 run += make_refcnt_check
 run += make_help
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index f424c0b7f43f..f33cfc3c19a4 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -113,7 +113,6 @@ DECLARE_SUITE(fdarray__filter);
 DECLARE_SUITE(fdarray__add);
 DECLARE_SUITE(kmod_path__parse);
 DECLARE_SUITE(thread_map);
-DECLARE_SUITE(llvm);
 DECLARE_SUITE(bpf);
 DECLARE_SUITE(session_topology);
 DECLARE_SUITE(thread_map_synthesize);
@@ -129,7 +128,6 @@ DECLARE_SUITE(sdt_event);
 DECLARE_SUITE(is_printable_array);
 DECLARE_SUITE(bitmap_print);
 DECLARE_SUITE(perf_hooks);
-DECLARE_SUITE(clang);
 DECLARE_SUITE(unit_number__scnprint);
 DECLARE_SUITE(mem2node);
 DECLARE_SUITE(maps__merge_in);
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index d487aec0b458..e7d2e780f9d2 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -22,7 +22,6 @@ perf-y += evswitch.o
 perf-y += find_bit.o
 perf-y += get_current_dir_name.o
 perf-y += levenshtein.o
-perf-y += llvm-utils.o
 perf-y += mmap.o
 perf-y += memswap.o
 perf-y += parse-events.o
@@ -149,7 +148,6 @@ perf-y += list_sort.o
 perf-y += mutex.o
 perf-y += sharded_mutex.o
 
-perf-$(CONFIG_LIBBPF) += bpf-loader.o
 perf-$(CONFIG_LIBBPF) += bpf_map.o
 perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter.o
 perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter_cgroup.o
@@ -167,7 +165,6 @@ ifeq ($(CONFIG_LIBTRACEEVENT),y)
   perf-$(CONFIG_PERF_BPF_SKEL) += bpf_kwork.o
 endif
 
-perf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
 perf-$(CONFIG_LIBELF) += symbol-elf.o
 perf-$(CONFIG_LIBELF) += probe-file.o
 perf-$(CONFIG_LIBELF) += probe-event.o
@@ -231,12 +228,9 @@ perf-y += perf-hooks.o
 perf-$(CONFIG_LIBBPF) += bpf-event.o
 perf-$(CONFIG_LIBBPF) += bpf-utils.o
 
-perf-$(CONFIG_CXX) += c++/
-
 perf-$(CONFIG_LIBPFM4) += pfm.o
 
 CFLAGS_config.o   += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
-CFLAGS_llvm-utils.o += -DLIBBPF_INCLUDE_DIR="BUILD_STR($(libbpf_include_dir_SQ))"
 
 # avoid compiler warnings in 32-bit mode
 CFLAGS_genelf_debug.o  += -Wno-packed
@@ -301,7 +295,7 @@ else
   flex_flags := -w
 endif
 
-CFLAGS_parse-events-flex.o  += $(flex_flags)
+CFLAGS_parse-events-flex.o  += $(flex_flags) -Wno-unused-label
 CFLAGS_pmu-flex.o           += $(flex_flags)
 CFLAGS_expr-flex.o          += $(flex_flags)
 CFLAGS_bpf-filter-flex.o    += $(flex_flags)
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
deleted file mode 100644
index 50e42698cbb7..000000000000
--- a/tools/perf/util/bpf-loader.c
+++ /dev/null
@@ -1,2006 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * bpf-loader.c
- *
- * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
- * Copyright (C) 2015 Huawei Inc.
- */
-
-#include <linux/bpf.h>
-#include <bpf/libbpf.h>
-#include <bpf/bpf.h>
-#include <linux/filter.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/zalloc.h>
-#include <errno.h>
-#include <stdlib.h>
-#include "debug.h"
-#include "evlist.h"
-#include "bpf-loader.h"
-#include "bpf-prologue.h"
-#include "probe-event.h"
-#include "probe-finder.h" // for MAX_PROBES
-#include "parse-events.h"
-#include "strfilter.h"
-#include "util.h"
-#include "llvm-utils.h"
-#include "c++/clang-c.h"
-#include "util/hashmap.h"
-#include "asm/bug.h"
-
-#include <internal/xyarray.h>
-
-static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)),
-			      const char *fmt, va_list args)
-{
-	return veprintf(1, verbose, pr_fmt(fmt), args);
-}
-
-struct bpf_prog_priv {
-	bool is_tp;
-	char *sys_name;
-	char *evt_name;
-	struct perf_probe_event pev;
-	bool need_prologue;
-	struct bpf_insn *insns_buf;
-	int nr_types;
-	int *type_mapping;
-	int *prologue_fds;
-};
-
-struct bpf_perf_object {
-	struct list_head list;
-	struct bpf_object *obj;
-};
-
-struct bpf_preproc_result {
-	struct bpf_insn *new_insn_ptr;
-	int new_insn_cnt;
-};
-
-static LIST_HEAD(bpf_objects_list);
-static struct hashmap *bpf_program_hash;
-static struct hashmap *bpf_map_hash;
-
-static struct bpf_perf_object *
-bpf_perf_object__next(struct bpf_perf_object *prev)
-{
-	if (!prev) {
-		if (list_empty(&bpf_objects_list))
-			return NULL;
-
-		return list_first_entry(&bpf_objects_list, struct bpf_perf_object, list);
-	}
-	if (list_is_last(&prev->list, &bpf_objects_list))
-		return NULL;
-
-	return list_next_entry(prev, list);
-}
-
-#define bpf_perf_object__for_each(perf_obj, tmp)	\
-	for ((perf_obj) = bpf_perf_object__next(NULL),	\
-	     (tmp) = bpf_perf_object__next(perf_obj);	\
-	     (perf_obj) != NULL;			\
-	     (perf_obj) = (tmp), (tmp) = bpf_perf_object__next(tmp))
-
-static bool libbpf_initialized;
-static int libbpf_sec_handler;
-
-static int bpf_perf_object__add(struct bpf_object *obj)
-{
-	struct bpf_perf_object *perf_obj = zalloc(sizeof(*perf_obj));
-
-	if (perf_obj) {
-		INIT_LIST_HEAD(&perf_obj->list);
-		perf_obj->obj = obj;
-		list_add_tail(&perf_obj->list, &bpf_objects_list);
-	}
-	return perf_obj ? 0 : -ENOMEM;
-}
-
-static void *program_priv(const struct bpf_program *prog)
-{
-	void *priv;
-
-	if (IS_ERR_OR_NULL(bpf_program_hash))
-		return NULL;
-	if (!hashmap__find(bpf_program_hash, prog, &priv))
-		return NULL;
-	return priv;
-}
-
-static struct bpf_insn prologue_init_insn[] = {
-	BPF_MOV64_IMM(BPF_REG_2, 0),
-	BPF_MOV64_IMM(BPF_REG_3, 0),
-	BPF_MOV64_IMM(BPF_REG_4, 0),
-	BPF_MOV64_IMM(BPF_REG_5, 0),
-};
-
-static int libbpf_prog_prepare_load_fn(struct bpf_program *prog,
-				       struct bpf_prog_load_opts *opts __maybe_unused,
-				       long cookie __maybe_unused)
-{
-	size_t init_size_cnt = ARRAY_SIZE(prologue_init_insn);
-	size_t orig_insn_cnt, insn_cnt, init_size, orig_size;
-	struct bpf_prog_priv *priv = program_priv(prog);
-	const struct bpf_insn *orig_insn;
-	struct bpf_insn *insn;
-
-	if (IS_ERR_OR_NULL(priv)) {
-		pr_debug("bpf: failed to get private field\n");
-		return -BPF_LOADER_ERRNO__INTERNAL;
-	}
-
-	if (!priv->need_prologue)
-		return 0;
-
-	/* prepend initialization code to program instructions */
-	orig_insn = bpf_program__insns(prog);
-	orig_insn_cnt = bpf_program__insn_cnt(prog);
-	init_size = init_size_cnt * sizeof(*insn);
-	orig_size = orig_insn_cnt * sizeof(*insn);
-
-	insn_cnt = orig_insn_cnt + init_size_cnt;
-	insn = malloc(insn_cnt * sizeof(*insn));
-	if (!insn)
-		return -ENOMEM;
-
-	memcpy(insn, prologue_init_insn, init_size);
-	memcpy((char *) insn + init_size, orig_insn, orig_size);
-	bpf_program__set_insns(prog, insn, insn_cnt);
-	return 0;
-}
-
-static int libbpf_init(void)
-{
-	LIBBPF_OPTS(libbpf_prog_handler_opts, handler_opts,
-		.prog_prepare_load_fn = libbpf_prog_prepare_load_fn,
-	);
-
-	if (libbpf_initialized)
-		return 0;
-
-	libbpf_set_print(libbpf_perf_print);
-	libbpf_sec_handler = libbpf_register_prog_handler(NULL, BPF_PROG_TYPE_KPROBE,
-							  0, &handler_opts);
-	if (libbpf_sec_handler < 0) {
-		pr_debug("bpf: failed to register libbpf section handler: %d\n",
-			 libbpf_sec_handler);
-		return -BPF_LOADER_ERRNO__INTERNAL;
-	}
-	libbpf_initialized = true;
-	return 0;
-}
-
-struct bpf_object *
-bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
-{
-	LIBBPF_OPTS(bpf_object_open_opts, opts, .object_name = name);
-	struct bpf_object *obj;
-	int err;
-
-	err = libbpf_init();
-	if (err)
-		return ERR_PTR(err);
-
-	obj = bpf_object__open_mem(obj_buf, obj_buf_sz, &opts);
-	if (IS_ERR_OR_NULL(obj)) {
-		pr_debug("bpf: failed to load buffer\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	if (bpf_perf_object__add(obj)) {
-		bpf_object__close(obj);
-		return ERR_PTR(-ENOMEM);
-	}
-
-	return obj;
-}
-
-static void bpf_perf_object__close(struct bpf_perf_object *perf_obj)
-{
-	list_del(&perf_obj->list);
-	bpf_object__close(perf_obj->obj);
-	free(perf_obj);
-}
-
-struct bpf_object *bpf__prepare_load(const char *filename, bool source)
-{
-	LIBBPF_OPTS(bpf_object_open_opts, opts, .object_name = filename);
-	struct bpf_object *obj;
-	int err;
-
-	err = libbpf_init();
-	if (err)
-		return ERR_PTR(err);
-
-	if (source) {
-		void *obj_buf;
-		size_t obj_buf_sz;
-
-		perf_clang__init();
-		err = perf_clang__compile_bpf(filename, &obj_buf, &obj_buf_sz);
-		perf_clang__cleanup();
-		if (err) {
-			pr_debug("bpf: builtin compilation failed: %d, try external compiler\n", err);
-			err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz);
-			if (err)
-				return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
-		} else
-			pr_debug("bpf: successful builtin compilation\n");
-		obj = bpf_object__open_mem(obj_buf, obj_buf_sz, &opts);
-
-		if (!IS_ERR_OR_NULL(obj) && llvm_param.dump_obj)
-			llvm__dump_obj(filename, obj_buf, obj_buf_sz);
-
-		free(obj_buf);
-	} else {
-		obj = bpf_object__open(filename);
-	}
-
-	if (IS_ERR_OR_NULL(obj)) {
-		pr_debug("bpf: failed to load %s\n", filename);
-		return obj;
-	}
-
-	if (bpf_perf_object__add(obj)) {
-		bpf_object__close(obj);
-		return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE);
-	}
-
-	return obj;
-}
-
-static void close_prologue_programs(struct bpf_prog_priv *priv)
-{
-	struct perf_probe_event *pev;
-	int i, fd;
-
-	if (!priv->need_prologue)
-		return;
-	pev = &priv->pev;
-	for (i = 0; i < pev->ntevs; i++) {
-		fd = priv->prologue_fds[i];
-		if (fd != -1)
-			close(fd);
-	}
-}
-
-static void
-clear_prog_priv(const struct bpf_program *prog __maybe_unused,
-		void *_priv)
-{
-	struct bpf_prog_priv *priv = _priv;
-
-	close_prologue_programs(priv);
-	cleanup_perf_probe_events(&priv->pev, 1);
-	zfree(&priv->insns_buf);
-	zfree(&priv->prologue_fds);
-	zfree(&priv->type_mapping);
-	zfree(&priv->sys_name);
-	zfree(&priv->evt_name);
-	free(priv);
-}
-
-static void bpf_program_hash_free(void)
-{
-	struct hashmap_entry *cur;
-	size_t bkt;
-
-	if (IS_ERR_OR_NULL(bpf_program_hash))
-		return;
-
-	hashmap__for_each_entry(bpf_program_hash, cur, bkt)
-		clear_prog_priv(cur->pkey, cur->pvalue);
-
-	hashmap__free(bpf_program_hash);
-	bpf_program_hash = NULL;
-}
-
-static void bpf_map_hash_free(void);
-
-void bpf__clear(void)
-{
-	struct bpf_perf_object *perf_obj, *tmp;
-
-	bpf_perf_object__for_each(perf_obj, tmp) {
-		bpf__unprobe(perf_obj->obj);
-		bpf_perf_object__close(perf_obj);
-	}
-
-	bpf_program_hash_free();
-	bpf_map_hash_free();
-}
-
-static size_t ptr_hash(const long __key, void *ctx __maybe_unused)
-{
-	return __key;
-}
-
-static bool ptr_equal(long key1, long key2, void *ctx __maybe_unused)
-{
-	return key1 == key2;
-}
-
-static int program_set_priv(struct bpf_program *prog, void *priv)
-{
-	void *old_priv;
-
-	/*
-	 * Should not happen, we warn about it in the
-	 * caller function - config_bpf_program
-	 */
-	if (IS_ERR(bpf_program_hash))
-		return PTR_ERR(bpf_program_hash);
-
-	if (!bpf_program_hash) {
-		bpf_program_hash = hashmap__new(ptr_hash, ptr_equal, NULL);
-		if (IS_ERR(bpf_program_hash))
-			return PTR_ERR(bpf_program_hash);
-	}
-
-	old_priv = program_priv(prog);
-	if (old_priv) {
-		clear_prog_priv(prog, old_priv);
-		return hashmap__set(bpf_program_hash, prog, priv, NULL, NULL);
-	}
-	return hashmap__add(bpf_program_hash, prog, priv);
-}
-
-static int
-prog_config__exec(const char *value, struct perf_probe_event *pev)
-{
-	pev->uprobes = true;
-	pev->target = strdup(value);
-	if (!pev->target)
-		return -ENOMEM;
-	return 0;
-}
-
-static int
-prog_config__module(const char *value, struct perf_probe_event *pev)
-{
-	pev->uprobes = false;
-	pev->target = strdup(value);
-	if (!pev->target)
-		return -ENOMEM;
-	return 0;
-}
-
-static int
-prog_config__bool(const char *value, bool *pbool, bool invert)
-{
-	int err;
-	bool bool_value;
-
-	if (!pbool)
-		return -EINVAL;
-
-	err = strtobool(value, &bool_value);
-	if (err)
-		return err;
-
-	*pbool = invert ? !bool_value : bool_value;
-	return 0;
-}
-
-static int
-prog_config__inlines(const char *value,
-		     struct perf_probe_event *pev __maybe_unused)
-{
-	return prog_config__bool(value, &probe_conf.no_inlines, true);
-}
-
-static int
-prog_config__force(const char *value,
-		   struct perf_probe_event *pev __maybe_unused)
-{
-	return prog_config__bool(value, &probe_conf.force_add, false);
-}
-
-static struct {
-	const char *key;
-	const char *usage;
-	const char *desc;
-	int (*func)(const char *, struct perf_probe_event *);
-} bpf_prog_config_terms[] = {
-	{
-		.key	= "exec",
-		.usage	= "exec=<full path of file>",
-		.desc	= "Set uprobe target",
-		.func	= prog_config__exec,
-	},
-	{
-		.key	= "module",
-		.usage	= "module=<module name>    ",
-		.desc	= "Set kprobe module",
-		.func	= prog_config__module,
-	},
-	{
-		.key	= "inlines",
-		.usage	= "inlines=[yes|no]        ",
-		.desc	= "Probe at inline symbol",
-		.func	= prog_config__inlines,
-	},
-	{
-		.key	= "force",
-		.usage	= "force=[yes|no]          ",
-		.desc	= "Forcibly add events with existing name",
-		.func	= prog_config__force,
-	},
-};
-
-static int
-do_prog_config(const char *key, const char *value,
-	       struct perf_probe_event *pev)
-{
-	unsigned int i;
-
-	pr_debug("config bpf program: %s=%s\n", key, value);
-	for (i = 0; i < ARRAY_SIZE(bpf_prog_config_terms); i++)
-		if (strcmp(key, bpf_prog_config_terms[i].key) == 0)
-			return bpf_prog_config_terms[i].func(value, pev);
-
-	pr_debug("BPF: ERROR: invalid program config option: %s=%s\n",
-		 key, value);
-
-	pr_debug("\nHint: Valid options are:\n");
-	for (i = 0; i < ARRAY_SIZE(bpf_prog_config_terms); i++)
-		pr_debug("\t%s:\t%s\n", bpf_prog_config_terms[i].usage,
-			 bpf_prog_config_terms[i].desc);
-	pr_debug("\n");
-
-	return -BPF_LOADER_ERRNO__PROGCONF_TERM;
-}
-
-static const char *
-parse_prog_config_kvpair(const char *config_str, struct perf_probe_event *pev)
-{
-	char *text = strdup(config_str);
-	char *sep, *line;
-	const char *main_str = NULL;
-	int err = 0;
-
-	if (!text) {
-		pr_debug("Not enough memory: dup config_str failed\n");
-		return ERR_PTR(-ENOMEM);
-	}
-
-	line = text;
-	while ((sep = strchr(line, ';'))) {
-		char *equ;
-
-		*sep = '\0';
-		equ = strchr(line, '=');
-		if (!equ) {
-			pr_warning("WARNING: invalid config in BPF object: %s\n",
-				   line);
-			pr_warning("\tShould be 'key=value'.\n");
-			goto nextline;
-		}
-		*equ = '\0';
-
-		err = do_prog_config(line, equ + 1, pev);
-		if (err)
-			break;
-nextline:
-		line = sep + 1;
-	}
-
-	if (!err)
-		main_str = config_str + (line - text);
-	free(text);
-
-	return err ? ERR_PTR(err) : main_str;
-}
-
-static int
-parse_prog_config(const char *config_str, const char **p_main_str,
-		  bool *is_tp, struct perf_probe_event *pev)
-{
-	int err;
-	const char *main_str = parse_prog_config_kvpair(config_str, pev);
-
-	if (IS_ERR(main_str))
-		return PTR_ERR(main_str);
-
-	*p_main_str = main_str;
-	if (!strchr(main_str, '=')) {
-		/* Is a tracepoint event? */
-		const char *s = strchr(main_str, ':');
-
-		if (!s) {
-			pr_debug("bpf: '%s' is not a valid tracepoint\n",
-				 config_str);
-			return -BPF_LOADER_ERRNO__CONFIG;
-		}
-
-		*is_tp = true;
-		return 0;
-	}
-
-	*is_tp = false;
-	err = parse_perf_probe_command(main_str, pev);
-	if (err < 0) {
-		pr_debug("bpf: '%s' is not a valid config string\n",
-			 config_str);
-		/* parse failed, don't need clear pev. */
-		return -BPF_LOADER_ERRNO__CONFIG;
-	}
-	return 0;
-}
-
-static int
-config_bpf_program(struct bpf_program *prog)
-{
-	struct perf_probe_event *pev = NULL;
-	struct bpf_prog_priv *priv = NULL;
-	const char *config_str, *main_str;
-	bool is_tp = false;
-	int err;
-
-	/* Initialize per-program probing setting */
-	probe_conf.no_inlines = false;
-	probe_conf.force_add = false;
-
-	priv = calloc(sizeof(*priv), 1);
-	if (!priv) {
-		pr_debug("bpf: failed to alloc priv\n");
-		return -ENOMEM;
-	}
-	pev = &priv->pev;
-
-	config_str = bpf_program__section_name(prog);
-	pr_debug("bpf: config program '%s'\n", config_str);
-	err = parse_prog_config(config_str, &main_str, &is_tp, pev);
-	if (err)
-		goto errout;
-
-	if (is_tp) {
-		char *s = strchr(main_str, ':');
-
-		priv->is_tp = true;
-		priv->sys_name = strndup(main_str, s - main_str);
-		priv->evt_name = strdup(s + 1);
-		goto set_priv;
-	}
-
-	if (pev->group && strcmp(pev->group, PERF_BPF_PROBE_GROUP)) {
-		pr_debug("bpf: '%s': group for event is set and not '%s'.\n",
-			 config_str, PERF_BPF_PROBE_GROUP);
-		err = -BPF_LOADER_ERRNO__GROUP;
-		goto errout;
-	} else if (!pev->group)
-		pev->group = strdup(PERF_BPF_PROBE_GROUP);
-
-	if (!pev->group) {
-		pr_debug("bpf: strdup failed\n");
-		err = -ENOMEM;
-		goto errout;
-	}
-
-	if (!pev->event) {
-		pr_debug("bpf: '%s': event name is missing. Section name should be 'key=value'\n",
-			 config_str);
-		err = -BPF_LOADER_ERRNO__EVENTNAME;
-		goto errout;
-	}
-	pr_debug("bpf: config '%s' is ok\n", config_str);
-
-set_priv:
-	err = program_set_priv(prog, priv);
-	if (err) {
-		pr_debug("Failed to set priv for program '%s'\n", config_str);
-		goto errout;
-	}
-
-	return 0;
-
-errout:
-	if (pev)
-		clear_perf_probe_event(pev);
-	free(priv);
-	return err;
-}
-
-static int bpf__prepare_probe(void)
-{
-	static int err = 0;
-	static bool initialized = false;
-
-	/*
-	 * Make err static, so if init failed the first, bpf__prepare_probe()
-	 * fails each time without calling init_probe_symbol_maps multiple
-	 * times.
-	 */
-	if (initialized)
-		return err;
-
-	initialized = true;
-	err = init_probe_symbol_maps(false);
-	if (err < 0)
-		pr_debug("Failed to init_probe_symbol_maps\n");
-	probe_conf.max_probes = MAX_PROBES;
-	return err;
-}
-
-static int
-preproc_gen_prologue(struct bpf_program *prog, int n,
-		     const struct bpf_insn *orig_insns, int orig_insns_cnt,
-		     struct bpf_preproc_result *res)
-{
-	struct bpf_prog_priv *priv = program_priv(prog);
-	struct probe_trace_event *tev;
-	struct perf_probe_event *pev;
-	struct bpf_insn *buf;
-	size_t prologue_cnt = 0;
-	int i, err;
-
-	if (IS_ERR_OR_NULL(priv) || priv->is_tp)
-		goto errout;
-
-	pev = &priv->pev;
-
-	if (n < 0 || n >= priv->nr_types)
-		goto errout;
-
-	/* Find a tev belongs to that type */
-	for (i = 0; i < pev->ntevs; i++) {
-		if (priv->type_mapping[i] == n)
-			break;
-	}
-
-	if (i >= pev->ntevs) {
-		pr_debug("Internal error: prologue type %d not found\n", n);
-		return -BPF_LOADER_ERRNO__PROLOGUE;
-	}
-
-	tev = &pev->tevs[i];
-
-	buf = priv->insns_buf;
-	err = bpf__gen_prologue(tev->args, tev->nargs,
-				buf, &prologue_cnt,
-				BPF_MAXINSNS - orig_insns_cnt);
-	if (err) {
-		const char *title;
-
-		title = bpf_program__section_name(prog);
-		pr_debug("Failed to generate prologue for program %s\n",
-			 title);
-		return err;
-	}
-
-	memcpy(&buf[prologue_cnt], orig_insns,
-	       sizeof(struct bpf_insn) * orig_insns_cnt);
-
-	res->new_insn_ptr = buf;
-	res->new_insn_cnt = prologue_cnt + orig_insns_cnt;
-	return 0;
-
-errout:
-	pr_debug("Internal error in preproc_gen_prologue\n");
-	return -BPF_LOADER_ERRNO__PROLOGUE;
-}
-
-/*
- * compare_tev_args is reflexive, transitive and antisymmetric.
- * I can proof it but this margin is too narrow to contain.
- */
-static int compare_tev_args(const void *ptev1, const void *ptev2)
-{
-	int i, ret;
-	const struct probe_trace_event *tev1 =
-		*(const struct probe_trace_event **)ptev1;
-	const struct probe_trace_event *tev2 =
-		*(const struct probe_trace_event **)ptev2;
-
-	ret = tev2->nargs - tev1->nargs;
-	if (ret)
-		return ret;
-
-	for (i = 0; i < tev1->nargs; i++) {
-		struct probe_trace_arg *arg1, *arg2;
-		struct probe_trace_arg_ref *ref1, *ref2;
-
-		arg1 = &tev1->args[i];
-		arg2 = &tev2->args[i];
-
-		ret = strcmp(arg1->value, arg2->value);
-		if (ret)
-			return ret;
-
-		ref1 = arg1->ref;
-		ref2 = arg2->ref;
-
-		while (ref1 && ref2) {
-			ret = ref2->offset - ref1->offset;
-			if (ret)
-				return ret;
-
-			ref1 = ref1->next;
-			ref2 = ref2->next;
-		}
-
-		if (ref1 || ref2)
-			return ref2 ? 1 : -1;
-	}
-
-	return 0;
-}
-
-/*
- * Assign a type number to each tevs in a pev.
- * mapping is an array with same slots as tevs in that pev.
- * nr_types will be set to number of types.
- */
-static int map_prologue(struct perf_probe_event *pev, int *mapping,
-			int *nr_types)
-{
-	int i, type = 0;
-	struct probe_trace_event **ptevs;
-
-	size_t array_sz = sizeof(*ptevs) * pev->ntevs;
-
-	ptevs = malloc(array_sz);
-	if (!ptevs) {
-		pr_debug("Not enough memory: alloc ptevs failed\n");
-		return -ENOMEM;
-	}
-
-	pr_debug("In map_prologue, ntevs=%d\n", pev->ntevs);
-	for (i = 0; i < pev->ntevs; i++)
-		ptevs[i] = &pev->tevs[i];
-
-	qsort(ptevs, pev->ntevs, sizeof(*ptevs),
-	      compare_tev_args);
-
-	for (i = 0; i < pev->ntevs; i++) {
-		int n;
-
-		n = ptevs[i] - pev->tevs;
-		if (i == 0) {
-			mapping[n] = type;
-			pr_debug("mapping[%d]=%d\n", n, type);
-			continue;
-		}
-
-		if (compare_tev_args(ptevs + i, ptevs + i - 1) == 0)
-			mapping[n] = type;
-		else
-			mapping[n] = ++type;
-
-		pr_debug("mapping[%d]=%d\n", n, mapping[n]);
-	}
-	free(ptevs);
-	*nr_types = type + 1;
-
-	return 0;
-}
-
-static int hook_load_preprocessor(struct bpf_program *prog)
-{
-	struct bpf_prog_priv *priv = program_priv(prog);
-	struct perf_probe_event *pev;
-	bool need_prologue = false;
-	int i;
-
-	if (IS_ERR_OR_NULL(priv)) {
-		pr_debug("Internal error when hook preprocessor\n");
-		return -BPF_LOADER_ERRNO__INTERNAL;
-	}
-
-	if (priv->is_tp) {
-		priv->need_prologue = false;
-		return 0;
-	}
-
-	pev = &priv->pev;
-	for (i = 0; i < pev->ntevs; i++) {
-		struct probe_trace_event *tev = &pev->tevs[i];
-
-		if (tev->nargs > 0) {
-			need_prologue = true;
-			break;
-		}
-	}
-
-	/*
-	 * Since all tevs don't have argument, we don't need generate
-	 * prologue.
-	 */
-	if (!need_prologue) {
-		priv->need_prologue = false;
-		return 0;
-	}
-
-	priv->need_prologue = true;
-	priv->insns_buf = malloc(sizeof(struct bpf_insn) * BPF_MAXINSNS);
-	if (!priv->insns_buf) {
-		pr_debug("Not enough memory: alloc insns_buf failed\n");
-		return -ENOMEM;
-	}
-
-	priv->prologue_fds = malloc(sizeof(int) * pev->ntevs);
-	if (!priv->prologue_fds) {
-		pr_debug("Not enough memory: alloc prologue fds failed\n");
-		return -ENOMEM;
-	}
-	memset(priv->prologue_fds, -1, sizeof(int) * pev->ntevs);
-
-	priv->type_mapping = malloc(sizeof(int) * pev->ntevs);
-	if (!priv->type_mapping) {
-		pr_debug("Not enough memory: alloc type_mapping failed\n");
-		return -ENOMEM;
-	}
-	memset(priv->type_mapping, -1,
-	       sizeof(int) * pev->ntevs);
-
-	return map_prologue(pev, priv->type_mapping, &priv->nr_types);
-}
-
-int bpf__probe(struct bpf_object *obj)
-{
-	int err = 0;
-	struct bpf_program *prog;
-	struct bpf_prog_priv *priv;
-	struct perf_probe_event *pev;
-
-	err = bpf__prepare_probe();
-	if (err) {
-		pr_debug("bpf__prepare_probe failed\n");
-		return err;
-	}
-
-	bpf_object__for_each_program(prog, obj) {
-		err = config_bpf_program(prog);
-		if (err)
-			goto out;
-
-		priv = program_priv(prog);
-		if (IS_ERR_OR_NULL(priv)) {
-			if (!priv)
-				err = -BPF_LOADER_ERRNO__INTERNAL;
-			else
-				err = PTR_ERR(priv);
-			goto out;
-		}
-
-		if (priv->is_tp) {
-			bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
-			continue;
-		}
-
-		bpf_program__set_type(prog, BPF_PROG_TYPE_KPROBE);
-		pev = &priv->pev;
-
-		err = convert_perf_probe_events(pev, 1);
-		if (err < 0) {
-			pr_debug("bpf_probe: failed to convert perf probe events\n");
-			goto out;
-		}
-
-		err = apply_perf_probe_events(pev, 1);
-		if (err < 0) {
-			pr_debug("bpf_probe: failed to apply perf probe events\n");
-			goto out;
-		}
-
-		/*
-		 * After probing, let's consider prologue, which
-		 * adds program fetcher to BPF programs.
-		 *
-		 * hook_load_preprocessor() hooks pre-processor
-		 * to bpf_program, let it generate prologue
-		 * dynamically during loading.
-		 */
-		err = hook_load_preprocessor(prog);
-		if (err)
-			goto out;
-	}
-out:
-	return err < 0 ? err : 0;
-}
-
-#define EVENTS_WRITE_BUFSIZE  4096
-int bpf__unprobe(struct bpf_object *obj)
-{
-	int err, ret = 0;
-	struct bpf_program *prog;
-
-	bpf_object__for_each_program(prog, obj) {
-		struct bpf_prog_priv *priv = program_priv(prog);
-		int i;
-
-		if (IS_ERR_OR_NULL(priv) || priv->is_tp)
-			continue;
-
-		for (i = 0; i < priv->pev.ntevs; i++) {
-			struct probe_trace_event *tev = &priv->pev.tevs[i];
-			char name_buf[EVENTS_WRITE_BUFSIZE];
-			struct strfilter *delfilter;
-
-			snprintf(name_buf, EVENTS_WRITE_BUFSIZE,
-				 "%s:%s", tev->group, tev->event);
-			name_buf[EVENTS_WRITE_BUFSIZE - 1] = '\0';
-
-			delfilter = strfilter__new(name_buf, NULL);
-			if (!delfilter) {
-				pr_debug("Failed to create filter for unprobing\n");
-				ret = -ENOMEM;
-				continue;
-			}
-
-			err = del_perf_probe_events(delfilter);
-			strfilter__delete(delfilter);
-			if (err) {
-				pr_debug("Failed to delete %s\n", name_buf);
-				ret = err;
-				continue;
-			}
-		}
-	}
-	return ret;
-}
-
-static int bpf_object__load_prologue(struct bpf_object *obj)
-{
-	int init_cnt = ARRAY_SIZE(prologue_init_insn);
-	const struct bpf_insn *orig_insns;
-	struct bpf_preproc_result res;
-	struct perf_probe_event *pev;
-	struct bpf_program *prog;
-	int orig_insns_cnt;
-
-	bpf_object__for_each_program(prog, obj) {
-		struct bpf_prog_priv *priv = program_priv(prog);
-		int err, i, fd;
-
-		if (IS_ERR_OR_NULL(priv)) {
-			pr_debug("bpf: failed to get private field\n");
-			return -BPF_LOADER_ERRNO__INTERNAL;
-		}
-
-		if (!priv->need_prologue)
-			continue;
-
-		/*
-		 * For each program that needs prologue we do following:
-		 *
-		 * - take its current instructions and use them
-		 *   to generate the new code with prologue
-		 * - load new instructions with bpf_prog_load
-		 *   and keep the fd in prologue_fds
-		 * - new fd will be used in bpf__foreach_event
-		 *   to connect this program with perf evsel
-		 */
-		orig_insns = bpf_program__insns(prog);
-		orig_insns_cnt = bpf_program__insn_cnt(prog);
-
-		pev = &priv->pev;
-		for (i = 0; i < pev->ntevs; i++) {
-			/*
-			 * Skipping artificall prologue_init_insn instructions
-			 * (init_cnt), so the prologue can be generated instead
-			 * of them.
-			 */
-			err = preproc_gen_prologue(prog, i,
-						   orig_insns + init_cnt,
-						   orig_insns_cnt - init_cnt,
-						   &res);
-			if (err)
-				return err;
-
-			fd = bpf_prog_load(bpf_program__get_type(prog),
-					   bpf_program__name(prog), "GPL",
-					   res.new_insn_ptr,
-					   res.new_insn_cnt, NULL);
-			if (fd < 0) {
-				char bf[128];
-
-				libbpf_strerror(-errno, bf, sizeof(bf));
-				pr_debug("bpf: load objects with prologue failed: err=%d: (%s)\n",
-					 -errno, bf);
-				return -errno;
-			}
-			priv->prologue_fds[i] = fd;
-		}
-		/*
-		 * We no longer need the original program,
-		 * we can unload it.
-		 */
-		bpf_program__unload(prog);
-	}
-	return 0;
-}
-
-int bpf__load(struct bpf_object *obj)
-{
-	int err;
-
-	err = bpf_object__load(obj);
-	if (err) {
-		char bf[128];
-		libbpf_strerror(err, bf, sizeof(bf));
-		pr_debug("bpf: load objects failed: err=%d: (%s)\n", err, bf);
-		return err;
-	}
-	return bpf_object__load_prologue(obj);
-}
-
-int bpf__foreach_event(struct bpf_object *obj,
-		       bpf_prog_iter_callback_t func,
-		       void *arg)
-{
-	struct bpf_program *prog;
-	int err;
-
-	bpf_object__for_each_program(prog, obj) {
-		struct bpf_prog_priv *priv = program_priv(prog);
-		struct probe_trace_event *tev;
-		struct perf_probe_event *pev;
-		int i, fd;
-
-		if (IS_ERR_OR_NULL(priv)) {
-			pr_debug("bpf: failed to get private field\n");
-			return -BPF_LOADER_ERRNO__INTERNAL;
-		}
-
-		if (priv->is_tp) {
-			fd = bpf_program__fd(prog);
-			err = (*func)(priv->sys_name, priv->evt_name, fd, obj, arg);
-			if (err) {
-				pr_debug("bpf: tracepoint call back failed, stop iterate\n");
-				return err;
-			}
-			continue;
-		}
-
-		pev = &priv->pev;
-		for (i = 0; i < pev->ntevs; i++) {
-			tev = &pev->tevs[i];
-
-			if (priv->need_prologue)
-				fd = priv->prologue_fds[i];
-			else
-				fd = bpf_program__fd(prog);
-
-			if (fd < 0) {
-				pr_debug("bpf: failed to get file descriptor\n");
-				return fd;
-			}
-
-			err = (*func)(tev->group, tev->event, fd, obj, arg);
-			if (err) {
-				pr_debug("bpf: call back failed, stop iterate\n");
-				return err;
-			}
-		}
-	}
-	return 0;
-}
-
-enum bpf_map_op_type {
-	BPF_MAP_OP_SET_VALUE,
-	BPF_MAP_OP_SET_EVSEL,
-};
-
-enum bpf_map_key_type {
-	BPF_MAP_KEY_ALL,
-};
-
-struct bpf_map_op {
-	struct list_head list;
-	enum bpf_map_op_type op_type;
-	enum bpf_map_key_type key_type;
-	union {
-		u64 value;
-		struct evsel *evsel;
-	} v;
-};
-
-struct bpf_map_priv {
-	struct list_head ops_list;
-};
-
-static void
-bpf_map_op__delete(struct bpf_map_op *op)
-{
-	if (!list_empty(&op->list))
-		list_del_init(&op->list);
-	free(op);
-}
-
-static void
-bpf_map_priv__purge(struct bpf_map_priv *priv)
-{
-	struct bpf_map_op *pos, *n;
-
-	list_for_each_entry_safe(pos, n, &priv->ops_list, list) {
-		list_del_init(&pos->list);
-		bpf_map_op__delete(pos);
-	}
-}
-
-static void
-bpf_map_priv__clear(const struct bpf_map *map __maybe_unused,
-		    void *_priv)
-{
-	struct bpf_map_priv *priv = _priv;
-
-	bpf_map_priv__purge(priv);
-	free(priv);
-}
-
-static void *map_priv(const struct bpf_map *map)
-{
-	void *priv;
-
-	if (IS_ERR_OR_NULL(bpf_map_hash))
-		return NULL;
-	if (!hashmap__find(bpf_map_hash, map, &priv))
-		return NULL;
-	return priv;
-}
-
-static void bpf_map_hash_free(void)
-{
-	struct hashmap_entry *cur;
-	size_t bkt;
-
-	if (IS_ERR_OR_NULL(bpf_map_hash))
-		return;
-
-	hashmap__for_each_entry(bpf_map_hash, cur, bkt)
-		bpf_map_priv__clear(cur->pkey, cur->pvalue);
-
-	hashmap__free(bpf_map_hash);
-	bpf_map_hash = NULL;
-}
-
-static int map_set_priv(struct bpf_map *map, void *priv)
-{
-	void *old_priv;
-
-	if (WARN_ON_ONCE(IS_ERR(bpf_map_hash)))
-		return PTR_ERR(bpf_program_hash);
-
-	if (!bpf_map_hash) {
-		bpf_map_hash = hashmap__new(ptr_hash, ptr_equal, NULL);
-		if (IS_ERR(bpf_map_hash))
-			return PTR_ERR(bpf_map_hash);
-	}
-
-	old_priv = map_priv(map);
-	if (old_priv) {
-		bpf_map_priv__clear(map, old_priv);
-		return hashmap__set(bpf_map_hash, map, priv, NULL, NULL);
-	}
-	return hashmap__add(bpf_map_hash, map, priv);
-}
-
-static int
-bpf_map_op_setkey(struct bpf_map_op *op, struct parse_events_term *term)
-{
-	op->key_type = BPF_MAP_KEY_ALL;
-	if (!term)
-		return 0;
-
-	return 0;
-}
-
-static struct bpf_map_op *
-bpf_map_op__new(struct parse_events_term *term)
-{
-	struct bpf_map_op *op;
-	int err;
-
-	op = zalloc(sizeof(*op));
-	if (!op) {
-		pr_debug("Failed to alloc bpf_map_op\n");
-		return ERR_PTR(-ENOMEM);
-	}
-	INIT_LIST_HEAD(&op->list);
-
-	err = bpf_map_op_setkey(op, term);
-	if (err) {
-		free(op);
-		return ERR_PTR(err);
-	}
-	return op;
-}
-
-static struct bpf_map_op *
-bpf_map_op__clone(struct bpf_map_op *op)
-{
-	struct bpf_map_op *newop;
-
-	newop = memdup(op, sizeof(*op));
-	if (!newop) {
-		pr_debug("Failed to alloc bpf_map_op\n");
-		return NULL;
-	}
-
-	INIT_LIST_HEAD(&newop->list);
-	return newop;
-}
-
-static struct bpf_map_priv *
-bpf_map_priv__clone(struct bpf_map_priv *priv)
-{
-	struct bpf_map_priv *newpriv;
-	struct bpf_map_op *pos, *newop;
-
-	newpriv = zalloc(sizeof(*newpriv));
-	if (!newpriv) {
-		pr_debug("Not enough memory to alloc map private\n");
-		return NULL;
-	}
-	INIT_LIST_HEAD(&newpriv->ops_list);
-
-	list_for_each_entry(pos, &priv->ops_list, list) {
-		newop = bpf_map_op__clone(pos);
-		if (!newop) {
-			bpf_map_priv__purge(newpriv);
-			return NULL;
-		}
-		list_add_tail(&newop->list, &newpriv->ops_list);
-	}
-
-	return newpriv;
-}
-
-static int
-bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
-{
-	const char *map_name = bpf_map__name(map);
-	struct bpf_map_priv *priv = map_priv(map);
-
-	if (IS_ERR(priv)) {
-		pr_debug("Failed to get private from map %s\n", map_name);
-		return PTR_ERR(priv);
-	}
-
-	if (!priv) {
-		priv = zalloc(sizeof(*priv));
-		if (!priv) {
-			pr_debug("Not enough memory to alloc map private\n");
-			return -ENOMEM;
-		}
-		INIT_LIST_HEAD(&priv->ops_list);
-
-		if (map_set_priv(map, priv)) {
-			free(priv);
-			return -BPF_LOADER_ERRNO__INTERNAL;
-		}
-	}
-
-	list_add_tail(&op->list, &priv->ops_list);
-	return 0;
-}
-
-static struct bpf_map_op *
-bpf_map__add_newop(struct bpf_map *map, struct parse_events_term *term)
-{
-	struct bpf_map_op *op;
-	int err;
-
-	op = bpf_map_op__new(term);
-	if (IS_ERR(op))
-		return op;
-
-	err = bpf_map__add_op(map, op);
-	if (err) {
-		bpf_map_op__delete(op);
-		return ERR_PTR(err);
-	}
-	return op;
-}
-
-static int
-__bpf_map__config_value(struct bpf_map *map,
-			struct parse_events_term *term)
-{
-	struct bpf_map_op *op;
-	const char *map_name = bpf_map__name(map);
-
-	if (!map) {
-		pr_debug("Map '%s' is invalid\n", map_name);
-		return -BPF_LOADER_ERRNO__INTERNAL;
-	}
-
-	if (bpf_map__type(map) != BPF_MAP_TYPE_ARRAY) {
-		pr_debug("Map %s type is not BPF_MAP_TYPE_ARRAY\n",
-			 map_name);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
-	}
-	if (bpf_map__key_size(map) < sizeof(unsigned int)) {
-		pr_debug("Map %s has incorrect key size\n", map_name);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE;
-	}
-	switch (bpf_map__value_size(map)) {
-	case 1:
-	case 2:
-	case 4:
-	case 8:
-		break;
-	default:
-		pr_debug("Map %s has incorrect value size\n", map_name);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE;
-	}
-
-	op = bpf_map__add_newop(map, term);
-	if (IS_ERR(op))
-		return PTR_ERR(op);
-	op->op_type = BPF_MAP_OP_SET_VALUE;
-	op->v.value = term->val.num;
-	return 0;
-}
-
-static int
-bpf_map__config_value(struct bpf_map *map,
-		      struct parse_events_term *term,
-		      struct evlist *evlist __maybe_unused)
-{
-	if (!term->err_val) {
-		pr_debug("Config value not set\n");
-		return -BPF_LOADER_ERRNO__OBJCONF_CONF;
-	}
-
-	if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM) {
-		pr_debug("ERROR: wrong value type for 'value'\n");
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE;
-	}
-
-	return __bpf_map__config_value(map, term);
-}
-
-static int
-__bpf_map__config_event(struct bpf_map *map,
-			struct parse_events_term *term,
-			struct evlist *evlist)
-{
-	struct bpf_map_op *op;
-	const char *map_name = bpf_map__name(map);
-	struct evsel *evsel = evlist__find_evsel_by_str(evlist, term->val.str);
-
-	if (!evsel) {
-		pr_debug("Event (for '%s') '%s' doesn't exist\n",
-			 map_name, term->val.str);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_NOEVT;
-	}
-
-	if (!map) {
-		pr_debug("Map '%s' is invalid\n", map_name);
-		return PTR_ERR(map);
-	}
-
-	/*
-	 * No need to check key_size and value_size:
-	 * kernel has already checked them.
-	 */
-	if (bpf_map__type(map) != BPF_MAP_TYPE_PERF_EVENT_ARRAY) {
-		pr_debug("Map %s type is not BPF_MAP_TYPE_PERF_EVENT_ARRAY\n",
-			 map_name);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
-	}
-
-	op = bpf_map__add_newop(map, term);
-	if (IS_ERR(op))
-		return PTR_ERR(op);
-	op->op_type = BPF_MAP_OP_SET_EVSEL;
-	op->v.evsel = evsel;
-	return 0;
-}
-
-static int
-bpf_map__config_event(struct bpf_map *map,
-		      struct parse_events_term *term,
-		      struct evlist *evlist)
-{
-	if (!term->err_val) {
-		pr_debug("Config value not set\n");
-		return -BPF_LOADER_ERRNO__OBJCONF_CONF;
-	}
-
-	if (term->type_val != PARSE_EVENTS__TERM_TYPE_STR) {
-		pr_debug("ERROR: wrong value type for 'event'\n");
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE;
-	}
-
-	return __bpf_map__config_event(map, term, evlist);
-}
-
-struct bpf_obj_config__map_func {
-	const char *config_opt;
-	int (*config_func)(struct bpf_map *, struct parse_events_term *,
-			   struct evlist *);
-};
-
-struct bpf_obj_config__map_func bpf_obj_config__map_funcs[] = {
-	{"value", bpf_map__config_value},
-	{"event", bpf_map__config_event},
-};
-
-static int
-bpf__obj_config_map(struct bpf_object *obj,
-		    struct parse_events_term *term,
-		    struct evlist *evlist,
-		    int *key_scan_pos)
-{
-	/* key is "map:<mapname>.<config opt>" */
-	char *map_name = strdup(term->config + sizeof("map:") - 1);
-	struct bpf_map *map;
-	int err = -BPF_LOADER_ERRNO__OBJCONF_OPT;
-	char *map_opt;
-	size_t i;
-
-	if (!map_name)
-		return -ENOMEM;
-
-	map_opt = strchr(map_name, '.');
-	if (!map_opt) {
-		pr_debug("ERROR: Invalid map config: %s\n", map_name);
-		goto out;
-	}
-
-	*map_opt++ = '\0';
-	if (*map_opt == '\0') {
-		pr_debug("ERROR: Invalid map option: %s\n", term->config);
-		goto out;
-	}
-
-	map = bpf_object__find_map_by_name(obj, map_name);
-	if (!map) {
-		pr_debug("ERROR: Map %s doesn't exist\n", map_name);
-		err = -BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST;
-		goto out;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(bpf_obj_config__map_funcs); i++) {
-		struct bpf_obj_config__map_func *func =
-				&bpf_obj_config__map_funcs[i];
-
-		if (strcmp(map_opt, func->config_opt) == 0) {
-			err = func->config_func(map, term, evlist);
-			goto out;
-		}
-	}
-
-	pr_debug("ERROR: Invalid map config option '%s'\n", map_opt);
-	err = -BPF_LOADER_ERRNO__OBJCONF_MAP_OPT;
-out:
-	if (!err)
-		*key_scan_pos += strlen(map_opt);
-
-	free(map_name);
-	return err;
-}
-
-int bpf__config_obj(struct bpf_object *obj,
-		    struct parse_events_term *term,
-		    struct evlist *evlist,
-		    int *error_pos)
-{
-	int key_scan_pos = 0;
-	int err;
-
-	if (!obj || !term || !term->config)
-		return -EINVAL;
-
-	if (strstarts(term->config, "map:")) {
-		key_scan_pos = sizeof("map:") - 1;
-		err = bpf__obj_config_map(obj, term, evlist, &key_scan_pos);
-		goto out;
-	}
-	err = -BPF_LOADER_ERRNO__OBJCONF_OPT;
-out:
-	if (error_pos)
-		*error_pos = key_scan_pos;
-	return err;
-
-}
-
-typedef int (*map_config_func_t)(const char *name, int map_fd,
-				 const struct bpf_map *map,
-				 struct bpf_map_op *op,
-				 void *pkey, void *arg);
-static int
-foreach_key_array_all(map_config_func_t func,
-		      void *arg, const char *name,
-		      int map_fd, const struct bpf_map *map,
-		      struct bpf_map_op *op)
-{
-	unsigned int i;
-	int err;
-
-	for (i = 0; i < bpf_map__max_entries(map); i++) {
-		err = func(name, map_fd, map, op, &i, arg);
-		if (err) {
-			pr_debug("ERROR: failed to insert value to %s[%u]\n",
-				 name, i);
-			return err;
-		}
-	}
-	return 0;
-}
-
-
-static int
-bpf_map_config_foreach_key(struct bpf_map *map,
-			   map_config_func_t func,
-			   void *arg)
-{
-	int err, map_fd, type;
-	struct bpf_map_op *op;
-	const char *name = bpf_map__name(map);
-	struct bpf_map_priv *priv = map_priv(map);
-
-	if (IS_ERR(priv)) {
-		pr_debug("ERROR: failed to get private from map %s\n", name);
-		return -BPF_LOADER_ERRNO__INTERNAL;
-	}
-	if (!priv || list_empty(&priv->ops_list)) {
-		pr_debug("INFO: nothing to config for map %s\n", name);
-		return 0;
-	}
-
-	if (!map) {
-		pr_debug("Map '%s' is invalid\n", name);
-		return -BPF_LOADER_ERRNO__INTERNAL;
-	}
-	map_fd = bpf_map__fd(map);
-	if (map_fd < 0) {
-		pr_debug("ERROR: failed to get fd from map %s\n", name);
-		return map_fd;
-	}
-
-	type = bpf_map__type(map);
-	list_for_each_entry(op, &priv->ops_list, list) {
-		switch (type) {
-		case BPF_MAP_TYPE_ARRAY:
-		case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
-			switch (op->key_type) {
-			case BPF_MAP_KEY_ALL:
-				err = foreach_key_array_all(func, arg, name,
-							    map_fd, map, op);
-				break;
-			default:
-				pr_debug("ERROR: keytype for map '%s' invalid\n",
-					 name);
-				return -BPF_LOADER_ERRNO__INTERNAL;
-			}
-			if (err)
-				return err;
-			break;
-		default:
-			pr_debug("ERROR: type of '%s' incorrect\n", name);
-			return -BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE;
-		}
-	}
-
-	return 0;
-}
-
-static int
-apply_config_value_for_key(int map_fd, void *pkey,
-			   size_t val_size, u64 val)
-{
-	int err = 0;
-
-	switch (val_size) {
-	case 1: {
-		u8 _val = (u8)(val);
-		err = bpf_map_update_elem(map_fd, pkey, &_val, BPF_ANY);
-		break;
-	}
-	case 2: {
-		u16 _val = (u16)(val);
-		err = bpf_map_update_elem(map_fd, pkey, &_val, BPF_ANY);
-		break;
-	}
-	case 4: {
-		u32 _val = (u32)(val);
-		err = bpf_map_update_elem(map_fd, pkey, &_val, BPF_ANY);
-		break;
-	}
-	case 8: {
-		err = bpf_map_update_elem(map_fd, pkey, &val, BPF_ANY);
-		break;
-	}
-	default:
-		pr_debug("ERROR: invalid value size\n");
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE;
-	}
-	if (err && errno)
-		err = -errno;
-	return err;
-}
-
-static int
-apply_config_evsel_for_key(const char *name, int map_fd, void *pkey,
-			   struct evsel *evsel)
-{
-	struct xyarray *xy = evsel->core.fd;
-	struct perf_event_attr *attr;
-	unsigned int key, events;
-	bool check_pass = false;
-	int *evt_fd;
-	int err;
-
-	if (!xy) {
-		pr_debug("ERROR: evsel not ready for map %s\n", name);
-		return -BPF_LOADER_ERRNO__INTERNAL;
-	}
-
-	if (xy->row_size / xy->entry_size != 1) {
-		pr_debug("ERROR: Dimension of target event is incorrect for map %s\n",
-			 name);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM;
-	}
-
-	attr = &evsel->core.attr;
-	if (attr->inherit) {
-		pr_debug("ERROR: Can't put inherit event into map %s\n", name);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH;
-	}
-
-	if (evsel__is_bpf_output(evsel))
-		check_pass = true;
-	if (attr->type == PERF_TYPE_RAW)
-		check_pass = true;
-	if (attr->type == PERF_TYPE_HARDWARE)
-		check_pass = true;
-	if (!check_pass) {
-		pr_debug("ERROR: Event type is wrong for map %s\n", name);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTTYPE;
-	}
-
-	events = xy->entries / (xy->row_size / xy->entry_size);
-	key = *((unsigned int *)pkey);
-	if (key >= events) {
-		pr_debug("ERROR: there is no event %d for map %s\n",
-			 key, name);
-		return -BPF_LOADER_ERRNO__OBJCONF_MAP_MAPSIZE;
-	}
-	evt_fd = xyarray__entry(xy, key, 0);
-	err = bpf_map_update_elem(map_fd, pkey, evt_fd, BPF_ANY);
-	if (err && errno)
-		err = -errno;
-	return err;
-}
-
-static int
-apply_obj_config_map_for_key(const char *name, int map_fd,
-			     const struct bpf_map *map,
-			     struct bpf_map_op *op,
-			     void *pkey, void *arg __maybe_unused)
-{
-	int err;
-
-	switch (op->op_type) {
-	case BPF_MAP_OP_SET_VALUE:
-		err = apply_config_value_for_key(map_fd, pkey,
-						 bpf_map__value_size(map),
-						 op->v.value);
-		break;
-	case BPF_MAP_OP_SET_EVSEL:
-		err = apply_config_evsel_for_key(name, map_fd, pkey,
-						 op->v.evsel);
-		break;
-	default:
-		pr_debug("ERROR: unknown value type for '%s'\n", name);
-		err = -BPF_LOADER_ERRNO__INTERNAL;
-	}
-	return err;
-}
-
-static int
-apply_obj_config_map(struct bpf_map *map)
-{
-	return bpf_map_config_foreach_key(map,
-					  apply_obj_config_map_for_key,
-					  NULL);
-}
-
-static int
-apply_obj_config_object(struct bpf_object *obj)
-{
-	struct bpf_map *map;
-	int err;
-
-	bpf_object__for_each_map(map, obj) {
-		err = apply_obj_config_map(map);
-		if (err)
-			return err;
-	}
-	return 0;
-}
-
-int bpf__apply_obj_config(void)
-{
-	struct bpf_perf_object *perf_obj, *tmp;
-	int err;
-
-	bpf_perf_object__for_each(perf_obj, tmp) {
-		err = apply_obj_config_object(perf_obj->obj);
-		if (err)
-			return err;
-	}
-
-	return 0;
-}
-
-#define bpf__perf_for_each_map(map, pobj, tmp)			\
-	bpf_perf_object__for_each(pobj, tmp)			\
-		bpf_object__for_each_map(map, pobj->obj)
-
-#define bpf__perf_for_each_map_named(map, pobj, pobjtmp, name)	\
-	bpf__perf_for_each_map(map, pobj, pobjtmp)		\
-		if (bpf_map__name(map) && (strcmp(name, bpf_map__name(map)) == 0))
-
-struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
-{
-	struct bpf_map_priv *tmpl_priv = NULL;
-	struct bpf_perf_object *perf_obj, *tmp;
-	struct evsel *evsel = NULL;
-	struct bpf_map *map;
-	int err;
-	bool need_init = false;
-
-	bpf__perf_for_each_map_named(map, perf_obj, tmp, name) {
-		struct bpf_map_priv *priv = map_priv(map);
-
-		if (IS_ERR(priv))
-			return ERR_PTR(-BPF_LOADER_ERRNO__INTERNAL);
-
-		/*
-		 * No need to check map type: type should have been
-		 * verified by kernel.
-		 */
-		if (!need_init && !priv)
-			need_init = !priv;
-		if (!tmpl_priv && priv)
-			tmpl_priv = priv;
-	}
-
-	if (!need_init)
-		return NULL;
-
-	if (!tmpl_priv) {
-		char *event_definition = NULL;
-
-		if (asprintf(&event_definition, "bpf-output/no-inherit=1,name=%s/", name) < 0)
-			return ERR_PTR(-ENOMEM);
-
-		err = parse_event(evlist, event_definition);
-		free(event_definition);
-
-		if (err) {
-			pr_debug("ERROR: failed to create the \"%s\" bpf-output event\n", name);
-			return ERR_PTR(-err);
-		}
-
-		evsel = evlist__last(evlist);
-	}
-
-	bpf__perf_for_each_map_named(map, perf_obj, tmp, name) {
-		struct bpf_map_priv *priv = map_priv(map);
-
-		if (IS_ERR(priv))
-			return ERR_PTR(-BPF_LOADER_ERRNO__INTERNAL);
-		if (priv)
-			continue;
-
-		if (tmpl_priv) {
-			priv = bpf_map_priv__clone(tmpl_priv);
-			if (!priv)
-				return ERR_PTR(-ENOMEM);
-
-			err = map_set_priv(map, priv);
-			if (err) {
-				bpf_map_priv__clear(map, priv);
-				return ERR_PTR(err);
-			}
-		} else if (evsel) {
-			struct bpf_map_op *op;
-
-			op = bpf_map__add_newop(map, NULL);
-			if (IS_ERR(op))
-				return ERR_CAST(op);
-			op->op_type = BPF_MAP_OP_SET_EVSEL;
-			op->v.evsel = evsel;
-		}
-	}
-
-	return evsel;
-}
-
-int bpf__setup_stdout(struct evlist *evlist)
-{
-	struct evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__");
-	return PTR_ERR_OR_ZERO(evsel);
-}
-
-#define ERRNO_OFFSET(e)		((e) - __BPF_LOADER_ERRNO__START)
-#define ERRCODE_OFFSET(c)	ERRNO_OFFSET(BPF_LOADER_ERRNO__##c)
-#define NR_ERRNO	(__BPF_LOADER_ERRNO__END - __BPF_LOADER_ERRNO__START)
-
-static const char *bpf_loader_strerror_table[NR_ERRNO] = {
-	[ERRCODE_OFFSET(CONFIG)]	= "Invalid config string",
-	[ERRCODE_OFFSET(GROUP)]		= "Invalid group name",
-	[ERRCODE_OFFSET(EVENTNAME)]	= "No event name found in config string",
-	[ERRCODE_OFFSET(INTERNAL)]	= "BPF loader internal error",
-	[ERRCODE_OFFSET(COMPILE)]	= "Error when compiling BPF scriptlet",
-	[ERRCODE_OFFSET(PROGCONF_TERM)]	= "Invalid program config term in config string",
-	[ERRCODE_OFFSET(PROLOGUE)]	= "Failed to generate prologue",
-	[ERRCODE_OFFSET(PROLOGUE2BIG)]	= "Prologue too big for program",
-	[ERRCODE_OFFSET(PROLOGUEOOB)]	= "Offset out of bound for prologue",
-	[ERRCODE_OFFSET(OBJCONF_OPT)]	= "Invalid object config option",
-	[ERRCODE_OFFSET(OBJCONF_CONF)]	= "Config value not set (missing '=')",
-	[ERRCODE_OFFSET(OBJCONF_MAP_OPT)]	= "Invalid object map config option",
-	[ERRCODE_OFFSET(OBJCONF_MAP_NOTEXIST)]	= "Target map doesn't exist",
-	[ERRCODE_OFFSET(OBJCONF_MAP_VALUE)]	= "Incorrect value type for map",
-	[ERRCODE_OFFSET(OBJCONF_MAP_TYPE)]	= "Incorrect map type",
-	[ERRCODE_OFFSET(OBJCONF_MAP_KEYSIZE)]	= "Incorrect map key size",
-	[ERRCODE_OFFSET(OBJCONF_MAP_VALUESIZE)]	= "Incorrect map value size",
-	[ERRCODE_OFFSET(OBJCONF_MAP_NOEVT)]	= "Event not found for map setting",
-	[ERRCODE_OFFSET(OBJCONF_MAP_MAPSIZE)]	= "Invalid map size for event setting",
-	[ERRCODE_OFFSET(OBJCONF_MAP_EVTDIM)]	= "Event dimension too large",
-	[ERRCODE_OFFSET(OBJCONF_MAP_EVTINH)]	= "Doesn't support inherit event",
-	[ERRCODE_OFFSET(OBJCONF_MAP_EVTTYPE)]	= "Wrong event type for map",
-	[ERRCODE_OFFSET(OBJCONF_MAP_IDX2BIG)]	= "Index too large",
-};
-
-static int
-bpf_loader_strerror(int err, char *buf, size_t size)
-{
-	char sbuf[STRERR_BUFSIZE];
-	const char *msg;
-
-	if (!buf || !size)
-		return -1;
-
-	err = err > 0 ? err : -err;
-
-	if (err >= __LIBBPF_ERRNO__START)
-		return libbpf_strerror(err, buf, size);
-
-	if (err >= __BPF_LOADER_ERRNO__START && err < __BPF_LOADER_ERRNO__END) {
-		msg = bpf_loader_strerror_table[ERRNO_OFFSET(err)];
-		snprintf(buf, size, "%s", msg);
-		buf[size - 1] = '\0';
-		return 0;
-	}
-
-	if (err >= __BPF_LOADER_ERRNO__END)
-		snprintf(buf, size, "Unknown bpf loader error %d", err);
-	else
-		snprintf(buf, size, "%s",
-			 str_error_r(err, sbuf, sizeof(sbuf)));
-
-	buf[size - 1] = '\0';
-	return -1;
-}
-
-#define bpf__strerror_head(err, buf, size) \
-	char sbuf[STRERR_BUFSIZE], *emsg;\
-	if (!size)\
-		return 0;\
-	if (err < 0)\
-		err = -err;\
-	bpf_loader_strerror(err, sbuf, sizeof(sbuf));\
-	emsg = sbuf;\
-	switch (err) {\
-	default:\
-		scnprintf(buf, size, "%s", emsg);\
-		break;
-
-#define bpf__strerror_entry(val, fmt...)\
-	case val: {\
-		scnprintf(buf, size, fmt);\
-		break;\
-	}
-
-#define bpf__strerror_end(buf, size)\
-	}\
-	buf[size - 1] = '\0';
-
-int bpf__strerror_prepare_load(const char *filename, bool source,
-			       int err, char *buf, size_t size)
-{
-	size_t n;
-	int ret;
-
-	n = snprintf(buf, size, "Failed to load %s%s: ",
-			 filename, source ? " from source" : "");
-	if (n >= size) {
-		buf[size - 1] = '\0';
-		return 0;
-	}
-	buf += n;
-	size -= n;
-
-	ret = bpf_loader_strerror(err, buf, size);
-	buf[size - 1] = '\0';
-	return ret;
-}
-
-int bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
-			int err, char *buf, size_t size)
-{
-	bpf__strerror_head(err, buf, size);
-	case BPF_LOADER_ERRNO__PROGCONF_TERM: {
-		scnprintf(buf, size, "%s (add -v to see detail)", emsg);
-		break;
-	}
-	bpf__strerror_entry(EEXIST, "Probe point exist. Try 'perf probe -d \"*\"' and set 'force=yes'");
-	bpf__strerror_entry(EACCES, "You need to be root");
-	bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0");
-	bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file");
-	bpf__strerror_end(buf, size);
-	return 0;
-}
-
-int bpf__strerror_load(struct bpf_object *obj,
-		       int err, char *buf, size_t size)
-{
-	bpf__strerror_head(err, buf, size);
-	case LIBBPF_ERRNO__KVER: {
-		unsigned int obj_kver = bpf_object__kversion(obj);
-		unsigned int real_kver;
-
-		if (fetch_kernel_version(&real_kver, NULL, 0)) {
-			scnprintf(buf, size, "Unable to fetch kernel version");
-			break;
-		}
-
-		if (obj_kver != real_kver) {
-			scnprintf(buf, size,
-				  "'version' ("KVER_FMT") doesn't match running kernel ("KVER_FMT")",
-				  KVER_PARAM(obj_kver),
-				  KVER_PARAM(real_kver));
-			break;
-		}
-
-		scnprintf(buf, size, "Failed to load program for unknown reason");
-		break;
-	}
-	bpf__strerror_end(buf, size);
-	return 0;
-}
-
-int bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused,
-			     struct parse_events_term *term __maybe_unused,
-			     struct evlist *evlist __maybe_unused,
-			     int *error_pos __maybe_unused, int err,
-			     char *buf, size_t size)
-{
-	bpf__strerror_head(err, buf, size);
-	bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE,
-			    "Can't use this config term with this map type");
-	bpf__strerror_end(buf, size);
-	return 0;
-}
-
-int bpf__strerror_apply_obj_config(int err, char *buf, size_t size)
-{
-	bpf__strerror_head(err, buf, size);
-	bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM,
-			    "Cannot set event to BPF map in multi-thread tracing");
-	bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH,
-			    "%s (Hint: use -i to turn off inherit)", emsg);
-	bpf__strerror_entry(BPF_LOADER_ERRNO__OBJCONF_MAP_EVTTYPE,
-			    "Can only put raw, hardware and BPF output event into a BPF map");
-	bpf__strerror_end(buf, size);
-	return 0;
-}
-
-int bpf__strerror_setup_output_event(struct evlist *evlist __maybe_unused,
-				     int err, char *buf, size_t size)
-{
-	bpf__strerror_head(err, buf, size);
-	bpf__strerror_end(buf, size);
-	return 0;
-}
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
deleted file mode 100644
index 5d1c725cea29..000000000000
--- a/tools/perf/util/bpf-loader.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com>
- * Copyright (C) 2015, Huawei Inc.
- */
-#ifndef __BPF_LOADER_H
-#define __BPF_LOADER_H
-
-#include <linux/compiler.h>
-#include <linux/err.h>
-
-#ifdef HAVE_LIBBPF_SUPPORT
-#include <bpf/libbpf.h>
-
-enum bpf_loader_errno {
-	__BPF_LOADER_ERRNO__START = __LIBBPF_ERRNO__START - 100,
-	/* Invalid config string */
-	BPF_LOADER_ERRNO__CONFIG = __BPF_LOADER_ERRNO__START,
-	BPF_LOADER_ERRNO__GROUP,	/* Invalid group name */
-	BPF_LOADER_ERRNO__EVENTNAME,	/* Event name is missing */
-	BPF_LOADER_ERRNO__INTERNAL,	/* BPF loader internal error */
-	BPF_LOADER_ERRNO__COMPILE,	/* Error when compiling BPF scriptlet */
-	BPF_LOADER_ERRNO__PROGCONF_TERM,/* Invalid program config term in config string */
-	BPF_LOADER_ERRNO__PROLOGUE,	/* Failed to generate prologue */
-	BPF_LOADER_ERRNO__PROLOGUE2BIG,	/* Prologue too big for program */
-	BPF_LOADER_ERRNO__PROLOGUEOOB,	/* Offset out of bound for prologue */
-	BPF_LOADER_ERRNO__OBJCONF_OPT,	/* Invalid object config option */
-	BPF_LOADER_ERRNO__OBJCONF_CONF,	/* Config value not set (lost '=')) */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_OPT,	/* Invalid object map config option */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_NOTEXIST,	/* Target map not exist */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE,	/* Incorrect value type for map */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_TYPE,	/* Incorrect map type */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_KEYSIZE,	/* Incorrect map key size */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_VALUESIZE,/* Incorrect map value size */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_NOEVT,	/* Event not found for map setting */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_MAPSIZE,	/* Invalid map size for event setting */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM,	/* Event dimension too large */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH,	/* Doesn't support inherit event */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_EVTTYPE,	/* Wrong event type for map */
-	BPF_LOADER_ERRNO__OBJCONF_MAP_IDX2BIG,	/* Index too large */
-	__BPF_LOADER_ERRNO__END,
-};
-#endif // HAVE_LIBBPF_SUPPORT
-
-struct evsel;
-struct evlist;
-struct bpf_object;
-struct parse_events_term;
-#define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
-
-typedef int (*bpf_prog_iter_callback_t)(const char *group, const char *event,
-					int fd, struct bpf_object *obj, void *arg);
-
-#ifdef HAVE_LIBBPF_SUPPORT
-struct bpf_object *bpf__prepare_load(const char *filename, bool source);
-int bpf__strerror_prepare_load(const char *filename, bool source,
-			       int err, char *buf, size_t size);
-
-struct bpf_object *bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz,
-					    const char *name);
-
-void bpf__clear(void);
-
-int bpf__probe(struct bpf_object *obj);
-int bpf__unprobe(struct bpf_object *obj);
-int bpf__strerror_probe(struct bpf_object *obj, int err,
-			char *buf, size_t size);
-
-int bpf__load(struct bpf_object *obj);
-int bpf__strerror_load(struct bpf_object *obj, int err,
-		       char *buf, size_t size);
-int bpf__foreach_event(struct bpf_object *obj,
-		       bpf_prog_iter_callback_t func, void *arg);
-
-int bpf__config_obj(struct bpf_object *obj, struct parse_events_term *term,
-		    struct evlist *evlist, int *error_pos);
-int bpf__strerror_config_obj(struct bpf_object *obj,
-			     struct parse_events_term *term,
-			     struct evlist *evlist,
-			     int *error_pos, int err, char *buf,
-			     size_t size);
-int bpf__apply_obj_config(void);
-int bpf__strerror_apply_obj_config(int err, char *buf, size_t size);
-
-int bpf__setup_stdout(struct evlist *evlist);
-struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name);
-int bpf__strerror_setup_output_event(struct evlist *evlist, int err, char *buf, size_t size);
-#else
-#include <errno.h>
-#include <string.h>
-#include "debug.h"
-
-static inline struct bpf_object *
-bpf__prepare_load(const char *filename __maybe_unused,
-		  bool source __maybe_unused)
-{
-	pr_debug("ERROR: eBPF object loading is disabled during compiling.\n");
-	return ERR_PTR(-ENOTSUP);
-}
-
-static inline struct bpf_object *
-bpf__prepare_load_buffer(void *obj_buf __maybe_unused,
-					   size_t obj_buf_sz __maybe_unused)
-{
-	return ERR_PTR(-ENOTSUP);
-}
-
-static inline void bpf__clear(void) { }
-
-static inline int bpf__probe(struct bpf_object *obj __maybe_unused) { return 0;}
-static inline int bpf__unprobe(struct bpf_object *obj __maybe_unused) { return 0;}
-static inline int bpf__load(struct bpf_object *obj __maybe_unused) { return 0; }
-
-static inline int
-bpf__foreach_event(struct bpf_object *obj __maybe_unused,
-		   bpf_prog_iter_callback_t func __maybe_unused,
-		   void *arg __maybe_unused)
-{
-	return 0;
-}
-
-static inline int
-bpf__config_obj(struct bpf_object *obj __maybe_unused,
-		struct parse_events_term *term __maybe_unused,
-		struct evlist *evlist __maybe_unused,
-		int *error_pos __maybe_unused)
-{
-	return 0;
-}
-
-static inline int
-bpf__apply_obj_config(void)
-{
-	return 0;
-}
-
-static inline int
-bpf__setup_stdout(struct evlist *evlist __maybe_unused)
-{
-	return 0;
-}
-
-static inline struct evsel *
-bpf__setup_output_event(struct evlist *evlist __maybe_unused, const char *name __maybe_unused)
-{
-	return NULL;
-}
-
-static inline int
-__bpf_strerror(char *buf, size_t size)
-{
-	if (!size)
-		return 0;
-	strncpy(buf,
-		"ERROR: eBPF object loading is disabled during compiling.\n",
-		size);
-	buf[size - 1] = '\0';
-	return 0;
-}
-
-static inline
-int bpf__strerror_prepare_load(const char *filename __maybe_unused,
-			       bool source __maybe_unused,
-			       int err __maybe_unused,
-			       char *buf, size_t size)
-{
-	return __bpf_strerror(buf, size);
-}
-
-static inline int
-bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
-		    int err __maybe_unused,
-		    char *buf, size_t size)
-{
-	return __bpf_strerror(buf, size);
-}
-
-static inline int bpf__strerror_load(struct bpf_object *obj __maybe_unused,
-				     int err __maybe_unused,
-				     char *buf, size_t size)
-{
-	return __bpf_strerror(buf, size);
-}
-
-static inline int
-bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused,
-			 struct parse_events_term *term __maybe_unused,
-			 struct evlist *evlist __maybe_unused,
-			 int *error_pos __maybe_unused,
-			 int err __maybe_unused,
-			 char *buf, size_t size)
-{
-	return __bpf_strerror(buf, size);
-}
-
-static inline int
-bpf__strerror_apply_obj_config(int err __maybe_unused,
-			       char *buf, size_t size)
-{
-	return __bpf_strerror(buf, size);
-}
-
-static inline int
-bpf__strerror_setup_output_event(struct evlist *evlist __maybe_unused,
-				 int err __maybe_unused, char *buf, size_t size)
-{
-	return __bpf_strerror(buf, size);
-}
-
-#endif
-
-static inline int bpf__strerror_setup_stdout(struct evlist *evlist, int err, char *buf, size_t size)
-{
-	return bpf__strerror_setup_output_event(evlist, err, buf, size);
-}
-#endif
diff --git a/tools/perf/util/c++/Build b/tools/perf/util/c++/Build
deleted file mode 100644
index 8610d032ac19..000000000000
--- a/tools/perf/util/c++/Build
+++ /dev/null
@@ -1,5 +0,0 @@
-perf-$(CONFIG_CLANGLLVM) += clang.o
-perf-$(CONFIG_CLANGLLVM) += clang-test.o
-
-CXXFLAGS_clang.o += -Wno-unused-parameter
-CXXFLAGS_clang-test.o += -Wno-unused-parameter
diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h
deleted file mode 100644
index d3731a876b6c..000000000000
--- a/tools/perf/util/c++/clang-c.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef PERF_UTIL_CLANG_C_H
-#define PERF_UTIL_CLANG_C_H
-
-#include <stddef.h>	/* for size_t */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef HAVE_LIBCLANGLLVM_SUPPORT
-extern void perf_clang__init(void);
-extern void perf_clang__cleanup(void);
-
-struct test_suite;
-extern int test__clang_to_IR(struct test_suite *test, int subtest);
-extern int test__clang_to_obj(struct test_suite *test, int subtest);
-
-extern int perf_clang__compile_bpf(const char *filename,
-				   void **p_obj_buf,
-				   size_t *p_obj_buf_sz);
-#else
-
-#include <errno.h>
-#include <linux/compiler.h>	/* for __maybe_unused */
-
-static inline void perf_clang__init(void) { }
-static inline void perf_clang__cleanup(void) { }
-
-static inline int
-perf_clang__compile_bpf(const char *filename __maybe_unused,
-			void **p_obj_buf __maybe_unused,
-			size_t *p_obj_buf_sz __maybe_unused)
-{
-	return -ENOTSUP;
-}
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/tools/perf/util/c++/clang-test.cpp b/tools/perf/util/c++/clang-test.cpp
deleted file mode 100644
index a4683ca53697..000000000000
--- a/tools/perf/util/c++/clang-test.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "clang.h"
-#include "clang-c.h"
-extern "C" {
-#include "../util.h"
-}
-#include "llvm/IR/Function.h"
-#include "llvm/IR/LLVMContext.h"
-
-#include <tests/llvm.h>
-#include <string>
-
-class perf_clang_scope {
-public:
-	explicit perf_clang_scope() {perf_clang__init();}
-	~perf_clang_scope() {perf_clang__cleanup();}
-};
-
-static std::unique_ptr<llvm::Module>
-__test__clang_to_IR(void)
-{
-	unsigned int kernel_version;
-
-	if (fetch_kernel_version(&kernel_version, NULL, 0))
-		return std::unique_ptr<llvm::Module>(nullptr);
-
-	std::string cflag_kver("-DLINUX_VERSION_CODE=" +
-				std::to_string(kernel_version));
-
-	std::unique_ptr<llvm::Module> M =
-		perf::getModuleFromSource({cflag_kver.c_str()},
-					  "perf-test.c",
-					  test_llvm__bpf_base_prog);
-	return M;
-}
-
-extern "C" {
-int test__clang_to_IR(struct test_suite *test __maybe_unused,
-                      int subtest __maybe_unused)
-{
-	perf_clang_scope _scope;
-
-	auto M = __test__clang_to_IR();
-	if (!M)
-		return -1;
-	for (llvm::Function& F : *M)
-		if (F.getName() == "bpf_func__SyS_epoll_pwait")
-			return 0;
-	return -1;
-}
-
-int test__clang_to_obj(struct test_suite *test __maybe_unused,
-                       int subtest __maybe_unused)
-{
-	perf_clang_scope _scope;
-
-	auto M = __test__clang_to_IR();
-	if (!M)
-		return -1;
-
-	auto Buffer = perf::getBPFObjectFromModule(&*M);
-	if (!Buffer)
-		return -1;
-	return 0;
-}
-
-}
diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp
deleted file mode 100644
index 1aad7d6d34aa..000000000000
--- a/tools/perf/util/c++/clang.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * llvm C frontend for perf. Support dynamically compile C file
- *
- * Inspired by clang example code:
- * http://llvm.org/svn/llvm-project/cfe/trunk/examples/clang-interpreter/main.cpp
- *
- * Copyright (C) 2016 Wang Nan <wangnan0@huawei.com>
- * Copyright (C) 2016 Huawei Inc.
- */
-
-#include "clang/Basic/Version.h"
-#include "clang/CodeGen/CodeGenAction.h"
-#include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/ManagedStatic.h"
-#if CLANG_VERSION_MAJOR >= 14
-#include "llvm/MC/TargetRegistry.h"
-#else
-#include "llvm/Support/TargetRegistry.h"
-#endif
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
-#include <memory>
-
-#include "clang.h"
-#include "clang-c.h"
-
-namespace perf {
-
-static std::unique_ptr<llvm::LLVMContext> LLVMCtx;
-
-using namespace clang;
-
-static CompilerInvocation *
-createCompilerInvocation(llvm::opt::ArgStringList CFlags, StringRef& Path,
-			 DiagnosticsEngine& Diags)
-{
-	llvm::opt::ArgStringList CCArgs {
-		"-cc1",
-		"-triple", "bpf-pc-linux",
-		"-fsyntax-only",
-		"-O2",
-		"-nostdsysteminc",
-		"-nobuiltininc",
-		"-vectorize-loops",
-		"-vectorize-slp",
-		"-Wno-unused-value",
-		"-Wno-pointer-sign",
-		"-x", "c"};
-
-	CCArgs.append(CFlags.begin(), CFlags.end());
-	CompilerInvocation *CI = tooling::newInvocation(&Diags, CCArgs
-#if CLANG_VERSION_MAJOR >= 11
-                                                        ,/*BinaryName=*/nullptr
-#endif
-                                                        );
-
-	FrontendOptions& Opts = CI->getFrontendOpts();
-	Opts.Inputs.clear();
-	Opts.Inputs.emplace_back(Path,
-			FrontendOptions::getInputKindForExtension("c"));
-	return CI;
-}
-
-static std::unique_ptr<llvm::Module>
-getModuleFromSource(llvm::opt::ArgStringList CFlags,
-		    StringRef Path, IntrusiveRefCntPtr<vfs::FileSystem> VFS)
-{
-	CompilerInstance Clang;
-	Clang.createDiagnostics();
-
-#if CLANG_VERSION_MAJOR < 9
-	Clang.setVirtualFileSystem(&*VFS);
-#else
-	Clang.createFileManager(&*VFS);
-#endif
-
-#if CLANG_VERSION_MAJOR < 4
-	IntrusiveRefCntPtr<CompilerInvocation> CI =
-		createCompilerInvocation(std::move(CFlags), Path,
-					 Clang.getDiagnostics());
-	Clang.setInvocation(&*CI);
-#else
-	std::shared_ptr<CompilerInvocation> CI(
-		createCompilerInvocation(std::move(CFlags), Path,
-					 Clang.getDiagnostics()));
-	Clang.setInvocation(CI);
-#endif
-
-	std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction(&*LLVMCtx));
-	if (!Clang.ExecuteAction(*Act))
-		return std::unique_ptr<llvm::Module>(nullptr);
-
-	return Act->takeModule();
-}
-
-std::unique_ptr<llvm::Module>
-getModuleFromSource(llvm::opt::ArgStringList CFlags,
-		    StringRef Name, StringRef Content)
-{
-	using namespace vfs;
-
-	llvm::IntrusiveRefCntPtr<OverlayFileSystem> OverlayFS(
-			new OverlayFileSystem(getRealFileSystem()));
-	llvm::IntrusiveRefCntPtr<InMemoryFileSystem> MemFS(
-			new InMemoryFileSystem(true));
-
-	/*
-	 * pushOverlay helps setting working dir for MemFS. Must call
-	 * before addFile.
-	 */
-	OverlayFS->pushOverlay(MemFS);
-	MemFS->addFile(Twine(Name), 0, llvm::MemoryBuffer::getMemBuffer(Content));
-
-	return getModuleFromSource(std::move(CFlags), Name, OverlayFS);
-}
-
-std::unique_ptr<llvm::Module>
-getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path)
-{
-	IntrusiveRefCntPtr<vfs::FileSystem> VFS(vfs::getRealFileSystem());
-	return getModuleFromSource(std::move(CFlags), Path, VFS);
-}
-
-std::unique_ptr<llvm::SmallVectorImpl<char>>
-getBPFObjectFromModule(llvm::Module *Module)
-{
-	using namespace llvm;
-
-	std::string TargetTriple("bpf-pc-linux");
-	std::string Error;
-	const Target* Target = TargetRegistry::lookupTarget(TargetTriple, Error);
-	if (!Target) {
-		llvm::errs() << Error;
-		return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);
-	}
-
-	llvm::TargetOptions Opt;
-	TargetMachine *TargetMachine =
-		Target->createTargetMachine(TargetTriple,
-					    "generic", "",
-					    Opt, Reloc::Static);
-
-	Module->setDataLayout(TargetMachine->createDataLayout());
-	Module->setTargetTriple(TargetTriple);
-
-	std::unique_ptr<SmallVectorImpl<char>> Buffer(new SmallVector<char, 0>());
-	raw_svector_ostream ostream(*Buffer);
-
-	legacy::PassManager PM;
-	bool NotAdded;
-	NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream
-#if CLANG_VERSION_MAJOR >= 7
-                                                      , /*DwoOut=*/nullptr
-#endif
-#if CLANG_VERSION_MAJOR < 10
-                                                      , TargetMachine::CGFT_ObjectFile
-#else
-                                                      , llvm::CGFT_ObjectFile
-#endif
-                                                      );
-	if (NotAdded) {
-		llvm::errs() << "TargetMachine can't emit a file of this type\n";
-		return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);
-	}
-	PM.run(*Module);
-
-	return Buffer;
-}
-
-}
-
-extern "C" {
-void perf_clang__init(void)
-{
-	perf::LLVMCtx.reset(new llvm::LLVMContext());
-	LLVMInitializeBPFTargetInfo();
-	LLVMInitializeBPFTarget();
-	LLVMInitializeBPFTargetMC();
-	LLVMInitializeBPFAsmPrinter();
-}
-
-void perf_clang__cleanup(void)
-{
-	perf::LLVMCtx.reset(nullptr);
-	llvm::llvm_shutdown();
-}
-
-int perf_clang__compile_bpf(const char *filename,
-			    void **p_obj_buf,
-			    size_t *p_obj_buf_sz)
-{
-	using namespace perf;
-
-	if (!p_obj_buf || !p_obj_buf_sz)
-		return -EINVAL;
-
-	llvm::opt::ArgStringList CFlags;
-	auto M = getModuleFromSource(std::move(CFlags), filename);
-	if (!M)
-		return  -EINVAL;
-	auto O = getBPFObjectFromModule(&*M);
-	if (!O)
-		return -EINVAL;
-
-	size_t size = O->size_in_bytes();
-	void *buffer;
-
-	buffer = malloc(size);
-	if (!buffer)
-		return -ENOMEM;
-	memcpy(buffer, O->data(), size);
-	*p_obj_buf = buffer;
-	*p_obj_buf_sz = size;
-	return 0;
-}
-}
diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h
deleted file mode 100644
index 6ce33e22f23c..000000000000
--- a/tools/perf/util/c++/clang.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef PERF_UTIL_CLANG_H
-#define PERF_UTIL_CLANG_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Option/Option.h"
-#include <memory>
-
-namespace perf {
-
-using namespace llvm;
-
-std::unique_ptr<Module>
-getModuleFromSource(opt::ArgStringList CFlags,
-		    StringRef Name, StringRef Content);
-
-std::unique_ptr<Module>
-getModuleFromSource(opt::ArgStringList CFlags,
-		    StringRef Path);
-
-std::unique_ptr<llvm::SmallVectorImpl<char>>
-getBPFObjectFromModule(llvm::Module *Module);
-
-}
-#endif
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 46f144c46827..7a650de0db83 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -16,7 +16,6 @@
 #include <subcmd/exec-cmd.h>
 #include "util/event.h"  /* proc_map_timeout */
 #include "util/hist.h"  /* perf_hist_config */
-#include "util/llvm-utils.h"   /* perf_llvm_config */
 #include "util/stat.h"  /* perf_stat__set_big_num */
 #include "util/evsel.h"  /* evsel__hw_names, evsel__use_bpf_counters */
 #include "util/srcline.h"  /* addr2line_timeout_ms */
@@ -486,9 +485,6 @@ int perf_default_config(const char *var, const char *value,
 	if (strstarts(var, "call-graph."))
 		return perf_callchain_config(var, value);
 
-	if (strstarts(var, "llvm."))
-		return perf_llvm_config(var, value);
-
 	if (strstarts(var, "buildid."))
 		return perf_buildid_config(var, value);
 
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
deleted file mode 100644
index c6c9c2228578..000000000000
--- a/tools/perf/util/llvm-utils.c
+++ /dev/null
@@ -1,612 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com>
- * Copyright (C) 2015, Huawei Inc.
- */
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/zalloc.h>
-#include "debug.h"
-#include "llvm-utils.h"
-#include "config.h"
-#include "util.h"
-#include <sys/wait.h>
-#include <subcmd/exec-cmd.h>
-
-#define CLANG_BPF_CMD_DEFAULT_TEMPLATE				\
-		"$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
-		"-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE "	\
-		"$CLANG_OPTIONS $PERF_BPF_INC_OPTIONS $KERNEL_INC_OPTIONS " \
-		"-Wno-unused-value -Wno-pointer-sign "		\
-		"-working-directory $WORKING_DIR "		\
-		"-c \"$CLANG_SOURCE\" --target=bpf $CLANG_EMIT_LLVM -g -O2 -o - $LLVM_OPTIONS_PIPE"
-
-struct llvm_param llvm_param = {
-	.clang_path = "clang",
-	.llc_path = "llc",
-	.clang_bpf_cmd_template = CLANG_BPF_CMD_DEFAULT_TEMPLATE,
-	.clang_opt = NULL,
-	.opts = NULL,
-	.kbuild_dir = NULL,
-	.kbuild_opts = NULL,
-	.user_set_param = false,
-};
-
-static void version_notice(void);
-
-int perf_llvm_config(const char *var, const char *value)
-{
-	if (!strstarts(var, "llvm."))
-		return 0;
-	var += sizeof("llvm.") - 1;
-
-	if (!strcmp(var, "clang-path"))
-		llvm_param.clang_path = strdup(value);
-	else if (!strcmp(var, "clang-bpf-cmd-template"))
-		llvm_param.clang_bpf_cmd_template = strdup(value);
-	else if (!strcmp(var, "clang-opt"))
-		llvm_param.clang_opt = strdup(value);
-	else if (!strcmp(var, "kbuild-dir"))
-		llvm_param.kbuild_dir = strdup(value);
-	else if (!strcmp(var, "kbuild-opts"))
-		llvm_param.kbuild_opts = strdup(value);
-	else if (!strcmp(var, "dump-obj"))
-		llvm_param.dump_obj = !!perf_config_bool(var, value);
-	else if (!strcmp(var, "opts"))
-		llvm_param.opts = strdup(value);
-	else {
-		pr_debug("Invalid LLVM config option: %s\n", value);
-		return -1;
-	}
-	llvm_param.user_set_param = true;
-	return 0;
-}
-
-static int
-search_program(const char *def, const char *name,
-	       char *output)
-{
-	char *env, *path, *tmp = NULL;
-	char buf[PATH_MAX];
-	int ret;
-
-	output[0] = '\0';
-	if (def && def[0] != '\0') {
-		if (def[0] == '/') {
-			if (access(def, F_OK) == 0) {
-				strlcpy(output, def, PATH_MAX);
-				return 0;
-			}
-		} else if (def[0] != '\0')
-			name = def;
-	}
-
-	env = getenv("PATH");
-	if (!env)
-		return -1;
-	env = strdup(env);
-	if (!env)
-		return -1;
-
-	ret = -ENOENT;
-	path = strtok_r(env, ":",  &tmp);
-	while (path) {
-		scnprintf(buf, sizeof(buf), "%s/%s", path, name);
-		if (access(buf, F_OK) == 0) {
-			strlcpy(output, buf, PATH_MAX);
-			ret = 0;
-			break;
-		}
-		path = strtok_r(NULL, ":", &tmp);
-	}
-
-	free(env);
-	return ret;
-}
-
-static int search_program_and_warn(const char *def, const char *name,
-				   char *output)
-{
-	int ret = search_program(def, name, output);
-
-	if (ret) {
-		pr_err("ERROR:\tunable to find %s.\n"
-		       "Hint:\tTry to install latest clang/llvm to support BPF. Check your $PATH\n"
-		       "     \tand '%s-path' option in [llvm] section of ~/.perfconfig.\n",
-		       name, name);
-		version_notice();
-	}
-	return ret;
-}
-
-#define READ_SIZE	4096
-static int
-read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
-{
-	int err = 0;
-	void *buf = NULL;
-	FILE *file = NULL;
-	size_t read_sz = 0, buf_sz = 0;
-	char serr[STRERR_BUFSIZE];
-
-	file = popen(cmd, "r");
-	if (!file) {
-		pr_err("ERROR: unable to popen cmd: %s\n",
-		       str_error_r(errno, serr, sizeof(serr)));
-		return -EINVAL;
-	}
-
-	while (!feof(file) && !ferror(file)) {
-		/*
-		 * Make buf_sz always have obe byte extra space so we
-		 * can put '\0' there.
-		 */
-		if (buf_sz - read_sz < READ_SIZE + 1) {
-			void *new_buf;
-
-			buf_sz = read_sz + READ_SIZE + 1;
-			new_buf = realloc(buf, buf_sz);
-
-			if (!new_buf) {
-				pr_err("ERROR: failed to realloc memory\n");
-				err = -ENOMEM;
-				goto errout;
-			}
-
-			buf = new_buf;
-		}
-		read_sz += fread(buf + read_sz, 1, READ_SIZE, file);
-	}
-
-	if (buf_sz - read_sz < 1) {
-		pr_err("ERROR: internal error\n");
-		err = -EINVAL;
-		goto errout;
-	}
-
-	if (ferror(file)) {
-		pr_err("ERROR: error occurred when reading from pipe: %s\n",
-		       str_error_r(errno, serr, sizeof(serr)));
-		err = -EIO;
-		goto errout;
-	}
-
-	err = WEXITSTATUS(pclose(file));
-	file = NULL;
-	if (err) {
-		err = -EINVAL;
-		goto errout;
-	}
-
-	/*
-	 * If buf is string, give it terminal '\0' to make our life
-	 * easier. If buf is not string, that '\0' is out of space
-	 * indicated by read_sz so caller won't even notice it.
-	 */
-	((char *)buf)[read_sz] = '\0';
-
-	if (!p_buf)
-		free(buf);
-	else
-		*p_buf = buf;
-
-	if (p_read_sz)
-		*p_read_sz = read_sz;
-	return 0;
-
-errout:
-	if (file)
-		pclose(file);
-	free(buf);
-	if (p_buf)
-		*p_buf = NULL;
-	if (p_read_sz)
-		*p_read_sz = 0;
-	return err;
-}
-
-static inline void
-force_set_env(const char *var, const char *value)
-{
-	if (value) {
-		setenv(var, value, 1);
-		pr_debug("set env: %s=%s\n", var, value);
-	} else {
-		unsetenv(var);
-		pr_debug("unset env: %s\n", var);
-	}
-}
-
-static void
-version_notice(void)
-{
-	pr_err(
-"     \tLLVM 3.7 or newer is required. Which can be found from http://llvm.org\n"
-"     \tYou may want to try git trunk:\n"
-"     \t\tgit clone http://llvm.org/git/llvm.git\n"
-"     \t\t     and\n"
-"     \t\tgit clone http://llvm.org/git/clang.git\n\n"
-"     \tOr fetch the latest clang/llvm 3.7 from pre-built llvm packages for\n"
-"     \tdebian/ubuntu:\n"
-"     \t\thttps://apt.llvm.org/\n\n"
-"     \tIf you are using old version of clang, change 'clang-bpf-cmd-template'\n"
-"     \toption in [llvm] section of ~/.perfconfig to:\n\n"
-"     \t  \"$CLANG_EXEC $CLANG_OPTIONS $KERNEL_INC_OPTIONS $PERF_BPF_INC_OPTIONS \\\n"
-"     \t     -working-directory $WORKING_DIR -c $CLANG_SOURCE \\\n"
-"     \t     -emit-llvm -o - | /path/to/llc -march=bpf -filetype=obj -o -\"\n"
-"     \t(Replace /path/to/llc with path to your llc)\n\n"
-);
-}
-
-static int detect_kbuild_dir(char **kbuild_dir)
-{
-	const char *test_dir = llvm_param.kbuild_dir;
-	const char *prefix_dir = "";
-	const char *suffix_dir = "";
-
-	/* _UTSNAME_LENGTH is 65 */
-	char release[128];
-
-	char *autoconf_path;
-
-	int err;
-
-	if (!test_dir) {
-		err = fetch_kernel_version(NULL, release,
-					   sizeof(release));
-		if (err)
-			return -EINVAL;
-
-		test_dir = release;
-		prefix_dir = "/lib/modules/";
-		suffix_dir = "/build";
-	}
-
-	err = asprintf(&autoconf_path, "%s%s%s/include/generated/autoconf.h",
-		       prefix_dir, test_dir, suffix_dir);
-	if (err < 0)
-		return -ENOMEM;
-
-	if (access(autoconf_path, R_OK) == 0) {
-		free(autoconf_path);
-
-		err = asprintf(kbuild_dir, "%s%s%s", prefix_dir, test_dir,
-			       suffix_dir);
-		if (err < 0)
-			return -ENOMEM;
-		return 0;
-	}
-	pr_debug("%s: Couldn't find \"%s\", missing kernel-devel package?.\n",
-		 __func__, autoconf_path);
-	free(autoconf_path);
-	return -ENOENT;
-}
-
-static const char *kinc_fetch_script =
-"#!/usr/bin/env sh\n"
-"if ! test -d \"$KBUILD_DIR\"\n"
-"then\n"
-"	exit 1\n"
-"fi\n"
-"if ! test -f \"$KBUILD_DIR/include/generated/autoconf.h\"\n"
-"then\n"
-"	exit 1\n"
-"fi\n"
-"TMPDIR=`mktemp -d`\n"
-"if test -z \"$TMPDIR\"\n"
-"then\n"
-"    exit 1\n"
-"fi\n"
-"cat << EOF > $TMPDIR/Makefile\n"
-"obj-y := dummy.o\n"
-"\\$(obj)/%.o: \\$(src)/%.c\n"
-"\t@echo -n \"\\$(NOSTDINC_FLAGS) \\$(LINUXINCLUDE) \\$(EXTRA_CFLAGS)\"\n"
-"\t\\$(CC) -c -o \\$@ \\$<\n"
-"EOF\n"
-"touch $TMPDIR/dummy.c\n"
-"make -s -C $KBUILD_DIR M=$TMPDIR $KBUILD_OPTS dummy.o 2>/dev/null\n"
-"RET=$?\n"
-"rm -rf $TMPDIR\n"
-"exit $RET\n";
-
-void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
-{
-	static char *saved_kbuild_dir;
-	static char *saved_kbuild_include_opts;
-	int err;
-
-	if (!kbuild_dir || !kbuild_include_opts)
-		return;
-
-	*kbuild_dir = NULL;
-	*kbuild_include_opts = NULL;
-
-	if (saved_kbuild_dir && saved_kbuild_include_opts &&
-	    !IS_ERR(saved_kbuild_dir) && !IS_ERR(saved_kbuild_include_opts)) {
-		*kbuild_dir = strdup(saved_kbuild_dir);
-		*kbuild_include_opts = strdup(saved_kbuild_include_opts);
-
-		if (*kbuild_dir && *kbuild_include_opts)
-			return;
-
-		zfree(kbuild_dir);
-		zfree(kbuild_include_opts);
-		/*
-		 * Don't fall through: it may breaks saved_kbuild_dir and
-		 * saved_kbuild_include_opts if detect them again when
-		 * memory is low.
-		 */
-		return;
-	}
-
-	if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) {
-		pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n");
-		pr_debug("Skip kbuild options detection.\n");
-		goto errout;
-	}
-
-	err = detect_kbuild_dir(kbuild_dir);
-	if (err) {
-		pr_warning(
-"WARNING:\tunable to get correct kernel building directory.\n"
-"Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]\n"
-"     \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild\n"
-"     \tdetection.\n\n");
-		goto errout;
-	}
-
-	pr_debug("Kernel build dir is set to %s\n", *kbuild_dir);
-	force_set_env("KBUILD_DIR", *kbuild_dir);
-	force_set_env("KBUILD_OPTS", llvm_param.kbuild_opts);
-	err = read_from_pipe(kinc_fetch_script,
-			     (void **)kbuild_include_opts,
-			     NULL);
-	if (err) {
-		pr_warning(
-"WARNING:\tunable to get kernel include directories from '%s'\n"
-"Hint:\tTry set clang include options using 'clang-bpf-cmd-template'\n"
-"     \toption in [llvm] section of ~/.perfconfig and set 'kbuild-dir'\n"
-"     \toption in [llvm] to \"\" to suppress this detection.\n\n",
-			*kbuild_dir);
-
-		zfree(kbuild_dir);
-		goto errout;
-	}
-
-	pr_debug("include option is set to %s\n", *kbuild_include_opts);
-
-	saved_kbuild_dir = strdup(*kbuild_dir);
-	saved_kbuild_include_opts = strdup(*kbuild_include_opts);
-
-	if (!saved_kbuild_dir || !saved_kbuild_include_opts) {
-		zfree(&saved_kbuild_dir);
-		zfree(&saved_kbuild_include_opts);
-	}
-	return;
-errout:
-	saved_kbuild_dir = ERR_PTR(-EINVAL);
-	saved_kbuild_include_opts = ERR_PTR(-EINVAL);
-}
-
-int llvm__get_nr_cpus(void)
-{
-	static int nr_cpus_avail = 0;
-	char serr[STRERR_BUFSIZE];
-
-	if (nr_cpus_avail > 0)
-		return nr_cpus_avail;
-
-	nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF);
-	if (nr_cpus_avail <= 0) {
-		pr_err(
-"WARNING:\tunable to get available CPUs in this system: %s\n"
-"        \tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr)));
-		nr_cpus_avail = 128;
-	}
-	return nr_cpus_avail;
-}
-
-void llvm__dump_obj(const char *path, void *obj_buf, size_t size)
-{
-	char *obj_path = strdup(path);
-	FILE *fp;
-	char *p;
-
-	if (!obj_path) {
-		pr_warning("WARNING: Not enough memory, skip object dumping\n");
-		return;
-	}
-
-	p = strrchr(obj_path, '.');
-	if (!p || (strcmp(p, ".c") != 0)) {
-		pr_warning("WARNING: invalid llvm source path: '%s', skip object dumping\n",
-			   obj_path);
-		goto out;
-	}
-
-	p[1] = 'o';
-	fp = fopen(obj_path, "wb");
-	if (!fp) {
-		pr_warning("WARNING: failed to open '%s': %s, skip object dumping\n",
-			   obj_path, strerror(errno));
-		goto out;
-	}
-
-	pr_debug("LLVM: dumping %s\n", obj_path);
-	if (fwrite(obj_buf, size, 1, fp) != 1)
-		pr_debug("WARNING: failed to write to file '%s': %s, skip object dumping\n", obj_path, strerror(errno));
-	fclose(fp);
-out:
-	free(obj_path);
-}
-
-int llvm__compile_bpf(const char *path, void **p_obj_buf,
-		      size_t *p_obj_buf_sz)
-{
-	size_t obj_buf_sz;
-	void *obj_buf = NULL;
-	int err, nr_cpus_avail;
-	unsigned int kernel_version;
-	char linux_version_code_str[64];
-	const char *clang_opt = llvm_param.clang_opt;
-	char clang_path[PATH_MAX], llc_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
-	char serr[STRERR_BUFSIZE];
-	char *kbuild_dir = NULL, *kbuild_include_opts = NULL,
-	     *perf_bpf_include_opts = NULL;
-	const char *template = llvm_param.clang_bpf_cmd_template;
-	char *pipe_template = NULL;
-	const char *opts = llvm_param.opts;
-	char *command_echo = NULL, *command_out;
-	char *libbpf_include_dir = system_path(LIBBPF_INCLUDE_DIR);
-
-	if (path[0] != '-' && realpath(path, abspath) == NULL) {
-		err = errno;
-		pr_err("ERROR: problems with path %s: %s\n",
-		       path, str_error_r(err, serr, sizeof(serr)));
-		return -err;
-	}
-
-	if (!template)
-		template = CLANG_BPF_CMD_DEFAULT_TEMPLATE;
-
-	err = search_program_and_warn(llvm_param.clang_path,
-			     "clang", clang_path);
-	if (err)
-		return -ENOENT;
-
-	/*
-	 * This is an optional work. Even it fail we can continue our
-	 * work. Needn't check error return.
-	 */
-	llvm__get_kbuild_opts(&kbuild_dir, &kbuild_include_opts);
-
-	nr_cpus_avail = llvm__get_nr_cpus();
-	snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
-		 nr_cpus_avail);
-
-	if (fetch_kernel_version(&kernel_version, NULL, 0))
-		kernel_version = 0;
-
-	snprintf(linux_version_code_str, sizeof(linux_version_code_str),
-		 "0x%x", kernel_version);
-	if (asprintf(&perf_bpf_include_opts, "-I%s/", libbpf_include_dir) < 0)
-		goto errout;
-	force_set_env("NR_CPUS", nr_cpus_avail_str);
-	force_set_env("LINUX_VERSION_CODE", linux_version_code_str);
-	force_set_env("CLANG_EXEC", clang_path);
-	force_set_env("CLANG_OPTIONS", clang_opt);
-	force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts);
-	force_set_env("PERF_BPF_INC_OPTIONS", perf_bpf_include_opts);
-	force_set_env("WORKING_DIR", kbuild_dir ? : ".");
-
-	if (opts) {
-		err = search_program_and_warn(llvm_param.llc_path, "llc", llc_path);
-		if (err)
-			goto errout;
-
-		err = -ENOMEM;
-		if (asprintf(&pipe_template, "%s -emit-llvm | %s -march=bpf %s -filetype=obj -o -",
-			      template, llc_path, opts) < 0) {
-			pr_err("ERROR:\tnot enough memory to setup command line\n");
-			goto errout;
-		}
-
-		template = pipe_template;
-
-	}
-
-	/*
-	 * Since we may reset clang's working dir, path of source file
-	 * should be transferred into absolute path, except we want
-	 * stdin to be source file (testing).
-	 */
-	force_set_env("CLANG_SOURCE",
-		      (path[0] == '-') ? path : abspath);
-
-	pr_debug("llvm compiling command template: %s\n", template);
-
-	/*
-	 * Below, substitute control characters for values that can cause the
-	 * echo to misbehave, then substitute the values back.
-	 */
-	err = -ENOMEM;
-	if (asprintf(&command_echo, "echo -n \a%s\a", template) < 0)
-		goto errout;
-
-#define SWAP_CHAR(a, b) do { if (*p == a) *p = b; } while (0)
-	for (char *p = command_echo; *p; p++) {
-		SWAP_CHAR('<', '\001');
-		SWAP_CHAR('>', '\002');
-		SWAP_CHAR('"', '\003');
-		SWAP_CHAR('\'', '\004');
-		SWAP_CHAR('|', '\005');
-		SWAP_CHAR('&', '\006');
-		SWAP_CHAR('\a', '"');
-	}
-	err = read_from_pipe(command_echo, (void **) &command_out, NULL);
-	if (err)
-		goto errout;
-
-	for (char *p = command_out; *p; p++) {
-		SWAP_CHAR('\001', '<');
-		SWAP_CHAR('\002', '>');
-		SWAP_CHAR('\003', '"');
-		SWAP_CHAR('\004', '\'');
-		SWAP_CHAR('\005', '|');
-		SWAP_CHAR('\006', '&');
-	}
-#undef SWAP_CHAR
-	pr_debug("llvm compiling command : %s\n", command_out);
-
-	err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
-	if (err) {
-		pr_err("ERROR:\tunable to compile %s\n", path);
-		pr_err("Hint:\tCheck error message shown above.\n");
-		pr_err("Hint:\tYou can also pre-compile it into .o using:\n");
-		pr_err("     \t\tclang --target=bpf -O2 -c %s\n", path);
-		pr_err("     \twith proper -I and -D options.\n");
-		goto errout;
-	}
-
-	free(command_echo);
-	free(command_out);
-	free(kbuild_dir);
-	free(kbuild_include_opts);
-	free(perf_bpf_include_opts);
-	free(libbpf_include_dir);
-
-	if (!p_obj_buf)
-		free(obj_buf);
-	else
-		*p_obj_buf = obj_buf;
-
-	if (p_obj_buf_sz)
-		*p_obj_buf_sz = obj_buf_sz;
-	return 0;
-errout:
-	free(command_echo);
-	free(kbuild_dir);
-	free(kbuild_include_opts);
-	free(obj_buf);
-	free(perf_bpf_include_opts);
-	free(libbpf_include_dir);
-	free(pipe_template);
-	if (p_obj_buf)
-		*p_obj_buf = NULL;
-	if (p_obj_buf_sz)
-		*p_obj_buf_sz = 0;
-	return err;
-}
-
-int llvm__search_clang(void)
-{
-	char clang_path[PATH_MAX];
-
-	return search_program_and_warn(llvm_param.clang_path, "clang", clang_path);
-}
diff --git a/tools/perf/util/llvm-utils.h b/tools/perf/util/llvm-utils.h
deleted file mode 100644
index 7878a0e3fa98..000000000000
--- a/tools/perf/util/llvm-utils.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com>
- * Copyright (C) 2015, Huawei Inc.
- */
-#ifndef __LLVM_UTILS_H
-#define __LLVM_UTILS_H
-
-#include <stdbool.h>
-
-struct llvm_param {
-	/* Path of clang executable */
-	const char *clang_path;
-	/* Path of llc executable */
-	const char *llc_path;
-	/*
-	 * Template of clang bpf compiling. 5 env variables
-	 * can be used:
-	 *   $CLANG_EXEC:		Path to clang.
-	 *   $CLANG_OPTIONS:		Extra options to clang.
-	 *   $KERNEL_INC_OPTIONS:	Kernel include directories.
-	 *   $WORKING_DIR:		Kernel source directory.
-	 *   $CLANG_SOURCE:		Source file to be compiled.
-	 */
-	const char *clang_bpf_cmd_template;
-	/* Will be filled in $CLANG_OPTIONS */
-	const char *clang_opt;
-	/*
-	 * If present it'll add -emit-llvm to $CLANG_OPTIONS to pipe
-	 * the clang output to llc, useful for new llvm options not
-	 * yet selectable via 'clang -mllvm option', such as -mattr=dwarfris
-	 * in clang 6.0/llvm 7
-	 */
-	const char *opts;
-	/* Where to find kbuild system */
-	const char *kbuild_dir;
-	/*
-	 * Arguments passed to make, like 'ARCH=arm' if doing cross
-	 * compiling. Should not be used for dynamic compiling.
-	 */
-	const char *kbuild_opts;
-	/*
-	 * Default is false. If set to true, write compiling result
-	 * to object file.
-	 */
-	bool dump_obj;
-	/*
-	 * Default is false. If one of the above fields is set by user
-	 * explicitly then user_set_llvm is set to true. This is used
-	 * for perf test. If user doesn't set anything in .perfconfig
-	 * and clang is not found, don't trigger llvm test.
-	 */
-	bool user_set_param;
-};
-
-extern struct llvm_param llvm_param;
-int perf_llvm_config(const char *var, const char *value);
-
-int llvm__compile_bpf(const char *path, void **p_obj_buf, size_t *p_obj_buf_sz);
-
-/* This function is for test__llvm() use only */
-int llvm__search_clang(void);
-
-/* Following functions are reused by builtin clang support */
-void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts);
-int llvm__get_nr_cpus(void);
-
-void llvm__dump_obj(const char *path, void *obj_buf, size_t size);
-#endif
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 0b5075ef00c8..00a8ec94f5b2 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -14,7 +14,6 @@
 #include "parse-events.h"
 #include "string2.h"
 #include "strlist.h"
-#include "bpf-loader.h"
 #include "debug.h"
 #include <api/fs/tracing_path.h>
 #include <perf/cpumap.h>
@@ -648,272 +647,6 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx,
 }
 #endif /* HAVE_LIBTRACEEVENT */
 
-#ifdef HAVE_LIBBPF_SUPPORT
-struct __add_bpf_event_param {
-	struct parse_events_state *parse_state;
-	struct list_head *list;
-	struct list_head *head_config;
-	YYLTYPE *loc;
-};
-
-static int add_bpf_event(const char *group, const char *event, int fd, struct bpf_object *obj,
-			 void *_param)
-{
-	LIST_HEAD(new_evsels);
-	struct __add_bpf_event_param *param = _param;
-	struct parse_events_state *parse_state = param->parse_state;
-	struct list_head *list = param->list;
-	struct evsel *pos;
-	int err;
-	/*
-	 * Check if we should add the event, i.e. if it is a TP but starts with a '!',
-	 * then don't add the tracepoint, this will be used for something else, like
-	 * adding to a BPF_MAP_TYPE_PROG_ARRAY.
-	 *
-	 * See tools/perf/examples/bpf/augmented_raw_syscalls.c
-	 */
-	if (group[0] == '!')
-		return 0;
-
-	pr_debug("add bpf event %s:%s and attach bpf program %d\n",
-		 group, event, fd);
-
-	err = parse_events_add_tracepoint(&new_evsels, &parse_state->idx, group,
-					  event, parse_state->error,
-					  param->head_config, param->loc);
-	if (err) {
-		struct evsel *evsel, *tmp;
-
-		pr_debug("Failed to add BPF event %s:%s\n",
-			 group, event);
-		list_for_each_entry_safe(evsel, tmp, &new_evsels, core.node) {
-			list_del_init(&evsel->core.node);
-			evsel__delete(evsel);
-		}
-		return err;
-	}
-	pr_debug("adding %s:%s\n", group, event);
-
-	list_for_each_entry(pos, &new_evsels, core.node) {
-		pr_debug("adding %s:%s to %p\n",
-			 group, event, pos);
-		pos->bpf_fd = fd;
-		pos->bpf_obj = obj;
-	}
-	list_splice(&new_evsels, list);
-	return 0;
-}
-
-int parse_events_load_bpf_obj(struct parse_events_state *parse_state,
-			      struct list_head *list,
-			      struct bpf_object *obj,
-			      struct list_head *head_config,
-			      void *loc)
-{
-	int err;
-	char errbuf[BUFSIZ];
-	struct __add_bpf_event_param param = {parse_state, list, head_config, loc};
-	static bool registered_unprobe_atexit = false;
-	YYLTYPE test_loc = {.first_column = -1};
-
-	if (IS_ERR(obj) || !obj) {
-		snprintf(errbuf, sizeof(errbuf),
-			 "Internal error: load bpf obj with NULL");
-		err = -EINVAL;
-		goto errout;
-	}
-
-	/*
-	 * Register atexit handler before calling bpf__probe() so
-	 * bpf__probe() don't need to unprobe probe points its already
-	 * created when failure.
-	 */
-	if (!registered_unprobe_atexit) {
-		atexit(bpf__clear);
-		registered_unprobe_atexit = true;
-	}
-
-	err = bpf__probe(obj);
-	if (err) {
-		bpf__strerror_probe(obj, err, errbuf, sizeof(errbuf));
-		goto errout;
-	}
-
-	err = bpf__load(obj);
-	if (err) {
-		bpf__strerror_load(obj, err, errbuf, sizeof(errbuf));
-		goto errout;
-	}
-
-	if (!param.loc)
-		param.loc = &test_loc;
-
-	err = bpf__foreach_event(obj, add_bpf_event, &param);
-	if (err) {
-		snprintf(errbuf, sizeof(errbuf),
-			 "Attach events in BPF object failed");
-		goto errout;
-	}
-
-	return 0;
-errout:
-	parse_events_error__handle(parse_state->error, param.loc ? param.loc->first_column : 0,
-				strdup(errbuf), strdup("(add -v to see detail)"));
-	return err;
-}
-
-static int
-parse_events_config_bpf(struct parse_events_state *parse_state,
-			struct bpf_object *obj,
-			struct list_head *head_config)
-{
-	struct parse_events_term *term;
-	int error_pos = 0;
-
-	if (!head_config || list_empty(head_config))
-		return 0;
-
-	list_for_each_entry(term, head_config, list) {
-		int err;
-
-		if (term->type_term != PARSE_EVENTS__TERM_TYPE_USER) {
-			parse_events_error__handle(parse_state->error, term->err_term,
-						strdup("Invalid config term for BPF object"),
-						NULL);
-			return -EINVAL;
-		}
-
-		err = bpf__config_obj(obj, term, parse_state->evlist, &error_pos);
-		if (err) {
-			char errbuf[BUFSIZ];
-			int idx;
-
-			bpf__strerror_config_obj(obj, term, parse_state->evlist,
-						 &error_pos, err, errbuf,
-						 sizeof(errbuf));
-
-			if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE)
-				idx = term->err_val;
-			else
-				idx = term->err_term + error_pos;
-
-			parse_events_error__handle(parse_state->error, idx,
-						strdup(errbuf),
-						NULL);
-			return err;
-		}
-	}
-	return 0;
-}
-
-/*
- * Split config terms:
- * perf record -e bpf.c/call-graph=fp,map:array.value[0]=1/ ...
- *  'call-graph=fp' is 'evt config', should be applied to each
- *  events in bpf.c.
- * 'map:array.value[0]=1' is 'obj config', should be processed
- * with parse_events_config_bpf.
- *
- * Move object config terms from the first list to obj_head_config.
- */
-static void
-split_bpf_config_terms(struct list_head *evt_head_config,
-		       struct list_head *obj_head_config)
-{
-	struct parse_events_term *term, *temp;
-
-	/*
-	 * Currently, all possible user config term
-	 * belong to bpf object. parse_events__is_hardcoded_term()
-	 * happens to be a good flag.
-	 *
-	 * See parse_events_config_bpf() and
-	 * config_term_tracepoint().
-	 */
-	list_for_each_entry_safe(term, temp, evt_head_config, list)
-		if (!parse_events__is_hardcoded_term(term))
-			list_move_tail(&term->list, obj_head_config);
-}
-
-int parse_events_load_bpf(struct parse_events_state *parse_state,
-			  struct list_head *list,
-			  char *bpf_file_name,
-			  bool source,
-			  struct list_head *head_config,
-			  void *loc_)
-{
-	int err;
-	struct bpf_object *obj;
-	LIST_HEAD(obj_head_config);
-	YYLTYPE *loc = loc_;
-
-	if (head_config)
-		split_bpf_config_terms(head_config, &obj_head_config);
-
-	obj = bpf__prepare_load(bpf_file_name, source);
-	if (IS_ERR(obj)) {
-		char errbuf[BUFSIZ];
-
-		err = PTR_ERR(obj);
-
-		if (err == -ENOTSUP)
-			snprintf(errbuf, sizeof(errbuf),
-				 "BPF support is not compiled");
-		else
-			bpf__strerror_prepare_load(bpf_file_name,
-						   source,
-						   -err, errbuf,
-						   sizeof(errbuf));
-
-		parse_events_error__handle(parse_state->error, loc->first_column,
-					strdup(errbuf), strdup("(add -v to see detail)"));
-		return err;
-	}
-
-	err = parse_events_load_bpf_obj(parse_state, list, obj, head_config, loc);
-	if (err)
-		return err;
-	err = parse_events_config_bpf(parse_state, obj, &obj_head_config);
-
-	/*
-	 * Caller doesn't know anything about obj_head_config,
-	 * so combine them together again before returning.
-	 */
-	if (head_config)
-		list_splice_tail(&obj_head_config, head_config);
-	return err;
-}
-#else // HAVE_LIBBPF_SUPPORT
-int parse_events_load_bpf_obj(struct parse_events_state *parse_state,
-			      struct list_head *list __maybe_unused,
-			      struct bpf_object *obj __maybe_unused,
-			      struct list_head *head_config __maybe_unused,
-			      void *loc_)
-{
-	YYLTYPE *loc = loc_;
-
-	parse_events_error__handle(parse_state->error, loc->first_column,
-				   strdup("BPF support is not compiled"),
-				   strdup("Make sure libbpf-devel is available at build time."));
-	return -ENOTSUP;
-}
-
-int parse_events_load_bpf(struct parse_events_state *parse_state,
-			  struct list_head *list __maybe_unused,
-			  char *bpf_file_name __maybe_unused,
-			  bool source __maybe_unused,
-			  struct list_head *head_config __maybe_unused,
-			  void *loc_)
-{
-	YYLTYPE *loc = loc_;
-
-	parse_events_error__handle(parse_state->error, loc->first_column,
-				   strdup("BPF support is not compiled"),
-				   strdup("Make sure libbpf-devel is available at build time."));
-	return -ENOTSUP;
-}
-#endif // HAVE_LIBBPF_SUPPORT
-
 static int
 parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
 {
@@ -2274,7 +2007,6 @@ int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filte
 		.list	  = LIST_HEAD_INIT(parse_state.list),
 		.idx	  = evlist->core.nr_entries,
 		.error	  = err,
-		.evlist	  = evlist,
 		.stoken	  = PE_START_EVENTS,
 		.fake_pmu = fake_pmu,
 		.pmu_filter = pmu_filter,
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index b77ff619a623..411f69b2ac3a 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -118,8 +118,6 @@ struct parse_events_state {
 	int			   idx;
 	/* Error information. */
 	struct parse_events_error *error;
-	/* Used by BPF event creation. */
-	struct evlist		  *evlist;
 	/* Holds returned terms for term parsing. */
 	struct list_head	  *terms;
 	/* Start token. */
@@ -160,19 +158,6 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx,
 				const char *sys, const char *event,
 				struct parse_events_error *error,
 				struct list_head *head_config, void *loc);
-int parse_events_load_bpf(struct parse_events_state *parse_state,
-			  struct list_head *list,
-			  char *bpf_file_name,
-			  bool source,
-			  struct list_head *head_config,
-			  void *loc);
-/* Provide this function for perf test */
-struct bpf_object;
-int parse_events_load_bpf_obj(struct parse_events_state *parse_state,
-			      struct list_head *list,
-			      struct bpf_object *obj,
-			      struct list_head *head_config,
-			      void *loc);
 int parse_events_add_numeric(struct parse_events_state *parse_state,
 			     struct list_head *list,
 			     u32 type, u64 config,
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index d7d084cc4140..1147084b2c76 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -68,31 +68,6 @@ static int lc_str(yyscan_t scanner, const struct parse_events_state *state)
 	return str(scanner, state->match_legacy_cache_terms ? PE_LEGACY_CACHE : PE_NAME);
 }
 
-static bool isbpf_suffix(char *text)
-{
-	int len = strlen(text);
-
-	if (len < 2)
-		return false;
-	if ((text[len - 1] == 'c' || text[len - 1] == 'o') &&
-	    text[len - 2] == '.')
-		return true;
-	if (len > 4 && !strcmp(text + len - 4, ".obj"))
-		return true;
-	return false;
-}
-
-static bool isbpf(yyscan_t scanner)
-{
-	char *text = parse_events_get_text(scanner);
-	struct stat st;
-
-	if (!isbpf_suffix(text))
-		return false;
-
-	return stat(text, &st) == 0;
-}
-
 /*
  * This function is called when the parser gets two kind of input:
  *
@@ -179,8 +154,6 @@ do {							\
 group		[^,{}/]*[{][^}]*[}][^,{}/]*
 event_pmu	[^,{}/]+[/][^/]*[/][^,{}/]*
 event		[^,{}/]+
-bpf_object	[^,{}]+\.(o|bpf)[a-zA-Z0-9._]*
-bpf_source	[^,{}]+\.c[a-zA-Z0-9._]*
 
 num_dec		[0-9]+
 num_hex		0x[a-fA-F0-9]+
@@ -233,8 +206,6 @@ non_digit	[^0-9]
 		}
 
 {event_pmu}	|
-{bpf_object}	|
-{bpf_source}	|
 {event}		{
 			BEGIN(INITIAL);
 			REWIND(1);
@@ -363,8 +334,6 @@ r{num_raw_hex}		{ return str(yyscanner, PE_RAW); }
 {num_hex}		{ return value(yyscanner, 16); }
 
 {modifier_event}	{ return str(yyscanner, PE_MODIFIER_EVENT); }
-{bpf_object}		{ if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_OBJECT); }
-{bpf_source}		{ if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_SOURCE); }
 {name}			{ return str(yyscanner, PE_NAME); }
 {name_tag}		{ return str(yyscanner, PE_NAME); }
 "/"			{ BEGIN(config); return '/'; }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index c3517e3498d7..00da1f8c0baf 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -60,7 +60,6 @@ static void free_list_evsel(struct list_head* list_evsel)
 %token PE_VALUE_SYM_TOOL
 %token PE_EVENT_NAME
 %token PE_RAW PE_NAME
-%token PE_BPF_OBJECT PE_BPF_SOURCE
 %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH
 %token PE_LEGACY_CACHE
 %token PE_PREFIX_MEM
@@ -75,8 +74,6 @@ static void free_list_evsel(struct list_head* list_evsel)
 %type <num> value_sym
 %type <str> PE_RAW
 %type <str> PE_NAME
-%type <str> PE_BPF_OBJECT
-%type <str> PE_BPF_SOURCE
 %type <str> PE_LEGACY_CACHE
 %type <str> PE_MODIFIER_EVENT
 %type <str> PE_MODIFIER_BP
@@ -97,7 +94,6 @@ static void free_list_evsel(struct list_head* list_evsel)
 %type <list_evsel> event_legacy_tracepoint
 %type <list_evsel> event_legacy_numeric
 %type <list_evsel> event_legacy_raw
-%type <list_evsel> event_bpf_file
 %type <list_evsel> event_def
 %type <list_evsel> event_mod
 %type <list_evsel> event_name
@@ -271,8 +267,7 @@ event_def: event_pmu |
 	   event_legacy_mem sep_dc |
 	   event_legacy_tracepoint sep_dc |
 	   event_legacy_numeric sep_dc |
-	   event_legacy_raw sep_dc |
-	   event_bpf_file
+	   event_legacy_raw sep_dc
 
 event_pmu:
 PE_NAME opt_pmu_config
@@ -620,43 +615,6 @@ PE_RAW opt_event_config
 	$$ = list;
 }
 
-event_bpf_file:
-PE_BPF_OBJECT opt_event_config
-{
-	struct parse_events_state *parse_state = _parse_state;
-	struct list_head *list;
-	int err;
-
-	list = alloc_list();
-	if (!list)
-		YYNOMEM;
-	err = parse_events_load_bpf(parse_state, list, $1, false, $2, &@1);
-	parse_events_terms__delete($2);
-	free($1);
-	if (err) {
-		free(list);
-		PE_ABORT(err);
-	}
-	$$ = list;
-}
-|
-PE_BPF_SOURCE opt_event_config
-{
-	struct list_head *list;
-	int err;
-
-	list = alloc_list();
-	if (!list)
-		YYNOMEM;
-	err = parse_events_load_bpf(_parse_state, list, $1, true, $2, &@1);
-	parse_events_terms__delete($2);
-	if (err) {
-		free(list);
-		PE_ABORT(err);
-	}
-	$$ = list;
-}
-
 opt_event_config:
 '/' event_config '/'
 {
