aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-03-22 05:56:19 -0400
committerIngo Molnar <mingo@kernel.org>2015-03-22 05:56:19 -0400
commit963a70b8a2d65538f7d58b2b84a2ae10a3ecb6ea (patch)
tree3c104859a1a4c5de6a30aee4e483ee2d0dfaf8c3
parent08b3f913900075a19564ab68967028ab99c95820 (diff)
parentca33380adf74afb985bf7aab09ec46707a5d2d57 (diff)
Merge tag 'perf-core-for-mingo-2' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: - Handle legacy syscalls tracepoints (David Ahern, Arnaldo Carvalho de Melo) - Indicate which callchain entries are annotated in the TUI hists browser (report/top) (Arnaldo Carvalho de Melo) - Fix failure to add multiple probes without debuginfo (He Kuang) - Fix 'trace' summary_only option (David Ahern) - Fix race in build_id_cache__add_s() in 'buildid-cache' (Milos Vyletel) - Don't allow empty argument for field-separator, fixing segfault (Wang Nan) Infrastructure: - Add destructor for format_field in libtraceevent (David Ahern) - Prep work for support lzma compressed kernel modules (Jiri Olsa) - Update .gitignore with recently added/renamed feature detection files (Yunlong Song) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/build/Makefile.feature171
-rw-r--r--tools/build/feature/.gitignore (renamed from tools/perf/config/feature-checks/.gitignore)1
-rw-r--r--tools/build/feature/Makefile (renamed from tools/perf/config/feature-checks/Makefile)8
-rw-r--r--tools/build/feature/test-all.c (renamed from tools/perf/config/feature-checks/test-all.c)5
-rw-r--r--tools/build/feature/test-backtrace.c (renamed from tools/perf/config/feature-checks/test-backtrace.c)0
-rw-r--r--tools/build/feature/test-bionic.c (renamed from tools/perf/config/feature-checks/test-bionic.c)0
-rw-r--r--tools/build/feature/test-compile.c (renamed from tools/perf/config/feature-checks/test-compile.c)0
-rw-r--r--tools/build/feature/test-cplus-demangle.c (renamed from tools/perf/config/feature-checks/test-cplus-demangle.c)0
-rw-r--r--tools/build/feature/test-dwarf.c (renamed from tools/perf/config/feature-checks/test-dwarf.c)0
-rw-r--r--tools/build/feature/test-fortify-source.c (renamed from tools/perf/config/feature-checks/test-fortify-source.c)0
-rw-r--r--tools/build/feature/test-glibc.c (renamed from tools/perf/config/feature-checks/test-glibc.c)0
-rw-r--r--tools/build/feature/test-gtk2-infobar.c (renamed from tools/perf/config/feature-checks/test-gtk2-infobar.c)0
-rw-r--r--tools/build/feature/test-gtk2.c (renamed from tools/perf/config/feature-checks/test-gtk2.c)0
-rw-r--r--tools/build/feature/test-hello.c (renamed from tools/perf/config/feature-checks/test-hello.c)0
-rw-r--r--tools/build/feature/test-libaudit.c (renamed from tools/perf/config/feature-checks/test-libaudit.c)0
-rw-r--r--tools/build/feature/test-libbabeltrace.c (renamed from tools/perf/config/feature-checks/test-libbabeltrace.c)0
-rw-r--r--tools/build/feature/test-libbfd.c (renamed from tools/perf/config/feature-checks/test-libbfd.c)0
-rw-r--r--tools/build/feature/test-libdw-dwarf-unwind.c (renamed from tools/perf/config/feature-checks/test-libdw-dwarf-unwind.c)0
-rw-r--r--tools/build/feature/test-libelf-getphdrnum.c (renamed from tools/perf/config/feature-checks/test-libelf-getphdrnum.c)0
-rw-r--r--tools/build/feature/test-libelf-mmap.c (renamed from tools/perf/config/feature-checks/test-libelf-mmap.c)0
-rw-r--r--tools/build/feature/test-libelf.c (renamed from tools/perf/config/feature-checks/test-libelf.c)0
-rw-r--r--tools/build/feature/test-libnuma.c (renamed from tools/perf/config/feature-checks/test-libnuma.c)0
-rw-r--r--tools/build/feature/test-libperl.c (renamed from tools/perf/config/feature-checks/test-libperl.c)0
-rw-r--r--tools/build/feature/test-libpython-version.c (renamed from tools/perf/config/feature-checks/test-libpython-version.c)0
-rw-r--r--tools/build/feature/test-libpython.c (renamed from tools/perf/config/feature-checks/test-libpython.c)0
-rw-r--r--tools/build/feature/test-libslang.c (renamed from tools/perf/config/feature-checks/test-libslang.c)0
-rw-r--r--tools/build/feature/test-libunwind-debug-frame.c (renamed from tools/perf/config/feature-checks/test-libunwind-debug-frame.c)0
-rw-r--r--tools/build/feature/test-libunwind.c (renamed from tools/perf/config/feature-checks/test-libunwind.c)0
-rw-r--r--tools/build/feature/test-lzma.c10
-rw-r--r--tools/build/feature/test-pthread-attr-setaffinity-np.c (renamed from tools/perf/config/feature-checks/test-pthread-attr-setaffinity-np.c)0
-rw-r--r--tools/build/feature/test-stackprotector-all.c (renamed from tools/perf/config/feature-checks/test-stackprotector-all.c)0
-rw-r--r--tools/build/feature/test-sync-compare-and-swap.c (renamed from tools/perf/config/feature-checks/test-sync-compare-and-swap.c)0
-rw-r--r--tools/build/feature/test-timerfd.c (renamed from tools/perf/config/feature-checks/test-timerfd.c)0
-rw-r--r--tools/build/feature/test-zlib.c (renamed from tools/perf/config/feature-checks/test-zlib.c)0
-rw-r--r--tools/lib/traceevent/event-parse.c11
-rw-r--r--tools/lib/traceevent/event-parse.h1
-rw-r--r--tools/perf/.gitignore2
-rw-r--r--tools/perf/Makefile.perf4
-rw-r--r--tools/perf/builtin-diff.c2
-rw-r--r--tools/perf/builtin-mem.c2
-rw-r--r--tools/perf/builtin-trace.c21
-rw-r--r--tools/perf/config/Makefile176
-rw-r--r--tools/perf/tests/Build1
-rw-r--r--tools/perf/tests/builtin-test.c4
-rw-r--r--tools/perf/tests/kmod-path.c73
-rw-r--r--tools/perf/tests/tests.h1
-rw-r--r--tools/perf/ui/browsers/hists.c4
-rw-r--r--tools/perf/util/Build1
-rw-r--r--tools/perf/util/build-id.c3
-rw-r--r--tools/perf/util/dso.c90
-rw-r--r--tools/perf/util/dso.h15
-rw-r--r--tools/perf/util/lzma.c95
-rw-r--r--tools/perf/util/machine.c83
-rw-r--r--tools/perf/util/probe-event.c4
-rw-r--r--tools/perf/util/util.h4
55 files changed, 557 insertions, 235 deletions
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
new file mode 100644
index 000000000000..3a0b0ca2a28c
--- /dev/null
+++ b/tools/build/Makefile.feature
@@ -0,0 +1,171 @@
1feature_dir := $(srctree)/tools/build/feature
2
3ifneq ($(OUTPUT),)
4 OUTPUT_FEATURES = $(OUTPUT)feature/
5 $(shell mkdir -p $(OUTPUT_FEATURES))
6endif
7
8feature_check = $(eval $(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)
11endef
12
13feature_set = $(eval $(feature_set_code))
14define feature_set_code
15 feature-$(1) := 1
16endef
17
18#
19# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
20#
21
22#
23# Note that this is not a complete list of all feature tests, just
24# those that are typically built on a fully configured system.
25#
26# [ Feature tests not mentioned here have to be built explicitly in
27# the rule that uses them - an example for that is the 'bionic'
28# feature check. ]
29#
30FEATURE_TESTS = \
31 backtrace \
32 dwarf \
33 fortify-source \
34 sync-compare-and-swap \
35 glibc \
36 gtk2 \
37 gtk2-infobar \
38 libaudit \
39 libbfd \
40 libelf \
41 libelf-getphdrnum \
42 libelf-mmap \
43 libnuma \
44 libperl \
45 libpython \
46 libpython-version \
47 libslang \
48 libunwind \
49 pthread-attr-setaffinity-np \
50 stackprotector-all \
51 timerfd \
52 libdw-dwarf-unwind \
53 zlib \
54 lzma
55
56FEATURE_DISPLAY = \
57 dwarf \
58 glibc \
59 gtk2 \
60 libaudit \
61 libbfd \
62 libelf \
63 libnuma \
64 libperl \
65 libpython \
66 libslang \
67 libunwind \
68 libdw-dwarf-unwind \
69 zlib \
70 lzma
71
72# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
73# If in the future we need per-feature checks/flags for features not
74# mentioned in this list we need to refactor this ;-).
75set_test_all_flags = $(eval $(set_test_all_flags_code))
76define set_test_all_flags_code
77 FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
78 FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
79endef
80
81$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
82
83#
84# Special fast-path for the 'all features are available' case:
85#
86$(call feature_check,all,$(MSG))
87
88#
89# Just in case the build freshly failed, make sure we print the
90# feature matrix:
91#
92ifeq ($(feature-all), 1)
93 #
94 # test-all.c passed - just set all the core feature flags to 1:
95 #
96 $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
97else
98 $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C $(feature_dir) $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
99 $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
100endif
101
102#
103# Print the result of the feature test:
104#
105feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG))
106
107define feature_print_status_code
108 ifeq ($(feature-$(1)), 1)
109 MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1))
110 else
111 MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
112 endif
113endef
114
115feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG))
116define feature_print_text_code
117 MSG = $(shell printf '...%30s: %s' $(1) $(2))
118endef
119
120FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
121FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
122
123ifeq ($(dwarf-post-unwind),1)
124 FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
125endif
126
127# The $(feature_display) controls the default detection message
128# output. It's set if:
129# - detected features differes from stored features from
130# last build (in FEATURE-DUMP file)
131# - one of the $(FEATURE_DISPLAY) is not detected
132# - VF is enabled
133
134ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
135 $(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
136 feature_display := 1
137endif
138
139feature_display_check = $(eval $(feature_check_code))
140define feature_display_check_code
141 ifneq ($(feature-$(1)), 1)
142 feature_display := 1
143 endif
144endef
145
146$(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat)))
147
148ifeq ($(VF),1)
149 feature_display := 1
150 feature_verbose := 1
151endif
152
153ifeq ($(feature_display),1)
154 $(info )
155 $(info Auto-detecting system features:)
156 $(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
157
158 ifeq ($(dwarf-post-unwind),1)
159 $(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text))
160 endif
161
162 ifneq ($(feature_verbose),1)
163 $(info )
164 endif
165endif
166
167ifeq ($(feature_verbose),1)
168 TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
169 $(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
170 $(info )
171endif
diff --git a/tools/perf/config/feature-checks/.gitignore b/tools/build/feature/.gitignore
index 80f3da0c3515..09b335b98842 100644
--- a/tools/perf/config/feature-checks/.gitignore
+++ b/tools/build/feature/.gitignore
@@ -1,2 +1,3 @@
1*.d 1*.d
2*.bin 2*.bin
3*.output
diff --git a/tools/perf/config/feature-checks/Makefile b/tools/build/feature/Makefile
index 0d694a94cda2..463ed8f2a267 100644
--- a/tools/perf/config/feature-checks/Makefile
+++ b/tools/build/feature/Makefile
@@ -32,7 +32,8 @@ FILES= \
32 test-libbabeltrace.bin \ 32 test-libbabeltrace.bin \
33 test-compile-32.bin \ 33 test-compile-32.bin \
34 test-compile-x32.bin \ 34 test-compile-x32.bin \
35 test-zlib.bin 35 test-zlib.bin \
36 test-lzma.bin
36 37
37CC := $(CROSS_COMPILE)gcc -MD 38CC := $(CROSS_COMPILE)gcc -MD
38PKG_CONFIG := $(CROSS_COMPILE)pkg-config 39PKG_CONFIG := $(CROSS_COMPILE)pkg-config
@@ -45,7 +46,7 @@ __BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@)
45############################### 46###############################
46 47
47test-all.bin: 48test-all.bin:
48 $(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 49 $(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
49 50
50test-hello.bin: 51test-hello.bin:
51 $(BUILD) 52 $(BUILD)
@@ -152,6 +153,9 @@ test-compile-x32.bin:
152test-zlib.bin: 153test-zlib.bin:
153 $(BUILD) -lz 154 $(BUILD) -lz
154 155
156test-lzma.bin:
157 $(BUILD) -llzma
158
155-include *.d 159-include *.d
156 160
157############################### 161###############################
diff --git a/tools/perf/config/feature-checks/test-all.c b/tools/build/feature/test-all.c
index a61c20456705..84689a67814a 100644
--- a/tools/perf/config/feature-checks/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -113,6 +113,10 @@
113#undef main 113#undef main
114#endif 114#endif
115 115
116#define main main_test_lzma
117# include "test-lzma.c"
118#undef main
119
116int main(int argc, char *argv[]) 120int main(int argc, char *argv[])
117{ 121{
118 main_test_libpython(); 122 main_test_libpython();
@@ -138,6 +142,7 @@ int main(int argc, char *argv[])
138 main_test_sync_compare_and_swap(argc, argv); 142 main_test_sync_compare_and_swap(argc, argv);
139 main_test_zlib(); 143 main_test_zlib();
140 main_test_pthread_attr_setaffinity_np(); 144 main_test_pthread_attr_setaffinity_np();
145 main_test_lzma();
141 146
142 return 0; 147 return 0;
143} 148}
diff --git a/tools/perf/config/feature-checks/test-backtrace.c b/tools/build/feature/test-backtrace.c
index 7124aa1dc8fb..7124aa1dc8fb 100644
--- a/tools/perf/config/feature-checks/test-backtrace.c
+++ b/tools/build/feature/test-backtrace.c
diff --git a/tools/perf/config/feature-checks/test-bionic.c b/tools/build/feature/test-bionic.c
index eac24e9513eb..eac24e9513eb 100644
--- a/tools/perf/config/feature-checks/test-bionic.c
+++ b/tools/build/feature/test-bionic.c
diff --git a/tools/perf/config/feature-checks/test-compile.c b/tools/build/feature/test-compile.c
index 31dbf45bf99c..31dbf45bf99c 100644
--- a/tools/perf/config/feature-checks/test-compile.c
+++ b/tools/build/feature/test-compile.c
diff --git a/tools/perf/config/feature-checks/test-cplus-demangle.c b/tools/build/feature/test-cplus-demangle.c
index 610c686e0009..610c686e0009 100644
--- a/tools/perf/config/feature-checks/test-cplus-demangle.c
+++ b/tools/build/feature/test-cplus-demangle.c
diff --git a/tools/perf/config/feature-checks/test-dwarf.c b/tools/build/feature/test-dwarf.c
index 3fc1801ce4a9..3fc1801ce4a9 100644
--- a/tools/perf/config/feature-checks/test-dwarf.c
+++ b/tools/build/feature/test-dwarf.c
diff --git a/tools/perf/config/feature-checks/test-fortify-source.c b/tools/build/feature/test-fortify-source.c
index c9f398d87868..c9f398d87868 100644
--- a/tools/perf/config/feature-checks/test-fortify-source.c
+++ b/tools/build/feature/test-fortify-source.c
diff --git a/tools/perf/config/feature-checks/test-glibc.c b/tools/build/feature/test-glibc.c
index b0820345cd98..b0820345cd98 100644
--- a/tools/perf/config/feature-checks/test-glibc.c
+++ b/tools/build/feature/test-glibc.c
diff --git a/tools/perf/config/feature-checks/test-gtk2-infobar.c b/tools/build/feature/test-gtk2-infobar.c
index 397b4646d066..397b4646d066 100644
--- a/tools/perf/config/feature-checks/test-gtk2-infobar.c
+++ b/tools/build/feature/test-gtk2-infobar.c
diff --git a/tools/perf/config/feature-checks/test-gtk2.c b/tools/build/feature/test-gtk2.c
index 6bd80e509439..6bd80e509439 100644
--- a/tools/perf/config/feature-checks/test-gtk2.c
+++ b/tools/build/feature/test-gtk2.c
diff --git a/tools/perf/config/feature-checks/test-hello.c b/tools/build/feature/test-hello.c
index c9f398d87868..c9f398d87868 100644
--- a/tools/perf/config/feature-checks/test-hello.c
+++ b/tools/build/feature/test-hello.c
diff --git a/tools/perf/config/feature-checks/test-libaudit.c b/tools/build/feature/test-libaudit.c
index afc019f08641..afc019f08641 100644
--- a/tools/perf/config/feature-checks/test-libaudit.c
+++ b/tools/build/feature/test-libaudit.c
diff --git a/tools/perf/config/feature-checks/test-libbabeltrace.c b/tools/build/feature/test-libbabeltrace.c
index 9cf802a04885..9cf802a04885 100644
--- a/tools/perf/config/feature-checks/test-libbabeltrace.c
+++ b/tools/build/feature/test-libbabeltrace.c
diff --git a/tools/perf/config/feature-checks/test-libbfd.c b/tools/build/feature/test-libbfd.c
index 24059907e990..24059907e990 100644
--- a/tools/perf/config/feature-checks/test-libbfd.c
+++ b/tools/build/feature/test-libbfd.c
diff --git a/tools/perf/config/feature-checks/test-libdw-dwarf-unwind.c b/tools/build/feature/test-libdw-dwarf-unwind.c
index f676a3ff442a..f676a3ff442a 100644
--- a/tools/perf/config/feature-checks/test-libdw-dwarf-unwind.c
+++ b/tools/build/feature/test-libdw-dwarf-unwind.c
diff --git a/tools/perf/config/feature-checks/test-libelf-getphdrnum.c b/tools/build/feature/test-libelf-getphdrnum.c
index d710459306c3..d710459306c3 100644
--- a/tools/perf/config/feature-checks/test-libelf-getphdrnum.c
+++ b/tools/build/feature/test-libelf-getphdrnum.c
diff --git a/tools/perf/config/feature-checks/test-libelf-mmap.c b/tools/build/feature/test-libelf-mmap.c
index 564427d7ef18..564427d7ef18 100644
--- a/tools/perf/config/feature-checks/test-libelf-mmap.c
+++ b/tools/build/feature/test-libelf-mmap.c
diff --git a/tools/perf/config/feature-checks/test-libelf.c b/tools/build/feature/test-libelf.c
index 08db322d8957..08db322d8957 100644
--- a/tools/perf/config/feature-checks/test-libelf.c
+++ b/tools/build/feature/test-libelf.c
diff --git a/tools/perf/config/feature-checks/test-libnuma.c b/tools/build/feature/test-libnuma.c
index 4763d9cd587d..4763d9cd587d 100644
--- a/tools/perf/config/feature-checks/test-libnuma.c
+++ b/tools/build/feature/test-libnuma.c
diff --git a/tools/perf/config/feature-checks/test-libperl.c b/tools/build/feature/test-libperl.c
index 8871f6a0fdb4..8871f6a0fdb4 100644
--- a/tools/perf/config/feature-checks/test-libperl.c
+++ b/tools/build/feature/test-libperl.c
diff --git a/tools/perf/config/feature-checks/test-libpython-version.c b/tools/build/feature/test-libpython-version.c
index facea122d812..facea122d812 100644
--- a/tools/perf/config/feature-checks/test-libpython-version.c
+++ b/tools/build/feature/test-libpython-version.c
diff --git a/tools/perf/config/feature-checks/test-libpython.c b/tools/build/feature/test-libpython.c
index b24b28ad6324..b24b28ad6324 100644
--- a/tools/perf/config/feature-checks/test-libpython.c
+++ b/tools/build/feature/test-libpython.c
diff --git a/tools/perf/config/feature-checks/test-libslang.c b/tools/build/feature/test-libslang.c
index 22ff22ed94d1..22ff22ed94d1 100644
--- a/tools/perf/config/feature-checks/test-libslang.c
+++ b/tools/build/feature/test-libslang.c
diff --git a/tools/perf/config/feature-checks/test-libunwind-debug-frame.c b/tools/build/feature/test-libunwind-debug-frame.c
index 0ef8087a104a..0ef8087a104a 100644
--- a/tools/perf/config/feature-checks/test-libunwind-debug-frame.c
+++ b/tools/build/feature/test-libunwind-debug-frame.c
diff --git a/tools/perf/config/feature-checks/test-libunwind.c b/tools/build/feature/test-libunwind.c
index 43b9369bcab7..43b9369bcab7 100644
--- a/tools/perf/config/feature-checks/test-libunwind.c
+++ b/tools/build/feature/test-libunwind.c
diff --git a/tools/build/feature/test-lzma.c b/tools/build/feature/test-lzma.c
new file mode 100644
index 000000000000..95adc8ced3dd
--- /dev/null
+++ b/tools/build/feature/test-lzma.c
@@ -0,0 +1,10 @@
1#include <lzma.h>
2
3int main(void)
4{
5 lzma_stream strm = LZMA_STREAM_INIT;
6 int ret;
7
8 ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
9 return ret ? -1 : 0;
10}
diff --git a/tools/perf/config/feature-checks/test-pthread-attr-setaffinity-np.c b/tools/build/feature/test-pthread-attr-setaffinity-np.c
index fdada5e8d454..fdada5e8d454 100644
--- a/tools/perf/config/feature-checks/test-pthread-attr-setaffinity-np.c
+++ b/tools/build/feature/test-pthread-attr-setaffinity-np.c
diff --git a/tools/perf/config/feature-checks/test-stackprotector-all.c b/tools/build/feature/test-stackprotector-all.c
index c9f398d87868..c9f398d87868 100644
--- a/tools/perf/config/feature-checks/test-stackprotector-all.c
+++ b/tools/build/feature/test-stackprotector-all.c
diff --git a/tools/perf/config/feature-checks/test-sync-compare-and-swap.c b/tools/build/feature/test-sync-compare-and-swap.c
index c34d4ca4af56..c34d4ca4af56 100644
--- a/tools/perf/config/feature-checks/test-sync-compare-and-swap.c
+++ b/tools/build/feature/test-sync-compare-and-swap.c
diff --git a/tools/perf/config/feature-checks/test-timerfd.c b/tools/build/feature/test-timerfd.c
index 8c5c083b4d3c..8c5c083b4d3c 100644
--- a/tools/perf/config/feature-checks/test-timerfd.c
+++ b/tools/build/feature/test-timerfd.c
diff --git a/tools/perf/config/feature-checks/test-zlib.c b/tools/build/feature/test-zlib.c
index e111fff6240e..e111fff6240e 100644
--- a/tools/perf/config/feature-checks/test-zlib.c
+++ b/tools/build/feature/test-zlib.c
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index afe20ed9fac8..d7c37a7d9255 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -6228,15 +6228,20 @@ void pevent_ref(struct pevent *pevent)
6228 pevent->ref_count++; 6228 pevent->ref_count++;
6229} 6229}
6230 6230
6231void pevent_free_format_field(struct format_field *field)
6232{
6233 free(field->type);
6234 free(field->name);
6235 free(field);
6236}
6237
6231static void free_format_fields(struct format_field *field) 6238static void free_format_fields(struct format_field *field)
6232{ 6239{
6233 struct format_field *next; 6240 struct format_field *next;
6234 6241
6235 while (field) { 6242 while (field) {
6236 next = field->next; 6243 next = field->next;
6237 free(field->type); 6244 pevent_free_format_field(field);
6238 free(field->name);
6239 free(field);
6240 field = next; 6245 field = next;
6241 } 6246 }
6242} 6247}
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 5b4efc062320..6abda54d76f2 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -619,6 +619,7 @@ enum pevent_errno pevent_parse_format(struct pevent *pevent,
619 const char *buf, 619 const char *buf,
620 unsigned long size, const char *sys); 620 unsigned long size, const char *sys);
621void pevent_free_format(struct event_format *event); 621void pevent_free_format(struct event_format *event);
622void pevent_free_format_field(struct format_field *field);
622 623
623void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, 624void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
624 const char *name, struct pevent_record *record, 625 const char *name, struct pevent_record *record,
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 68328f517a2e..812f904193e8 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -1,7 +1,7 @@
1PERF-CFLAGS 1PERF-CFLAGS
2PERF-GUI-VARS 2PERF-GUI-VARS
3PERF-VERSION-FILE 3PERF-VERSION-FILE
4PERF-FEATURES 4FEATURE-DUMP
5perf 5perf
6perf-read-vdso32 6perf-read-vdso32
7perf-read-vdsox32 7perf-read-vdsox32
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index e323eab10694..e9925e6ad1d0 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -71,6 +71,8 @@ include config/utilities.mak
71# 71#
72# Define NO_LIBBABELTRACE if you do not want libbabeltrace support 72# Define NO_LIBBABELTRACE if you do not want libbabeltrace support
73# for CTF data format. 73# for CTF data format.
74#
75# Define NO_LZMA if you do not want to support compressed (xz) kernel modules
74 76
75ifeq ($(srctree),) 77ifeq ($(srctree),)
76srctree := $(patsubst %/,%,$(dir $(shell pwd))) 78srctree := $(patsubst %/,%,$(dir $(shell pwd)))
@@ -521,7 +523,7 @@ $(INSTALL_DOC_TARGETS):
521# 523#
522config-clean: 524config-clean:
523 $(call QUIET_CLEAN, config) 525 $(call QUIET_CLEAN, config)
524 $(Q)$(MAKE) -C config/feature-checks clean >/dev/null 526 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null
525 527
526clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean 528clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean
527 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) 529 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index f800fc95f5d7..473887d1d61a 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -802,7 +802,7 @@ static const struct option options[] = {
802 OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 802 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
803 "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." 803 "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
804 " Please refer the man page for the complete list."), 804 " Please refer the man page for the complete list."),
805 OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator", 805 OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
806 "separator for columns, no spaces will be added between " 806 "separator for columns, no spaces will be added between "
807 "columns '.' is reserved."), 807 "columns '.' is reserved."),
808 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 808 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 46c69318de84..b4dcf0bfc029 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -286,7 +286,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
286 "input file name"), 286 "input file name"),
287 OPT_STRING('C', "cpu", &mem.cpu_list, "cpu", 287 OPT_STRING('C', "cpu", &mem.cpu_list, "cpu",
288 "list of cpus to profile"), 288 "list of cpus to profile"),
289 OPT_STRING('x', "field-separator", &symbol_conf.field_sep, 289 OPT_STRING_NOEMPTY('x', "field-separator", &symbol_conf.field_sep,
290 "separator", 290 "separator",
291 "separator for columns, no spaces will be added" 291 "separator for columns, no spaces will be added"
292 " between columns '.' is reserved."), 292 " between columns '.' is reserved."),
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 0b3b4e4984b9..001c6ae9a1b1 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1135,6 +1135,8 @@ static struct syscall_fmt *syscall_fmt__find(const char *name)
1135 1135
1136struct syscall { 1136struct syscall {
1137 struct event_format *tp_format; 1137 struct event_format *tp_format;
1138 int nr_args;
1139 struct format_field *args;
1138 const char *name; 1140 const char *name;
1139 bool filtered; 1141 bool filtered;
1140 bool is_exit; 1142 bool is_exit;
@@ -1442,14 +1444,14 @@ static int syscall__set_arg_fmts(struct syscall *sc)
1442 struct format_field *field; 1444 struct format_field *field;
1443 int idx = 0; 1445 int idx = 0;
1444 1446
1445 sc->arg_scnprintf = calloc(sc->tp_format->format.nr_fields - 1, sizeof(void *)); 1447 sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *));
1446 if (sc->arg_scnprintf == NULL) 1448 if (sc->arg_scnprintf == NULL)
1447 return -1; 1449 return -1;
1448 1450
1449 if (sc->fmt) 1451 if (sc->fmt)
1450 sc->arg_parm = sc->fmt->arg_parm; 1452 sc->arg_parm = sc->fmt->arg_parm;
1451 1453
1452 for (field = sc->tp_format->format.fields->next; field; field = field->next) { 1454 for (field = sc->args; field; field = field->next) {
1453 if (sc->fmt && sc->fmt->arg_scnprintf[idx]) 1455 if (sc->fmt && sc->fmt->arg_scnprintf[idx])
1454 sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; 1456 sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
1455 else if (field->flags & FIELD_IS_POINTER) 1457 else if (field->flags & FIELD_IS_POINTER)
@@ -1515,6 +1517,14 @@ static int trace__read_syscall_info(struct trace *trace, int id)
1515 if (sc->tp_format == NULL) 1517 if (sc->tp_format == NULL)
1516 return -1; 1518 return -1;
1517 1519
1520 sc->args = sc->tp_format->format.fields;
1521 sc->nr_args = sc->tp_format->format.nr_fields;
1522 /* drop nr field - not relevant here; does not exist on older kernels */
1523 if (sc->args && strcmp(sc->args->name, "nr") == 0) {
1524 sc->args = sc->args->next;
1525 --sc->nr_args;
1526 }
1527
1518 sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit"); 1528 sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit");
1519 1529
1520 return syscall__set_arg_fmts(sc); 1530 return syscall__set_arg_fmts(sc);
@@ -1537,7 +1547,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
1537 unsigned char *p; 1547 unsigned char *p;
1538 unsigned long val; 1548 unsigned long val;
1539 1549
1540 if (sc->tp_format != NULL) { 1550 if (sc->args != NULL) {
1541 struct format_field *field; 1551 struct format_field *field;
1542 u8 bit = 1; 1552 u8 bit = 1;
1543 struct syscall_arg arg = { 1553 struct syscall_arg arg = {
@@ -1547,7 +1557,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
1547 .thread = thread, 1557 .thread = thread,
1548 }; 1558 };
1549 1559
1550 for (field = sc->tp_format->format.fields->next; field; 1560 for (field = sc->args; field;
1551 field = field->next, ++arg.idx, bit <<= 1) { 1561 field = field->next, ++arg.idx, bit <<= 1) {
1552 if (arg.mask & bit) 1562 if (arg.mask & bit)
1553 continue; 1563 continue;
@@ -1724,7 +1734,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
1724 return -1; 1734 return -1;
1725 } 1735 }
1726 1736
1727 printed += trace__printf_interrupted_entry(trace, sample); 1737 if (!trace->summary_only)
1738 printed += trace__printf_interrupted_entry(trace, sample);
1728 1739
1729 ttrace->entry_time = sample->time; 1740 ttrace->entry_time = sample->time;
1730 msg = ttrace->entry_str; 1741 msg = ttrace->entry_str;
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index e7f83b15fcbf..cd121dfc4de9 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -176,102 +176,7 @@ LDFLAGS += -Wl,-z,noexecstack
176 176
177EXTLIBS = -lpthread -lrt -lm -ldl 177EXTLIBS = -lpthread -lrt -lm -ldl
178 178
179ifneq ($(OUTPUT),) 179include $(srctree)/tools/build/Makefile.feature
180 OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
181 $(shell mkdir -p $(OUTPUT_FEATURES))
182endif
183
184feature_check = $(eval $(feature_check_code))
185define feature_check_code
186 feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
187endef
188
189feature_set = $(eval $(feature_set_code))
190define feature_set_code
191 feature-$(1) := 1
192endef
193
194#
195# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
196#
197
198#
199# Note that this is not a complete list of all feature tests, just
200# those that are typically built on a fully configured system.
201#
202# [ Feature tests not mentioned here have to be built explicitly in
203# the rule that uses them - an example for that is the 'bionic'
204# feature check. ]
205#
206FEATURE_TESTS = \
207 backtrace \
208 dwarf \
209 fortify-source \
210 sync-compare-and-swap \
211 glibc \
212 gtk2 \
213 gtk2-infobar \
214 libaudit \
215 libbfd \
216 libelf \
217 libelf-getphdrnum \
218 libelf-mmap \
219 libnuma \
220 libperl \
221 libpython \
222 libpython-version \
223 libslang \
224 libunwind \
225 pthread-attr-setaffinity-np \
226 stackprotector-all \
227 timerfd \
228 libdw-dwarf-unwind \
229 zlib
230
231FEATURE_DISPLAY = \
232 dwarf \
233 glibc \
234 gtk2 \
235 libaudit \
236 libbfd \
237 libelf \
238 libnuma \
239 libperl \
240 libpython \
241 libslang \
242 libunwind \
243 libdw-dwarf-unwind \
244 zlib
245
246# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
247# If in the future we need per-feature checks/flags for features not
248# mentioned in this list we need to refactor this ;-).
249set_test_all_flags = $(eval $(set_test_all_flags_code))
250define set_test_all_flags_code
251 FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
252 FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
253endef
254
255$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
256
257#
258# Special fast-path for the 'all features are available' case:
259#
260$(call feature_check,all,$(MSG))
261
262#
263# Just in case the build freshly failed, make sure we print the
264# feature matrix:
265#
266ifeq ($(feature-all), 1)
267 #
268 # test-all.c passed - just set all the core feature flags to 1:
269 #
270 $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
271else
272 $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
273 $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
274endif
275 180
276ifeq ($(feature-stackprotector-all), 1) 181ifeq ($(feature-stackprotector-all), 1)
277 CFLAGS += -fstack-protector-all 182 CFLAGS += -fstack-protector-all
@@ -636,6 +541,17 @@ ifndef NO_ZLIB
636 endif 541 endif
637endif 542endif
638 543
544ifndef NO_LZMA
545 ifeq ($(feature-lzma), 1)
546 CFLAGS += -DHAVE_LZMA_SUPPORT
547 EXTLIBS += -llzma
548 $(call detected,CONFIG_LZMA)
549 else
550 msg := $(warning No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev);
551 NO_LZMA := 1
552 endif
553endif
554
639ifndef NO_BACKTRACE 555ifndef NO_BACKTRACE
640 ifeq ($(feature-backtrace), 1) 556 ifeq ($(feature-backtrace), 1)
641 CFLAGS += -DHAVE_BACKTRACE_SUPPORT 557 CFLAGS += -DHAVE_BACKTRACE_SUPPORT
@@ -763,80 +679,12 @@ plugindir=$(libdir)/traceevent/plugins
763plugindir_SQ= $(subst ','\'',$(plugindir)) 679plugindir_SQ= $(subst ','\'',$(plugindir))
764endif 680endif
765 681
766#
767# Print the result of the feature test:
768#
769feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG))
770
771define feature_print_status_code
772 ifeq ($(feature-$(1)), 1)
773 MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1))
774 else
775 MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
776 endif
777endef
778
779print_var = $(eval $(print_var_code)) $(info $(MSG)) 682print_var = $(eval $(print_var_code)) $(info $(MSG))
780define print_var_code 683define print_var_code
781 MSG = $(shell printf '...%30s: %s' $(1) $($(1))) 684 MSG = $(shell printf '...%30s: %s' $(1) $($(1)))
782endef 685endef
783 686
784feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG))
785define feature_print_text_code
786 MSG = $(shell printf '...%30s: %s' $(1) $(2))
787endef
788
789FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
790FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
791
792ifeq ($(dwarf-post-unwind),1)
793 FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
794endif
795
796# The $(feature_display) controls the default detection message
797# output. It's set if:
798# - detected features differes from stored features from
799# last build (in FEATURE-DUMP file)
800# - one of the $(FEATURE_DISPLAY) is not detected
801# - VF is enabled
802
803ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
804 $(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
805 feature_display := 1
806endif
807
808feature_check = $(eval $(feature_check_code))
809define feature_check_code
810 ifneq ($(feature-$(1)), 1)
811 feature_display := 1
812 endif
813endef
814
815$(foreach feat,$(FEATURE_DISPLAY),$(call feature_check,$(feat)))
816
817ifeq ($(VF),1) 687ifeq ($(VF),1)
818 feature_display := 1
819 feature_verbose := 1
820endif
821
822ifeq ($(feature_display),1)
823 $(info )
824 $(info Auto-detecting system features:)
825 $(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
826
827 ifeq ($(dwarf-post-unwind),1)
828 $(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text))
829 endif
830
831 ifneq ($(feature_verbose),1)
832 $(info )
833 endif
834endif
835
836ifeq ($(feature_verbose),1)
837 TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
838 $(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
839 $(info )
840 $(call print_var,prefix) 688 $(call print_var,prefix)
841 $(call print_var,bindir) 689 $(call print_var,bindir)
842 $(call print_var,libdir) 690 $(call print_var,libdir)
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 2de01a4b4084..6a8801b32017 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -30,6 +30,7 @@ perf-y += keep-tracking.o
30perf-y += code-reading.o 30perf-y += code-reading.o
31perf-y += sample-parsing.o 31perf-y += sample-parsing.o
32perf-y += parse-no-sample-id-all.o 32perf-y += parse-no-sample-id-all.o
33perf-y += kmod-path.o
33 34
34perf-$(CONFIG_X86) += perf-time-to-tsc.o 35perf-$(CONFIG_X86) += perf-time-to-tsc.o
35 36
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index ed8e05c6839a..4f4098167112 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -167,6 +167,10 @@ static struct test {
167 .func = test__fdarray__add, 167 .func = test__fdarray__add,
168 }, 168 },
169 { 169 {
170 .desc = "Test kmod_path__parse function",
171 .func = test__kmod_path__parse,
172 },
173 {
170 .func = NULL, 174 .func = NULL,
171 }, 175 },
172}; 176};
diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c
new file mode 100644
index 000000000000..e8d7cbb9320c
--- /dev/null
+++ b/tools/perf/tests/kmod-path.c
@@ -0,0 +1,73 @@
1#include <stdbool.h>
2#include "tests.h"
3#include "dso.h"
4#include "debug.h"
5
6static int test(const char *path, bool alloc_name, bool alloc_ext,
7 bool kmod, bool comp, const char *name, const char *ext)
8{
9 struct kmod_path m;
10
11 memset(&m, 0x0, sizeof(m));
12
13 TEST_ASSERT_VAL("kmod_path__parse",
14 !__kmod_path__parse(&m, path, alloc_name, alloc_ext));
15
16 pr_debug("%s - alloc name %d, alloc ext %d, kmod %d, comp %d, name '%s', ext '%s'\n",
17 path, alloc_name, alloc_ext, m.kmod, m.comp, m.name, m.ext);
18
19 TEST_ASSERT_VAL("wrong kmod", m.kmod == kmod);
20 TEST_ASSERT_VAL("wrong comp", m.comp == comp);
21
22 if (ext)
23 TEST_ASSERT_VAL("wrong ext", m.ext && !strcmp(ext, m.ext));
24 else
25 TEST_ASSERT_VAL("wrong ext", !m.ext);
26
27 if (name)
28 TEST_ASSERT_VAL("wrong name", m.name && !strcmp(name, m.name));
29 else
30 TEST_ASSERT_VAL("wrong name", !m.name);
31
32 free(m.name);
33 free(m.ext);
34 return 0;
35}
36
37#define T(path, an, ae, k, c, n, e) \
38 TEST_ASSERT_VAL("failed", !test(path, an, ae, k, c, n, e))
39
40int test__kmod_path__parse(void)
41{
42 /* path alloc_name alloc_ext kmod comp name ext */
43 T("/xxxx/xxxx/x-x.ko", true , true , true, false, "[x_x]", NULL);
44 T("/xxxx/xxxx/x-x.ko", false , true , true, false, NULL , NULL);
45 T("/xxxx/xxxx/x-x.ko", true , false , true, false, "[x_x]", NULL);
46 T("/xxxx/xxxx/x-x.ko", false , false , true, false, NULL , NULL);
47
48 /* path alloc_name alloc_ext kmod comp name ext */
49 T("/xxxx/xxxx/x.ko.gz", true , true , true, true, "[x]", "gz");
50 T("/xxxx/xxxx/x.ko.gz", false , true , true, true, NULL , "gz");
51 T("/xxxx/xxxx/x.ko.gz", true , false , true, true, "[x]", NULL);
52 T("/xxxx/xxxx/x.ko.gz", false , false , true, true, NULL , NULL);
53
54 /* path alloc_name alloc_ext kmod comp name ext */
55 T("/xxxx/xxxx/x.gz", true , true , false, true, "x.gz" ,"gz");
56 T("/xxxx/xxxx/x.gz", false , true , false, true, NULL ,"gz");
57 T("/xxxx/xxxx/x.gz", true , false , false, true, "x.gz" , NULL);
58 T("/xxxx/xxxx/x.gz", false , false , false, true, NULL , NULL);
59
60 /* path alloc_name alloc_ext kmod comp name ext */
61 T("x.gz", true , true , false, true, "x.gz", "gz");
62 T("x.gz", false , true , false, true, NULL , "gz");
63 T("x.gz", true , false , false, true, "x.gz", NULL);
64 T("x.gz", false , false , false, true, NULL , NULL);
65
66 /* path alloc_name alloc_ext kmod comp name ext */
67 T("x.ko.gz", true , true , true, true, "[x]", "gz");
68 T("x.ko.gz", false , true , true, true, NULL , "gz");
69 T("x.ko.gz", true , false , true, true, "[x]", NULL);
70 T("x.ko.gz", false , false , true, true, NULL , NULL);
71
72 return 0;
73}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 00e776a87a9c..52758a33f64c 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -51,6 +51,7 @@ int test__hists_cumulate(void);
51int test__switch_tracking(void); 51int test__switch_tracking(void);
52int test__fdarray__filter(void); 52int test__fdarray__filter(void);
53int test__fdarray__add(void); 53int test__fdarray__add(void);
54int test__kmod_path__parse(void);
54 55
55#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) 56#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
56#ifdef HAVE_DWARF_UNWIND_SUPPORT 57#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index cd7350aeb8e7..995b7a8596b1 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -511,6 +511,7 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,
511{ 511{
512 int color, width; 512 int color, width;
513 char folded_sign = callchain_list__folded(chain); 513 char folded_sign = callchain_list__folded(chain);
514 bool show_annotated = browser->show_dso && chain->ms.sym && symbol__annotation(chain->ms.sym)->src;
514 515
515 color = HE_COLORSET_NORMAL; 516 color = HE_COLORSET_NORMAL;
516 width = browser->b.width - (offset + 2); 517 width = browser->b.width - (offset + 2);
@@ -523,7 +524,8 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,
523 ui_browser__set_color(&browser->b, color); 524 ui_browser__set_color(&browser->b, color);
524 hist_browser__gotorc(browser, row, 0); 525 hist_browser__gotorc(browser, row, 0);
525 slsmg_write_nstring(" ", offset); 526 slsmg_write_nstring(" ", offset);
526 slsmg_printf("%c ", folded_sign); 527 slsmg_printf("%c", folded_sign);
528 ui_browser__write_graph(&browser->b, show_annotated ? SLSMG_RARROW_CHAR : ' ');
527 slsmg_write_nstring(str, width); 529 slsmg_write_nstring(str, width);
528} 530}
529 531
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 972a6e0da7ad..797490a40075 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -94,6 +94,7 @@ libperf-y += scripting-engines/
94 94
95libperf-$(CONFIG_PERF_REGS) += perf_regs.o 95libperf-$(CONFIG_PERF_REGS) += perf_regs.o
96libperf-$(CONFIG_ZLIB) += zlib.o 96libperf-$(CONFIG_ZLIB) += zlib.o
97libperf-$(CONFIG_LZMA) += lzma.o
97 98
98CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" 99CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
99CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" 100CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))"
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index a19674666b4e..f7fb2587df69 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -374,7 +374,8 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
374 if (is_kallsyms) { 374 if (is_kallsyms) {
375 if (copyfile("/proc/kallsyms", filename)) 375 if (copyfile("/proc/kallsyms", filename))
376 goto out_free; 376 goto out_free;
377 } else if (link(realname, filename) && copyfile(name, filename)) 377 } else if (link(realname, filename) && errno != EEXIST &&
378 copyfile(name, filename))
378 goto out_free; 379 goto out_free;
379 } 380 }
380 381
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 814554d1b857..7a7c54b42b41 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -148,6 +148,9 @@ static const struct {
148#ifdef HAVE_ZLIB_SUPPORT 148#ifdef HAVE_ZLIB_SUPPORT
149 { "gz", gzip_decompress_to_file }, 149 { "gz", gzip_decompress_to_file },
150#endif 150#endif
151#ifdef HAVE_LZMA_SUPPORT
152 { "xz", lzma_decompress_to_file },
153#endif
151 { NULL, NULL }, 154 { NULL, NULL },
152}; 155};
153 156
@@ -209,6 +212,72 @@ bool dso__needs_decompress(struct dso *dso)
209} 212}
210 213
211/* 214/*
215 * Parses kernel module specified in @path and updates
216 * @m argument like:
217 *
218 * @comp - true if @path contains supported compression suffix,
219 * false otherwise
220 * @kmod - true if @path contains '.ko' suffix in right position,
221 * false otherwise
222 * @name - if (@alloc_name && @kmod) is true, it contains strdup-ed base name
223 * of the kernel module without suffixes, otherwise strudup-ed
224 * base name of @path
225 * @ext - if (@alloc_ext && @comp) is true, it contains strdup-ed string
226 * the compression suffix
227 *
228 * Returns 0 if there's no strdup error, -ENOMEM otherwise.
229 */
230int __kmod_path__parse(struct kmod_path *m, const char *path,
231 bool alloc_name, bool alloc_ext)
232{
233 const char *name = strrchr(path, '/');
234 const char *ext = strrchr(path, '.');
235
236 memset(m, 0x0, sizeof(*m));
237 name = name ? name + 1 : path;
238
239 /* No extension, just return name. */
240 if (ext == NULL) {
241 if (alloc_name) {
242 m->name = strdup(name);
243 return m->name ? 0 : -ENOMEM;
244 }
245 return 0;
246 }
247
248 if (is_supported_compression(ext + 1)) {
249 m->comp = true;
250 ext -= 3;
251 }
252
253 /* Check .ko extension only if there's enough name left. */
254 if (ext > name)
255 m->kmod = !strncmp(ext, ".ko", 3);
256
257 if (alloc_name) {
258 if (m->kmod) {
259 if (asprintf(&m->name, "[%.*s]", (int) (ext - name), name) == -1)
260 return -ENOMEM;
261 } else {
262 if (asprintf(&m->name, "%s", name) == -1)
263 return -ENOMEM;
264 }
265
266 strxfrchar(m->name, '-', '_');
267 }
268
269 if (alloc_ext && m->comp) {
270 m->ext = strdup(ext + 4);
271 if (!m->ext) {
272 free((void *) m->name);
273 return -ENOMEM;
274 }
275 }
276
277 return 0;
278}
279
280/*
212 * Global list of open DSOs and the counter. 281 * Global list of open DSOs and the counter.
213 */ 282 */
214static LIST_HEAD(dso__data_open); 283static LIST_HEAD(dso__data_open);
@@ -1002,21 +1071,24 @@ struct dso *dsos__find(const struct dsos *dsos, const char *name,
1002 return dso__find_by_longname(&dsos->root, name); 1071 return dso__find_by_longname(&dsos->root, name);
1003} 1072}
1004 1073
1005struct dso *__dsos__findnew(struct dsos *dsos, const char *name) 1074struct dso *dsos__addnew(struct dsos *dsos, const char *name)
1006{ 1075{
1007 struct dso *dso = dsos__find(dsos, name, false); 1076 struct dso *dso = dso__new(name);
1008 1077
1009 if (!dso) { 1078 if (dso != NULL) {
1010 dso = dso__new(name); 1079 dsos__add(dsos, dso);
1011 if (dso != NULL) { 1080 dso__set_basename(dso);
1012 dsos__add(dsos, dso);
1013 dso__set_basename(dso);
1014 }
1015 } 1081 }
1016
1017 return dso; 1082 return dso;
1018} 1083}
1019 1084
1085struct dso *__dsos__findnew(struct dsos *dsos, const char *name)
1086{
1087 struct dso *dso = dsos__find(dsos, name, false);
1088
1089 return dso ? dso : dsos__addnew(dsos, name);
1090}
1091
1020size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, 1092size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
1021 bool (skip)(struct dso *dso, int parm), int parm) 1093 bool (skip)(struct dso *dso, int parm), int parm)
1022{ 1094{
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 408c65f1a757..3c81d8378bc7 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -195,6 +195,20 @@ bool is_kernel_module(const char *pathname, bool *compressed);
195bool decompress_to_file(const char *ext, const char *filename, int output_fd); 195bool decompress_to_file(const char *ext, const char *filename, int output_fd);
196bool dso__needs_decompress(struct dso *dso); 196bool dso__needs_decompress(struct dso *dso);
197 197
198struct kmod_path {
199 char *name;
200 char *ext;
201 bool comp;
202 bool kmod;
203};
204
205int __kmod_path__parse(struct kmod_path *m, const char *path,
206 bool alloc_name, bool alloc_ext);
207
208#define kmod_path__parse(__m, __p) __kmod_path__parse(__m, __p, false, false)
209#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
210#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true)
211
198/* 212/*
199 * The dso__data_* external interface provides following functions: 213 * The dso__data_* external interface provides following functions:
200 * dso__data_fd 214 * dso__data_fd
@@ -250,6 +264,7 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
250 const char *short_name, int dso_type); 264 const char *short_name, int dso_type);
251 265
252void dsos__add(struct dsos *dsos, struct dso *dso); 266void dsos__add(struct dsos *dsos, struct dso *dso);
267struct dso *dsos__addnew(struct dsos *dsos, const char *name);
253struct dso *dsos__find(const struct dsos *dsos, const char *name, 268struct dso *dsos__find(const struct dsos *dsos, const char *name,
254 bool cmp_short); 269 bool cmp_short);
255struct dso *__dsos__findnew(struct dsos *dsos, const char *name); 270struct dso *__dsos__findnew(struct dsos *dsos, const char *name);
diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c
new file mode 100644
index 000000000000..95a1acb61245
--- /dev/null
+++ b/tools/perf/util/lzma.c
@@ -0,0 +1,95 @@
1#include <lzma.h>
2#include <stdio.h>
3#include <linux/compiler.h>
4#include "util.h"
5#include "debug.h"
6
7#define BUFSIZE 8192
8
9static const char *lzma_strerror(lzma_ret ret)
10{
11 switch ((int) ret) {
12 case LZMA_MEM_ERROR:
13 return "Memory allocation failed";
14 case LZMA_OPTIONS_ERROR:
15 return "Unsupported decompressor flags";
16 case LZMA_FORMAT_ERROR:
17 return "The input is not in the .xz format";
18 case LZMA_DATA_ERROR:
19 return "Compressed file is corrupt";
20 case LZMA_BUF_ERROR:
21 return "Compressed file is truncated or otherwise corrupt";
22 default:
23 return "Unknown error, possibly a bug";
24 }
25}
26
27int lzma_decompress_to_file(const char *input, int output_fd)
28{
29 lzma_action action = LZMA_RUN;
30 lzma_stream strm = LZMA_STREAM_INIT;
31 lzma_ret ret;
32
33 u8 buf_in[BUFSIZE];
34 u8 buf_out[BUFSIZE];
35 FILE *infile;
36
37 infile = fopen(input, "rb");
38 if (!infile) {
39 pr_err("lzma: fopen failed on %s: '%s'\n",
40 input, strerror(errno));
41 return -1;
42 }
43
44 ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
45 if (ret != LZMA_OK) {
46 pr_err("lzma: lzma_stream_decoder failed %s (%d)\n",
47 lzma_strerror(ret), ret);
48 return -1;
49 }
50
51 strm.next_in = NULL;
52 strm.avail_in = 0;
53 strm.next_out = buf_out;
54 strm.avail_out = sizeof(buf_out);
55
56 while (1) {
57 if (strm.avail_in == 0 && !feof(infile)) {
58 strm.next_in = buf_in;
59 strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile);
60
61 if (ferror(infile)) {
62 pr_err("lzma: read error: %s\n", strerror(errno));
63 return -1;
64 }
65
66 if (feof(infile))
67 action = LZMA_FINISH;
68 }
69
70 ret = lzma_code(&strm, action);
71
72 if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
73 ssize_t write_size = sizeof(buf_out) - strm.avail_out;
74
75 if (writen(output_fd, buf_out, write_size) != write_size) {
76 pr_err("lzma: write error: %s\n", strerror(errno));
77 return -1;
78 }
79
80 strm.next_out = buf_out;
81 strm.avail_out = sizeof(buf_out);
82 }
83
84 if (ret != LZMA_OK) {
85 if (ret == LZMA_STREAM_END)
86 return 0;
87
88 pr_err("lzma: failed %s\n", lzma_strerror(ret));
89 return -1;
90 }
91 }
92
93 fclose(infile);
94 return 0;
95}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 24f8c978cfd4..eb95b883fb44 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -460,30 +460,56 @@ int machine__process_lost_event(struct machine *machine __maybe_unused,
460 return 0; 460 return 0;
461} 461}
462 462
463static struct dso*
464machine__module_dso(struct machine *machine, struct kmod_path *m,
465 const char *filename)
466{
467 struct dso *dso;
468
469 dso = dsos__find(&machine->kernel_dsos, m->name, true);
470 if (!dso) {
471 dso = dsos__addnew(&machine->kernel_dsos, m->name);
472 if (dso == NULL)
473 return NULL;
474
475 if (machine__is_host(machine))
476 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
477 else
478 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
479
480 /* _KMODULE_COMP should be next to _KMODULE */
481 if (m->kmod && m->comp)
482 dso->symtab_type++;
483
484 dso__set_short_name(dso, strdup(m->name), true);
485 dso__set_long_name(dso, strdup(filename), true);
486 }
487
488 return dso;
489}
490
463struct map *machine__new_module(struct machine *machine, u64 start, 491struct map *machine__new_module(struct machine *machine, u64 start,
464 const char *filename) 492 const char *filename)
465{ 493{
466 struct map *map; 494 struct map *map = NULL;
467 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename); 495 struct dso *dso;
468 bool compressed; 496 struct kmod_path m;
469 497
470 if (dso == NULL) 498 if (kmod_path__parse_name(&m, filename))
471 return NULL; 499 return NULL;
472 500
501 dso = machine__module_dso(machine, &m, filename);
502 if (dso == NULL)
503 goto out;
504
473 map = map__new2(start, dso, MAP__FUNCTION); 505 map = map__new2(start, dso, MAP__FUNCTION);
474 if (map == NULL) 506 if (map == NULL)
475 return NULL; 507 goto out;
476
477 if (machine__is_host(machine))
478 dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
479 else
480 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
481
482 /* _KMODULE_COMP should be next to _KMODULE */
483 if (is_kernel_module(filename, &compressed) && compressed)
484 dso->symtab_type++;
485 508
486 map_groups__insert(&machine->kmaps, map); 509 map_groups__insert(&machine->kmaps, map);
510
511out:
512 free(m.name);
487 return map; 513 return map;
488} 514}
489 515
@@ -1044,40 +1070,11 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
1044 strlen(kmmap_prefix) - 1) == 0; 1070 strlen(kmmap_prefix) - 1) == 0;
1045 if (event->mmap.filename[0] == '/' || 1071 if (event->mmap.filename[0] == '/' ||
1046 (!is_kernel_mmap && event->mmap.filename[0] == '[')) { 1072 (!is_kernel_mmap && event->mmap.filename[0] == '[')) {
1047
1048 char short_module_name[1024];
1049 char *name, *dot;
1050
1051 if (event->mmap.filename[0] == '/') {
1052 name = strrchr(event->mmap.filename, '/');
1053 if (name == NULL)
1054 goto out_problem;
1055
1056 ++name; /* skip / */
1057 dot = strrchr(name, '.');
1058 if (dot == NULL)
1059 goto out_problem;
1060 /* On some system, modules are compressed like .ko.gz */
1061 if (is_supported_compression(dot + 1))
1062 dot -= 3;
1063 if (!is_kmodule_extension(dot + 1))
1064 goto out_problem;
1065 snprintf(short_module_name, sizeof(short_module_name),
1066 "[%.*s]", (int)(dot - name), name);
1067 strxfrchar(short_module_name, '-', '_');
1068 } else
1069 strcpy(short_module_name, event->mmap.filename);
1070
1071 map = machine__new_module(machine, event->mmap.start, 1073 map = machine__new_module(machine, event->mmap.start,
1072 event->mmap.filename); 1074 event->mmap.filename);
1073 if (map == NULL) 1075 if (map == NULL)
1074 goto out_problem; 1076 goto out_problem;
1075 1077
1076 name = strdup(short_module_name);
1077 if (name == NULL)
1078 goto out_problem;
1079
1080 dso__set_short_name(map->dso, name, true);
1081 map->end = map->start + event->mmap.len; 1078 map->end = map->start + event->mmap.len;
1082 } else if (is_kernel_mmap) { 1079 } else if (is_kernel_mmap) {
1083 const char *symbol_name = (event->mmap.filename + 1080 const char *symbol_name = (event->mmap.filename +
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f272a711ad15..6b95985db5b0 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2507,7 +2507,6 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2507 int max_tevs, const char *target) 2507 int max_tevs, const char *target)
2508{ 2508{
2509 struct map *map = NULL; 2509 struct map *map = NULL;
2510 struct kmap *kmap = NULL;
2511 struct ref_reloc_sym *reloc_sym = NULL; 2510 struct ref_reloc_sym *reloc_sym = NULL;
2512 struct symbol *sym; 2511 struct symbol *sym;
2513 struct probe_trace_event *tev; 2512 struct probe_trace_event *tev;
@@ -2540,8 +2539,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2540 } 2539 }
2541 2540
2542 if (!pev->uprobes && !pp->retprobe) { 2541 if (!pev->uprobes && !pp->retprobe) {
2543 kmap = map__kmap(map); 2542 reloc_sym = kernel_get_ref_reloc_sym();
2544 reloc_sym = kmap->ref_reloc_sym;
2545 if (!reloc_sym) { 2543 if (!reloc_sym) {
2546 pr_warning("Relocated base symbol is not found!\n"); 2544 pr_warning("Relocated base symbol is not found!\n");
2547 ret = -EINVAL; 2545 ret = -EINVAL;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index fbd598afc606..1ff23e04ad27 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -329,4 +329,8 @@ bool find_process(const char *name);
329int gzip_decompress_to_file(const char *input, int output_fd); 329int gzip_decompress_to_file(const char *input, int output_fd);
330#endif 330#endif
331 331
332#ifdef HAVE_LZMA_SUPPORT
333int lzma_decompress_to_file(const char *input, int output_fd);
334#endif
335
332#endif /* GIT_COMPAT_UTIL_H */ 336#endif /* GIT_COMPAT_UTIL_H */