aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-03-22 10:56:19 +0100
committerIngo Molnar <mingo@kernel.org>2015-03-22 10:56:19 +0100
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 @@
+feature_dir := $(srctree)/tools/build/feature
+
+ifneq ($(OUTPUT),)
+ OUTPUT_FEATURES = $(OUTPUT)feature/
+ $(shell mkdir -p $(OUTPUT_FEATURES))
+endif
+
+feature_check = $(eval $(feature_check_code))
+define feature_check_code
+ 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)
+endef
+
+feature_set = $(eval $(feature_set_code))
+define feature_set_code
+ feature-$(1) := 1
+endef
+
+#
+# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
+#
+
+#
+# Note that this is not a complete list of all feature tests, just
+# those that are typically built on a fully configured system.
+#
+# [ Feature tests not mentioned here have to be built explicitly in
+# the rule that uses them - an example for that is the 'bionic'
+# feature check. ]
+#
+FEATURE_TESTS = \
+ backtrace \
+ dwarf \
+ fortify-source \
+ sync-compare-and-swap \
+ glibc \
+ gtk2 \
+ gtk2-infobar \
+ libaudit \
+ libbfd \
+ libelf \
+ libelf-getphdrnum \
+ libelf-mmap \
+ libnuma \
+ libperl \
+ libpython \
+ libpython-version \
+ libslang \
+ libunwind \
+ pthread-attr-setaffinity-np \
+ stackprotector-all \
+ timerfd \
+ libdw-dwarf-unwind \
+ zlib \
+ lzma
+
+FEATURE_DISPLAY = \
+ dwarf \
+ glibc \
+ gtk2 \
+ libaudit \
+ libbfd \
+ libelf \
+ libnuma \
+ libperl \
+ libpython \
+ libslang \
+ libunwind \
+ libdw-dwarf-unwind \
+ zlib \
+ lzma
+
+# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
+# If in the future we need per-feature checks/flags for features not
+# mentioned in this list we need to refactor this ;-).
+set_test_all_flags = $(eval $(set_test_all_flags_code))
+define set_test_all_flags_code
+ FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
+ FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
+endef
+
+$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
+
+#
+# Special fast-path for the 'all features are available' case:
+#
+$(call feature_check,all,$(MSG))
+
+#
+# Just in case the build freshly failed, make sure we print the
+# feature matrix:
+#
+ifeq ($(feature-all), 1)
+ #
+ # test-all.c passed - just set all the core feature flags to 1:
+ #
+ $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
+else
+ $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C $(feature_dir) $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
+ $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
+endif
+
+#
+# Print the result of the feature test:
+#
+feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG))
+
+define feature_print_status_code
+ ifeq ($(feature-$(1)), 1)
+ MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1))
+ else
+ MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
+ endif
+endef
+
+feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG))
+define feature_print_text_code
+ MSG = $(shell printf '...%30s: %s' $(1) $(2))
+endef
+
+FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
+FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
+
+ifeq ($(dwarf-post-unwind),1)
+ FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
+endif
+
+# The $(feature_display) controls the default detection message
+# output. It's set if:
+# - detected features differes from stored features from
+# last build (in FEATURE-DUMP file)
+# - one of the $(FEATURE_DISPLAY) is not detected
+# - VF is enabled
+
+ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
+ $(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
+ feature_display := 1
+endif
+
+feature_display_check = $(eval $(feature_check_code))
+define feature_display_check_code
+ ifneq ($(feature-$(1)), 1)
+ feature_display := 1
+ endif
+endef
+
+$(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat)))
+
+ifeq ($(VF),1)
+ feature_display := 1
+ feature_verbose := 1
+endif
+
+ifeq ($(feature_display),1)
+ $(info )
+ $(info Auto-detecting system features:)
+ $(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
+
+ ifeq ($(dwarf-post-unwind),1)
+ $(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text))
+ endif
+
+ ifneq ($(feature_verbose),1)
+ $(info )
+ endif
+endif
+
+ifeq ($(feature_verbose),1)
+ TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
+ $(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
+ $(info )
+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 @@
*.d
*.bin
+*.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= \
test-libbabeltrace.bin \
test-compile-32.bin \
test-compile-x32.bin \
- test-zlib.bin
+ test-zlib.bin \
+ test-lzma.bin
CC := $(CROSS_COMPILE)gcc -MD
PKG_CONFIG := $(CROSS_COMPILE)pkg-config
@@ -45,7 +46,7 @@ __BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@)
###############################
test-all.bin:
- $(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
+ $(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
test-hello.bin:
$(BUILD)
@@ -152,6 +153,9 @@ test-compile-x32.bin:
test-zlib.bin:
$(BUILD) -lz
+test-lzma.bin:
+ $(BUILD) -llzma
+
-include *.d
###############################
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 @@
#undef main
#endif
+#define main main_test_lzma
+# include "test-lzma.c"
+#undef main
+
int main(int argc, char *argv[])
{
main_test_libpython();
@@ -138,6 +142,7 @@ int main(int argc, char *argv[])
main_test_sync_compare_and_swap(argc, argv);
main_test_zlib();
main_test_pthread_attr_setaffinity_np();
+ main_test_lzma();
return 0;
}
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 @@
+#include <lzma.h>
+
+int main(void)
+{
+ lzma_stream strm = LZMA_STREAM_INIT;
+ int ret;
+
+ ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
+ return ret ? -1 : 0;
+}
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)
pevent->ref_count++;
}
+void pevent_free_format_field(struct format_field *field)
+{
+ free(field->type);
+ free(field->name);
+ free(field);
+}
+
static void free_format_fields(struct format_field *field)
{
struct format_field *next;
while (field) {
next = field->next;
- free(field->type);
- free(field->name);
- free(field);
+ pevent_free_format_field(field);
field = next;
}
}
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,
const char *buf,
unsigned long size, const char *sys);
void pevent_free_format(struct event_format *event);
+void pevent_free_format_field(struct format_field *field);
void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
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 @@
PERF-CFLAGS
PERF-GUI-VARS
PERF-VERSION-FILE
-PERF-FEATURES
+FEATURE-DUMP
perf
perf-read-vdso32
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
#
# Define NO_LIBBABELTRACE if you do not want libbabeltrace support
# for CTF data format.
+#
+# Define NO_LZMA if you do not want to support compressed (xz) kernel modules
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
@@ -521,7 +523,7 @@ $(INSTALL_DOC_TARGETS):
#
config-clean:
$(call QUIET_CLEAN, config)
- $(Q)$(MAKE) -C config/feature-checks clean >/dev/null
+ $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null
clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean
$(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[] = {
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
" Please refer the man page for the complete list."),
- OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
+ OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
"separator for columns, no spaces will be added between "
"columns '.' is reserved."),
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)
"input file name"),
OPT_STRING('C', "cpu", &mem.cpu_list, "cpu",
"list of cpus to profile"),
- OPT_STRING('x', "field-separator", &symbol_conf.field_sep,
+ OPT_STRING_NOEMPTY('x', "field-separator", &symbol_conf.field_sep,
"separator",
"separator for columns, no spaces will be added"
" 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)
struct syscall {
struct event_format *tp_format;
+ int nr_args;
+ struct format_field *args;
const char *name;
bool filtered;
bool is_exit;
@@ -1442,14 +1444,14 @@ static int syscall__set_arg_fmts(struct syscall *sc)
struct format_field *field;
int idx = 0;
- sc->arg_scnprintf = calloc(sc->tp_format->format.nr_fields - 1, sizeof(void *));
+ sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *));
if (sc->arg_scnprintf == NULL)
return -1;
if (sc->fmt)
sc->arg_parm = sc->fmt->arg_parm;
- for (field = sc->tp_format->format.fields->next; field; field = field->next) {
+ for (field = sc->args; field; field = field->next) {
if (sc->fmt && sc->fmt->arg_scnprintf[idx])
sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
else if (field->flags & FIELD_IS_POINTER)
@@ -1515,6 +1517,14 @@ static int trace__read_syscall_info(struct trace *trace, int id)
if (sc->tp_format == NULL)
return -1;
+ sc->args = sc->tp_format->format.fields;
+ sc->nr_args = sc->tp_format->format.nr_fields;
+ /* drop nr field - not relevant here; does not exist on older kernels */
+ if (sc->args && strcmp(sc->args->name, "nr") == 0) {
+ sc->args = sc->args->next;
+ --sc->nr_args;
+ }
+
sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit");
return syscall__set_arg_fmts(sc);
@@ -1537,7 +1547,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
unsigned char *p;
unsigned long val;
- if (sc->tp_format != NULL) {
+ if (sc->args != NULL) {
struct format_field *field;
u8 bit = 1;
struct syscall_arg arg = {
@@ -1547,7 +1557,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
.thread = thread,
};
- for (field = sc->tp_format->format.fields->next; field;
+ for (field = sc->args; field;
field = field->next, ++arg.idx, bit <<= 1) {
if (arg.mask & bit)
continue;
@@ -1724,7 +1734,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
return -1;
}
- printed += trace__printf_interrupted_entry(trace, sample);
+ if (!trace->summary_only)
+ printed += trace__printf_interrupted_entry(trace, sample);
ttrace->entry_time = sample->time;
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
EXTLIBS = -lpthread -lrt -lm -ldl
-ifneq ($(OUTPUT),)
- OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
- $(shell mkdir -p $(OUTPUT_FEATURES))
-endif
-
-feature_check = $(eval $(feature_check_code))
-define feature_check_code
- 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)
-endef
-
-feature_set = $(eval $(feature_set_code))
-define feature_set_code
- feature-$(1) := 1
-endef
-
-#
-# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
-#
-
-#
-# Note that this is not a complete list of all feature tests, just
-# those that are typically built on a fully configured system.
-#
-# [ Feature tests not mentioned here have to be built explicitly in
-# the rule that uses them - an example for that is the 'bionic'
-# feature check. ]
-#
-FEATURE_TESTS = \
- backtrace \
- dwarf \
- fortify-source \
- sync-compare-and-swap \
- glibc \
- gtk2 \
- gtk2-infobar \
- libaudit \
- libbfd \
- libelf \
- libelf-getphdrnum \
- libelf-mmap \
- libnuma \
- libperl \
- libpython \
- libpython-version \
- libslang \
- libunwind \
- pthread-attr-setaffinity-np \
- stackprotector-all \
- timerfd \
- libdw-dwarf-unwind \
- zlib
-
-FEATURE_DISPLAY = \
- dwarf \
- glibc \
- gtk2 \
- libaudit \
- libbfd \
- libelf \
- libnuma \
- libperl \
- libpython \
- libslang \
- libunwind \
- libdw-dwarf-unwind \
- zlib
-
-# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
-# If in the future we need per-feature checks/flags for features not
-# mentioned in this list we need to refactor this ;-).
-set_test_all_flags = $(eval $(set_test_all_flags_code))
-define set_test_all_flags_code
- FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
- FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
-endef
-
-$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
-
-#
-# Special fast-path for the 'all features are available' case:
-#
-$(call feature_check,all,$(MSG))
-
-#
-# Just in case the build freshly failed, make sure we print the
-# feature matrix:
-#
-ifeq ($(feature-all), 1)
- #
- # test-all.c passed - just set all the core feature flags to 1:
- #
- $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
-else
- $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
- $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
-endif
+include $(srctree)/tools/build/Makefile.feature
ifeq ($(feature-stackprotector-all), 1)
CFLAGS += -fstack-protector-all
@@ -636,6 +541,17 @@ ifndef NO_ZLIB
endif
endif
+ifndef NO_LZMA
+ ifeq ($(feature-lzma), 1)
+ CFLAGS += -DHAVE_LZMA_SUPPORT
+ EXTLIBS += -llzma
+ $(call detected,CONFIG_LZMA)
+ else
+ msg := $(warning No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev);
+ NO_LZMA := 1
+ endif
+endif
+
ifndef NO_BACKTRACE
ifeq ($(feature-backtrace), 1)
CFLAGS += -DHAVE_BACKTRACE_SUPPORT
@@ -763,80 +679,12 @@ plugindir=$(libdir)/traceevent/plugins
plugindir_SQ= $(subst ','\'',$(plugindir))
endif
-#
-# Print the result of the feature test:
-#
-feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG))
-
-define feature_print_status_code
- ifeq ($(feature-$(1)), 1)
- MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1))
- else
- MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
- endif
-endef
-
print_var = $(eval $(print_var_code)) $(info $(MSG))
define print_var_code
MSG = $(shell printf '...%30s: %s' $(1) $($(1)))
endef
-feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG))
-define feature_print_text_code
- MSG = $(shell printf '...%30s: %s' $(1) $(2))
-endef
-
-FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
-FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
-
-ifeq ($(dwarf-post-unwind),1)
- FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
-endif
-
-# The $(feature_display) controls the default detection message
-# output. It's set if:
-# - detected features differes from stored features from
-# last build (in FEATURE-DUMP file)
-# - one of the $(FEATURE_DISPLAY) is not detected
-# - VF is enabled
-
-ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
- $(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
- feature_display := 1
-endif
-
-feature_check = $(eval $(feature_check_code))
-define feature_check_code
- ifneq ($(feature-$(1)), 1)
- feature_display := 1
- endif
-endef
-
-$(foreach feat,$(FEATURE_DISPLAY),$(call feature_check,$(feat)))
-
ifeq ($(VF),1)
- feature_display := 1
- feature_verbose := 1
-endif
-
-ifeq ($(feature_display),1)
- $(info )
- $(info Auto-detecting system features:)
- $(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
-
- ifeq ($(dwarf-post-unwind),1)
- $(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text))
- endif
-
- ifneq ($(feature_verbose),1)
- $(info )
- endif
-endif
-
-ifeq ($(feature_verbose),1)
- TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
- $(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
- $(info )
$(call print_var,prefix)
$(call print_var,bindir)
$(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
perf-y += code-reading.o
perf-y += sample-parsing.o
perf-y += parse-no-sample-id-all.o
+perf-y += kmod-path.o
perf-$(CONFIG_X86) += perf-time-to-tsc.o
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 {
.func = test__fdarray__add,
},
{
+ .desc = "Test kmod_path__parse function",
+ .func = test__kmod_path__parse,
+ },
+ {
.func = NULL,
},
};
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 @@
+#include <stdbool.h>
+#include "tests.h"
+#include "dso.h"
+#include "debug.h"
+
+static int test(const char *path, bool alloc_name, bool alloc_ext,
+ bool kmod, bool comp, const char *name, const char *ext)
+{
+ struct kmod_path m;
+
+ memset(&m, 0x0, sizeof(m));
+
+ TEST_ASSERT_VAL("kmod_path__parse",
+ !__kmod_path__parse(&m, path, alloc_name, alloc_ext));
+
+ pr_debug("%s - alloc name %d, alloc ext %d, kmod %d, comp %d, name '%s', ext '%s'\n",
+ path, alloc_name, alloc_ext, m.kmod, m.comp, m.name, m.ext);
+
+ TEST_ASSERT_VAL("wrong kmod", m.kmod == kmod);
+ TEST_ASSERT_VAL("wrong comp", m.comp == comp);
+
+ if (ext)
+ TEST_ASSERT_VAL("wrong ext", m.ext && !strcmp(ext, m.ext));
+ else
+ TEST_ASSERT_VAL("wrong ext", !m.ext);
+
+ if (name)
+ TEST_ASSERT_VAL("wrong name", m.name && !strcmp(name, m.name));
+ else
+ TEST_ASSERT_VAL("wrong name", !m.name);
+
+ free(m.name);
+ free(m.ext);
+ return 0;
+}
+
+#define T(path, an, ae, k, c, n, e) \
+ TEST_ASSERT_VAL("failed", !test(path, an, ae, k, c, n, e))
+
+int test__kmod_path__parse(void)
+{
+ /* path alloc_name alloc_ext kmod comp name ext */
+ T("/xxxx/xxxx/x-x.ko", true , true , true, false, "[x_x]", NULL);
+ T("/xxxx/xxxx/x-x.ko", false , true , true, false, NULL , NULL);
+ T("/xxxx/xxxx/x-x.ko", true , false , true, false, "[x_x]", NULL);
+ T("/xxxx/xxxx/x-x.ko", false , false , true, false, NULL , NULL);
+
+ /* path alloc_name alloc_ext kmod comp name ext */
+ T("/xxxx/xxxx/x.ko.gz", true , true , true, true, "[x]", "gz");
+ T("/xxxx/xxxx/x.ko.gz", false , true , true, true, NULL , "gz");
+ T("/xxxx/xxxx/x.ko.gz", true , false , true, true, "[x]", NULL);
+ T("/xxxx/xxxx/x.ko.gz", false , false , true, true, NULL , NULL);
+
+ /* path alloc_name alloc_ext kmod comp name ext */
+ T("/xxxx/xxxx/x.gz", true , true , false, true, "x.gz" ,"gz");
+ T("/xxxx/xxxx/x.gz", false , true , false, true, NULL ,"gz");
+ T("/xxxx/xxxx/x.gz", true , false , false, true, "x.gz" , NULL);
+ T("/xxxx/xxxx/x.gz", false , false , false, true, NULL , NULL);
+
+ /* path alloc_name alloc_ext kmod comp name ext */
+ T("x.gz", true , true , false, true, "x.gz", "gz");
+ T("x.gz", false , true , false, true, NULL , "gz");
+ T("x.gz", true , false , false, true, "x.gz", NULL);
+ T("x.gz", false , false , false, true, NULL , NULL);
+
+ /* path alloc_name alloc_ext kmod comp name ext */
+ T("x.ko.gz", true , true , true, true, "[x]", "gz");
+ T("x.ko.gz", false , true , true, true, NULL , "gz");
+ T("x.ko.gz", true , false , true, true, "[x]", NULL);
+ T("x.ko.gz", false , false , true, true, NULL , NULL);
+
+ return 0;
+}
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);
int test__switch_tracking(void);
int test__fdarray__filter(void);
int test__fdarray__add(void);
+int test__kmod_path__parse(void);
#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
#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,
{
int color, width;
char folded_sign = callchain_list__folded(chain);
+ bool show_annotated = browser->show_dso && chain->ms.sym && symbol__annotation(chain->ms.sym)->src;
color = HE_COLORSET_NORMAL;
width = browser->b.width - (offset + 2);
@@ -523,7 +524,8 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,
ui_browser__set_color(&browser->b, color);
hist_browser__gotorc(browser, row, 0);
slsmg_write_nstring(" ", offset);
- slsmg_printf("%c ", folded_sign);
+ slsmg_printf("%c", folded_sign);
+ ui_browser__write_graph(&browser->b, show_annotated ? SLSMG_RARROW_CHAR : ' ');
slsmg_write_nstring(str, width);
}
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/
libperf-$(CONFIG_PERF_REGS) += perf_regs.o
libperf-$(CONFIG_ZLIB) += zlib.o
+libperf-$(CONFIG_LZMA) += lzma.o
CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
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,
if (is_kallsyms) {
if (copyfile("/proc/kallsyms", filename))
goto out_free;
- } else if (link(realname, filename) && copyfile(name, filename))
+ } else if (link(realname, filename) && errno != EEXIST &&
+ copyfile(name, filename))
goto out_free;
}
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 {
#ifdef HAVE_ZLIB_SUPPORT
{ "gz", gzip_decompress_to_file },
#endif
+#ifdef HAVE_LZMA_SUPPORT
+ { "xz", lzma_decompress_to_file },
+#endif
{ NULL, NULL },
};
@@ -209,6 +212,72 @@ bool dso__needs_decompress(struct dso *dso)
}
/*
+ * Parses kernel module specified in @path and updates
+ * @m argument like:
+ *
+ * @comp - true if @path contains supported compression suffix,
+ * false otherwise
+ * @kmod - true if @path contains '.ko' suffix in right position,
+ * false otherwise
+ * @name - if (@alloc_name && @kmod) is true, it contains strdup-ed base name
+ * of the kernel module without suffixes, otherwise strudup-ed
+ * base name of @path
+ * @ext - if (@alloc_ext && @comp) is true, it contains strdup-ed string
+ * the compression suffix
+ *
+ * Returns 0 if there's no strdup error, -ENOMEM otherwise.
+ */
+int __kmod_path__parse(struct kmod_path *m, const char *path,
+ bool alloc_name, bool alloc_ext)
+{
+ const char *name = strrchr(path, '/');
+ const char *ext = strrchr(path, '.');
+
+ memset(m, 0x0, sizeof(*m));
+ name = name ? name + 1 : path;
+
+ /* No extension, just return name. */
+ if (ext == NULL) {
+ if (alloc_name) {
+ m->name = strdup(name);
+ return m->name ? 0 : -ENOMEM;
+ }
+ return 0;
+ }
+
+ if (is_supported_compression(ext + 1)) {
+ m->comp = true;
+ ext -= 3;
+ }
+
+ /* Check .ko extension only if there's enough name left. */
+ if (ext > name)
+ m->kmod = !strncmp(ext, ".ko", 3);
+
+ if (alloc_name) {
+ if (m->kmod) {
+ if (asprintf(&m->name, "[%.*s]", (int) (ext - name), name) == -1)
+ return -ENOMEM;
+ } else {
+ if (asprintf(&m->name, "%s", name) == -1)
+ return -ENOMEM;
+ }
+
+ strxfrchar(m->name, '-', '_');
+ }
+
+ if (alloc_ext && m->comp) {
+ m->ext = strdup(ext + 4);
+ if (!m->ext) {
+ free((void *) m->name);
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+/*
* Global list of open DSOs and the counter.
*/
static LIST_HEAD(dso__data_open);
@@ -1002,21 +1071,24 @@ struct dso *dsos__find(const struct dsos *dsos, const char *name,
return dso__find_by_longname(&dsos->root, name);
}
-struct dso *__dsos__findnew(struct dsos *dsos, const char *name)
+struct dso *dsos__addnew(struct dsos *dsos, const char *name)
{
- struct dso *dso = dsos__find(dsos, name, false);
+ struct dso *dso = dso__new(name);
- if (!dso) {
- dso = dso__new(name);
- if (dso != NULL) {
- dsos__add(dsos, dso);
- dso__set_basename(dso);
- }
+ if (dso != NULL) {
+ dsos__add(dsos, dso);
+ dso__set_basename(dso);
}
-
return dso;
}
+struct dso *__dsos__findnew(struct dsos *dsos, const char *name)
+{
+ struct dso *dso = dsos__find(dsos, name, false);
+
+ return dso ? dso : dsos__addnew(dsos, name);
+}
+
size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
bool (skip)(struct dso *dso, int parm), int parm)
{
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);
bool decompress_to_file(const char *ext, const char *filename, int output_fd);
bool dso__needs_decompress(struct dso *dso);
+struct kmod_path {
+ char *name;
+ char *ext;
+ bool comp;
+ bool kmod;
+};
+
+int __kmod_path__parse(struct kmod_path *m, const char *path,
+ bool alloc_name, bool alloc_ext);
+
+#define kmod_path__parse(__m, __p) __kmod_path__parse(__m, __p, false, false)
+#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
+#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true)
+
/*
* The dso__data_* external interface provides following functions:
* dso__data_fd
@@ -250,6 +264,7 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
const char *short_name, int dso_type);
void dsos__add(struct dsos *dsos, struct dso *dso);
+struct dso *dsos__addnew(struct dsos *dsos, const char *name);
struct dso *dsos__find(const struct dsos *dsos, const char *name,
bool cmp_short);
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 @@
+#include <lzma.h>
+#include <stdio.h>
+#include <linux/compiler.h>
+#include "util.h"
+#include "debug.h"
+
+#define BUFSIZE 8192
+
+static const char *lzma_strerror(lzma_ret ret)
+{
+ switch ((int) ret) {
+ case LZMA_MEM_ERROR:
+ return "Memory allocation failed";
+ case LZMA_OPTIONS_ERROR:
+ return "Unsupported decompressor flags";
+ case LZMA_FORMAT_ERROR:
+ return "The input is not in the .xz format";
+ case LZMA_DATA_ERROR:
+ return "Compressed file is corrupt";
+ case LZMA_BUF_ERROR:
+ return "Compressed file is truncated or otherwise corrupt";
+ default:
+ return "Unknown error, possibly a bug";
+ }
+}
+
+int lzma_decompress_to_file(const char *input, int output_fd)
+{
+ lzma_action action = LZMA_RUN;
+ lzma_stream strm = LZMA_STREAM_INIT;
+ lzma_ret ret;
+
+ u8 buf_in[BUFSIZE];
+ u8 buf_out[BUFSIZE];
+ FILE *infile;
+
+ infile = fopen(input, "rb");
+ if (!infile) {
+ pr_err("lzma: fopen failed on %s: '%s'\n",
+ input, strerror(errno));
+ return -1;
+ }
+
+ ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
+ if (ret != LZMA_OK) {
+ pr_err("lzma: lzma_stream_decoder failed %s (%d)\n",
+ lzma_strerror(ret), ret);
+ return -1;
+ }
+
+ strm.next_in = NULL;
+ strm.avail_in = 0;
+ strm.next_out = buf_out;
+ strm.avail_out = sizeof(buf_out);
+
+ while (1) {
+ if (strm.avail_in == 0 && !feof(infile)) {
+ strm.next_in = buf_in;
+ strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile);
+
+ if (ferror(infile)) {
+ pr_err("lzma: read error: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (feof(infile))
+ action = LZMA_FINISH;
+ }
+
+ ret = lzma_code(&strm, action);
+
+ if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
+ ssize_t write_size = sizeof(buf_out) - strm.avail_out;
+
+ if (writen(output_fd, buf_out, write_size) != write_size) {
+ pr_err("lzma: write error: %s\n", strerror(errno));
+ return -1;
+ }
+
+ strm.next_out = buf_out;
+ strm.avail_out = sizeof(buf_out);
+ }
+
+ if (ret != LZMA_OK) {
+ if (ret == LZMA_STREAM_END)
+ return 0;
+
+ pr_err("lzma: failed %s\n", lzma_strerror(ret));
+ return -1;
+ }
+ }
+
+ fclose(infile);
+ return 0;
+}
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,
return 0;
}
+static struct dso*
+machine__module_dso(struct machine *machine, struct kmod_path *m,
+ const char *filename)
+{
+ struct dso *dso;
+
+ dso = dsos__find(&machine->kernel_dsos, m->name, true);
+ if (!dso) {
+ dso = dsos__addnew(&machine->kernel_dsos, m->name);
+ if (dso == NULL)
+ return NULL;
+
+ if (machine__is_host(machine))
+ dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
+ else
+ dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
+
+ /* _KMODULE_COMP should be next to _KMODULE */
+ if (m->kmod && m->comp)
+ dso->symtab_type++;
+
+ dso__set_short_name(dso, strdup(m->name), true);
+ dso__set_long_name(dso, strdup(filename), true);
+ }
+
+ return dso;
+}
+
struct map *machine__new_module(struct machine *machine, u64 start,
const char *filename)
{
- struct map *map;
- struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
- bool compressed;
+ struct map *map = NULL;
+ struct dso *dso;
+ struct kmod_path m;
- if (dso == NULL)
+ if (kmod_path__parse_name(&m, filename))
return NULL;
+ dso = machine__module_dso(machine, &m, filename);
+ if (dso == NULL)
+ goto out;
+
map = map__new2(start, dso, MAP__FUNCTION);
if (map == NULL)
- return NULL;
-
- if (machine__is_host(machine))
- dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
- else
- dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
-
- /* _KMODULE_COMP should be next to _KMODULE */
- if (is_kernel_module(filename, &compressed) && compressed)
- dso->symtab_type++;
+ goto out;
map_groups__insert(&machine->kmaps, map);
+
+out:
+ free(m.name);
return map;
}
@@ -1044,40 +1070,11 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
strlen(kmmap_prefix) - 1) == 0;
if (event->mmap.filename[0] == '/' ||
(!is_kernel_mmap && event->mmap.filename[0] == '[')) {
-
- char short_module_name[1024];
- char *name, *dot;
-
- if (event->mmap.filename[0] == '/') {
- name = strrchr(event->mmap.filename, '/');
- if (name == NULL)
- goto out_problem;
-
- ++name; /* skip / */
- dot = strrchr(name, '.');
- if (dot == NULL)
- goto out_problem;
- /* On some system, modules are compressed like .ko.gz */
- if (is_supported_compression(dot + 1))
- dot -= 3;
- if (!is_kmodule_extension(dot + 1))
- goto out_problem;
- snprintf(short_module_name, sizeof(short_module_name),
- "[%.*s]", (int)(dot - name), name);
- strxfrchar(short_module_name, '-', '_');
- } else
- strcpy(short_module_name, event->mmap.filename);
-
map = machine__new_module(machine, event->mmap.start,
event->mmap.filename);
if (map == NULL)
goto out_problem;
- name = strdup(short_module_name);
- if (name == NULL)
- goto out_problem;
-
- dso__set_short_name(map->dso, name, true);
map->end = map->start + event->mmap.len;
} else if (is_kernel_mmap) {
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,
int max_tevs, const char *target)
{
struct map *map = NULL;
- struct kmap *kmap = NULL;
struct ref_reloc_sym *reloc_sym = NULL;
struct symbol *sym;
struct probe_trace_event *tev;
@@ -2540,8 +2539,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
}
if (!pev->uprobes && !pp->retprobe) {
- kmap = map__kmap(map);
- reloc_sym = kmap->ref_reloc_sym;
+ reloc_sym = kernel_get_ref_reloc_sym();
if (!reloc_sym) {
pr_warning("Relocated base symbol is not found!\n");
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);
int gzip_decompress_to_file(const char *input, int output_fd);
#endif
+#ifdef HAVE_LZMA_SUPPORT
+int lzma_decompress_to_file(const char *input, int output_fd);
+#endif
+
#endif /* GIT_COMPAT_UTIL_H */