aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-12-18 03:37:51 -0500
committerIngo Molnar <mingo@kernel.org>2015-12-18 03:37:51 -0500
commitb21daaede100d102b1687a403df74be0a02031af (patch)
treecdc7fe583ee8d4837a1bc2246d861a69828edbce
parent0d76ded582c178d3cca55c9112eceb5b0f12f558 (diff)
parent1843b4e057b7717db21a3ad96fa16d6b4ee8f6c4 (diff)
Merge tag 'perf-core-for-mingo-2.1' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements from Arnaldo Carvalho de Melo: User visible changes: - Add record.build-id config option to 'perf record', to allow configuring in the ~/.perfconfig file if and how build-ids should be processed, allowing a permanent setting for options such as -B and -N: (Namhyung Kim) $ perf record -h -B -N Usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] -B, --no-buildid do not collect buildids in perf.data -N, --no-buildid-cache do not update the buildid cache $ Infrastructure changes: - Move code for options parsing and subcommand handling from tools/perf/ to tools/lib/subcmd/, so that it can be used by other tools/ living utilities (Josh Poimboeuf) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/build/Makefile.feature3
-rw-r--r--tools/build/feature/Makefile93
-rw-r--r--tools/include/linux/string.h4
-rw-r--r--tools/lib/string.c27
-rw-r--r--tools/lib/subcmd/Build7
-rw-r--r--tools/lib/subcmd/Makefile48
-rw-r--r--tools/lib/subcmd/exec-cmd.c209
-rw-r--r--tools/lib/subcmd/exec-cmd.h16
-rw-r--r--tools/lib/subcmd/help.c (renamed from tools/perf/util/help.c)170
-rw-r--r--tools/lib/subcmd/help.h (renamed from tools/perf/util/help.h)13
-rw-r--r--tools/lib/subcmd/pager.c (renamed from tools/perf/util/pager.c)23
-rw-r--r--tools/lib/subcmd/pager.h9
-rw-r--r--tools/lib/subcmd/parse-options.c (renamed from tools/perf/util/parse-options.c)245
-rw-r--r--tools/lib/subcmd/parse-options.h (renamed from tools/perf/util/parse-options.h)26
-rw-r--r--tools/lib/subcmd/run-command.c (renamed from tools/perf/util/run-command.c)24
-rw-r--r--tools/lib/subcmd/run-command.h (renamed from tools/perf/util/run-command.h)12
-rw-r--r--tools/lib/subcmd/sigchain.c (renamed from tools/perf/util/sigchain.c)3
-rw-r--r--tools/lib/subcmd/sigchain.h (renamed from tools/perf/util/sigchain.h)6
-rw-r--r--tools/lib/subcmd/subcmd-config.c11
-rw-r--r--tools/lib/subcmd/subcmd-config.h14
-rw-r--r--tools/lib/subcmd/subcmd-util.h91
-rw-r--r--tools/perf/Build5
-rw-r--r--tools/perf/Documentation/perf-record.txt24
-rw-r--r--tools/perf/MANIFEST1
-rw-r--r--tools/perf/Makefile.perf35
-rw-r--r--tools/perf/arch/x86/util/intel-pt.c2
-rw-r--r--tools/perf/bench/futex-hash.c2
-rw-r--r--tools/perf/bench/futex-lock-pi.c2
-rw-r--r--tools/perf/bench/futex-requeue.c2
-rw-r--r--tools/perf/bench/futex-wake-parallel.c2
-rw-r--r--tools/perf/bench/futex-wake.c2
-rw-r--r--tools/perf/bench/mem-functions.c2
-rw-r--r--tools/perf/bench/numa.c2
-rw-r--r--tools/perf/bench/sched-messaging.c2
-rw-r--r--tools/perf/bench/sched-pipe.c2
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-bench.c2
-rw-r--r--tools/perf/builtin-buildid-cache.c2
-rw-r--r--tools/perf/builtin-buildid-list.c2
-rw-r--r--tools/perf/builtin-config.c2
-rw-r--r--tools/perf/builtin-data.c2
-rw-r--r--tools/perf/builtin-evlist.c2
-rw-r--r--tools/perf/builtin-help.c10
-rw-r--r--tools/perf/builtin-inject.c2
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/builtin-kvm.c2
-rw-r--r--tools/perf/builtin-list.c2
-rw-r--r--tools/perf/builtin-lock.c2
-rw-r--r--tools/perf/builtin-mem.c2
-rw-r--r--tools/perf/builtin-probe.c17
-rw-r--r--tools/perf/builtin-record.c40
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-sched.c2
-rw-r--r--tools/perf/builtin-script.c12
-rw-r--r--tools/perf/builtin-stat.c2
-rw-r--r--tools/perf/builtin-timechart.c2
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/builtin-trace.c4
-rw-r--r--tools/perf/perf.c18
-rw-r--r--tools/perf/tests/Build6
-rw-r--r--tools/perf/tests/attr.c4
-rw-r--r--tools/perf/tests/builtin-test.c5
-rw-r--r--tools/perf/tests/hists_common.c5
-rw-r--r--tools/perf/tests/make3
-rw-r--r--tools/perf/util/Build8
-rw-r--r--tools/perf/util/auxtrace.c2
-rw-r--r--tools/perf/util/cache.h13
-rw-r--r--tools/perf/util/cgroup.c2
-rw-r--r--tools/perf/util/config.c2
-rw-r--r--tools/perf/util/evlist.c2
-rw-r--r--tools/perf/util/evsel.c14
-rw-r--r--tools/perf/util/exec_cmd.c149
-rw-r--r--tools/perf/util/exec_cmd.h13
-rw-r--r--tools/perf/util/help-unknown-cmd.c103
-rw-r--r--tools/perf/util/help-unknown-cmd.h0
-rw-r--r--tools/perf/util/intel-pt.c4
-rw-r--r--tools/perf/util/machine.c19
-rw-r--r--tools/perf/util/parse-branch-options.c2
-rw-r--r--tools/perf/util/parse-events.c4
-rw-r--r--tools/perf/util/parse-regs-options.c2
-rw-r--r--tools/perf/util/path.c18
-rw-r--r--tools/perf/util/sort.h2
-rw-r--r--tools/perf/util/thread.c10
-rw-r--r--tools/perf/util/util.c3
-rw-r--r--tools/perf/util/util.h14
85 files changed, 1103 insertions, 582 deletions
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 37ff4c9f92f1..6c0519de765d 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -7,7 +7,7 @@ endif
7 7
8feature_check = $(eval $(feature_check_code)) 8feature_check = $(eval $(feature_check_code))
9define feature_check_code 9define feature_check_code
10 feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0) 10 feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
11endef 11endef
12 12
13feature_set = $(eval $(feature_set_code)) 13feature_set = $(eval $(feature_set_code))
@@ -101,7 +101,6 @@ ifeq ($(feature-all), 1)
101 # 101 #
102 $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat))) 102 $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
103else 103else
104 $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C $(feature_dir) $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
105 $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat))) 104 $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
106endif 105endif
107 106
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index cea04ce9f35c..bf8f0352264d 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -1,4 +1,3 @@
1
2FILES= \ 1FILES= \
3 test-all.bin \ 2 test-all.bin \
4 test-backtrace.bin \ 3 test-backtrace.bin \
@@ -38,38 +37,40 @@ FILES= \
38 test-bpf.bin \ 37 test-bpf.bin \
39 test-get_cpuid.bin 38 test-get_cpuid.bin
40 39
40FILES := $(addprefix $(OUTPUT),$(FILES))
41
41CC := $(CROSS_COMPILE)gcc -MD 42CC := $(CROSS_COMPILE)gcc -MD
42PKG_CONFIG := $(CROSS_COMPILE)pkg-config 43PKG_CONFIG := $(CROSS_COMPILE)pkg-config
43 44
44all: $(FILES) 45all: $(FILES)
45 46
46__BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS) 47__BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $@ $(patsubst %.bin,%.c,$(@F)) $(LDFLAGS)
47 BUILD = $(__BUILD) > $(OUTPUT)$(@:.bin=.make.output) 2>&1 48 BUILD = $(__BUILD) > $(@:.bin=.make.output) 2>&1
48 49
49############################### 50###############################
50 51
51test-all.bin: 52$(OUTPUT)test-all.bin:
52 $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma 53 $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma
53 54
54test-hello.bin: 55$(OUTPUT)test-hello.bin:
55 $(BUILD) 56 $(BUILD)
56 57
57test-pthread-attr-setaffinity-np.bin: 58$(OUTPUT)test-pthread-attr-setaffinity-np.bin:
58 $(BUILD) -D_GNU_SOURCE -lpthread 59 $(BUILD) -D_GNU_SOURCE -lpthread
59 60
60test-stackprotector-all.bin: 61$(OUTPUT)test-stackprotector-all.bin:
61 $(BUILD) -fstack-protector-all 62 $(BUILD) -fstack-protector-all
62 63
63test-fortify-source.bin: 64$(OUTPUT)test-fortify-source.bin:
64 $(BUILD) -O2 -D_FORTIFY_SOURCE=2 65 $(BUILD) -O2 -D_FORTIFY_SOURCE=2
65 66
66test-bionic.bin: 67$(OUTPUT)test-bionic.bin:
67 $(BUILD) 68 $(BUILD)
68 69
69test-libelf.bin: 70$(OUTPUT)test-libelf.bin:
70 $(BUILD) -lelf 71 $(BUILD) -lelf
71 72
72test-glibc.bin: 73$(OUTPUT)test-glibc.bin:
73 $(BUILD) 74 $(BUILD)
74 75
75DWARFLIBS := -ldw 76DWARFLIBS := -ldw
@@ -77,37 +78,37 @@ ifeq ($(findstring -static,${LDFLAGS}),-static)
77DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 78DWARFLIBS += -lelf -lebl -lz -llzma -lbz2
78endif 79endif
79 80
80test-dwarf.bin: 81$(OUTPUT)test-dwarf.bin:
81 $(BUILD) $(DWARFLIBS) 82 $(BUILD) $(DWARFLIBS)
82 83
83test-libelf-mmap.bin: 84$(OUTPUT)test-libelf-mmap.bin:
84 $(BUILD) -lelf 85 $(BUILD) -lelf
85 86
86test-libelf-getphdrnum.bin: 87$(OUTPUT)test-libelf-getphdrnum.bin:
87 $(BUILD) -lelf 88 $(BUILD) -lelf
88 89
89test-libnuma.bin: 90$(OUTPUT)test-libnuma.bin:
90 $(BUILD) -lnuma 91 $(BUILD) -lnuma
91 92
92test-numa_num_possible_cpus.bin: 93$(OUTPUT)test-numa_num_possible_cpus.bin:
93 $(BUILD) -lnuma 94 $(BUILD) -lnuma
94 95
95test-libunwind.bin: 96$(OUTPUT)test-libunwind.bin:
96 $(BUILD) -lelf 97 $(BUILD) -lelf
97 98
98test-libunwind-debug-frame.bin: 99$(OUTPUT)test-libunwind-debug-frame.bin:
99 $(BUILD) -lelf 100 $(BUILD) -lelf
100 101
101test-libaudit.bin: 102$(OUTPUT)test-libaudit.bin:
102 $(BUILD) -laudit 103 $(BUILD) -laudit
103 104
104test-libslang.bin: 105$(OUTPUT)test-libslang.bin:
105 $(BUILD) -I/usr/include/slang -lslang 106 $(BUILD) -I/usr/include/slang -lslang
106 107
107test-gtk2.bin: 108$(OUTPUT)test-gtk2.bin:
108 $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) 109 $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null)
109 110
110test-gtk2-infobar.bin: 111$(OUTPUT)test-gtk2-infobar.bin:
111 $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) 112 $(BUILD) $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null)
112 113
113grep-libs = $(filter -l%,$(1)) 114grep-libs = $(filter -l%,$(1))
@@ -119,63 +120,63 @@ PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
119PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` 120PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
120FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) 121FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
121 122
122test-libperl.bin: 123$(OUTPUT)test-libperl.bin:
123 $(BUILD) $(FLAGS_PERL_EMBED) 124 $(BUILD) $(FLAGS_PERL_EMBED)
124 125
125test-libpython.bin: 126$(OUTPUT)test-libpython.bin:
126 $(BUILD) 127 $(BUILD)
127 128
128test-libpython-version.bin: 129$(OUTPUT)test-libpython-version.bin:
129 $(BUILD) 130 $(BUILD)
130 131
131test-libbfd.bin: 132$(OUTPUT)test-libbfd.bin:
132 $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl 133 $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl
133 134
134test-liberty.bin: 135$(OUTPUT)test-liberty.bin:
135 $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty 136 $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty
136 137
137test-liberty-z.bin: 138$(OUTPUT)test-liberty-z.bin:
138 $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty -lz 139 $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty -lz
139 140
140test-cplus-demangle.bin: 141$(OUTPUT)test-cplus-demangle.bin:
141 $(BUILD) -liberty 142 $(BUILD) -liberty
142 143
143test-backtrace.bin: 144$(OUTPUT)test-backtrace.bin:
144 $(BUILD) 145 $(BUILD)
145 146
146test-timerfd.bin: 147$(OUTPUT)test-timerfd.bin:
147 $(BUILD) 148 $(BUILD)
148 149
149test-libdw-dwarf-unwind.bin: 150$(OUTPUT)test-libdw-dwarf-unwind.bin:
150 $(BUILD) # -ldw provided by $(FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind) 151 $(BUILD) # -ldw provided by $(FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind)
151 152
152test-libbabeltrace.bin: 153$(OUTPUT)test-libbabeltrace.bin:
153 $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace) 154 $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace)
154 155
155test-sync-compare-and-swap.bin: 156$(OUTPUT)test-sync-compare-and-swap.bin:
156 $(BUILD) 157 $(BUILD)
157 158
158test-compile-32.bin: 159$(OUTPUT)test-compile-32.bin:
159 $(CC) -m32 -o $(OUTPUT)$@ test-compile.c 160 $(CC) -m32 -o $@ test-compile.c
160 161
161test-compile-x32.bin: 162$(OUTPUT)test-compile-x32.bin:
162 $(CC) -mx32 -o $(OUTPUT)$@ test-compile.c 163 $(CC) -mx32 -o $@ test-compile.c
163 164
164test-zlib.bin: 165$(OUTPUT)test-zlib.bin:
165 $(BUILD) -lz 166 $(BUILD) -lz
166 167
167test-lzma.bin: 168$(OUTPUT)test-lzma.bin:
168 $(BUILD) -llzma 169 $(BUILD) -llzma
169 170
170test-get_cpuid.bin: 171$(OUTPUT)test-get_cpuid.bin:
171 $(BUILD) 172 $(BUILD)
172 173
173test-bpf.bin: 174$(OUTPUT)test-bpf.bin:
174 $(BUILD) 175 $(BUILD)
175 176
176-include *.d 177-include $(OUTPUT)*.d
177 178
178############################### 179###############################
179 180
180clean: 181clean:
181 rm -f $(FILES) *.d $(FILES:.bin=.make.output) 182 rm -f $(FILES) $(OUTPUT)*.d $(FILES:.bin=.make.output)
diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h
index 2e2f736c039c..e26223f1f287 100644
--- a/tools/include/linux/string.h
+++ b/tools/include/linux/string.h
@@ -8,4 +8,8 @@ void *memdup(const void *src, size_t len);
8 8
9int strtobool(const char *s, bool *res); 9int strtobool(const char *s, bool *res);
10 10
11#ifndef __UCLIBC__
12extern size_t strlcpy(char *dest, const char *src, size_t size);
13#endif
14
11#endif /* _LINUX_STRING_H_ */ 15#endif /* _LINUX_STRING_H_ */
diff --git a/tools/lib/string.c b/tools/lib/string.c
index 065e54f42d8f..bd239bc1d557 100644
--- a/tools/lib/string.c
+++ b/tools/lib/string.c
@@ -16,6 +16,7 @@
16#include <string.h> 16#include <string.h>
17#include <errno.h> 17#include <errno.h>
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/compiler.h>
19 20
20/** 21/**
21 * memdup - duplicate region of memory 22 * memdup - duplicate region of memory
@@ -60,3 +61,29 @@ int strtobool(const char *s, bool *res)
60 } 61 }
61 return 0; 62 return 0;
62} 63}
64
65/**
66 * strlcpy - Copy a C-string into a sized buffer
67 * @dest: Where to copy the string to
68 * @src: Where to copy the string from
69 * @size: size of destination buffer
70 *
71 * Compatible with *BSD: the result is always a valid
72 * NUL-terminated string that fits in the buffer (unless,
73 * of course, the buffer size is zero). It does not pad
74 * out the result like strncpy() does.
75 *
76 * If libc has strlcpy() then that version will override this
77 * implementation:
78 */
79size_t __weak strlcpy(char *dest, const char *src, size_t size)
80{
81 size_t ret = strlen(src);
82
83 if (size) {
84 size_t len = (ret >= size) ? size - 1 : ret;
85 memcpy(dest, src, len);
86 dest[len] = '\0';
87 }
88 return ret;
89}
diff --git a/tools/lib/subcmd/Build b/tools/lib/subcmd/Build
new file mode 100644
index 000000000000..ee31288788c1
--- /dev/null
+++ b/tools/lib/subcmd/Build
@@ -0,0 +1,7 @@
1libsubcmd-y += exec-cmd.o
2libsubcmd-y += help.o
3libsubcmd-y += pager.o
4libsubcmd-y += parse-options.o
5libsubcmd-y += run-command.o
6libsubcmd-y += sigchain.o
7libsubcmd-y += subcmd-config.o
diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile
new file mode 100644
index 000000000000..629cf8c14e68
--- /dev/null
+++ b/tools/lib/subcmd/Makefile
@@ -0,0 +1,48 @@
1include ../../scripts/Makefile.include
2include ../../perf/config/utilities.mak # QUIET_CLEAN
3
4ifeq ($(srctree),)
5srctree := $(patsubst %/,%,$(dir $(shell pwd)))
6srctree := $(patsubst %/,%,$(dir $(srctree)))
7srctree := $(patsubst %/,%,$(dir $(srctree)))
8#$(info Determined 'srctree' to be $(srctree))
9endif
10
11CC = $(CROSS_COMPILE)gcc
12AR = $(CROSS_COMPILE)ar
13RM = rm -f
14
15MAKEFLAGS += --no-print-directory
16
17LIBFILE = $(OUTPUT)libsubcmd.a
18
19CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
20CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
21CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
22
23CFLAGS += -I$(srctree)/tools/include/
24CFLAGS += -I$(srctree)/include/uapi
25CFLAGS += -I$(srctree)/include
26
27SUBCMD_IN := $(OUTPUT)libsubcmd-in.o
28
29all:
30
31export srctree OUTPUT CC LD CFLAGS V
32include $(srctree)/tools/build/Makefile.include
33
34all: fixdep $(LIBFILE)
35
36$(SUBCMD_IN): FORCE
37 @$(MAKE) $(build)=libsubcmd
38
39$(LIBFILE): $(SUBCMD_IN)
40 $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(SUBCMD_IN)
41
42clean:
43 $(call QUIET_CLEAN, libsubcmd) $(RM) $(LIBFILE); \
44 find $(if $(OUTPUT),$(OUTPUT),.) -name \*.o -or -name \*.o.cmd -or -name \*.o.d | xargs $(RM)
45
46FORCE:
47
48.PHONY: clean FORCE
diff --git a/tools/lib/subcmd/exec-cmd.c b/tools/lib/subcmd/exec-cmd.c
new file mode 100644
index 000000000000..1ae833af1a4a
--- /dev/null
+++ b/tools/lib/subcmd/exec-cmd.c
@@ -0,0 +1,209 @@
1#include <linux/compiler.h>
2#include <linux/string.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <unistd.h>
6#include <string.h>
7#include <stdlib.h>
8#include <stdio.h>
9#include "subcmd-util.h"
10#include "exec-cmd.h"
11#include "subcmd-config.h"
12
13#define MAX_ARGS 32
14#define PATH_MAX 4096
15
16static const char *argv_exec_path;
17static const char *argv0_path;
18
19void exec_cmd_init(const char *exec_name, const char *prefix,
20 const char *exec_path, const char *exec_path_env)
21{
22 subcmd_config.exec_name = exec_name;
23 subcmd_config.prefix = prefix;
24 subcmd_config.exec_path = exec_path;
25 subcmd_config.exec_path_env = exec_path_env;
26}
27
28#define is_dir_sep(c) ((c) == '/')
29
30static int is_absolute_path(const char *path)
31{
32 return path[0] == '/';
33}
34
35static const char *get_pwd_cwd(void)
36{
37 static char cwd[PATH_MAX + 1];
38 char *pwd;
39 struct stat cwd_stat, pwd_stat;
40 if (getcwd(cwd, PATH_MAX) == NULL)
41 return NULL;
42 pwd = getenv("PWD");
43 if (pwd && strcmp(pwd, cwd)) {
44 stat(cwd, &cwd_stat);
45 if (!stat(pwd, &pwd_stat) &&
46 pwd_stat.st_dev == cwd_stat.st_dev &&
47 pwd_stat.st_ino == cwd_stat.st_ino) {
48 strlcpy(cwd, pwd, PATH_MAX);
49 }
50 }
51 return cwd;
52}
53
54static const char *make_nonrelative_path(const char *path)
55{
56 static char buf[PATH_MAX + 1];
57
58 if (is_absolute_path(path)) {
59 if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
60 die("Too long path: %.*s", 60, path);
61 } else {
62 const char *cwd = get_pwd_cwd();
63 if (!cwd)
64 die("Cannot determine the current working directory");
65 if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
66 die("Too long path: %.*s", 60, path);
67 }
68 return buf;
69}
70
71char *system_path(const char *path)
72{
73 char *buf = NULL;
74
75 if (is_absolute_path(path))
76 return strdup(path);
77
78 astrcatf(&buf, "%s/%s", subcmd_config.prefix, path);
79
80 return buf;
81}
82
83const char *extract_argv0_path(const char *argv0)
84{
85 const char *slash;
86
87 if (!argv0 || !*argv0)
88 return NULL;
89 slash = argv0 + strlen(argv0);
90
91 while (argv0 <= slash && !is_dir_sep(*slash))
92 slash--;
93
94 if (slash >= argv0) {
95 argv0_path = strndup(argv0, slash - argv0);
96 return argv0_path ? slash + 1 : NULL;
97 }
98
99 return argv0;
100}
101
102void set_argv_exec_path(const char *exec_path)
103{
104 argv_exec_path = exec_path;
105 /*
106 * Propagate this setting to external programs.
107 */
108 setenv(subcmd_config.exec_path_env, exec_path, 1);
109}
110
111
112/* Returns the highest-priority location to look for subprograms. */
113char *get_argv_exec_path(void)
114{
115 char *env;
116
117 if (argv_exec_path)
118 return strdup(argv_exec_path);
119
120 env = getenv(subcmd_config.exec_path_env);
121 if (env && *env)
122 return strdup(env);
123
124 return system_path(subcmd_config.exec_path);
125}
126
127static void add_path(char **out, const char *path)
128{
129 if (path && *path) {
130 if (is_absolute_path(path))
131 astrcat(out, path);
132 else
133 astrcat(out, make_nonrelative_path(path));
134
135 astrcat(out, ":");
136 }
137}
138
139void setup_path(void)
140{
141 const char *old_path = getenv("PATH");
142 char *new_path = NULL;
143 char *tmp = get_argv_exec_path();
144
145 add_path(&new_path, tmp);
146 add_path(&new_path, argv0_path);
147 free(tmp);
148
149 if (old_path)
150 astrcat(&new_path, old_path);
151 else
152 astrcat(&new_path, "/usr/local/bin:/usr/bin:/bin");
153
154 setenv("PATH", new_path, 1);
155
156 free(new_path);
157}
158
159static const char **prepare_exec_cmd(const char **argv)
160{
161 int argc;
162 const char **nargv;
163
164 for (argc = 0; argv[argc]; argc++)
165 ; /* just counting */
166 nargv = malloc(sizeof(*nargv) * (argc + 2));
167
168 nargv[0] = subcmd_config.exec_name;
169 for (argc = 0; argv[argc]; argc++)
170 nargv[argc + 1] = argv[argc];
171 nargv[argc + 1] = NULL;
172 return nargv;
173}
174
175int execv_cmd(const char **argv) {
176 const char **nargv = prepare_exec_cmd(argv);
177
178 /* execvp() can only ever return if it fails */
179 execvp(subcmd_config.exec_name, (char **)nargv);
180
181 free(nargv);
182 return -1;
183}
184
185
186int execl_cmd(const char *cmd,...)
187{
188 int argc;
189 const char *argv[MAX_ARGS + 1];
190 const char *arg;
191 va_list param;
192
193 va_start(param, cmd);
194 argv[0] = cmd;
195 argc = 1;
196 while (argc < MAX_ARGS) {
197 arg = argv[argc++] = va_arg(param, char *);
198 if (!arg)
199 break;
200 }
201 va_end(param);
202 if (MAX_ARGS <= argc) {
203 fprintf(stderr, " Error: too many args to run %s\n", cmd);
204 return -1;
205 }
206
207 argv[argc] = NULL;
208 return execv_cmd(argv);
209}
diff --git a/tools/lib/subcmd/exec-cmd.h b/tools/lib/subcmd/exec-cmd.h
new file mode 100644
index 000000000000..5d08bda31d90
--- /dev/null
+++ b/tools/lib/subcmd/exec-cmd.h
@@ -0,0 +1,16 @@
1#ifndef __SUBCMD_EXEC_CMD_H
2#define __SUBCMD_EXEC_CMD_H
3
4extern void exec_cmd_init(const char *exec_name, const char *prefix,
5 const char *exec_path, const char *exec_path_env);
6
7extern void set_argv_exec_path(const char *exec_path);
8extern const char *extract_argv0_path(const char *path);
9extern void setup_path(void);
10extern int execv_cmd(const char **argv); /* NULL terminated */
11extern int execl_cmd(const char *cmd, ...);
12/* get_argv_exec_path and system_path return malloc'd string, caller must free it */
13extern char *get_argv_exec_path(void);
14extern char *system_path(const char *path);
15
16#endif /* __SUBCMD_EXEC_CMD_H */
diff --git a/tools/perf/util/help.c b/tools/lib/subcmd/help.c
index 929c93f2c333..e228c3cb3716 100644
--- a/tools/perf/util/help.c
+++ b/tools/lib/subcmd/help.c
@@ -1,9 +1,15 @@
1#include "cache.h" 1#include <stdio.h>
2#include "../builtin.h" 2#include <stdlib.h>
3#include "exec_cmd.h" 3#include <string.h>
4#include "levenshtein.h"
5#include "help.h"
6#include <termios.h> 4#include <termios.h>
5#include <sys/ioctl.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <unistd.h>
9#include <dirent.h>
10#include "subcmd-util.h"
11#include "help.h"
12#include "exec-cmd.h"
7 13
8void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) 14void add_cmdname(struct cmdnames *cmds, const char *name, size_t len)
9{ 15{
@@ -17,7 +23,7 @@ void add_cmdname(struct cmdnames *cmds, const char *name, size_t len)
17 cmds->names[cmds->cnt++] = ent; 23 cmds->names[cmds->cnt++] = ent;
18} 24}
19 25
20static void clean_cmdnames(struct cmdnames *cmds) 26void clean_cmdnames(struct cmdnames *cmds)
21{ 27{
22 unsigned int i; 28 unsigned int i;
23 29
@@ -28,14 +34,14 @@ static void clean_cmdnames(struct cmdnames *cmds)
28 cmds->alloc = 0; 34 cmds->alloc = 0;
29} 35}
30 36
31static int cmdname_compare(const void *a_, const void *b_) 37int cmdname_compare(const void *a_, const void *b_)
32{ 38{
33 struct cmdname *a = *(struct cmdname **)a_; 39 struct cmdname *a = *(struct cmdname **)a_;
34 struct cmdname *b = *(struct cmdname **)b_; 40 struct cmdname *b = *(struct cmdname **)b_;
35 return strcmp(a->name, b->name); 41 return strcmp(a->name, b->name);
36} 42}
37 43
38static void uniq(struct cmdnames *cmds) 44void uniq(struct cmdnames *cmds)
39{ 45{
40 unsigned int i, j; 46 unsigned int i, j;
41 47
@@ -71,6 +77,28 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
71 cmds->cnt = cj; 77 cmds->cnt = cj;
72} 78}
73 79
80static void get_term_dimensions(struct winsize *ws)
81{
82 char *s = getenv("LINES");
83
84 if (s != NULL) {
85 ws->ws_row = atoi(s);
86 s = getenv("COLUMNS");
87 if (s != NULL) {
88 ws->ws_col = atoi(s);
89 if (ws->ws_row && ws->ws_col)
90 return;
91 }
92 }
93#ifdef TIOCGWINSZ
94 if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
95 ws->ws_row && ws->ws_col)
96 return;
97#endif
98 ws->ws_row = 25;
99 ws->ws_col = 80;
100}
101
74static void pretty_print_string_list(struct cmdnames *cmds, int longest) 102static void pretty_print_string_list(struct cmdnames *cmds, int longest)
75{ 103{
76 int cols = 1, rows; 104 int cols = 1, rows;
@@ -114,6 +142,14 @@ static int is_executable(const char *name)
114 return st.st_mode & S_IXUSR; 142 return st.st_mode & S_IXUSR;
115} 143}
116 144
145static int has_extension(const char *filename, const char *ext)
146{
147 size_t len = strlen(filename);
148 size_t extlen = strlen(ext);
149
150 return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
151}
152
117static void list_commands_in_dir(struct cmdnames *cmds, 153static void list_commands_in_dir(struct cmdnames *cmds,
118 const char *path, 154 const char *path,
119 const char *prefix) 155 const char *prefix)
@@ -121,8 +157,7 @@ static void list_commands_in_dir(struct cmdnames *cmds,
121 int prefix_len; 157 int prefix_len;
122 DIR *dir = opendir(path); 158 DIR *dir = opendir(path);
123 struct dirent *de; 159 struct dirent *de;
124 struct strbuf buf = STRBUF_INIT; 160 char *buf = NULL;
125 int len;
126 161
127 if (!dir) 162 if (!dir)
128 return; 163 return;
@@ -130,8 +165,7 @@ static void list_commands_in_dir(struct cmdnames *cmds,
130 prefix = "perf-"; 165 prefix = "perf-";
131 prefix_len = strlen(prefix); 166 prefix_len = strlen(prefix);
132 167
133 strbuf_addf(&buf, "%s/", path); 168 astrcatf(&buf, "%s/", path);
134 len = buf.len;
135 169
136 while ((de = readdir(dir)) != NULL) { 170 while ((de = readdir(dir)) != NULL) {
137 int entlen; 171 int entlen;
@@ -139,9 +173,8 @@ static void list_commands_in_dir(struct cmdnames *cmds,
139 if (prefixcmp(de->d_name, prefix)) 173 if (prefixcmp(de->d_name, prefix))
140 continue; 174 continue;
141 175
142 strbuf_setlen(&buf, len); 176 astrcat(&buf, de->d_name);
143 strbuf_addstr(&buf, de->d_name); 177 if (!is_executable(buf))
144 if (!is_executable(buf.buf))
145 continue; 178 continue;
146 179
147 entlen = strlen(de->d_name) - prefix_len; 180 entlen = strlen(de->d_name) - prefix_len;
@@ -151,7 +184,7 @@ static void list_commands_in_dir(struct cmdnames *cmds,
151 add_cmdname(cmds, de->d_name + prefix_len, entlen); 184 add_cmdname(cmds, de->d_name + prefix_len, entlen);
152 } 185 }
153 closedir(dir); 186 closedir(dir);
154 strbuf_release(&buf); 187 free(buf);
155} 188}
156 189
157void load_command_list(const char *prefix, 190void load_command_list(const char *prefix,
@@ -159,7 +192,7 @@ void load_command_list(const char *prefix,
159 struct cmdnames *other_cmds) 192 struct cmdnames *other_cmds)
160{ 193{
161 const char *env_path = getenv("PATH"); 194 const char *env_path = getenv("PATH");
162 char *exec_path = perf_exec_path(); 195 char *exec_path = get_argv_exec_path();
163 196
164 if (exec_path) { 197 if (exec_path) {
165 list_commands_in_dir(main_cmds, exec_path, prefix); 198 list_commands_in_dir(main_cmds, exec_path, prefix);
@@ -172,7 +205,7 @@ void load_command_list(const char *prefix,
172 char *paths, *path, *colon; 205 char *paths, *path, *colon;
173 path = paths = strdup(env_path); 206 path = paths = strdup(env_path);
174 while (1) { 207 while (1) {
175 if ((colon = strchr(path, PATH_SEP))) 208 if ((colon = strchr(path, ':')))
176 *colon = 0; 209 *colon = 0;
177 if (!exec_path || strcmp(path, exec_path)) 210 if (!exec_path || strcmp(path, exec_path))
178 list_commands_in_dir(other_cmds, path, prefix); 211 list_commands_in_dir(other_cmds, path, prefix);
@@ -204,7 +237,7 @@ void list_commands(const char *title, struct cmdnames *main_cmds,
204 longest = other_cmds->names[i]->len; 237 longest = other_cmds->names[i]->len;
205 238
206 if (main_cmds->cnt) { 239 if (main_cmds->cnt) {
207 char *exec_path = perf_exec_path(); 240 char *exec_path = get_argv_exec_path();
208 printf("available %s in '%s'\n", title, exec_path); 241 printf("available %s in '%s'\n", title, exec_path);
209 printf("----------------"); 242 printf("----------------");
210 mput_char('-', strlen(title) + strlen(exec_path)); 243 mput_char('-', strlen(title) + strlen(exec_path));
@@ -233,102 +266,3 @@ int is_in_cmdlist(struct cmdnames *c, const char *s)
233 return 1; 266 return 1;
234 return 0; 267 return 0;
235} 268}
236
237static int autocorrect;
238static struct cmdnames aliases;
239
240static int perf_unknown_cmd_config(const char *var, const char *value, void *cb)
241{
242 if (!strcmp(var, "help.autocorrect"))
243 autocorrect = perf_config_int(var,value);
244 /* Also use aliases for command lookup */
245 if (!prefixcmp(var, "alias."))
246 add_cmdname(&aliases, var + 6, strlen(var + 6));
247
248 return perf_default_config(var, value, cb);
249}
250
251static int levenshtein_compare(const void *p1, const void *p2)
252{
253 const struct cmdname *const *c1 = p1, *const *c2 = p2;
254 const char *s1 = (*c1)->name, *s2 = (*c2)->name;
255 int l1 = (*c1)->len;
256 int l2 = (*c2)->len;
257 return l1 != l2 ? l1 - l2 : strcmp(s1, s2);
258}
259
260static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
261{
262 unsigned int i;
263
264 ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);
265
266 for (i = 0; i < old->cnt; i++)
267 cmds->names[cmds->cnt++] = old->names[i];
268 zfree(&old->names);
269 old->cnt = 0;
270}
271
272const char *help_unknown_cmd(const char *cmd)
273{
274 unsigned int i, n = 0, best_similarity = 0;
275 struct cmdnames main_cmds, other_cmds;
276
277 memset(&main_cmds, 0, sizeof(main_cmds));
278 memset(&other_cmds, 0, sizeof(main_cmds));
279 memset(&aliases, 0, sizeof(aliases));
280
281 perf_config(perf_unknown_cmd_config, NULL);
282
283 load_command_list("perf-", &main_cmds, &other_cmds);
284
285 add_cmd_list(&main_cmds, &aliases);
286 add_cmd_list(&main_cmds, &other_cmds);
287 qsort(main_cmds.names, main_cmds.cnt,
288 sizeof(main_cmds.names), cmdname_compare);
289 uniq(&main_cmds);
290
291 if (main_cmds.cnt) {
292 /* This reuses cmdname->len for similarity index */
293 for (i = 0; i < main_cmds.cnt; ++i)
294 main_cmds.names[i]->len =
295 levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4);
296
297 qsort(main_cmds.names, main_cmds.cnt,
298 sizeof(*main_cmds.names), levenshtein_compare);
299
300 best_similarity = main_cmds.names[0]->len;
301 n = 1;
302 while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len)
303 ++n;
304 }
305
306 if (autocorrect && n == 1) {
307 const char *assumed = main_cmds.names[0]->name;
308
309 main_cmds.names[0] = NULL;
310 clean_cmdnames(&main_cmds);
311 fprintf(stderr, "WARNING: You called a perf program named '%s', "
312 "which does not exist.\n"
313 "Continuing under the assumption that you meant '%s'\n",
314 cmd, assumed);
315 if (autocorrect > 0) {
316 fprintf(stderr, "in %0.1f seconds automatically...\n",
317 (float)autocorrect/10.0);
318 poll(NULL, 0, autocorrect * 100);
319 }
320 return assumed;
321 }
322
323 fprintf(stderr, "perf: '%s' is not a perf-command. See 'perf --help'.\n", cmd);
324
325 if (main_cmds.cnt && best_similarity < 6) {
326 fprintf(stderr, "\nDid you mean %s?\n",
327 n < 2 ? "this": "one of these");
328
329 for (i = 0; i < n; i++)
330 fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
331 }
332
333 exit(1);
334}
diff --git a/tools/perf/util/help.h b/tools/lib/subcmd/help.h
index 7f5c6dedd714..e145a020780c 100644
--- a/tools/perf/util/help.h
+++ b/tools/lib/subcmd/help.h
@@ -1,12 +1,14 @@
1#ifndef __PERF_HELP_H 1#ifndef __SUBCMD_HELP_H
2#define __PERF_HELP_H 2#define __SUBCMD_HELP_H
3
4#include <sys/types.h>
3 5
4struct cmdnames { 6struct cmdnames {
5 size_t alloc; 7 size_t alloc;
6 size_t cnt; 8 size_t cnt;
7 struct cmdname { 9 struct cmdname {
8 size_t len; /* also used for similarity index in help.c */ 10 size_t len; /* also used for similarity index in help.c */
9 char name[FLEX_ARRAY]; 11 char name[];
10 } **names; 12 } **names;
11}; 13};
12 14
@@ -20,10 +22,13 @@ void load_command_list(const char *prefix,
20 struct cmdnames *main_cmds, 22 struct cmdnames *main_cmds,
21 struct cmdnames *other_cmds); 23 struct cmdnames *other_cmds);
22void add_cmdname(struct cmdnames *cmds, const char *name, size_t len); 24void add_cmdname(struct cmdnames *cmds, const char *name, size_t len);
25void clean_cmdnames(struct cmdnames *cmds);
26int cmdname_compare(const void *a, const void *b);
27void uniq(struct cmdnames *cmds);
23/* Here we require that excludes is a sorted list. */ 28/* Here we require that excludes is a sorted list. */
24void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); 29void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);
25int is_in_cmdlist(struct cmdnames *c, const char *s); 30int is_in_cmdlist(struct cmdnames *c, const char *s);
26void list_commands(const char *title, struct cmdnames *main_cmds, 31void list_commands(const char *title, struct cmdnames *main_cmds,
27 struct cmdnames *other_cmds); 32 struct cmdnames *other_cmds);
28 33
29#endif /* __PERF_HELP_H */ 34#endif /* __SUBCMD_HELP_H */
diff --git a/tools/perf/util/pager.c b/tools/lib/subcmd/pager.c
index 53ef006a951c..d50f3b58606b 100644
--- a/tools/perf/util/pager.c
+++ b/tools/lib/subcmd/pager.c
@@ -1,6 +1,12 @@
1#include "cache.h" 1#include <sys/select.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5#include <signal.h>
6#include "pager.h"
2#include "run-command.h" 7#include "run-command.h"
3#include "sigchain.h" 8#include "sigchain.h"
9#include "subcmd-config.h"
4 10
5/* 11/*
6 * This is split up from the rest of git so that we can do 12 * This is split up from the rest of git so that we can do
@@ -9,6 +15,11 @@
9 15
10static int spawned_pager; 16static int spawned_pager;
11 17
18void pager_init(const char *pager_env)
19{
20 subcmd_config.pager_env = pager_env;
21}
22
12static void pager_preexec(void) 23static void pager_preexec(void)
13{ 24{
14 /* 25 /*
@@ -46,7 +57,7 @@ static void wait_for_pager_signal(int signo)
46 57
47void setup_pager(void) 58void setup_pager(void)
48{ 59{
49 const char *pager = getenv("PERF_PAGER"); 60 const char *pager = getenv(subcmd_config.pager_env);
50 61
51 if (!isatty(1)) 62 if (!isatty(1))
52 return; 63 return;
@@ -85,11 +96,5 @@ void setup_pager(void)
85 96
86int pager_in_use(void) 97int pager_in_use(void)
87{ 98{
88 const char *env; 99 return spawned_pager;
89
90 if (spawned_pager)
91 return 1;
92
93 env = getenv("PERF_PAGER_IN_USE");
94 return env ? perf_config_bool("PERF_PAGER_IN_USE", env) : 0;
95} 100}
diff --git a/tools/lib/subcmd/pager.h b/tools/lib/subcmd/pager.h
new file mode 100644
index 000000000000..8b83714ecf73
--- /dev/null
+++ b/tools/lib/subcmd/pager.h
@@ -0,0 +1,9 @@
1#ifndef __SUBCMD_PAGER_H
2#define __SUBCMD_PAGER_H
3
4extern void pager_init(const char *pager_env);
5
6extern void setup_pager(void);
7extern int pager_in_use(void);
8
9#endif /* __SUBCMD_PAGER_H */
diff --git a/tools/perf/util/parse-options.c b/tools/lib/subcmd/parse-options.c
index de3290b47db1..981bb4481fd5 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/lib/subcmd/parse-options.c
@@ -1,37 +1,66 @@
1#include "util.h" 1#include <linux/compiler.h>
2#include <linux/types.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <stdint.h>
6#include <string.h>
7#include <ctype.h>
8#include "subcmd-util.h"
2#include "parse-options.h" 9#include "parse-options.h"
3#include "cache.h" 10#include "subcmd-config.h"
4#include "header.h" 11#include "pager.h"
5#include <linux/string.h>
6 12
7#define OPT_SHORT 1 13#define OPT_SHORT 1
8#define OPT_UNSET 2 14#define OPT_UNSET 2
9 15
10static struct strbuf error_buf = STRBUF_INIT; 16char *error_buf;
11 17
12static int opterror(const struct option *opt, const char *reason, int flags) 18static int opterror(const struct option *opt, const char *reason, int flags)
13{ 19{
14 if (flags & OPT_SHORT) 20 if (flags & OPT_SHORT)
15 return error("switch `%c' %s", opt->short_name, reason); 21 fprintf(stderr, " Error: switch `%c' %s", opt->short_name, reason);
16 if (flags & OPT_UNSET) 22 else if (flags & OPT_UNSET)
17 return error("option `no-%s' %s", opt->long_name, reason); 23 fprintf(stderr, " Error: option `no-%s' %s", opt->long_name, reason);
18 return error("option `%s' %s", opt->long_name, reason); 24 else
25 fprintf(stderr, " Error: option `%s' %s", opt->long_name, reason);
26
27 return -1;
28}
29
30static const char *skip_prefix(const char *str, const char *prefix)
31{
32 size_t len = strlen(prefix);
33 return strncmp(str, prefix, len) ? NULL : str + len;
34}
35
36static void optwarning(const struct option *opt, const char *reason, int flags)
37{
38 if (flags & OPT_SHORT)
39 fprintf(stderr, " Warning: switch `%c' %s", opt->short_name, reason);
40 else if (flags & OPT_UNSET)
41 fprintf(stderr, " Warning: option `no-%s' %s", opt->long_name, reason);
42 else
43 fprintf(stderr, " Warning: option `%s' %s", opt->long_name, reason);
19} 44}
20 45
21static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt, 46static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
22 int flags, const char **arg) 47 int flags, const char **arg)
23{ 48{
49 const char *res;
50
24 if (p->opt) { 51 if (p->opt) {
25 *arg = p->opt; 52 res = p->opt;
26 p->opt = NULL; 53 p->opt = NULL;
27 } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 || 54 } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
28 **(p->argv + 1) == '-')) { 55 **(p->argv + 1) == '-')) {
29 *arg = (const char *)opt->defval; 56 res = (const char *)opt->defval;
30 } else if (p->argc > 1) { 57 } else if (p->argc > 1) {
31 p->argc--; 58 p->argc--;
32 *arg = *++p->argv; 59 res = *++p->argv;
33 } else 60 } else
34 return opterror(opt, "requires a value", flags); 61 return opterror(opt, "requires a value", flags);
62 if (arg)
63 *arg = res;
35 return 0; 64 return 0;
36} 65}
37 66
@@ -55,11 +84,11 @@ static int get_value(struct parse_opt_ctx_t *p,
55 84
56 if (((flags & OPT_SHORT) && p->excl_opt->short_name) || 85 if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
57 p->excl_opt->long_name == NULL) { 86 p->excl_opt->long_name == NULL) {
58 scnprintf(msg, sizeof(msg), "cannot be used with switch `%c'", 87 snprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
59 p->excl_opt->short_name); 88 p->excl_opt->short_name);
60 } else { 89 } else {
61 scnprintf(msg, sizeof(msg), "cannot be used with %s", 90 snprintf(msg, sizeof(msg), "cannot be used with %s",
62 p->excl_opt->long_name); 91 p->excl_opt->long_name);
63 } 92 }
64 opterror(opt, msg, flags); 93 opterror(opt, msg, flags);
65 return -3; 94 return -3;
@@ -91,6 +120,64 @@ static int get_value(struct parse_opt_ctx_t *p,
91 } 120 }
92 } 121 }
93 122
123 if (opt->flags & PARSE_OPT_NOBUILD) {
124 char reason[128];
125 bool noarg = false;
126
127 err = snprintf(reason, sizeof(reason),
128 opt->flags & PARSE_OPT_CANSKIP ?
129 "is being ignored because %s " :
130 "is not available because %s",
131 opt->build_opt);
132 reason[sizeof(reason) - 1] = '\0';
133
134 if (err < 0)
135 strncpy(reason, opt->flags & PARSE_OPT_CANSKIP ?
136 "is being ignored" :
137 "is not available",
138 sizeof(reason));
139
140 if (!(opt->flags & PARSE_OPT_CANSKIP))
141 return opterror(opt, reason, flags);
142
143 err = 0;
144 if (unset)
145 noarg = true;
146 if (opt->flags & PARSE_OPT_NOARG)
147 noarg = true;
148 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
149 noarg = true;
150
151 switch (opt->type) {
152 case OPTION_BOOLEAN:
153 case OPTION_INCR:
154 case OPTION_BIT:
155 case OPTION_SET_UINT:
156 case OPTION_SET_PTR:
157 case OPTION_END:
158 case OPTION_ARGUMENT:
159 case OPTION_GROUP:
160 noarg = true;
161 break;
162 case OPTION_CALLBACK:
163 case OPTION_STRING:
164 case OPTION_INTEGER:
165 case OPTION_UINTEGER:
166 case OPTION_LONG:
167 case OPTION_U64:
168 default:
169 break;
170 }
171
172 if (!noarg)
173 err = get_arg(p, opt, flags, NULL);
174 if (err)
175 return err;
176
177 optwarning(opt, reason, flags);
178 return 0;
179 }
180
94 switch (opt->type) { 181 switch (opt->type) {
95 case OPTION_BIT: 182 case OPTION_BIT:
96 if (unset) 183 if (unset)
@@ -327,14 +414,16 @@ match:
327 return get_value(p, options, flags); 414 return get_value(p, options, flags);
328 } 415 }
329 416
330 if (ambiguous_option) 417 if (ambiguous_option) {
331 return error("Ambiguous option: %s " 418 fprintf(stderr,
332 "(could be --%s%s or --%s%s)", 419 " Error: Ambiguous option: %s (could be --%s%s or --%s%s)",
333 arg, 420 arg,
334 (ambiguous_flags & OPT_UNSET) ? "no-" : "", 421 (ambiguous_flags & OPT_UNSET) ? "no-" : "",
335 ambiguous_option->long_name, 422 ambiguous_option->long_name,
336 (abbrev_flags & OPT_UNSET) ? "no-" : "", 423 (abbrev_flags & OPT_UNSET) ? "no-" : "",
337 abbrev_option->long_name); 424 abbrev_option->long_name);
425 return -1;
426 }
338 if (abbrev_option) 427 if (abbrev_option)
339 return get_value(p, abbrev_option, abbrev_flags); 428 return get_value(p, abbrev_option, abbrev_flags);
340 return -2; 429 return -2;
@@ -346,7 +435,7 @@ static void check_typos(const char *arg, const struct option *options)
346 return; 435 return;
347 436
348 if (!prefixcmp(arg, "no-")) { 437 if (!prefixcmp(arg, "no-")) {
349 error ("did you mean `--%s` (with two dashes ?)", arg); 438 fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
350 exit(129); 439 exit(129);
351 } 440 }
352 441
@@ -354,14 +443,14 @@ static void check_typos(const char *arg, const struct option *options)
354 if (!options->long_name) 443 if (!options->long_name)
355 continue; 444 continue;
356 if (!prefixcmp(options->long_name, arg)) { 445 if (!prefixcmp(options->long_name, arg)) {
357 error ("did you mean `--%s` (with two dashes ?)", arg); 446 fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
358 exit(129); 447 exit(129);
359 } 448 }
360 } 449 }
361} 450}
362 451
363void parse_options_start(struct parse_opt_ctx_t *ctx, 452static void parse_options_start(struct parse_opt_ctx_t *ctx,
364 int argc, const char **argv, int flags) 453 int argc, const char **argv, int flags)
365{ 454{
366 memset(ctx, 0, sizeof(*ctx)); 455 memset(ctx, 0, sizeof(*ctx));
367 ctx->argc = argc - 1; 456 ctx->argc = argc - 1;
@@ -378,9 +467,9 @@ static int usage_with_options_internal(const char * const *,
378 const struct option *, int, 467 const struct option *, int,
379 struct parse_opt_ctx_t *); 468 struct parse_opt_ctx_t *);
380 469
381int parse_options_step(struct parse_opt_ctx_t *ctx, 470static int parse_options_step(struct parse_opt_ctx_t *ctx,
382 const struct option *options, 471 const struct option *options,
383 const char * const usagestr[]) 472 const char * const usagestr[])
384{ 473{
385 int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); 474 int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
386 int excl_short_opt = 1; 475 int excl_short_opt = 1;
@@ -489,7 +578,7 @@ exclusive:
489 return PARSE_OPT_HELP; 578 return PARSE_OPT_HELP;
490} 579}
491 580
492int parse_options_end(struct parse_opt_ctx_t *ctx) 581static int parse_options_end(struct parse_opt_ctx_t *ctx)
493{ 582{
494 memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out)); 583 memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
495 ctx->out[ctx->cpidx + ctx->argc] = NULL; 584 ctx->out[ctx->cpidx + ctx->argc] = NULL;
@@ -503,18 +592,18 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
503 592
504 /* build usage string if it's not provided */ 593 /* build usage string if it's not provided */
505 if (subcommands && !usagestr[0]) { 594 if (subcommands && !usagestr[0]) {
506 struct strbuf buf = STRBUF_INIT; 595 char *buf = NULL;
596
597 astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]);
507 598
508 strbuf_addf(&buf, "perf %s [<options>] {", argv[0]);
509 for (int i = 0; subcommands[i]; i++) { 599 for (int i = 0; subcommands[i]; i++) {
510 if (i) 600 if (i)
511 strbuf_addstr(&buf, "|"); 601 astrcat(&buf, "|");
512 strbuf_addstr(&buf, subcommands[i]); 602 astrcat(&buf, subcommands[i]);
513 } 603 }
514 strbuf_addstr(&buf, "}"); 604 astrcat(&buf, "}");
515 605
516 usagestr[0] = strdup(buf.buf); 606 usagestr[0] = buf;
517 strbuf_release(&buf);
518 } 607 }
519 608
520 parse_options_start(&ctx, argc, argv, flags); 609 parse_options_start(&ctx, argc, argv, flags);
@@ -539,13 +628,11 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o
539 putchar('\n'); 628 putchar('\n');
540 exit(130); 629 exit(130);
541 default: /* PARSE_OPT_UNKNOWN */ 630 default: /* PARSE_OPT_UNKNOWN */
542 if (ctx.argv[0][1] == '-') { 631 if (ctx.argv[0][1] == '-')
543 strbuf_addf(&error_buf, "unknown option `%s'", 632 astrcatf(&error_buf, "unknown option `%s'",
544 ctx.argv[0] + 2); 633 ctx.argv[0] + 2);
545 } else { 634 else
546 strbuf_addf(&error_buf, "unknown switch `%c'", 635 astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt);
547 *ctx.opt);
548 }
549 usage_with_options(usagestr, options); 636 usage_with_options(usagestr, options);
550 } 637 }
551 638
@@ -645,6 +732,10 @@ static void print_option_help(const struct option *opts, int full)
645 pad = USAGE_OPTS_WIDTH; 732 pad = USAGE_OPTS_WIDTH;
646 } 733 }
647 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help); 734 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
735 if (opts->flags & PARSE_OPT_NOBUILD)
736 fprintf(stderr, "%*s(not built-in because %s)\n",
737 USAGE_OPTS_WIDTH + USAGE_GAP, "",
738 opts->build_opt);
648} 739}
649 740
650static int option__cmp(const void *va, const void *vb) 741static int option__cmp(const void *va, const void *vb)
@@ -670,16 +761,18 @@ static int option__cmp(const void *va, const void *vb)
670 761
671static struct option *options__order(const struct option *opts) 762static struct option *options__order(const struct option *opts)
672{ 763{
673 int nr_opts = 0; 764 int nr_opts = 0, len;
674 const struct option *o = opts; 765 const struct option *o = opts;
675 struct option *ordered; 766 struct option *ordered;
676 767
677 for (o = opts; o->type != OPTION_END; o++) 768 for (o = opts; o->type != OPTION_END; o++)
678 ++nr_opts; 769 ++nr_opts;
679 770
680 ordered = memdup(opts, sizeof(*o) * (nr_opts + 1)); 771 len = sizeof(*o) * (nr_opts + 1);
681 if (ordered == NULL) 772 ordered = malloc(len);
773 if (!ordered)
682 goto out; 774 goto out;
775 memcpy(ordered, opts, len);
683 776
684 qsort(ordered, nr_opts, sizeof(*o), option__cmp); 777 qsort(ordered, nr_opts, sizeof(*o), option__cmp);
685out: 778out:
@@ -717,9 +810,9 @@ static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx
717 return false; 810 return false;
718} 811}
719 812
720int usage_with_options_internal(const char * const *usagestr, 813static int usage_with_options_internal(const char * const *usagestr,
721 const struct option *opts, int full, 814 const struct option *opts, int full,
722 struct parse_opt_ctx_t *ctx) 815 struct parse_opt_ctx_t *ctx)
723{ 816{
724 struct option *ordered; 817 struct option *ordered;
725 818
@@ -728,9 +821,9 @@ int usage_with_options_internal(const char * const *usagestr,
728 821
729 setup_pager(); 822 setup_pager();
730 823
731 if (strbuf_avail(&error_buf)) { 824 if (error_buf) {
732 fprintf(stderr, " Error: %s\n", error_buf.buf); 825 fprintf(stderr, " Error: %s\n", error_buf);
733 strbuf_release(&error_buf); 826 zfree(&error_buf);
734 } 827 }
735 828
736 fprintf(stderr, "\n Usage: %s\n", *usagestr++); 829 fprintf(stderr, "\n Usage: %s\n", *usagestr++);
@@ -774,11 +867,15 @@ void usage_with_options_msg(const char * const *usagestr,
774 const struct option *opts, const char *fmt, ...) 867 const struct option *opts, const char *fmt, ...)
775{ 868{
776 va_list ap; 869 va_list ap;
870 char *tmp = error_buf;
777 871
778 va_start(ap, fmt); 872 va_start(ap, fmt);
779 strbuf_addv(&error_buf, fmt, ap); 873 if (vasprintf(&error_buf, fmt, ap) == -1)
874 die("vasprintf failed");
780 va_end(ap); 875 va_end(ap);
781 876
877 free(tmp);
878
782 usage_with_options_internal(usagestr, opts, 0, NULL); 879 usage_with_options_internal(usagestr, opts, 0, NULL);
783 exit(129); 880 exit(129);
784} 881}
@@ -848,15 +945,39 @@ int parse_opt_verbosity_cb(const struct option *opt,
848 return 0; 945 return 0;
849} 946}
850 947
851void set_option_flag(struct option *opts, int shortopt, const char *longopt, 948static struct option *
852 int flag) 949find_option(struct option *opts, int shortopt, const char *longopt)
853{ 950{
854 for (; opts->type != OPTION_END; opts++) { 951 for (; opts->type != OPTION_END; opts++) {
855 if ((shortopt && opts->short_name == shortopt) || 952 if ((shortopt && opts->short_name == shortopt) ||
856 (opts->long_name && longopt && 953 (opts->long_name && longopt &&
857 !strcmp(opts->long_name, longopt))) { 954 !strcmp(opts->long_name, longopt)))
858 opts->flags |= flag; 955 return opts;
859 break;
860 }
861 } 956 }
957 return NULL;
958}
959
960void set_option_flag(struct option *opts, int shortopt, const char *longopt,
961 int flag)
962{
963 struct option *opt = find_option(opts, shortopt, longopt);
964
965 if (opt)
966 opt->flags |= flag;
967 return;
968}
969
970void set_option_nobuild(struct option *opts, int shortopt,
971 const char *longopt,
972 const char *build_opt,
973 bool can_skip)
974{
975 struct option *opt = find_option(opts, shortopt, longopt);
976
977 if (!opt)
978 return;
979
980 opt->flags |= PARSE_OPT_NOBUILD;
981 opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0;
982 opt->build_opt = build_opt;
862} 983}
diff --git a/tools/perf/util/parse-options.h b/tools/lib/subcmd/parse-options.h
index a8e407bc251e..13a2cc1d6140 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/lib/subcmd/parse-options.h
@@ -1,8 +1,8 @@
1#ifndef __PERF_PARSE_OPTIONS_H 1#ifndef __SUBCMD_PARSE_OPTIONS_H
2#define __PERF_PARSE_OPTIONS_H 2#define __SUBCMD_PARSE_OPTIONS_H
3 3
4#include <linux/kernel.h>
5#include <stdbool.h> 4#include <stdbool.h>
5#include <stdint.h>
6 6
7enum parse_opt_type { 7enum parse_opt_type {
8 /* special types */ 8 /* special types */
@@ -41,6 +41,8 @@ enum parse_opt_option_flags {
41 PARSE_OPT_DISABLED = 32, 41 PARSE_OPT_DISABLED = 32,
42 PARSE_OPT_EXCLUSIVE = 64, 42 PARSE_OPT_EXCLUSIVE = 64,
43 PARSE_OPT_NOEMPTY = 128, 43 PARSE_OPT_NOEMPTY = 128,
44 PARSE_OPT_NOBUILD = 256,
45 PARSE_OPT_CANSKIP = 512,
44}; 46};
45 47
46struct option; 48struct option;
@@ -96,6 +98,7 @@ struct option {
96 void *value; 98 void *value;
97 const char *argh; 99 const char *argh;
98 const char *help; 100 const char *help;
101 const char *build_opt;
99 102
100 int flags; 103 int flags;
101 parse_opt_cb *callback; 104 parse_opt_cb *callback;
@@ -149,6 +152,9 @@ struct option {
149/* parse_options() will filter out the processed options and leave the 152/* parse_options() will filter out the processed options and leave the
150 * non-option argments in argv[]. 153 * non-option argments in argv[].
151 * Returns the number of arguments left in argv[]. 154 * Returns the number of arguments left in argv[].
155 *
156 * NOTE: parse_options() and parse_options_subcommand() may call exit() in the
157 * case of an error (or for 'special' options like --list-cmds or --list-opts).
152 */ 158 */
153extern int parse_options(int argc, const char **argv, 159extern int parse_options(int argc, const char **argv,
154 const struct option *options, 160 const struct option *options,
@@ -195,15 +201,6 @@ extern int parse_options_usage(const char * const *usagestr,
195 const char *optstr, 201 const char *optstr,
196 bool short_opt); 202 bool short_opt);
197 203
198extern void parse_options_start(struct parse_opt_ctx_t *ctx,
199 int argc, const char **argv, int flags);
200
201extern int parse_options_step(struct parse_opt_ctx_t *ctx,
202 const struct option *options,
203 const char * const usagestr[]);
204
205extern int parse_options_end(struct parse_opt_ctx_t *ctx);
206
207 204
208/*----- some often used options -----*/ 205/*----- some often used options -----*/
209extern int parse_opt_abbrev_cb(const struct option *, const char *, int); 206extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
@@ -226,4 +223,7 @@ extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
226extern const char *parse_options_fix_filename(const char *prefix, const char *file); 223extern const char *parse_options_fix_filename(const char *prefix, const char *file);
227 224
228void set_option_flag(struct option *opts, int sopt, const char *lopt, int flag); 225void set_option_flag(struct option *opts, int sopt, const char *lopt, int flag);
229#endif /* __PERF_PARSE_OPTIONS_H */ 226void set_option_nobuild(struct option *opts, int shortopt, const char *longopt,
227 const char *build_opt, bool can_skip);
228
229#endif /* __SUBCMD_PARSE_OPTIONS_H */
diff --git a/tools/perf/util/run-command.c b/tools/lib/subcmd/run-command.c
index 34622b53e733..f4f6c9eb8e59 100644
--- a/tools/perf/util/run-command.c
+++ b/tools/lib/subcmd/run-command.c
@@ -1,7 +1,15 @@
1#include "cache.h" 1#include <unistd.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <string.h>
6#include <errno.h>
7#include <sys/wait.h>
8#include "subcmd-util.h"
2#include "run-command.h" 9#include "run-command.h"
3#include "exec_cmd.h" 10#include "exec-cmd.h"
4#include "debug.h" 11
12#define STRERR_BUFSIZE 128
5 13
6static inline void close_pair(int fd[2]) 14static inline void close_pair(int fd[2])
7{ 15{
@@ -112,8 +120,8 @@ int start_command(struct child_process *cmd)
112 } 120 }
113 if (cmd->preexec_cb) 121 if (cmd->preexec_cb)
114 cmd->preexec_cb(); 122 cmd->preexec_cb();
115 if (cmd->perf_cmd) { 123 if (cmd->exec_cmd) {
116 execv_perf_cmd(cmd->argv); 124 execv_cmd(cmd->argv);
117 } else { 125 } else {
118 execvp(cmd->argv[0], (char *const*) cmd->argv); 126 execvp(cmd->argv[0], (char *const*) cmd->argv);
119 } 127 }
@@ -164,8 +172,8 @@ static int wait_or_whine(pid_t pid)
164 if (waiting < 0) { 172 if (waiting < 0) {
165 if (errno == EINTR) 173 if (errno == EINTR)
166 continue; 174 continue;
167 error("waitpid failed (%s)", 175 fprintf(stderr, " Error: waitpid failed (%s)",
168 strerror_r(errno, sbuf, sizeof(sbuf))); 176 strerror_r(errno, sbuf, sizeof(sbuf)));
169 return -ERR_RUN_COMMAND_WAITPID; 177 return -ERR_RUN_COMMAND_WAITPID;
170 } 178 }
171 if (waiting != pid) 179 if (waiting != pid)
@@ -207,7 +215,7 @@ static void prepare_run_command_v_opt(struct child_process *cmd,
207 memset(cmd, 0, sizeof(*cmd)); 215 memset(cmd, 0, sizeof(*cmd));
208 cmd->argv = argv; 216 cmd->argv = argv;
209 cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; 217 cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0;
210 cmd->perf_cmd = opt & RUN_PERF_CMD ? 1 : 0; 218 cmd->exec_cmd = opt & RUN_EXEC_CMD ? 1 : 0;
211 cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0; 219 cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
212} 220}
213 221
diff --git a/tools/perf/util/run-command.h b/tools/lib/subcmd/run-command.h
index 1ef264d5069c..fe2befea1e73 100644
--- a/tools/perf/util/run-command.h
+++ b/tools/lib/subcmd/run-command.h
@@ -1,5 +1,7 @@
1#ifndef __PERF_RUN_COMMAND_H 1#ifndef __SUBCMD_RUN_COMMAND_H
2#define __PERF_RUN_COMMAND_H 2#define __SUBCMD_RUN_COMMAND_H
3
4#include <unistd.h>
3 5
4enum { 6enum {
5 ERR_RUN_COMMAND_FORK = 10000, 7 ERR_RUN_COMMAND_FORK = 10000,
@@ -41,7 +43,7 @@ struct child_process {
41 unsigned no_stdin:1; 43 unsigned no_stdin:1;
42 unsigned no_stdout:1; 44 unsigned no_stdout:1;
43 unsigned no_stderr:1; 45 unsigned no_stderr:1;
44 unsigned perf_cmd:1; /* if this is to be perf sub-command */ 46 unsigned exec_cmd:1; /* if this is to be external sub-command */
45 unsigned stdout_to_stderr:1; 47 unsigned stdout_to_stderr:1;
46 void (*preexec_cb)(void); 48 void (*preexec_cb)(void);
47}; 49};
@@ -51,8 +53,8 @@ int finish_command(struct child_process *);
51int run_command(struct child_process *); 53int run_command(struct child_process *);
52 54
53#define RUN_COMMAND_NO_STDIN 1 55#define RUN_COMMAND_NO_STDIN 1
54#define RUN_PERF_CMD 2 /*If this is to be perf sub-command */ 56#define RUN_EXEC_CMD 2 /*If this is to be external sub-command */
55#define RUN_COMMAND_STDOUT_TO_STDERR 4 57#define RUN_COMMAND_STDOUT_TO_STDERR 4
56int run_command_v_opt(const char **argv, int opt); 58int run_command_v_opt(const char **argv, int opt);
57 59
58#endif /* __PERF_RUN_COMMAND_H */ 60#endif /* __SUBCMD_RUN_COMMAND_H */
diff --git a/tools/perf/util/sigchain.c b/tools/lib/subcmd/sigchain.c
index ba785e9b1841..3537c348a18e 100644
--- a/tools/perf/util/sigchain.c
+++ b/tools/lib/subcmd/sigchain.c
@@ -1,5 +1,6 @@
1#include <signal.h>
2#include "subcmd-util.h"
1#include "sigchain.h" 3#include "sigchain.h"
2#include "cache.h"
3 4
4#define SIGCHAIN_MAX_SIGNALS 32 5#define SIGCHAIN_MAX_SIGNALS 32
5 6
diff --git a/tools/perf/util/sigchain.h b/tools/lib/subcmd/sigchain.h
index 959d64eb5557..0c919f2874ca 100644
--- a/tools/perf/util/sigchain.h
+++ b/tools/lib/subcmd/sigchain.h
@@ -1,5 +1,5 @@
1#ifndef __PERF_SIGCHAIN_H 1#ifndef __SUBCMD_SIGCHAIN_H
2#define __PERF_SIGCHAIN_H 2#define __SUBCMD_SIGCHAIN_H
3 3
4typedef void (*sigchain_fun)(int); 4typedef void (*sigchain_fun)(int);
5 5
@@ -7,4 +7,4 @@ int sigchain_pop(int sig);
7 7
8void sigchain_push_common(sigchain_fun f); 8void sigchain_push_common(sigchain_fun f);
9 9
10#endif /* __PERF_SIGCHAIN_H */ 10#endif /* __SUBCMD_SIGCHAIN_H */
diff --git a/tools/lib/subcmd/subcmd-config.c b/tools/lib/subcmd/subcmd-config.c
new file mode 100644
index 000000000000..d017c728bd1b
--- /dev/null
+++ b/tools/lib/subcmd/subcmd-config.c
@@ -0,0 +1,11 @@
1#include "subcmd-config.h"
2
3#define UNDEFINED "SUBCMD_HAS_NOT_BEEN_INITIALIZED"
4
5struct subcmd_config subcmd_config = {
6 .exec_name = UNDEFINED,
7 .prefix = UNDEFINED,
8 .exec_path = UNDEFINED,
9 .exec_path_env = UNDEFINED,
10 .pager_env = UNDEFINED,
11};
diff --git a/tools/lib/subcmd/subcmd-config.h b/tools/lib/subcmd/subcmd-config.h
new file mode 100644
index 000000000000..cc8514030b5c
--- /dev/null
+++ b/tools/lib/subcmd/subcmd-config.h
@@ -0,0 +1,14 @@
1#ifndef __PERF_SUBCMD_CONFIG_H
2#define __PERF_SUBCMD_CONFIG_H
3
4struct subcmd_config {
5 const char *exec_name;
6 const char *prefix;
7 const char *exec_path;
8 const char *exec_path_env;
9 const char *pager_env;
10};
11
12extern struct subcmd_config subcmd_config;
13
14#endif /* __PERF_SUBCMD_CONFIG_H */
diff --git a/tools/lib/subcmd/subcmd-util.h b/tools/lib/subcmd/subcmd-util.h
new file mode 100644
index 000000000000..fc2e45d8aaf1
--- /dev/null
+++ b/tools/lib/subcmd/subcmd-util.h
@@ -0,0 +1,91 @@
1#ifndef __SUBCMD_UTIL_H
2#define __SUBCMD_UTIL_H
3
4#include <stdarg.h>
5#include <stdlib.h>
6#include <stdio.h>
7
8#define NORETURN __attribute__((__noreturn__))
9
10static inline void report(const char *prefix, const char *err, va_list params)
11{
12 char msg[1024];
13 vsnprintf(msg, sizeof(msg), err, params);
14 fprintf(stderr, " %s%s\n", prefix, msg);
15}
16
17static NORETURN inline void die(const char *err, ...)
18{
19 va_list params;
20
21 va_start(params, err);
22 report(" Fatal: ", err, params);
23 exit(128);
24 va_end(params);
25}
26
27#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
28
29#define alloc_nr(x) (((x)+16)*3/2)
30
31/*
32 * Realloc the buffer pointed at by variable 'x' so that it can hold
33 * at least 'nr' entries; the number of entries currently allocated
34 * is 'alloc', using the standard growing factor alloc_nr() macro.
35 *
36 * DO NOT USE any expression with side-effect for 'x' or 'alloc'.
37 */
38#define ALLOC_GROW(x, nr, alloc) \
39 do { \
40 if ((nr) > alloc) { \
41 if (alloc_nr(alloc) < (nr)) \
42 alloc = (nr); \
43 else \
44 alloc = alloc_nr(alloc); \
45 x = xrealloc((x), alloc * sizeof(*(x))); \
46 } \
47 } while(0)
48
49static inline void *xrealloc(void *ptr, size_t size)
50{
51 void *ret = realloc(ptr, size);
52 if (!ret && !size)
53 ret = realloc(ptr, 1);
54 if (!ret) {
55 ret = realloc(ptr, size);
56 if (!ret && !size)
57 ret = realloc(ptr, 1);
58 if (!ret)
59 die("Out of memory, realloc failed");
60 }
61 return ret;
62}
63
64#define astrcatf(out, fmt, ...) \
65({ \
66 char *tmp = *(out); \
67 if (asprintf((out), "%s" fmt, tmp ?: "", ## __VA_ARGS__) == -1) \
68 die("asprintf failed"); \
69 free(tmp); \
70})
71
72static inline void astrcat(char **out, const char *add)
73{
74 char *tmp = *out;
75
76 if (asprintf(out, "%s%s", tmp ?: "", add) == -1)
77 die("asprintf failed");
78
79 free(tmp);
80}
81
82static inline int prefixcmp(const char *str, const char *prefix)
83{
84 for (; ; str++, prefix++)
85 if (!*prefix)
86 return 0;
87 else if (*str != *prefix)
88 return (unsigned char)*prefix - (unsigned char)*str;
89}
90
91#endif /* __SUBCMD_UTIL_H */
diff --git a/tools/perf/Build b/tools/perf/Build
index 2a41217e9d88..00c4b8c3d8ca 100644
--- a/tools/perf/Build
+++ b/tools/perf/Build
@@ -36,7 +36,10 @@ paths += -DPERF_MAN_PATH="BUILD_STR($(mandir_SQ))"
36 36
37CFLAGS_builtin-help.o += $(paths) 37CFLAGS_builtin-help.o += $(paths)
38CFLAGS_builtin-timechart.o += $(paths) 38CFLAGS_builtin-timechart.o += $(paths)
39CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" -include $(OUTPUT)PERF-VERSION-FILE 39CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" \
40 -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" \
41 -DPREFIX="BUILD_STR($(prefix_SQ))" \
42 -include $(OUTPUT)PERF-VERSION-FILE
40CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))" 43CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))"
41 44
42libperf-y += util/ 45libperf-y += util/
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index e630a7d2c348..3a1a32f5479f 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -207,11 +207,23 @@ comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-
207In per-thread mode with inheritance mode on (default), samples are captured only when 207In per-thread mode with inheritance mode on (default), samples are captured only when
208the thread executes on the designated CPUs. Default is to monitor all CPUs. 208the thread executes on the designated CPUs. Default is to monitor all CPUs.
209 209
210-B::
211--no-buildid::
212Do not save the build ids of binaries in the perf.data files. This skips
213post processing after recording, which sometimes makes the final step in
214the recording process to take a long time, as it needs to process all
215events looking for mmap records. The downside is that it can misresolve
216symbols if the workload binaries used when recording get locally rebuilt
217or upgraded, because the only key available in this case is the
218pathname. You can also set the "record.build-id" config variable to
219'skip to have this behaviour permanently.
220
210-N:: 221-N::
211--no-buildid-cache:: 222--no-buildid-cache::
212Do not update the buildid cache. This saves some overhead in situations 223Do not update the buildid cache. This saves some overhead in situations
213where the information in the perf.data file (which includes buildids) 224where the information in the perf.data file (which includes buildids)
214is sufficient. 225is sufficient. You can also set the "record.build-id" config variable to
226'no-cache' to have the same effect.
215 227
216-G name,...:: 228-G name,...::
217--cgroup name,...:: 229--cgroup name,...::
@@ -314,11 +326,17 @@ This option sets the time out limit. The default value is 500 ms.
314Record context switch events i.e. events of type PERF_RECORD_SWITCH or 326Record context switch events i.e. events of type PERF_RECORD_SWITCH or
315PERF_RECORD_SWITCH_CPU_WIDE. 327PERF_RECORD_SWITCH_CPU_WIDE.
316 328
317--clang-path:: 329--clang-path=PATH::
318Path to clang binary to use for compiling BPF scriptlets. 330Path to clang binary to use for compiling BPF scriptlets.
331(enabled when BPF support is on)
319 332
320--clang-opt:: 333--clang-opt=OPTIONS::
321Options passed to clang when compiling BPF scriptlets. 334Options passed to clang when compiling BPF scriptlets.
335(enabled when BPF support is on)
336
337--vmlinux=PATH::
338Specify vmlinux path which has debuginfo.
339(enabled when BPF prologue is on)
322 340
323SEE ALSO 341SEE ALSO
324-------- 342--------
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 2562eac6451d..ce3932ee4893 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -20,6 +20,7 @@ tools/lib/traceevent
20tools/lib/bpf 20tools/lib/bpf
21tools/lib/api 21tools/lib/api
22tools/lib/bpf 22tools/lib/bpf
23tools/lib/subcmd
23tools/lib/hweight.c 24tools/lib/hweight.c
24tools/lib/rbtree.c 25tools/lib/rbtree.c
25tools/lib/string.c 26tools/lib/string.c
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 929a32ba15f5..569fcf022531 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -145,9 +145,10 @@ BISON = bison
145STRIP = strip 145STRIP = strip
146AWK = awk 146AWK = awk
147 147
148LIB_DIR = $(srctree)/tools/lib/api/ 148LIB_DIR = $(srctree)/tools/lib/api/
149TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ 149TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
150BPF_DIR = $(srctree)/tools/lib/bpf/ 150BPF_DIR = $(srctree)/tools/lib/bpf/
151SUBCMD_DIR = $(srctree)/tools/lib/subcmd/
151 152
152# include config/Makefile by default and rule out 153# include config/Makefile by default and rule out
153# non-config cases 154# non-config cases
@@ -184,15 +185,17 @@ strip-libs = $(filter-out -l%,$(1))
184ifneq ($(OUTPUT),) 185ifneq ($(OUTPUT),)
185 TE_PATH=$(OUTPUT) 186 TE_PATH=$(OUTPUT)
186 BPF_PATH=$(OUTPUT) 187 BPF_PATH=$(OUTPUT)
188 SUBCMD_PATH=$(OUTPUT)
187ifneq ($(subdir),) 189ifneq ($(subdir),)
188 LIB_PATH=$(OUTPUT)/../lib/api/ 190 API_PATH=$(OUTPUT)/../lib/api/
189else 191else
190 LIB_PATH=$(OUTPUT) 192 API_PATH=$(OUTPUT)
191endif 193endif
192else 194else
193 TE_PATH=$(TRACE_EVENT_DIR) 195 TE_PATH=$(TRACE_EVENT_DIR)
194 LIB_PATH=$(LIB_DIR) 196 API_PATH=$(LIB_DIR)
195 BPF_PATH=$(BPF_DIR) 197 BPF_PATH=$(BPF_DIR)
198 SUBCMD_PATH=$(SUBCMD_DIR)
196endif 199endif
197 200
198LIBTRACEEVENT = $(TE_PATH)libtraceevent.a 201LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
@@ -201,11 +204,13 @@ export LIBTRACEEVENT
201LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list 204LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list
202LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) 205LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST)
203 206
204LIBAPI = $(LIB_PATH)libapi.a 207LIBAPI = $(API_PATH)libapi.a
205export LIBAPI 208export LIBAPI
206 209
207LIBBPF = $(BPF_PATH)libbpf.a 210LIBBPF = $(BPF_PATH)libbpf.a
208 211
212LIBSUBCMD = $(SUBCMD_PATH)libsubcmd.a
213
209# python extension build directories 214# python extension build directories
210PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ 215PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/
211PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/ 216PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/
@@ -257,7 +262,7 @@ export PERL_PATH
257 262
258LIB_FILE=$(OUTPUT)libperf.a 263LIB_FILE=$(OUTPUT)libperf.a
259 264
260PERFLIBS = $(LIB_FILE) $(LIBAPI) $(LIBTRACEEVENT) 265PERFLIBS = $(LIB_FILE) $(LIBAPI) $(LIBTRACEEVENT) $(LIBSUBCMD)
261ifndef NO_LIBBPF 266ifndef NO_LIBBPF
262 PERFLIBS += $(LIBBPF) 267 PERFLIBS += $(LIBBPF)
263endif 268endif
@@ -437,6 +442,13 @@ $(LIBBPF)-clean:
437 $(call QUIET_CLEAN, libbpf) 442 $(call QUIET_CLEAN, libbpf)
438 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null 443 $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null
439 444
445$(LIBSUBCMD): fixdep FORCE
446 $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a
447
448$(LIBSUBCMD)-clean:
449 $(call QUIET_CLEAN, libsubcmd)
450 $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) clean
451
440help: 452help:
441 @echo 'Perf make targets:' 453 @echo 'Perf make targets:'
442 @echo ' doc - make *all* documentation (see below)' 454 @echo ' doc - make *all* documentation (see below)'
@@ -582,15 +594,16 @@ $(INSTALL_DOC_TARGETS):
582# 594#
583config-clean: 595config-clean:
584 $(call QUIET_CLEAN, config) 596 $(call QUIET_CLEAN, config)
585 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null 597 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null
586 598
587clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean config-clean 599clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean
588 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) 600 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
589 $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete 601 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
590 $(Q)$(RM) $(OUTPUT).config-detected 602 $(Q)$(RM) $(OUTPUT).config-detected
591 $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 603 $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32
592 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ 604 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \
593 $(OUTPUT)util/intel-pt-decoder/inat-tables.c 605 $(OUTPUT)util/intel-pt-decoder/inat-tables.c $(OUTPUT)fixdep \
606 $(OUTPUT)tests/llvm-src-{base,kbuild,prologue}.c
594 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean 607 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
595 $(python-clean) 608 $(python-clean)
596 609
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index b02af064f0f9..b64d46285ebb 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -26,7 +26,7 @@
26#include "../../util/evlist.h" 26#include "../../util/evlist.h"
27#include "../../util/evsel.h" 27#include "../../util/evsel.h"
28#include "../../util/cpumap.h" 28#include "../../util/cpumap.h"
29#include "../../util/parse-options.h" 29#include <subcmd/parse-options.h>
30#include "../../util/parse-events.h" 30#include "../../util/parse-events.h"
31#include "../../util/pmu.h" 31#include "../../util/pmu.h"
32#include "../../util/debug.h" 32#include "../../util/debug.h"
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
index fc9bebd2cca0..0999ac536d86 100644
--- a/tools/perf/bench/futex-hash.c
+++ b/tools/perf/bench/futex-hash.c
@@ -11,7 +11,7 @@
11#include "../perf.h" 11#include "../perf.h"
12#include "../util/util.h" 12#include "../util/util.h"
13#include "../util/stat.h" 13#include "../util/stat.h"
14#include "../util/parse-options.h" 14#include <subcmd/parse-options.h>
15#include "../util/header.h" 15#include "../util/header.h"
16#include "bench.h" 16#include "bench.h"
17#include "futex.h" 17#include "futex.h"
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
index bc6a16adbca8..6a18ce21f865 100644
--- a/tools/perf/bench/futex-lock-pi.c
+++ b/tools/perf/bench/futex-lock-pi.c
@@ -5,7 +5,7 @@
5#include "../perf.h" 5#include "../perf.h"
6#include "../util/util.h" 6#include "../util/util.h"
7#include "../util/stat.h" 7#include "../util/stat.h"
8#include "../util/parse-options.h" 8#include <subcmd/parse-options.h>
9#include "../util/header.h" 9#include "../util/header.h"
10#include "bench.h" 10#include "bench.h"
11#include "futex.h" 11#include "futex.h"
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c
index ad0d9b5342fb..718238683013 100644
--- a/tools/perf/bench/futex-requeue.c
+++ b/tools/perf/bench/futex-requeue.c
@@ -11,7 +11,7 @@
11#include "../perf.h" 11#include "../perf.h"
12#include "../util/util.h" 12#include "../util/util.h"
13#include "../util/stat.h" 13#include "../util/stat.h"
14#include "../util/parse-options.h" 14#include <subcmd/parse-options.h>
15#include "../util/header.h" 15#include "../util/header.h"
16#include "bench.h" 16#include "bench.h"
17#include "futex.h" 17#include "futex.h"
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c
index 6d8c9fa2a16c..91aaf2a1fa90 100644
--- a/tools/perf/bench/futex-wake-parallel.c
+++ b/tools/perf/bench/futex-wake-parallel.c
@@ -10,7 +10,7 @@
10#include "../perf.h" 10#include "../perf.h"
11#include "../util/util.h" 11#include "../util/util.h"
12#include "../util/stat.h" 12#include "../util/stat.h"
13#include "../util/parse-options.h" 13#include <subcmd/parse-options.h>
14#include "../util/header.h" 14#include "../util/header.h"
15#include "bench.h" 15#include "bench.h"
16#include "futex.h" 16#include "futex.h"
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c
index e5e41d3bdce7..f416bd705f66 100644
--- a/tools/perf/bench/futex-wake.c
+++ b/tools/perf/bench/futex-wake.c
@@ -11,7 +11,7 @@
11#include "../perf.h" 11#include "../perf.h"
12#include "../util/util.h" 12#include "../util/util.h"
13#include "../util/stat.h" 13#include "../util/stat.h"
14#include "../util/parse-options.h" 14#include <subcmd/parse-options.h>
15#include "../util/header.h" 15#include "../util/header.h"
16#include "bench.h" 16#include "bench.h"
17#include "futex.h" 17#include "futex.h"
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c
index 9419b944220f..a91aa85d80ff 100644
--- a/tools/perf/bench/mem-functions.c
+++ b/tools/perf/bench/mem-functions.c
@@ -8,7 +8,7 @@
8 8
9#include "../perf.h" 9#include "../perf.h"
10#include "../util/util.h" 10#include "../util/util.h"
11#include "../util/parse-options.h" 11#include <subcmd/parse-options.h>
12#include "../util/header.h" 12#include "../util/header.h"
13#include "../util/cloexec.h" 13#include "../util/cloexec.h"
14#include "bench.h" 14#include "bench.h"
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 492df2752a2d..5049d6357a46 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -7,7 +7,7 @@
7#include "../perf.h" 7#include "../perf.h"
8#include "../builtin.h" 8#include "../builtin.h"
9#include "../util/util.h" 9#include "../util/util.h"
10#include "../util/parse-options.h" 10#include <subcmd/parse-options.h>
11#include "../util/cloexec.h" 11#include "../util/cloexec.h"
12 12
13#include "bench.h" 13#include "bench.h"
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c
index d4ff1b539cfd..bfaf9503de8e 100644
--- a/tools/perf/bench/sched-messaging.c
+++ b/tools/perf/bench/sched-messaging.c
@@ -11,7 +11,7 @@
11 11
12#include "../perf.h" 12#include "../perf.h"
13#include "../util/util.h" 13#include "../util/util.h"
14#include "../util/parse-options.h" 14#include <subcmd/parse-options.h>
15#include "../builtin.h" 15#include "../builtin.h"
16#include "bench.h" 16#include "bench.h"
17 17
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c
index 005cc283790c..1dc2d13cc272 100644
--- a/tools/perf/bench/sched-pipe.c
+++ b/tools/perf/bench/sched-pipe.c
@@ -10,7 +10,7 @@
10 */ 10 */
11#include "../perf.h" 11#include "../perf.h"
12#include "../util/util.h" 12#include "../util/util.h"
13#include "../util/parse-options.h" 13#include <subcmd/parse-options.h>
14#include "../builtin.h" 14#include "../builtin.h"
15#include "bench.h" 15#include "bench.h"
16 16
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 1f00dc7cecba..e18f1b995ffd 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -21,7 +21,7 @@
21#include "util/evsel.h" 21#include "util/evsel.h"
22#include "util/annotate.h" 22#include "util/annotate.h"
23#include "util/event.h" 23#include "util/event.h"
24#include "util/parse-options.h" 24#include <subcmd/parse-options.h>
25#include "util/parse-events.h" 25#include "util/parse-events.h"
26#include "util/thread.h" 26#include "util/thread.h"
27#include "util/sort.h" 27#include "util/sort.h"
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index b17aed36ca16..a1cddc6bbf0f 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -16,7 +16,7 @@
16 */ 16 */
17#include "perf.h" 17#include "perf.h"
18#include "util/util.h" 18#include "util/util.h"
19#include "util/parse-options.h" 19#include <subcmd/parse-options.h>
20#include "builtin.h" 20#include "builtin.h"
21#include "bench/bench.h" 21#include "bench/bench.h"
22 22
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index 7b8450cd33c2..d93bff7fc0e4 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -16,7 +16,7 @@
16#include "util/cache.h" 16#include "util/cache.h"
17#include "util/debug.h" 17#include "util/debug.h"
18#include "util/header.h" 18#include "util/header.h"
19#include "util/parse-options.h" 19#include <subcmd/parse-options.h>
20#include "util/strlist.h" 20#include "util/strlist.h"
21#include "util/build-id.h" 21#include "util/build-id.h"
22#include "util/session.h" 22#include "util/session.h"
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 6419f57b0850..5e914ee79eb3 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -12,7 +12,7 @@
12#include "util/build-id.h" 12#include "util/build-id.h"
13#include "util/cache.h" 13#include "util/cache.h"
14#include "util/debug.h" 14#include "util/debug.h"
15#include "util/parse-options.h" 15#include <subcmd/parse-options.h>
16#include "util/session.h" 16#include "util/session.h"
17#include "util/symbol.h" 17#include "util/symbol.h"
18#include "util/data.h" 18#include "util/data.h"
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 427ea7a705b8..f04e804a9fad 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -9,7 +9,7 @@
9#include "perf.h" 9#include "perf.h"
10 10
11#include "util/cache.h" 11#include "util/cache.h"
12#include "util/parse-options.h" 12#include <subcmd/parse-options.h>
13#include "util/util.h" 13#include "util/util.h"
14#include "util/debug.h" 14#include "util/debug.h"
15 15
diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c
index d6525bc54d13..b97bc1518b44 100644
--- a/tools/perf/builtin-data.c
+++ b/tools/perf/builtin-data.c
@@ -2,7 +2,7 @@
2#include "builtin.h" 2#include "builtin.h"
3#include "perf.h" 3#include "perf.h"
4#include "debug.h" 4#include "debug.h"
5#include "parse-options.h" 5#include <subcmd/parse-options.h>
6#include "data-convert-bt.h" 6#include "data-convert-bt.h"
7 7
8typedef int (*data_cmd_fn_t)(int argc, const char **argv, const char *prefix); 8typedef int (*data_cmd_fn_t)(int argc, const char **argv, const char *prefix);
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index f4d62510acbb..08a7d36a2cf8 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -12,7 +12,7 @@
12#include "util/evlist.h" 12#include "util/evlist.h"
13#include "util/evsel.h" 13#include "util/evsel.h"
14#include "util/parse-events.h" 14#include "util/parse-events.h"
15#include "util/parse-options.h" 15#include <subcmd/parse-options.h>
16#include "util/session.h" 16#include "util/session.h"
17#include "util/data.h" 17#include "util/data.h"
18#include "util/debug.h" 18#include "util/debug.h"
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index a7d588bf3cdd..96c1a4cfbbbf 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -6,11 +6,11 @@
6#include "perf.h" 6#include "perf.h"
7#include "util/cache.h" 7#include "util/cache.h"
8#include "builtin.h" 8#include "builtin.h"
9#include "util/exec_cmd.h" 9#include <subcmd/exec-cmd.h>
10#include "common-cmds.h" 10#include "common-cmds.h"
11#include "util/parse-options.h" 11#include <subcmd/parse-options.h>
12#include "util/run-command.h" 12#include <subcmd/run-command.h>
13#include "util/help.h" 13#include <subcmd/help.h>
14#include "util/debug.h" 14#include "util/debug.h"
15 15
16static struct man_viewer_list { 16static struct man_viewer_list {
@@ -407,7 +407,7 @@ static int get_html_page_path(struct strbuf *page_path, const char *page)
407#ifndef open_html 407#ifndef open_html
408static void open_html(const char *path) 408static void open_html(const char *path)
409{ 409{
410 execl_perf_cmd("web--browse", "-c", "help.browser", path, NULL); 410 execl_cmd("web--browse", "-c", "help.browser", path, NULL);
411} 411}
412#endif 412#endif
413 413
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 99d127fe9c35..0022e02ed31a 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -18,7 +18,7 @@
18#include "util/data.h" 18#include "util/data.h"
19#include "util/auxtrace.h" 19#include "util/auxtrace.h"
20 20
21#include "util/parse-options.h" 21#include <subcmd/parse-options.h>
22 22
23#include <linux/list.h> 23#include <linux/list.h>
24 24
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 93ce665f976f..118010553d0c 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -12,7 +12,7 @@
12#include "util/tool.h" 12#include "util/tool.h"
13#include "util/callchain.h" 13#include "util/callchain.h"
14 14
15#include "util/parse-options.h" 15#include <subcmd/parse-options.h>
16#include "util/trace-event.h" 16#include "util/trace-event.h"
17#include "util/data.h" 17#include "util/data.h"
18#include "util/cpumap.h" 18#include "util/cpumap.h"
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 031f9f55c281..4418d9214872 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -10,7 +10,7 @@
10#include "util/header.h" 10#include "util/header.h"
11#include "util/session.h" 11#include "util/session.h"
12#include "util/intlist.h" 12#include "util/intlist.h"
13#include "util/parse-options.h" 13#include <subcmd/parse-options.h>
14#include "util/trace-event.h" 14#include "util/trace-event.h"
15#include "util/debug.h" 15#include "util/debug.h"
16#include "util/tool.h" 16#include "util/tool.h"
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index bf679e2c978b..5e22db4684b8 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -14,7 +14,7 @@
14#include "util/parse-events.h" 14#include "util/parse-events.h"
15#include "util/cache.h" 15#include "util/cache.h"
16#include "util/pmu.h" 16#include "util/pmu.h"
17#include "util/parse-options.h" 17#include <subcmd/parse-options.h>
18 18
19int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused) 19int cmd_list(int argc, const char **argv, const char *prefix __maybe_unused)
20{ 20{
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index de16aaed516e..ce3bfb48b26f 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -9,7 +9,7 @@
9#include "util/thread.h" 9#include "util/thread.h"
10#include "util/header.h" 10#include "util/header.h"
11 11
12#include "util/parse-options.h" 12#include <subcmd/parse-options.h>
13#include "util/trace-event.h" 13#include "util/trace-event.h"
14 14
15#include "util/debug.h" 15#include "util/debug.h"
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 80170aace5d4..390170041696 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -1,7 +1,7 @@
1#include "builtin.h" 1#include "builtin.h"
2#include "perf.h" 2#include "perf.h"
3 3
4#include "util/parse-options.h" 4#include <subcmd/parse-options.h>
5#include "util/trace-event.h" 5#include "util/trace-event.h"
6#include "util/tool.h" 6#include "util/tool.h"
7#include "util/session.h" 7#include "util/session.h"
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 132afc97676c..9af859b28b15 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -37,7 +37,7 @@
37#include "util/strfilter.h" 37#include "util/strfilter.h"
38#include "util/symbol.h" 38#include "util/symbol.h"
39#include "util/debug.h" 39#include "util/debug.h"
40#include "util/parse-options.h" 40#include <subcmd/parse-options.h>
41#include "util/probe-finder.h" 41#include "util/probe-finder.h"
42#include "util/probe-event.h" 42#include "util/probe-event.h"
43#include "util/probe-file.h" 43#include "util/probe-file.h"
@@ -249,6 +249,9 @@ static int opt_show_vars(const struct option *opt,
249 249
250 return ret; 250 return ret;
251} 251}
252#else
253# define opt_show_lines NULL
254# define opt_show_vars NULL
252#endif 255#endif
253static int opt_add_probe_event(const struct option *opt, 256static int opt_add_probe_event(const struct option *opt,
254 const char *str, int unset __maybe_unused) 257 const char *str, int unset __maybe_unused)
@@ -473,7 +476,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
473 opt_add_probe_event), 476 opt_add_probe_event),
474 OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events" 477 OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events"
475 " with existing name"), 478 " with existing name"),
476#ifdef HAVE_DWARF_SUPPORT
477 OPT_CALLBACK('L', "line", NULL, 479 OPT_CALLBACK('L', "line", NULL,
478 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]", 480 "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
479 "Show source code lines.", opt_show_lines), 481 "Show source code lines.", opt_show_lines),
@@ -490,7 +492,6 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
490 "directory", "path to kernel source"), 492 "directory", "path to kernel source"),
491 OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines, 493 OPT_BOOLEAN('\0', "no-inlines", &probe_conf.no_inlines,
492 "Don't search inlined functions"), 494 "Don't search inlined functions"),
493#endif
494 OPT__DRY_RUN(&probe_event_dry_run), 495 OPT__DRY_RUN(&probe_event_dry_run),
495 OPT_INTEGER('\0', "max-probes", &probe_conf.max_probes, 496 OPT_INTEGER('\0', "max-probes", &probe_conf.max_probes,
496 "Set how many probe points can be found for a probe."), 497 "Set how many probe points can be found for a probe."),
@@ -521,6 +522,16 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
521#ifdef HAVE_DWARF_SUPPORT 522#ifdef HAVE_DWARF_SUPPORT
522 set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE); 523 set_option_flag(options, 'L', "line", PARSE_OPT_EXCLUSIVE);
523 set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE); 524 set_option_flag(options, 'V', "vars", PARSE_OPT_EXCLUSIVE);
525#else
526# define set_nobuild(s, l, c) set_option_nobuild(options, s, l, "NO_DWARF=1", c)
527 set_nobuild('L', "line", false);
528 set_nobuild('V', "vars", false);
529 set_nobuild('\0', "externs", false);
530 set_nobuild('\0', "range", false);
531 set_nobuild('k', "vmlinux", true);
532 set_nobuild('s', "source", true);
533 set_nobuild('\0', "no-inlines", true);
534# undef set_nobuild
524#endif 535#endif
525 set_option_flag(options, 'F', "funcs", PARSE_OPT_EXCLUSIVE); 536 set_option_flag(options, 'F', "funcs", PARSE_OPT_EXCLUSIVE);
526 537
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 199fc31e3919..1435ef6265b6 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -11,7 +11,7 @@
11 11
12#include "util/build-id.h" 12#include "util/build-id.h"
13#include "util/util.h" 13#include "util/util.h"
14#include "util/parse-options.h" 14#include <subcmd/parse-options.h>
15#include "util/parse-events.h" 15#include "util/parse-events.h"
16 16
17#include "util/callchain.h" 17#include "util/callchain.h"
@@ -837,6 +837,19 @@ int record_callchain_opt(const struct option *opt,
837 837
838static int perf_record_config(const char *var, const char *value, void *cb) 838static int perf_record_config(const char *var, const char *value, void *cb)
839{ 839{
840 struct record *rec = cb;
841
842 if (!strcmp(var, "record.build-id")) {
843 if (!strcmp(value, "cache"))
844 rec->no_buildid_cache = false;
845 else if (!strcmp(value, "no-cache"))
846 rec->no_buildid_cache = true;
847 else if (!strcmp(value, "skip"))
848 rec->no_buildid = true;
849 else
850 return -1;
851 return 0;
852 }
840 if (!strcmp(var, "record.call-graph")) 853 if (!strcmp(var, "record.call-graph"))
841 var = "call-graph.record-mode"; /* fall-through */ 854 var = "call-graph.record-mode"; /* fall-through */
842 855
@@ -1113,12 +1126,12 @@ struct option __record_options[] = {
1113 "per thread proc mmap processing timeout in ms"), 1126 "per thread proc mmap processing timeout in ms"),
1114 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events, 1127 OPT_BOOLEAN(0, "switch-events", &record.opts.record_switch_events,
1115 "Record context switch events"), 1128 "Record context switch events"),
1116#ifdef HAVE_LIBBPF_SUPPORT
1117 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", 1129 OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path",
1118 "clang binary to use for compiling BPF scriptlets"), 1130 "clang binary to use for compiling BPF scriptlets"),
1119 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", 1131 OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options",
1120 "options passed to clang when compiling BPF scriptlets"), 1132 "options passed to clang when compiling BPF scriptlets"),
1121#endif 1133 OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name,
1134 "file", "vmlinux pathname"),
1122 OPT_END() 1135 OPT_END()
1123}; 1136};
1124 1137
@@ -1130,6 +1143,27 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1130 struct record *rec = &record; 1143 struct record *rec = &record;
1131 char errbuf[BUFSIZ]; 1144 char errbuf[BUFSIZ];
1132 1145
1146#ifndef HAVE_LIBBPF_SUPPORT
1147# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
1148 set_nobuild('\0', "clang-path", true);
1149 set_nobuild('\0', "clang-opt", true);
1150# undef set_nobuild
1151#endif
1152
1153#ifndef HAVE_BPF_PROLOGUE
1154# if !defined (HAVE_DWARF_SUPPORT)
1155# define REASON "NO_DWARF=1"
1156# elif !defined (HAVE_LIBBPF_SUPPORT)
1157# define REASON "NO_LIBBPF=1"
1158# else
1159# define REASON "this architecture doesn't support BPF prologue"
1160# endif
1161# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c)
1162 set_nobuild('\0', "vmlinux", true);
1163# undef set_nobuild
1164# undef REASON
1165#endif
1166
1133 rec->evlist = perf_evlist__new(); 1167 rec->evlist = perf_evlist__new();
1134 if (rec->evlist == NULL) 1168 if (rec->evlist == NULL)
1135 return -ENOMEM; 1169 return -ENOMEM;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 5a454669d075..2a7330b99b82 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -27,7 +27,7 @@
27#include "util/session.h" 27#include "util/session.h"
28#include "util/tool.h" 28#include "util/tool.h"
29 29
30#include "util/parse-options.h" 30#include <subcmd/parse-options.h>
31#include "util/parse-events.h" 31#include "util/parse-events.h"
32 32
33#include "util/thread.h" 33#include "util/thread.h"
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index e3d3e32c0a93..871b55ae22a4 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -12,7 +12,7 @@
12#include "util/tool.h" 12#include "util/tool.h"
13#include "util/cloexec.h" 13#include "util/cloexec.h"
14 14
15#include "util/parse-options.h" 15#include <subcmd/parse-options.h>
16#include "util/trace-event.h" 16#include "util/trace-event.h"
17 17
18#include "util/debug.h" 18#include "util/debug.h"
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index d259e9aa3a71..bcc3542d9df5 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -3,9 +3,9 @@
3#include "perf.h" 3#include "perf.h"
4#include "util/cache.h" 4#include "util/cache.h"
5#include "util/debug.h" 5#include "util/debug.h"
6#include "util/exec_cmd.h" 6#include <subcmd/exec-cmd.h>
7#include "util/header.h" 7#include "util/header.h"
8#include "util/parse-options.h" 8#include <subcmd/parse-options.h>
9#include "util/perf_regs.h" 9#include "util/perf_regs.h"
10#include "util/session.h" 10#include "util/session.h"
11#include "util/tool.h" 11#include "util/tool.h"
@@ -1408,7 +1408,7 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
1408 char first_half[BUFSIZ]; 1408 char first_half[BUFSIZ];
1409 char *script_root; 1409 char *script_root;
1410 1410
1411 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 1411 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
1412 1412
1413 scripts_dir = opendir(scripts_path); 1413 scripts_dir = opendir(scripts_path);
1414 if (!scripts_dir) 1414 if (!scripts_dir)
@@ -1529,7 +1529,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
1529 if (!session) 1529 if (!session)
1530 return -1; 1530 return -1;
1531 1531
1532 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 1532 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
1533 1533
1534 scripts_dir = opendir(scripts_path); 1534 scripts_dir = opendir(scripts_path);
1535 if (!scripts_dir) { 1535 if (!scripts_dir) {
@@ -1587,7 +1587,7 @@ static char *get_script_path(const char *script_root, const char *suffix)
1587 char lang_path[MAXPATHLEN]; 1587 char lang_path[MAXPATHLEN];
1588 char *__script_root; 1588 char *__script_root;
1589 1589
1590 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); 1590 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
1591 1591
1592 scripts_dir = opendir(scripts_path); 1592 scripts_dir = opendir(scripts_path);
1593 if (!scripts_dir) 1593 if (!scripts_dir)
@@ -1823,7 +1823,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1823 scripting_max_stack = itrace_synth_opts.callchain_sz; 1823 scripting_max_stack = itrace_synth_opts.callchain_sz;
1824 1824
1825 /* make sure PERF_EXEC_PATH is set for scripts */ 1825 /* make sure PERF_EXEC_PATH is set for scripts */
1826 perf_set_argv_exec_path(perf_exec_path()); 1826 set_argv_exec_path(get_argv_exec_path());
1827 1827
1828 if (argc && !script_name && !rec_script_path && !rep_script_path) { 1828 if (argc && !script_name && !rec_script_path && !rep_script_path) {
1829 int live_pipe[2]; 1829 int live_pipe[2];
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 25a95f49c36e..bbf42eefd5e5 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -45,7 +45,7 @@
45#include "builtin.h" 45#include "builtin.h"
46#include "util/cgroup.h" 46#include "util/cgroup.h"
47#include "util/util.h" 47#include "util/util.h"
48#include "util/parse-options.h" 48#include <subcmd/parse-options.h>
49#include "util/parse-events.h" 49#include "util/parse-events.h"
50#include "util/pmu.h" 50#include "util/pmu.h"
51#include "util/event.h" 51#include "util/event.h"
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 30e59620179d..bd7a7757176f 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -30,7 +30,7 @@
30 30
31#include "perf.h" 31#include "perf.h"
32#include "util/header.h" 32#include "util/header.h"
33#include "util/parse-options.h" 33#include <subcmd/parse-options.h>
34#include "util/parse-events.h" 34#include "util/parse-events.h"
35#include "util/event.h" 35#include "util/event.h"
36#include "util/session.h" 36#include "util/session.h"
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 92fe963e43c4..9ebd67a42ede 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -34,7 +34,7 @@
34#include "util/top.h" 34#include "util/top.h"
35#include "util/util.h" 35#include "util/util.h"
36#include <linux/rbtree.h> 36#include <linux/rbtree.h>
37#include "util/parse-options.h" 37#include <subcmd/parse-options.h>
38#include "util/parse-events.h" 38#include "util/parse-events.h"
39#include "util/cpumap.h" 39#include "util/cpumap.h"
40#include "util/xyarray.h" 40#include "util/xyarray.h"
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index c783d8fd3a80..20916dd77aac 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -22,11 +22,11 @@
22#include "util/color.h" 22#include "util/color.h"
23#include "util/debug.h" 23#include "util/debug.h"
24#include "util/evlist.h" 24#include "util/evlist.h"
25#include "util/exec_cmd.h" 25#include <subcmd/exec-cmd.h>
26#include "util/machine.h" 26#include "util/machine.h"
27#include "util/session.h" 27#include "util/session.h"
28#include "util/thread.h" 28#include "util/thread.h"
29#include "util/parse-options.h" 29#include <subcmd/parse-options.h>
30#include "util/strlist.h" 30#include "util/strlist.h"
31#include "util/intlist.h" 31#include "util/intlist.h"
32#include "util/thread_map.h" 32#include "util/thread_map.h"
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 59ea48c7e26c..cb1d2499c45c 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -9,12 +9,12 @@
9#include "builtin.h" 9#include "builtin.h"
10 10
11#include "util/env.h" 11#include "util/env.h"
12#include "util/exec_cmd.h" 12#include <subcmd/exec-cmd.h>
13#include "util/cache.h" 13#include "util/cache.h"
14#include "util/quote.h" 14#include "util/quote.h"
15#include "util/run-command.h" 15#include <subcmd/run-command.h>
16#include "util/parse-events.h" 16#include "util/parse-events.h"
17#include "util/parse-options.h" 17#include <subcmd/parse-options.h>
18#include "util/bpf-loader.h" 18#include "util/bpf-loader.h"
19#include "util/debug.h" 19#include "util/debug.h"
20#include <api/fs/tracing_path.h> 20#include <api/fs/tracing_path.h>
@@ -119,7 +119,7 @@ static void commit_pager_choice(void)
119{ 119{
120 switch (use_pager) { 120 switch (use_pager) {
121 case 0: 121 case 0:
122 setenv("PERF_PAGER", "cat", 1); 122 setenv(PERF_PAGER_ENVIRONMENT, "cat", 1);
123 break; 123 break;
124 case 1: 124 case 1:
125 /* setup_pager(); */ 125 /* setup_pager(); */
@@ -183,9 +183,9 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
183 if (!prefixcmp(cmd, CMD_EXEC_PATH)) { 183 if (!prefixcmp(cmd, CMD_EXEC_PATH)) {
184 cmd += strlen(CMD_EXEC_PATH); 184 cmd += strlen(CMD_EXEC_PATH);
185 if (*cmd == '=') 185 if (*cmd == '=')
186 perf_set_argv_exec_path(cmd + 1); 186 set_argv_exec_path(cmd + 1);
187 else { 187 else {
188 puts(perf_exec_path()); 188 puts(get_argv_exec_path());
189 exit(0); 189 exit(0);
190 } 190 }
191 } else if (!strcmp(cmd, "--html-path")) { 191 } else if (!strcmp(cmd, "--html-path")) {
@@ -530,11 +530,15 @@ int main(int argc, const char **argv)
530 const char *cmd; 530 const char *cmd;
531 char sbuf[STRERR_BUFSIZE]; 531 char sbuf[STRERR_BUFSIZE];
532 532
533 /* libsubcmd init */
534 exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT);
535 pager_init(PERF_PAGER_ENVIRONMENT);
536
533 /* The page_size is placed in util object. */ 537 /* The page_size is placed in util object. */
534 page_size = sysconf(_SC_PAGE_SIZE); 538 page_size = sysconf(_SC_PAGE_SIZE);
535 cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); 539 cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
536 540
537 cmd = perf_extract_argv0_path(argv[0]); 541 cmd = extract_argv0_path(argv[0]);
538 if (!cmd) 542 if (!cmd)
539 cmd = "perf-help"; 543 cmd = "perf-help";
540 544
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 0ff8a973b81c..f23fb7ed4400 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -35,21 +35,21 @@ perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o
35perf-y += bpf.o 35perf-y += bpf.o
36perf-y += topology.o 36perf-y += topology.o
37 37
38$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c 38$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
39 $(call rule_mkdir) 39 $(call rule_mkdir)
40 $(Q)echo '#include <tests/llvm.h>' > $@ 40 $(Q)echo '#include <tests/llvm.h>' > $@
41 $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@ 41 $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@
42 $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ 42 $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
43 $(Q)echo ';' >> $@ 43 $(Q)echo ';' >> $@
44 44
45$(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c 45$(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c tests/Build
46 $(call rule_mkdir) 46 $(call rule_mkdir)
47 $(Q)echo '#include <tests/llvm.h>' > $@ 47 $(Q)echo '#include <tests/llvm.h>' > $@
48 $(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@ 48 $(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@
49 $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ 49 $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@
50 $(Q)echo ';' >> $@ 50 $(Q)echo ';' >> $@
51 51
52$(OUTPUT)tests/llvm-src-prologue.c: tests/bpf-script-test-prologue.c 52$(OUTPUT)tests/llvm-src-prologue.c: tests/bpf-script-test-prologue.c tests/Build
53 $(call rule_mkdir) 53 $(call rule_mkdir)
54 $(Q)echo '#include <tests/llvm.h>' > $@ 54 $(Q)echo '#include <tests/llvm.h>' > $@
55 $(Q)echo 'const char test_llvm__bpf_test_prologue_prog[] =' >> $@ 55 $(Q)echo 'const char test_llvm__bpf_test_prologue_prog[] =' >> $@
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index b66730eb94e3..28d1605b0338 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -24,7 +24,7 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include "../perf.h" 25#include "../perf.h"
26#include "util.h" 26#include "util.h"
27#include "exec_cmd.h" 27#include <subcmd/exec-cmd.h>
28#include "tests.h" 28#include "tests.h"
29 29
30#define ENV "PERF_TEST_ATTR" 30#define ENV "PERF_TEST_ATTR"
@@ -164,7 +164,7 @@ int test__attr(int subtest __maybe_unused)
164 return run_dir("./tests", "./perf"); 164 return run_dir("./tests", "./perf");
165 165
166 /* Then installed path. */ 166 /* Then installed path. */
167 snprintf(path_dir, PATH_MAX, "%s/tests", perf_exec_path()); 167 snprintf(path_dir, PATH_MAX, "%s/tests", get_argv_exec_path());
168 snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR); 168 snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR);
169 169
170 if (!lstat(path_dir, &st) && 170 if (!lstat(path_dir, &st) &&
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 2b1ade1aafc3..0372d5945910 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -11,7 +11,7 @@
11#include "tests.h" 11#include "tests.h"
12#include "debug.h" 12#include "debug.h"
13#include "color.h" 13#include "color.h"
14#include "parse-options.h" 14#include <subcmd/parse-options.h>
15#include "symbol.h" 15#include "symbol.h"
16 16
17struct test __weak arch_tests[] = { 17struct test __weak arch_tests[] = {
@@ -236,6 +236,9 @@ static int run_test(struct test *test, int subtest)
236 dup2(STDOUT_FILENO, STDERR_FILENO); 236 dup2(STDOUT_FILENO, STDERR_FILENO);
237 close(nullfd); 237 close(nullfd);
238 } 238 }
239 } else {
240 signal(SIGSEGV, sighandler_dump_stack);
241 signal(SIGFPE, sighandler_dump_stack);
239 } 242 }
240 243
241 err = test->func(subtest); 244 err = test->func(subtest);
diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c
index 46f453b1de60..bcfd081ee1d2 100644
--- a/tools/perf/tests/hists_common.c
+++ b/tools/perf/tests/hists_common.c
@@ -88,8 +88,8 @@ struct machine *setup_fake_machine(struct machines *machines)
88 } 88 }
89 89
90 if (machine__create_kernel_maps(machine)) { 90 if (machine__create_kernel_maps(machine)) {
91 pr_debug("Not enough memory for machine setup\n"); 91 pr_debug("Cannot create kernel maps\n");
92 goto out; 92 return NULL;
93 } 93 }
94 94
95 for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { 95 for (i = 0; i < ARRAY_SIZE(fake_threads); i++) {
@@ -155,7 +155,6 @@ struct machine *setup_fake_machine(struct machines *machines)
155out: 155out:
156 pr_debug("Not enough memory for machine setup\n"); 156 pr_debug("Not enough memory for machine setup\n");
157 machine__delete_threads(machine); 157 machine__delete_threads(machine);
158 machine__delete(machine);
159 return NULL; 158 return NULL;
160} 159}
161 160
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 8ea3dffc5065..c1fbb8e884c0 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -259,7 +259,8 @@ $(run_O):
259tarpkg: 259tarpkg:
260 @cmd="$(PERF)/tests/perf-targz-src-pkg $(PERF)"; \ 260 @cmd="$(PERF)/tests/perf-targz-src-pkg $(PERF)"; \
261 echo "- $@: $$cmd" && echo $$cmd > $@ && \ 261 echo "- $@: $$cmd" && echo $$cmd > $@ && \
262 ( eval $$cmd ) >> $@ 2>&1 262 ( eval $$cmd ) >> $@ 2>&1 && \
263 rm -f $@
263 264
264make_kernelsrc: 265make_kernelsrc:
265 @echo "- make -C <kernelsrc> tools/perf" 266 @echo "- make -C <kernelsrc> tools/perf"
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 65fef5951c7d..94b1099f2c22 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -9,13 +9,10 @@ libperf-y += env.o
9libperf-y += event.o 9libperf-y += event.o
10libperf-y += evlist.o 10libperf-y += evlist.o
11libperf-y += evsel.o 11libperf-y += evsel.o
12libperf-y += exec_cmd.o
13libperf-y += find_next_bit.o 12libperf-y += find_next_bit.o
14libperf-y += help.o
15libperf-y += kallsyms.o 13libperf-y += kallsyms.o
16libperf-y += levenshtein.o 14libperf-y += levenshtein.o
17libperf-y += llvm-utils.o 15libperf-y += llvm-utils.o
18libperf-y += parse-options.o
19libperf-y += parse-events.o 16libperf-y += parse-events.o
20libperf-y += perf_regs.o 17libperf-y += perf_regs.o
21libperf-y += path.o 18libperf-y += path.o
@@ -23,7 +20,6 @@ libperf-y += rbtree.o
23libperf-y += libstring.o 20libperf-y += libstring.o
24libperf-y += bitmap.o 21libperf-y += bitmap.o
25libperf-y += hweight.o 22libperf-y += hweight.o
26libperf-y += run-command.o
27libperf-y += quote.o 23libperf-y += quote.o
28libperf-y += strbuf.o 24libperf-y += strbuf.o
29libperf-y += string.o 25libperf-y += string.o
@@ -32,11 +28,9 @@ libperf-y += strfilter.o
32libperf-y += top.o 28libperf-y += top.o
33libperf-y += usage.o 29libperf-y += usage.o
34libperf-y += wrapper.o 30libperf-y += wrapper.o
35libperf-y += sigchain.o
36libperf-y += dso.o 31libperf-y += dso.o
37libperf-y += symbol.o 32libperf-y += symbol.o
38libperf-y += color.o 33libperf-y += color.o
39libperf-y += pager.o
40libperf-y += header.o 34libperf-y += header.o
41libperf-y += callchain.o 35libperf-y += callchain.o
42libperf-y += values.o 36libperf-y += values.o
@@ -87,6 +81,7 @@ libperf-$(CONFIG_AUXTRACE) += intel-bts.o
87libperf-y += parse-branch-options.o 81libperf-y += parse-branch-options.o
88libperf-y += parse-regs-options.o 82libperf-y += parse-regs-options.o
89libperf-y += term.o 83libperf-y += term.o
84libperf-y += help-unknown-cmd.o
90 85
91libperf-$(CONFIG_LIBBPF) += bpf-loader.o 86libperf-$(CONFIG_LIBBPF) += bpf-loader.o
92libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o 87libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
@@ -112,7 +107,6 @@ libperf-$(CONFIG_ZLIB) += zlib.o
112libperf-$(CONFIG_LZMA) += lzma.o 107libperf-$(CONFIG_LZMA) += lzma.o
113 108
114CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" 109CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
115CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))"
116 110
117$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c 111$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
118 $(call rule_mkdir) 112 $(call rule_mkdir)
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 7f10430af39c..360fda01f3b0 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -45,7 +45,7 @@
45#include "event.h" 45#include "event.h"
46#include "session.h" 46#include "session.h"
47#include "debug.h" 47#include "debug.h"
48#include "parse-options.h" 48#include <subcmd/parse-options.h>
49 49
50#include "intel-pt.h" 50#include "intel-pt.h"
51#include "intel-bts.h" 51#include "intel-bts.h"
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 4c2b76499dd5..07b5d63947b1 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -4,9 +4,12 @@
4#include <stdbool.h> 4#include <stdbool.h>
5#include "util.h" 5#include "util.h"
6#include "strbuf.h" 6#include "strbuf.h"
7#include <subcmd/pager.h>
7#include "../perf.h" 8#include "../perf.h"
8#include "../ui/ui.h" 9#include "../ui/ui.h"
9 10
11#include <linux/string.h>
12
10#define CMD_EXEC_PATH "--exec-path" 13#define CMD_EXEC_PATH "--exec-path"
11#define CMD_PERF_DIR "--perf-dir=" 14#define CMD_PERF_DIR "--perf-dir="
12#define CMD_WORK_TREE "--work-tree=" 15#define CMD_WORK_TREE "--work-tree="
@@ -18,6 +21,7 @@
18#define DEFAULT_PERF_DIR_ENVIRONMENT ".perf" 21#define DEFAULT_PERF_DIR_ENVIRONMENT ".perf"
19#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" 22#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
20#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR" 23#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
24#define PERF_PAGER_ENVIRONMENT "PERF_PAGER"
21 25
22typedef int (*config_fn_t)(const char *, const char *, void *); 26typedef int (*config_fn_t)(const char *, const char *, void *);
23extern int perf_default_config(const char *, const char *, void *); 27extern int perf_default_config(const char *, const char *, void *);
@@ -28,10 +32,6 @@ extern int perf_config_bool(const char *, const char *);
28extern int config_error_nonbool(const char *); 32extern int config_error_nonbool(const char *);
29extern const char *perf_config_dirname(const char *, const char *); 33extern const char *perf_config_dirname(const char *, const char *);
30 34
31/* pager.c */
32extern void setup_pager(void);
33extern int pager_in_use(void);
34
35char *alias_lookup(const char *alias); 35char *alias_lookup(const char *alias);
36int split_cmdline(char *cmdline, const char ***argv); 36int split_cmdline(char *cmdline, const char ***argv);
37 37
@@ -70,9 +70,4 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2
70extern char *perf_pathdup(const char *fmt, ...) 70extern char *perf_pathdup(const char *fmt, ...)
71 __attribute__((format (printf, 1, 2))); 71 __attribute__((format (printf, 1, 2)));
72 72
73#ifndef __UCLIBC__
74/* Matches the libc/libbsd function attribute so we declare this unconditionally: */
75extern size_t strlcpy(char *dest, const char *src, size_t size);
76#endif
77
78#endif /* __PERF_CACHE_H */ 73#endif /* __PERF_CACHE_H */
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 32e12ecfe9c5..90aa1b46b2e5 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -1,6 +1,6 @@
1#include "util.h" 1#include "util.h"
2#include "../perf.h" 2#include "../perf.h"
3#include "parse-options.h" 3#include <subcmd/parse-options.h>
4#include "evsel.h" 4#include "evsel.h"
5#include "cgroup.h" 5#include "cgroup.h"
6#include "evlist.h" 6#include "evlist.h"
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 2e452ac1353d..d3e12e30e1d5 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -10,7 +10,7 @@
10 */ 10 */
11#include "util.h" 11#include "util.h"
12#include "cache.h" 12#include "cache.h"
13#include "exec_cmd.h" 13#include <subcmd/exec-cmd.h>
14#include "util/hist.h" /* perf_hist_config */ 14#include "util/hist.h" /* perf_hist_config */
15#include "util/llvm-utils.h" /* perf_llvm_config */ 15#include "util/llvm-utils.h" /* perf_llvm_config */
16 16
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index d1b6c206bb93..8c44aadb9810 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -18,7 +18,7 @@
18#include <unistd.h> 18#include <unistd.h>
19 19
20#include "parse-events.h" 20#include "parse-events.h"
21#include "parse-options.h" 21#include <subcmd/parse-options.h>
22 22
23#include <sys/mman.h> 23#include <sys/mman.h>
24 24
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 47f033089349..544e4400de13 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -36,6 +36,7 @@ static struct {
36 bool cloexec; 36 bool cloexec;
37 bool clockid; 37 bool clockid;
38 bool clockid_wrong; 38 bool clockid_wrong;
39 bool lbr_flags;
39} perf_missing_features; 40} perf_missing_features;
40 41
41static clockid_t clockid; 42static clockid_t clockid;
@@ -574,7 +575,9 @@ perf_evsel__config_callgraph(struct perf_evsel *evsel,
574 } else { 575 } else {
575 perf_evsel__set_sample_bit(evsel, BRANCH_STACK); 576 perf_evsel__set_sample_bit(evsel, BRANCH_STACK);
576 attr->branch_sample_type = PERF_SAMPLE_BRANCH_USER | 577 attr->branch_sample_type = PERF_SAMPLE_BRANCH_USER |
577 PERF_SAMPLE_BRANCH_CALL_STACK; 578 PERF_SAMPLE_BRANCH_CALL_STACK |
579 PERF_SAMPLE_BRANCH_NO_CYCLES |
580 PERF_SAMPLE_BRANCH_NO_FLAGS;
578 } 581 }
579 } else 582 } else
580 pr_warning("Cannot use LBR callstack with branch stack. " 583 pr_warning("Cannot use LBR callstack with branch stack. "
@@ -1337,6 +1340,9 @@ fallback_missing_features:
1337 evsel->attr.mmap2 = 0; 1340 evsel->attr.mmap2 = 0;
1338 if (perf_missing_features.exclude_guest) 1341 if (perf_missing_features.exclude_guest)
1339 evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; 1342 evsel->attr.exclude_guest = evsel->attr.exclude_host = 0;
1343 if (perf_missing_features.lbr_flags)
1344 evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS |
1345 PERF_SAMPLE_BRANCH_NO_CYCLES);
1340retry_sample_id: 1346retry_sample_id:
1341 if (perf_missing_features.sample_id_all) 1347 if (perf_missing_features.sample_id_all)
1342 evsel->attr.sample_id_all = 0; 1348 evsel->attr.sample_id_all = 0;
@@ -1455,6 +1461,12 @@ try_fallback:
1455 } else if (!perf_missing_features.sample_id_all) { 1461 } else if (!perf_missing_features.sample_id_all) {
1456 perf_missing_features.sample_id_all = true; 1462 perf_missing_features.sample_id_all = true;
1457 goto retry_sample_id; 1463 goto retry_sample_id;
1464 } else if (!perf_missing_features.lbr_flags &&
1465 (evsel->attr.branch_sample_type &
1466 (PERF_SAMPLE_BRANCH_NO_CYCLES |
1467 PERF_SAMPLE_BRANCH_NO_FLAGS))) {
1468 perf_missing_features.lbr_flags = true;
1469 goto fallback_missing_features;
1458 } 1470 }
1459 1471
1460out_close: 1472out_close:
diff --git a/tools/perf/util/exec_cmd.c b/tools/perf/util/exec_cmd.c
deleted file mode 100644
index 1099e92f5ee1..000000000000
--- a/tools/perf/util/exec_cmd.c
+++ /dev/null
@@ -1,149 +0,0 @@
1#include "cache.h"
2#include "exec_cmd.h"
3#include "quote.h"
4
5#include <string.h>
6
7#define MAX_ARGS 32
8
9static const char *argv_exec_path;
10static const char *argv0_path;
11
12char *system_path(const char *path)
13{
14 static const char *prefix = PREFIX;
15 struct strbuf d = STRBUF_INIT;
16
17 if (is_absolute_path(path))
18 return strdup(path);
19
20 strbuf_addf(&d, "%s/%s", prefix, path);
21 path = strbuf_detach(&d, NULL);
22 return (char *)path;
23}
24
25const char *perf_extract_argv0_path(const char *argv0)
26{
27 const char *slash;
28
29 if (!argv0 || !*argv0)
30 return NULL;
31 slash = argv0 + strlen(argv0);
32
33 while (argv0 <= slash && !is_dir_sep(*slash))
34 slash--;
35
36 if (slash >= argv0) {
37 argv0_path = strndup(argv0, slash - argv0);
38 return argv0_path ? slash + 1 : NULL;
39 }
40
41 return argv0;
42}
43
44void perf_set_argv_exec_path(const char *exec_path)
45{
46 argv_exec_path = exec_path;
47 /*
48 * Propagate this setting to external programs.
49 */
50 setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
51}
52
53
54/* Returns the highest-priority, location to look for perf programs. */
55char *perf_exec_path(void)
56{
57 char *env;
58
59 if (argv_exec_path)
60 return strdup(argv_exec_path);
61
62 env = getenv(EXEC_PATH_ENVIRONMENT);
63 if (env && *env)
64 return strdup(env);
65
66 return system_path(PERF_EXEC_PATH);
67}
68
69static void add_path(struct strbuf *out, const char *path)
70{
71 if (path && *path) {
72 if (is_absolute_path(path))
73 strbuf_addstr(out, path);
74 else
75 strbuf_addstr(out, make_nonrelative_path(path));
76
77 strbuf_addch(out, PATH_SEP);
78 }
79}
80
81void setup_path(void)
82{
83 const char *old_path = getenv("PATH");
84 struct strbuf new_path = STRBUF_INIT;
85 char *tmp = perf_exec_path();
86
87 add_path(&new_path, tmp);
88 add_path(&new_path, argv0_path);
89 free(tmp);
90
91 if (old_path)
92 strbuf_addstr(&new_path, old_path);
93 else
94 strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin");
95
96 setenv("PATH", new_path.buf, 1);
97
98 strbuf_release(&new_path);
99}
100
101static const char **prepare_perf_cmd(const char **argv)
102{
103 int argc;
104 const char **nargv;
105
106 for (argc = 0; argv[argc]; argc++)
107 ; /* just counting */
108 nargv = malloc(sizeof(*nargv) * (argc + 2));
109
110 nargv[0] = "perf";
111 for (argc = 0; argv[argc]; argc++)
112 nargv[argc + 1] = argv[argc];
113 nargv[argc + 1] = NULL;
114 return nargv;
115}
116
117int execv_perf_cmd(const char **argv) {
118 const char **nargv = prepare_perf_cmd(argv);
119
120 /* execvp() can only ever return if it fails */
121 execvp("perf", (char **)nargv);
122
123 free(nargv);
124 return -1;
125}
126
127
128int execl_perf_cmd(const char *cmd,...)
129{
130 int argc;
131 const char *argv[MAX_ARGS + 1];
132 const char *arg;
133 va_list param;
134
135 va_start(param, cmd);
136 argv[0] = cmd;
137 argc = 1;
138 while (argc < MAX_ARGS) {
139 arg = argv[argc++] = va_arg(param, char *);
140 if (!arg)
141 break;
142 }
143 va_end(param);
144 if (MAX_ARGS <= argc)
145 return error("too many args to run %s", cmd);
146
147 argv[argc] = NULL;
148 return execv_perf_cmd(argv);
149}
diff --git a/tools/perf/util/exec_cmd.h b/tools/perf/util/exec_cmd.h
deleted file mode 100644
index 48b4175f1e11..000000000000
--- a/tools/perf/util/exec_cmd.h
+++ /dev/null
@@ -1,13 +0,0 @@
1#ifndef __PERF_EXEC_CMD_H
2#define __PERF_EXEC_CMD_H
3
4extern void perf_set_argv_exec_path(const char *exec_path);
5extern const char *perf_extract_argv0_path(const char *path);
6extern void setup_path(void);
7extern int execv_perf_cmd(const char **argv); /* NULL terminated */
8extern int execl_perf_cmd(const char *cmd, ...);
9/* perf_exec_path and system_path return malloc'd string, caller must free it */
10extern char *perf_exec_path(void);
11extern char *system_path(const char *path);
12
13#endif /* __PERF_EXEC_CMD_H */
diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c
new file mode 100644
index 000000000000..dc1e41c9b054
--- /dev/null
+++ b/tools/perf/util/help-unknown-cmd.c
@@ -0,0 +1,103 @@
1#include "cache.h"
2#include <subcmd/help.h>
3#include "../builtin.h"
4#include "levenshtein.h"
5
6static int autocorrect;
7static struct cmdnames aliases;
8
9static int perf_unknown_cmd_config(const char *var, const char *value, void *cb)
10{
11 if (!strcmp(var, "help.autocorrect"))
12 autocorrect = perf_config_int(var,value);
13 /* Also use aliases for command lookup */
14 if (!prefixcmp(var, "alias."))
15 add_cmdname(&aliases, var + 6, strlen(var + 6));
16
17 return perf_default_config(var, value, cb);
18}
19
20static int levenshtein_compare(const void *p1, const void *p2)
21{
22 const struct cmdname *const *c1 = p1, *const *c2 = p2;
23 const char *s1 = (*c1)->name, *s2 = (*c2)->name;
24 int l1 = (*c1)->len;
25 int l2 = (*c2)->len;
26 return l1 != l2 ? l1 - l2 : strcmp(s1, s2);
27}
28
29static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
30{
31 unsigned int i;
32
33 ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);
34
35 for (i = 0; i < old->cnt; i++)
36 cmds->names[cmds->cnt++] = old->names[i];
37 zfree(&old->names);
38 old->cnt = 0;
39}
40
41const char *help_unknown_cmd(const char *cmd)
42{
43 unsigned int i, n = 0, best_similarity = 0;
44 struct cmdnames main_cmds, other_cmds;
45
46 memset(&main_cmds, 0, sizeof(main_cmds));
47 memset(&other_cmds, 0, sizeof(main_cmds));
48 memset(&aliases, 0, sizeof(aliases));
49
50 perf_config(perf_unknown_cmd_config, NULL);
51
52 load_command_list("perf-", &main_cmds, &other_cmds);
53
54 add_cmd_list(&main_cmds, &aliases);
55 add_cmd_list(&main_cmds, &other_cmds);
56 qsort(main_cmds.names, main_cmds.cnt,
57 sizeof(main_cmds.names), cmdname_compare);
58 uniq(&main_cmds);
59
60 if (main_cmds.cnt) {
61 /* This reuses cmdname->len for similarity index */
62 for (i = 0; i < main_cmds.cnt; ++i)
63 main_cmds.names[i]->len =
64 levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4);
65
66 qsort(main_cmds.names, main_cmds.cnt,
67 sizeof(*main_cmds.names), levenshtein_compare);
68
69 best_similarity = main_cmds.names[0]->len;
70 n = 1;
71 while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len)
72 ++n;
73 }
74
75 if (autocorrect && n == 1) {
76 const char *assumed = main_cmds.names[0]->name;
77
78 main_cmds.names[0] = NULL;
79 clean_cmdnames(&main_cmds);
80 fprintf(stderr, "WARNING: You called a perf program named '%s', "
81 "which does not exist.\n"
82 "Continuing under the assumption that you meant '%s'\n",
83 cmd, assumed);
84 if (autocorrect > 0) {
85 fprintf(stderr, "in %0.1f seconds automatically...\n",
86 (float)autocorrect/10.0);
87 poll(NULL, 0, autocorrect * 100);
88 }
89 return assumed;
90 }
91
92 fprintf(stderr, "perf: '%s' is not a perf-command. See 'perf --help'.\n", cmd);
93
94 if (main_cmds.cnt && best_similarity < 6) {
95 fprintf(stderr, "\nDid you mean %s?\n",
96 n < 2 ? "this": "one of these");
97
98 for (i = 0; i < n; i++)
99 fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
100 }
101
102 exit(1);
103}
diff --git a/tools/perf/util/help-unknown-cmd.h b/tools/perf/util/help-unknown-cmd.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/perf/util/help-unknown-cmd.h
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 97f963a3dcb9..81a2eb77ba7f 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -1744,7 +1744,7 @@ static void intel_pt_free(struct perf_session *session)
1744 auxtrace_heap__free(&pt->heap); 1744 auxtrace_heap__free(&pt->heap);
1745 intel_pt_free_events(session); 1745 intel_pt_free_events(session);
1746 session->auxtrace = NULL; 1746 session->auxtrace = NULL;
1747 thread__delete(pt->unknown_thread); 1747 thread__put(pt->unknown_thread);
1748 free(pt); 1748 free(pt);
1749} 1749}
1750 1750
@@ -2153,7 +2153,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event,
2153 return 0; 2153 return 0;
2154 2154
2155err_delete_thread: 2155err_delete_thread:
2156 thread__delete(pt->unknown_thread); 2156 thread__zput(pt->unknown_thread);
2157err_free_queues: 2157err_free_queues:
2158 intel_pt_log_disable(); 2158 intel_pt_log_disable();
2159 auxtrace_queues__free(&pt->queues); 2159 auxtrace_queues__free(&pt->queues);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 1407d5107480..ad79297c76c8 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -352,13 +352,18 @@ static void machine__update_thread_pid(struct machine *machine,
352 } 352 }
353 353
354 th->mg = map_groups__get(leader->mg); 354 th->mg = map_groups__get(leader->mg);
355 355out_put:
356 thread__put(leader);
356 return; 357 return;
357
358out_err: 358out_err:
359 pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid); 359 pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid);
360 goto out_put;
360} 361}
361 362
363/*
364 * Caller must eventually drop thread->refcnt returned with a successfull
365 * lookup/new thread inserted.
366 */
362static struct thread *____machine__findnew_thread(struct machine *machine, 367static struct thread *____machine__findnew_thread(struct machine *machine,
363 pid_t pid, pid_t tid, 368 pid_t pid, pid_t tid,
364 bool create) 369 bool create)
@@ -376,7 +381,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
376 if (th != NULL) { 381 if (th != NULL) {
377 if (th->tid == tid) { 382 if (th->tid == tid) {
378 machine__update_thread_pid(machine, th, pid); 383 machine__update_thread_pid(machine, th, pid);
379 return th; 384 return thread__get(th);
380 } 385 }
381 386
382 machine->last_match = NULL; 387 machine->last_match = NULL;
@@ -389,7 +394,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
389 if (th->tid == tid) { 394 if (th->tid == tid) {
390 machine->last_match = th; 395 machine->last_match = th;
391 machine__update_thread_pid(machine, th, pid); 396 machine__update_thread_pid(machine, th, pid);
392 return th; 397 return thread__get(th);
393 } 398 }
394 399
395 if (tid < th->tid) 400 if (tid < th->tid)
@@ -417,7 +422,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
417 if (thread__init_map_groups(th, machine)) { 422 if (thread__init_map_groups(th, machine)) {
418 rb_erase_init(&th->rb_node, &machine->threads); 423 rb_erase_init(&th->rb_node, &machine->threads);
419 RB_CLEAR_NODE(&th->rb_node); 424 RB_CLEAR_NODE(&th->rb_node);
420 thread__delete(th); 425 thread__put(th);
421 return NULL; 426 return NULL;
422 } 427 }
423 /* 428 /*
@@ -441,7 +446,7 @@ struct thread *machine__findnew_thread(struct machine *machine, pid_t pid,
441 struct thread *th; 446 struct thread *th;
442 447
443 pthread_rwlock_wrlock(&machine->threads_lock); 448 pthread_rwlock_wrlock(&machine->threads_lock);
444 th = thread__get(__machine__findnew_thread(machine, pid, tid)); 449 th = __machine__findnew_thread(machine, pid, tid);
445 pthread_rwlock_unlock(&machine->threads_lock); 450 pthread_rwlock_unlock(&machine->threads_lock);
446 return th; 451 return th;
447} 452}
@@ -451,7 +456,7 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid,
451{ 456{
452 struct thread *th; 457 struct thread *th;
453 pthread_rwlock_rdlock(&machine->threads_lock); 458 pthread_rwlock_rdlock(&machine->threads_lock);
454 th = thread__get(____machine__findnew_thread(machine, pid, tid, false)); 459 th = ____machine__findnew_thread(machine, pid, tid, false);
455 pthread_rwlock_unlock(&machine->threads_lock); 460 pthread_rwlock_unlock(&machine->threads_lock);
456 return th; 461 return th;
457} 462}
diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
index 355eecf6bf59..afc088dd7d20 100644
--- a/tools/perf/util/parse-branch-options.c
+++ b/tools/perf/util/parse-branch-options.c
@@ -1,7 +1,7 @@
1#include "perf.h" 1#include "perf.h"
2#include "util/util.h" 2#include "util/util.h"
3#include "util/debug.h" 3#include "util/debug.h"
4#include "util/parse-options.h" 4#include <subcmd/parse-options.h>
5#include "util/parse-branch-options.h" 5#include "util/parse-branch-options.h"
6 6
7#define BRANCH_OPT(n, m) \ 7#define BRANCH_OPT(n, m) \
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6fc8cd753e1a..4f7b0efdde2f 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -4,9 +4,9 @@
4#include "../perf.h" 4#include "../perf.h"
5#include "evlist.h" 5#include "evlist.h"
6#include "evsel.h" 6#include "evsel.h"
7#include "parse-options.h" 7#include <subcmd/parse-options.h>
8#include "parse-events.h" 8#include "parse-events.h"
9#include "exec_cmd.h" 9#include <subcmd/exec-cmd.h>
10#include "string.h" 10#include "string.h"
11#include "symbol.h" 11#include "symbol.h"
12#include "cache.h" 12#include "cache.h"
diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
index 4f2c1c255d81..646ecf736aad 100644
--- a/tools/perf/util/parse-regs-options.c
+++ b/tools/perf/util/parse-regs-options.c
@@ -1,7 +1,7 @@
1#include "perf.h" 1#include "perf.h"
2#include "util/util.h" 2#include "util/util.h"
3#include "util/debug.h" 3#include "util/debug.h"
4#include "util/parse-options.h" 4#include <subcmd/parse-options.h>
5#include "util/parse-regs-options.h" 5#include "util/parse-regs-options.h"
6 6
7int 7int
diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
index 5d13cb45b317..3654d964e49d 100644
--- a/tools/perf/util/path.c
+++ b/tools/perf/util/path.c
@@ -22,24 +22,6 @@ static const char *get_perf_dir(void)
22 return "."; 22 return ".";
23} 23}
24 24
25/*
26 * If libc has strlcpy() then that version will override this
27 * implementation:
28 */
29size_t __weak strlcpy(char *dest, const char *src, size_t size)
30{
31 size_t ret = strlen(src);
32
33 if (size) {
34 size_t len = (ret >= size) ? size - 1 : ret;
35
36 memcpy(dest, src, len);
37 dest[len] = '\0';
38 }
39
40 return ret;
41}
42
43static char *get_pathname(void) 25static char *get_pathname(void)
44{ 26{
45 static char pathname_array[4][PATH_MAX]; 27 static char pathname_array[4][PATH_MAX];
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 31228851e397..86f05e7a5566 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -18,7 +18,7 @@
18#include "debug.h" 18#include "debug.h"
19#include "header.h" 19#include "header.h"
20 20
21#include "parse-options.h" 21#include <subcmd/parse-options.h>
22#include "parse-events.h" 22#include "parse-events.h"
23#include "hist.h" 23#include "hist.h"
24#include "thread.h" 24#include "thread.h"
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 0a9ae8014729..dfd00c6dad6e 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -19,8 +19,10 @@ int thread__init_map_groups(struct thread *thread, struct machine *machine)
19 thread->mg = map_groups__new(machine); 19 thread->mg = map_groups__new(machine);
20 } else { 20 } else {
21 leader = __machine__findnew_thread(machine, pid, pid); 21 leader = __machine__findnew_thread(machine, pid, pid);
22 if (leader) 22 if (leader) {
23 thread->mg = map_groups__get(leader->mg); 23 thread->mg = map_groups__get(leader->mg);
24 thread__put(leader);
25 }
24 } 26 }
25 27
26 return thread->mg ? 0 : -1; 28 return thread->mg ? 0 : -1;
@@ -53,7 +55,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
53 goto err_thread; 55 goto err_thread;
54 56
55 list_add(&comm->list, &thread->comm_list); 57 list_add(&comm->list, &thread->comm_list);
56 atomic_set(&thread->refcnt, 0); 58 atomic_set(&thread->refcnt, 1);
57 RB_CLEAR_NODE(&thread->rb_node); 59 RB_CLEAR_NODE(&thread->rb_node);
58 } 60 }
59 61
@@ -95,6 +97,10 @@ struct thread *thread__get(struct thread *thread)
95void thread__put(struct thread *thread) 97void thread__put(struct thread *thread)
96{ 98{
97 if (thread && atomic_dec_and_test(&thread->refcnt)) { 99 if (thread && atomic_dec_and_test(&thread->refcnt)) {
100 /*
101 * Remove it from the dead_threads list, as last reference
102 * is gone.
103 */
98 list_del_init(&thread->node); 104 list_del_init(&thread->node);
99 thread__delete(thread); 105 thread__delete(thread);
100 } 106 }
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 07da970a62a3..aff0cfd83662 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -352,7 +352,8 @@ void sighandler_dump_stack(int sig)
352{ 352{
353 psignal(sig, "perf"); 353 psignal(sig, "perf");
354 dump_stack(); 354 dump_stack();
355 exit(sig); 355 signal(sig, SIG_DFL);
356 raise(sig);
356} 357}
357 358
358int parse_nsec_time(const char *str, u64 *ptime) 359int parse_nsec_time(const char *str, u64 *ptime)
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 150858f3b4f0..4b519c59bdc3 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -151,12 +151,6 @@ extern void set_warning_routine(void (*routine)(const char *err, va_list params)
151extern int prefixcmp(const char *str, const char *prefix); 151extern int prefixcmp(const char *str, const char *prefix);
152extern void set_buildid_dir(const char *dir); 152extern void set_buildid_dir(const char *dir);
153 153
154static inline const char *skip_prefix(const char *str, const char *prefix)
155{
156 size_t len = strlen(prefix);
157 return strncmp(str, prefix, len) ? NULL : str + len;
158}
159
160#ifdef __GLIBC_PREREQ 154#ifdef __GLIBC_PREREQ
161#if __GLIBC_PREREQ(2, 1) 155#if __GLIBC_PREREQ(2, 1)
162#define HAVE_STRCHRNUL 156#define HAVE_STRCHRNUL
@@ -187,14 +181,6 @@ static inline void *zalloc(size_t size)
187 181
188#define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) 182#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
189 183
190static inline int has_extension(const char *filename, const char *ext)
191{
192 size_t len = strlen(filename);
193 size_t extlen = strlen(ext);
194
195 return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
196}
197
198/* Sane ctype - no locale, and works with signed chars */ 184/* Sane ctype - no locale, and works with signed chars */
199#undef isascii 185#undef isascii
200#undef isspace 186#undef isspace