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 /tools | |
| 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>
Diffstat (limited to 'tools')
| -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 */ |
