diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-03-22 05:56:19 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-03-22 05:56:19 -0400 |
commit | 963a70b8a2d65538f7d58b2b84a2ae10a3ecb6ea (patch) | |
tree | 3c104859a1a4c5de6a30aee4e483ee2d0dfaf8c3 | |
parent | 08b3f913900075a19564ab68967028ab99c95820 (diff) | |
parent | ca33380adf74afb985bf7aab09ec46707a5d2d57 (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.feature | 171 | ||||
-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.c | 10 | ||||
-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.c | 11 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.h | 1 | ||||
-rw-r--r-- | tools/perf/.gitignore | 2 | ||||
-rw-r--r-- | tools/perf/Makefile.perf | 4 | ||||
-rw-r--r-- | tools/perf/builtin-diff.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-mem.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-trace.c | 21 | ||||
-rw-r--r-- | tools/perf/config/Makefile | 176 | ||||
-rw-r--r-- | tools/perf/tests/Build | 1 | ||||
-rw-r--r-- | tools/perf/tests/builtin-test.c | 4 | ||||
-rw-r--r-- | tools/perf/tests/kmod-path.c | 73 | ||||
-rw-r--r-- | tools/perf/tests/tests.h | 1 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 4 | ||||
-rw-r--r-- | tools/perf/util/Build | 1 | ||||
-rw-r--r-- | tools/perf/util/build-id.c | 3 | ||||
-rw-r--r-- | tools/perf/util/dso.c | 90 | ||||
-rw-r--r-- | tools/perf/util/dso.h | 15 | ||||
-rw-r--r-- | tools/perf/util/lzma.c | 95 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 83 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 4 | ||||
-rw-r--r-- | tools/perf/util/util.h | 4 |
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 @@ | |||
1 | feature_dir := $(srctree)/tools/build/feature | ||
2 | |||
3 | ifneq ($(OUTPUT),) | ||
4 | OUTPUT_FEATURES = $(OUTPUT)feature/ | ||
5 | $(shell mkdir -p $(OUTPUT_FEATURES)) | ||
6 | endif | ||
7 | |||
8 | feature_check = $(eval $(feature_check_code)) | ||
9 | define 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) | ||
11 | endef | ||
12 | |||
13 | feature_set = $(eval $(feature_set_code)) | ||
14 | define feature_set_code | ||
15 | feature-$(1) := 1 | ||
16 | endef | ||
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 | # | ||
30 | FEATURE_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 | |||
56 | FEATURE_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 ;-). | ||
75 | set_test_all_flags = $(eval $(set_test_all_flags_code)) | ||
76 | define set_test_all_flags_code | ||
77 | FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1)) | ||
78 | FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1)) | ||
79 | endef | ||
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 | # | ||
92 | ifeq ($(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))) | ||
97 | else | ||
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))) | ||
100 | endif | ||
101 | |||
102 | # | ||
103 | # Print the result of the feature test: | ||
104 | # | ||
105 | feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG)) | ||
106 | |||
107 | define 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 | ||
113 | endef | ||
114 | |||
115 | feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG)) | ||
116 | define feature_print_text_code | ||
117 | MSG = $(shell printf '...%30s: %s' $(1) $(2)) | ||
118 | endef | ||
119 | |||
120 | FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat)))) | ||
121 | FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP) | ||
122 | |||
123 | ifeq ($(dwarf-post-unwind),1) | ||
124 | FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text)) | ||
125 | endif | ||
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 | |||
134 | ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)") | ||
135 | $(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP) | ||
136 | feature_display := 1 | ||
137 | endif | ||
138 | |||
139 | feature_display_check = $(eval $(feature_check_code)) | ||
140 | define feature_display_check_code | ||
141 | ifneq ($(feature-$(1)), 1) | ||
142 | feature_display := 1 | ||
143 | endif | ||
144 | endef | ||
145 | |||
146 | $(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat))) | ||
147 | |||
148 | ifeq ($(VF),1) | ||
149 | feature_display := 1 | ||
150 | feature_verbose := 1 | ||
151 | endif | ||
152 | |||
153 | ifeq ($(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 | ||
165 | endif | ||
166 | |||
167 | ifeq ($(feature_verbose),1) | ||
168 | TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS)) | ||
169 | $(foreach feat,$(TMP),$(call feature_print_status,$(feat),)) | ||
170 | $(info ) | ||
171 | endif | ||
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 | ||
37 | CC := $(CROSS_COMPILE)gcc -MD | 38 | CC := $(CROSS_COMPILE)gcc -MD |
38 | PKG_CONFIG := $(CROSS_COMPILE)pkg-config | 39 | PKG_CONFIG := $(CROSS_COMPILE)pkg-config |
@@ -45,7 +46,7 @@ __BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) | |||
45 | ############################### | 46 | ############################### |
46 | 47 | ||
47 | test-all.bin: | 48 | test-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 | ||
50 | test-hello.bin: | 51 | test-hello.bin: |
51 | $(BUILD) | 52 | $(BUILD) |
@@ -152,6 +153,9 @@ test-compile-x32.bin: | |||
152 | test-zlib.bin: | 153 | test-zlib.bin: |
153 | $(BUILD) -lz | 154 | $(BUILD) -lz |
154 | 155 | ||
156 | test-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 | |||
116 | int main(int argc, char *argv[]) | 120 | int 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 | |||
3 | int 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 | ||
6231 | void pevent_free_format_field(struct format_field *field) | ||
6232 | { | ||
6233 | free(field->type); | ||
6234 | free(field->name); | ||
6235 | free(field); | ||
6236 | } | ||
6237 | |||
6231 | static void free_format_fields(struct format_field *field) | 6238 | static 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); |
621 | void pevent_free_format(struct event_format *event); | 621 | void pevent_free_format(struct event_format *event); |
622 | void pevent_free_format_field(struct format_field *field); | ||
622 | 623 | ||
623 | void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, | 624 | void *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 @@ | |||
1 | PERF-CFLAGS | 1 | PERF-CFLAGS |
2 | PERF-GUI-VARS | 2 | PERF-GUI-VARS |
3 | PERF-VERSION-FILE | 3 | PERF-VERSION-FILE |
4 | PERF-FEATURES | 4 | FEATURE-DUMP |
5 | perf | 5 | perf |
6 | perf-read-vdso32 | 6 | perf-read-vdso32 |
7 | perf-read-vdsox32 | 7 | perf-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 | ||
75 | ifeq ($(srctree),) | 77 | ifeq ($(srctree),) |
76 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) | 78 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) |
@@ -521,7 +523,7 @@ $(INSTALL_DOC_TARGETS): | |||
521 | # | 523 | # |
522 | config-clean: | 524 | config-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 | ||
526 | clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean | 528 | clean: $(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 | ||
1136 | struct syscall { | 1136 | struct 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 | ||
177 | EXTLIBS = -lpthread -lrt -lm -ldl | 177 | EXTLIBS = -lpthread -lrt -lm -ldl |
178 | 178 | ||
179 | ifneq ($(OUTPUT),) | 179 | include $(srctree)/tools/build/Makefile.feature |
180 | OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/ | ||
181 | $(shell mkdir -p $(OUTPUT_FEATURES)) | ||
182 | endif | ||
183 | |||
184 | feature_check = $(eval $(feature_check_code)) | ||
185 | define 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) | ||
187 | endef | ||
188 | |||
189 | feature_set = $(eval $(feature_set_code)) | ||
190 | define feature_set_code | ||
191 | feature-$(1) := 1 | ||
192 | endef | ||
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 | # | ||
206 | FEATURE_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 | |||
231 | FEATURE_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 ;-). | ||
249 | set_test_all_flags = $(eval $(set_test_all_flags_code)) | ||
250 | define set_test_all_flags_code | ||
251 | FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1)) | ||
252 | FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1)) | ||
253 | endef | ||
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 | # | ||
266 | ifeq ($(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))) | ||
271 | else | ||
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))) | ||
274 | endif | ||
275 | 180 | ||
276 | ifeq ($(feature-stackprotector-all), 1) | 181 | ifeq ($(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 |
637 | endif | 542 | endif |
638 | 543 | ||
544 | ifndef 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 | ||
553 | endif | ||
554 | |||
639 | ifndef NO_BACKTRACE | 555 | ifndef 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 | |||
763 | plugindir_SQ= $(subst ','\'',$(plugindir)) | 679 | plugindir_SQ= $(subst ','\'',$(plugindir)) |
764 | endif | 680 | endif |
765 | 681 | ||
766 | # | ||
767 | # Print the result of the feature test: | ||
768 | # | ||
769 | feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG)) | ||
770 | |||
771 | define 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 | ||
777 | endef | ||
778 | |||
779 | print_var = $(eval $(print_var_code)) $(info $(MSG)) | 682 | print_var = $(eval $(print_var_code)) $(info $(MSG)) |
780 | define print_var_code | 683 | define print_var_code |
781 | MSG = $(shell printf '...%30s: %s' $(1) $($(1))) | 684 | MSG = $(shell printf '...%30s: %s' $(1) $($(1))) |
782 | endef | 685 | endef |
783 | 686 | ||
784 | feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG)) | ||
785 | define feature_print_text_code | ||
786 | MSG = $(shell printf '...%30s: %s' $(1) $(2)) | ||
787 | endef | ||
788 | |||
789 | FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat)))) | ||
790 | FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP) | ||
791 | |||
792 | ifeq ($(dwarf-post-unwind),1) | ||
793 | FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text)) | ||
794 | endif | ||
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 | |||
803 | ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)") | ||
804 | $(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP) | ||
805 | feature_display := 1 | ||
806 | endif | ||
807 | |||
808 | feature_check = $(eval $(feature_check_code)) | ||
809 | define feature_check_code | ||
810 | ifneq ($(feature-$(1)), 1) | ||
811 | feature_display := 1 | ||
812 | endif | ||
813 | endef | ||
814 | |||
815 | $(foreach feat,$(FEATURE_DISPLAY),$(call feature_check,$(feat))) | ||
816 | |||
817 | ifeq ($(VF),1) | 687 | ifeq ($(VF),1) |
818 | feature_display := 1 | ||
819 | feature_verbose := 1 | ||
820 | endif | ||
821 | |||
822 | ifeq ($(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 | ||
834 | endif | ||
835 | |||
836 | ifeq ($(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 | |||
30 | perf-y += code-reading.o | 30 | perf-y += code-reading.o |
31 | perf-y += sample-parsing.o | 31 | perf-y += sample-parsing.o |
32 | perf-y += parse-no-sample-id-all.o | 32 | perf-y += parse-no-sample-id-all.o |
33 | perf-y += kmod-path.o | ||
33 | 34 | ||
34 | perf-$(CONFIG_X86) += perf-time-to-tsc.o | 35 | perf-$(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 | |||
6 | static 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 | |||
40 | int 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); | |||
51 | int test__switch_tracking(void); | 51 | int test__switch_tracking(void); |
52 | int test__fdarray__filter(void); | 52 | int test__fdarray__filter(void); |
53 | int test__fdarray__add(void); | 53 | int test__fdarray__add(void); |
54 | int 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 | ||
95 | libperf-$(CONFIG_PERF_REGS) += perf_regs.o | 95 | libperf-$(CONFIG_PERF_REGS) += perf_regs.o |
96 | libperf-$(CONFIG_ZLIB) += zlib.o | 96 | libperf-$(CONFIG_ZLIB) += zlib.o |
97 | libperf-$(CONFIG_LZMA) += lzma.o | ||
97 | 98 | ||
98 | CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" | 99 | CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" |
99 | CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" | 100 | CFLAGS_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 | */ | ||
230 | int __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 | */ |
214 | static LIST_HEAD(dso__data_open); | 283 | static 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 | ||
1005 | struct dso *__dsos__findnew(struct dsos *dsos, const char *name) | 1074 | struct 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 | ||
1085 | struct 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 | |||
1020 | size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, | 1092 | size_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); | |||
195 | bool decompress_to_file(const char *ext, const char *filename, int output_fd); | 195 | bool decompress_to_file(const char *ext, const char *filename, int output_fd); |
196 | bool dso__needs_decompress(struct dso *dso); | 196 | bool dso__needs_decompress(struct dso *dso); |
197 | 197 | ||
198 | struct kmod_path { | ||
199 | char *name; | ||
200 | char *ext; | ||
201 | bool comp; | ||
202 | bool kmod; | ||
203 | }; | ||
204 | |||
205 | int __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 | ||
252 | void dsos__add(struct dsos *dsos, struct dso *dso); | 266 | void dsos__add(struct dsos *dsos, struct dso *dso); |
267 | struct dso *dsos__addnew(struct dsos *dsos, const char *name); | ||
253 | struct dso *dsos__find(const struct dsos *dsos, const char *name, | 268 | struct dso *dsos__find(const struct dsos *dsos, const char *name, |
254 | bool cmp_short); | 269 | bool cmp_short); |
255 | struct dso *__dsos__findnew(struct dsos *dsos, const char *name); | 270 | struct 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 | |||
9 | static 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 | |||
27 | int 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 | ||
463 | static struct dso* | ||
464 | machine__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 | |||
463 | struct map *machine__new_module(struct machine *machine, u64 start, | 491 | struct 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 | |||
511 | out: | ||
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); | |||
329 | int gzip_decompress_to_file(const char *input, int output_fd); | 329 | int gzip_decompress_to_file(const char *input, int output_fd); |
330 | #endif | 330 | #endif |
331 | 331 | ||
332 | #ifdef HAVE_LZMA_SUPPORT | ||
333 | int 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 */ |