Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'perf-core-for-mingo-20161205' 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:

Fixes:

- Do not show a bogus target address in 'perf annotate' for targetless powerpc
jump instructions such as 'bctr' (Ravi Bangoria)

- Fix tools/build race conditions with the fixdep utility (Jiri Olsa)

- Fix building objtool with clang (Peter Foley)

Infrastructure changes:

- Support linking perf with clang and LLVM libraries, initially statically, but
this limitation will be lifted and shared libraries, when available, will
be preferred to the static build, that should, as with other features, be
enabled explicitly (Wang Nan)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

+795 -195
+10 -10
tools/build/Build.include
··· 65 65 printf '\# cannot find fixdep (%s)\n' $(fixdep) > $(dot-target).cmd; \ 66 66 printf '\# using basic dep data\n\n' >> $(dot-target).cmd; \ 67 67 cat $(depfile) >> $(dot-target).cmd; \ 68 - printf '%s\n' 'cmd_$@ := $(make-cmd)' >> $(dot-target).cmd) 68 + printf '\n%s\n' 'cmd_$@ := $(make-cmd)' >> $(dot-target).cmd) 69 69 70 70 ### 71 71 # if_changed_dep - execute command if any prerequisite is newer than 72 72 # target, or command line has changed and update 73 73 # dependencies in the cmd file 74 74 if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)), \ 75 - @set -e; \ 76 - $(echo-cmd) $(cmd_$(1)) && $(dep-cmd)) 75 + @set -e; \ 76 + $(echo-cmd) $(cmd_$(1)) && $(dep-cmd)) 77 77 78 78 # if_changed - execute command if any prerequisite is newer than 79 79 # target, or command line has changed 80 - if_changed = $(if $(strip $(any-prereq) $(arg-check)), \ 81 - @set -e; \ 82 - $(echo-cmd) $(cmd_$(1)); \ 83 - printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd) 80 + if_changed = $(if $(strip $(any-prereq) $(arg-check)), \ 81 + @set -e; \ 82 + $(echo-cmd) $(cmd_$(1)); \ 83 + printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd) 84 84 85 85 ### 86 86 # C flags to be used in rule definitions, includes: ··· 89 89 # - per target C flags 90 90 # - per object C flags 91 91 # - BUILD_STR macro to allow '-D"$(variable)"' constructs 92 - c_flags_1 = -Wp,-MD,$(depfile),-MT,$@ $(CFLAGS) -D"BUILD_STR(s)=\#s" $(CFLAGS_$(basetarget).o) $(CFLAGS_$(obj)) 92 + c_flags_1 = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CFLAGS) -D"BUILD_STR(s)=\#s" $(CFLAGS_$(basetarget).o) $(CFLAGS_$(obj)) 93 93 c_flags_2 = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(c_flags_1)) 94 94 c_flags = $(filter-out $(CFLAGS_REMOVE_$(obj)), $(c_flags_2)) 95 - cxx_flags = -Wp,-MD,$(depfile),-MT,$@ $(CXXFLAGS) -D"BUILD_STR(s)=\#s" $(CXXFLAGS_$(basetarget).o) $(CXXFLAGS_$(obj)) 95 + cxx_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CXXFLAGS) -D"BUILD_STR(s)=\#s" $(CXXFLAGS_$(basetarget).o) $(CXXFLAGS_$(obj)) 96 96 97 97 ### 98 98 ## HOSTCC C flags 99 99 100 - host_c_flags = -Wp,-MD,$(depfile),-MT,$@ $(CHOSTFLAGS) -D"BUILD_STR(s)=\#s" $(CHOSTFLAGS_$(basetarget).o) $(CHOSTFLAGS_$(obj)) 100 + host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CHOSTFLAGS) -D"BUILD_STR(s)=\#s" $(CHOSTFLAGS_$(basetarget).o) $(CHOSTFLAGS_$(obj))
+69 -69
tools/build/Makefile.feature
··· 27 27 # the rule that uses them - an example for that is the 'bionic' 28 28 # feature check. ] 29 29 # 30 - FEATURE_TESTS_BASIC := \ 31 - backtrace \ 32 - dwarf \ 33 - dwarf_getlocations \ 34 - fortify-source \ 35 - sync-compare-and-swap \ 36 - glibc \ 37 - gtk2 \ 38 - gtk2-infobar \ 39 - libaudit \ 40 - libbfd \ 41 - libelf \ 42 - libelf-getphdrnum \ 43 - libelf-gelf_getnote \ 44 - libelf-getshdrstrndx \ 45 - libelf-mmap \ 46 - libnuma \ 47 - numa_num_possible_cpus \ 48 - libperl \ 49 - libpython \ 50 - libpython-version \ 51 - libslang \ 52 - libcrypto \ 53 - libunwind \ 54 - libunwind-x86 \ 55 - libunwind-x86_64 \ 56 - libunwind-arm \ 57 - libunwind-aarch64 \ 58 - pthread-attr-setaffinity-np \ 59 - stackprotector-all \ 60 - timerfd \ 61 - libdw-dwarf-unwind \ 62 - zlib \ 63 - lzma \ 64 - get_cpuid \ 65 - bpf \ 66 - sdt 30 + FEATURE_TESTS_BASIC := \ 31 + backtrace \ 32 + dwarf \ 33 + dwarf_getlocations \ 34 + fortify-source \ 35 + sync-compare-and-swap \ 36 + glibc \ 37 + gtk2 \ 38 + gtk2-infobar \ 39 + libaudit \ 40 + libbfd \ 41 + libelf \ 42 + libelf-getphdrnum \ 43 + libelf-gelf_getnote \ 44 + libelf-getshdrstrndx \ 45 + libelf-mmap \ 46 + libnuma \ 47 + numa_num_possible_cpus \ 48 + libperl \ 49 + libpython \ 50 + libpython-version \ 51 + libslang \ 52 + libcrypto \ 53 + libunwind \ 54 + libunwind-x86 \ 55 + libunwind-x86_64 \ 56 + libunwind-arm \ 57 + libunwind-aarch64 \ 58 + pthread-attr-setaffinity-np \ 59 + stackprotector-all \ 60 + timerfd \ 61 + libdw-dwarf-unwind \ 62 + zlib \ 63 + lzma \ 64 + get_cpuid \ 65 + bpf \ 66 + sdt 67 67 68 68 # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list 69 69 # of all feature tests 70 - FEATURE_TESTS_EXTRA := \ 71 - bionic \ 72 - compile-32 \ 73 - compile-x32 \ 74 - cplus-demangle \ 75 - hello \ 76 - libbabeltrace \ 77 - liberty \ 78 - liberty-z \ 79 - libunwind-debug-frame \ 80 - libunwind-debug-frame-arm \ 81 - libunwind-debug-frame-aarch64 70 + FEATURE_TESTS_EXTRA := \ 71 + bionic \ 72 + compile-32 \ 73 + compile-x32 \ 74 + cplus-demangle \ 75 + hello \ 76 + libbabeltrace \ 77 + liberty \ 78 + liberty-z \ 79 + libunwind-debug-frame \ 80 + libunwind-debug-frame-arm \ 81 + libunwind-debug-frame-aarch64 82 82 83 83 FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC) 84 84 ··· 86 86 FEATURE_TESTS := $(FEATURE_TESTS_BASIC) $(FEATURE_TESTS_EXTRA) 87 87 endif 88 88 89 - FEATURE_DISPLAY ?= \ 90 - dwarf \ 91 - dwarf_getlocations \ 92 - glibc \ 93 - gtk2 \ 94 - libaudit \ 95 - libbfd \ 96 - libelf \ 97 - libnuma \ 98 - numa_num_possible_cpus \ 99 - libperl \ 100 - libpython \ 101 - libslang \ 102 - libcrypto \ 103 - libunwind \ 104 - libdw-dwarf-unwind \ 105 - zlib \ 106 - lzma \ 107 - get_cpuid \ 108 - bpf 89 + FEATURE_DISPLAY ?= \ 90 + dwarf \ 91 + dwarf_getlocations \ 92 + glibc \ 93 + gtk2 \ 94 + libaudit \ 95 + libbfd \ 96 + libelf \ 97 + libnuma \ 98 + numa_num_possible_cpus \ 99 + libperl \ 100 + libpython \ 101 + libslang \ 102 + libcrypto \ 103 + libunwind \ 104 + libdw-dwarf-unwind \ 105 + zlib \ 106 + lzma \ 107 + get_cpuid \ 108 + bpf 109 109 110 110 # Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features. 111 111 # If in the future we need per-feature checks/flags for features not
+69 -51
tools/build/feature/Makefile
··· 1 - FILES= \ 2 - test-all.bin \ 3 - test-backtrace.bin \ 4 - test-bionic.bin \ 5 - test-dwarf.bin \ 6 - test-dwarf_getlocations.bin \ 7 - test-fortify-source.bin \ 8 - test-sync-compare-and-swap.bin \ 9 - test-glibc.bin \ 10 - test-gtk2.bin \ 11 - test-gtk2-infobar.bin \ 12 - test-hello.bin \ 13 - test-libaudit.bin \ 14 - test-libbfd.bin \ 15 - test-liberty.bin \ 16 - test-liberty-z.bin \ 17 - test-cplus-demangle.bin \ 18 - test-libelf.bin \ 19 - test-libelf-getphdrnum.bin \ 20 - test-libelf-gelf_getnote.bin \ 21 - test-libelf-getshdrstrndx.bin \ 22 - test-libelf-mmap.bin \ 23 - test-libnuma.bin \ 24 - test-numa_num_possible_cpus.bin \ 25 - test-libperl.bin \ 26 - test-libpython.bin \ 27 - test-libpython-version.bin \ 28 - test-libslang.bin \ 29 - test-libcrypto.bin \ 30 - test-libunwind.bin \ 31 - test-libunwind-debug-frame.bin \ 32 - test-libunwind-x86.bin \ 33 - test-libunwind-x86_64.bin \ 34 - test-libunwind-arm.bin \ 35 - test-libunwind-aarch64.bin \ 36 - test-libunwind-debug-frame-arm.bin \ 37 - test-libunwind-debug-frame-aarch64.bin \ 38 - test-pthread-attr-setaffinity-np.bin \ 39 - test-stackprotector-all.bin \ 40 - test-timerfd.bin \ 41 - test-libdw-dwarf-unwind.bin \ 42 - test-libbabeltrace.bin \ 43 - test-compile-32.bin \ 44 - test-compile-x32.bin \ 45 - test-zlib.bin \ 46 - test-lzma.bin \ 47 - test-bpf.bin \ 48 - test-get_cpuid.bin \ 49 - test-sdt.bin \ 50 - test-cxx.bin \ 51 - test-jvmti.bin 1 + FILES= \ 2 + test-all.bin \ 3 + test-backtrace.bin \ 4 + test-bionic.bin \ 5 + test-dwarf.bin \ 6 + test-dwarf_getlocations.bin \ 7 + test-fortify-source.bin \ 8 + test-sync-compare-and-swap.bin \ 9 + test-glibc.bin \ 10 + test-gtk2.bin \ 11 + test-gtk2-infobar.bin \ 12 + test-hello.bin \ 13 + test-libaudit.bin \ 14 + test-libbfd.bin \ 15 + test-liberty.bin \ 16 + test-liberty-z.bin \ 17 + test-cplus-demangle.bin \ 18 + test-libelf.bin \ 19 + test-libelf-getphdrnum.bin \ 20 + test-libelf-gelf_getnote.bin \ 21 + test-libelf-getshdrstrndx.bin \ 22 + test-libelf-mmap.bin \ 23 + test-libnuma.bin \ 24 + test-numa_num_possible_cpus.bin \ 25 + test-libperl.bin \ 26 + test-libpython.bin \ 27 + test-libpython-version.bin \ 28 + test-libslang.bin \ 29 + test-libcrypto.bin \ 30 + test-libunwind.bin \ 31 + test-libunwind-debug-frame.bin \ 32 + test-libunwind-x86.bin \ 33 + test-libunwind-x86_64.bin \ 34 + test-libunwind-arm.bin \ 35 + test-libunwind-aarch64.bin \ 36 + test-libunwind-debug-frame-arm.bin \ 37 + test-libunwind-debug-frame-aarch64.bin \ 38 + test-pthread-attr-setaffinity-np.bin \ 39 + test-stackprotector-all.bin \ 40 + test-timerfd.bin \ 41 + test-libdw-dwarf-unwind.bin \ 42 + test-libbabeltrace.bin \ 43 + test-compile-32.bin \ 44 + test-compile-x32.bin \ 45 + test-zlib.bin \ 46 + test-lzma.bin \ 47 + test-bpf.bin \ 48 + test-get_cpuid.bin \ 49 + test-sdt.bin \ 50 + test-cxx.bin \ 51 + test-jvmti.bin 52 52 53 53 FILES := $(addprefix $(OUTPUT),$(FILES)) 54 54 55 55 CC := $(CROSS_COMPILE)gcc -MD 56 56 CXX := $(CROSS_COMPILE)g++ -MD 57 57 PKG_CONFIG := $(CROSS_COMPILE)pkg-config 58 + LLVM_CONFIG ?= llvm-config 58 59 59 60 all: $(FILES) 60 61 ··· 229 228 230 229 $(OUTPUT)test-jvmti.bin: 231 230 $(BUILD) 231 + 232 + $(OUTPUT)test-llvm.bin: 233 + $(BUILDXX) -std=gnu++11 \ 234 + -I$(shell $(LLVM_CONFIG) --includedir) \ 235 + -L$(shell $(LLVM_CONFIG) --libdir) \ 236 + $(shell $(LLVM_CONFIG) --libs Core BPF) \ 237 + $(shell $(LLVM_CONFIG) --system-libs) 238 + 239 + $(OUTPUT)test-clang.bin: 240 + $(BUILDXX) -std=gnu++11 \ 241 + -I$(shell $(LLVM_CONFIG) --includedir) \ 242 + -L$(shell $(LLVM_CONFIG) --libdir) \ 243 + -Wl,--start-group -lclangBasic -lclangDriver \ 244 + -lclangFrontend -lclangEdit -lclangLex \ 245 + -lclangAST -Wl,--end-group \ 246 + $(shell $(LLVM_CONFIG) --libs Core option) \ 247 + $(shell $(LLVM_CONFIG) --system-libs) 232 248 233 249 -include $(OUTPUT)*.d 234 250
+21
tools/build/feature/test-clang.cpp
··· 1 + #include "clang/Basic/VirtualFileSystem.h" 2 + #include "clang/Driver/Driver.h" 3 + #include "clang/Frontend/TextDiagnosticPrinter.h" 4 + #include "llvm/ADT/IntrusiveRefCntPtr.h" 5 + #include "llvm/Support/ManagedStatic.h" 6 + #include "llvm/Support/raw_ostream.h" 7 + 8 + using namespace clang; 9 + using namespace clang::driver; 10 + 11 + int main() 12 + { 13 + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 14 + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 15 + 16 + DiagnosticsEngine Diags(DiagID, &*DiagOpts); 17 + Driver TheDriver("test", "bpf-pc-linux", Diags); 18 + 19 + llvm::llvm_shutdown(); 20 + return 0; 21 + }
+8
tools/build/feature/test-llvm.cpp
··· 1 + #include "llvm/Support/ManagedStatic.h" 2 + #include "llvm/Support/raw_ostream.h" 3 + int main() 4 + { 5 + llvm::errs() << "Hello World!\n"; 6 + llvm::llvm_shutdown(); 7 + return 0; 8 + }
+3 -2
tools/build/fixdep.c
··· 49 49 char *end = m + len; 50 50 char *p; 51 51 char s[PATH_MAX]; 52 - int is_target; 52 + int is_target, has_target = 0; 53 53 int saw_any_target = 0; 54 54 int is_first_dep = 0; 55 55 ··· 67 67 if (is_target) { 68 68 /* The /next/ file is the first dependency */ 69 69 is_first_dep = 1; 70 - } else { 70 + has_target = 1; 71 + } else if (has_target) { 71 72 /* Save this token/filename */ 72 73 memcpy(s, m, p-m); 73 74 s[p - m] = 0;
+50 -12
tools/perf/Makefile.config
··· 136 136 # Treat warnings as errors unless directed not to 137 137 ifneq ($(WERROR),0) 138 138 CFLAGS += -Werror 139 + CXXFLAGS += -Werror 139 140 endif 140 141 141 142 ifndef DEBUG ··· 183 182 CFLAGS += -Wextra 184 183 CFLAGS += -std=gnu99 185 184 185 + CXXFLAGS += -std=gnu++11 -fno-exceptions -fno-rtti 186 + CXXFLAGS += -Wall 187 + CXXFLAGS += -fno-omit-frame-pointer 188 + CXXFLAGS += -ggdb3 189 + CXXFLAGS += -funwind-tables 190 + CXXFLAGS += -Wno-strict-aliasing 191 + 186 192 # Enforce a non-executable stack, as we may regress (again) in the future by 187 193 # adding assembler files missing the .GNU-stack linker note. 188 194 LDFLAGS += -Wl,-z,noexecstack ··· 212 204 endif 213 205 endif 214 206 215 - CFLAGS += -I$(src-perf)/util/include 216 - CFLAGS += -I$(src-perf)/arch/$(ARCH)/include 217 - CFLAGS += -I$(srctree)/tools/include/uapi 218 - CFLAGS += -I$(srctree)/tools/include/ 219 - CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi 220 - CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/ 221 - CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/ 207 + INC_FLAGS += -I$(src-perf)/util/include 208 + INC_FLAGS += -I$(src-perf)/arch/$(ARCH)/include 209 + INC_FLAGS += -I$(srctree)/tools/include/uapi 210 + INC_FLAGS += -I$(srctree)/tools/include/ 211 + INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/uapi 212 + INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/include/ 213 + INC_FLAGS += -I$(srctree)/tools/arch/$(ARCH)/ 222 214 223 215 # $(obj-perf) for generated common-cmds.h 224 216 # $(obj-perf)/util for generated bison/flex headers 225 217 ifneq ($(OUTPUT),) 226 - CFLAGS += -I$(obj-perf)/util 227 - CFLAGS += -I$(obj-perf) 218 + INC_FLAGS += -I$(obj-perf)/util 219 + INC_FLAGS += -I$(obj-perf) 228 220 endif 229 221 230 - CFLAGS += -I$(src-perf)/util 231 - CFLAGS += -I$(src-perf) 232 - CFLAGS += -I$(srctree)/tools/lib/ 222 + INC_FLAGS += -I$(src-perf)/util 223 + INC_FLAGS += -I$(src-perf) 224 + INC_FLAGS += -I$(srctree)/tools/lib/ 225 + 226 + CFLAGS += $(INC_FLAGS) 227 + CXXFLAGS += $(INC_FLAGS) 233 228 234 229 CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE 235 230 ··· 791 780 else 792 781 $(warning No openjdk development package found, please install JDK package) 793 782 NO_JVMTI := 1 783 + endif 784 + endif 785 + 786 + USE_CXX = 0 787 + USE_CLANGLLVM = 0 788 + ifdef LIBCLANGLLVM 789 + $(call feature_check,cxx) 790 + ifneq ($(feature-cxx), 1) 791 + msg := $(warning No g++ found, disable clang and llvm support. Please install g++) 792 + else 793 + $(call feature_check,llvm) 794 + ifneq ($(feature-llvm), 1) 795 + msg := $(warning No libLLVM found, disable clang and llvm support. Please install llvm-dev) 796 + else 797 + $(call feature_check,clang) 798 + ifneq ($(feature-clang), 1) 799 + msg := $(warning No libclang found, disable clang and llvm support. Please install libclang-dev) 800 + else 801 + CFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT 802 + CXXFLAGS += -DHAVE_LIBCLANGLLVM_SUPPORT -I$(shell $(LLVM_CONFIG) --includedir) 803 + $(call detected,CONFIG_CXX) 804 + $(call detected,CONFIG_CLANGLLVM) 805 + USE_CXX = 1 806 + USE_LLVM = 1 807 + USE_CLANG = 1 808 + endif 809 + endif 794 810 endif 795 811 endif 796 812
+38 -18
tools/perf/Makefile.perf
··· 88 88 # and bypass the feature detection 89 89 # 90 90 # Define NO_JVMTI if you do not want jvmti agent built 91 + # 92 + # Define LIBCLANGLLVM if you DO want builtin clang and llvm support. 93 + # When selected, pass LLVM_CONFIG=/path/to/llvm-config to `make' if 94 + # llvm-config is not in $PATH. 91 95 92 96 # As per kernel Makefile, avoid funny character set dependencies 93 97 unexport LC_ALL ··· 147 143 $(call allow-override,CC,$(CROSS_COMPILE)gcc) 148 144 $(call allow-override,AR,$(CROSS_COMPILE)ar) 149 145 $(call allow-override,LD,$(CROSS_COMPILE)ld) 146 + $(call allow-override,CXX,$(CROSS_COMPILE)g++) 150 147 151 148 LD += $(EXTRA_LDFLAGS) 152 149 ··· 156 151 HOSTAR ?= ar 157 152 158 153 PKG_CONFIG = $(CROSS_COMPILE)pkg-config 154 + LLVM_CONFIG ?= llvm-config 159 155 160 156 RM = rm -f 161 157 LN = ln -f ··· 177 171 # non-config cases 178 172 config := 1 179 173 180 - NON_CONFIG_TARGETS := clean TAGS tags cscope help install-doc 174 + NON_CONFIG_TARGETS := clean TAGS tags cscope help install-doc install-man install-html install-info install-pdf doc man html info pdf 181 175 182 176 ifdef MAKECMDGOALS 183 177 ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),) ··· 268 262 PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) 269 263 PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI) 270 264 271 - $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) 272 - $(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \ 273 - CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \ 274 - $(PYTHON_WORD) util/setup.py \ 275 - --quiet build_ext; \ 276 - mkdir -p $(OUTPUT)python && \ 277 - cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/ 278 - # 279 - # No Perl scripts right now: 280 - # 281 - 282 265 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) 283 266 284 267 PROGRAMS += $(OUTPUT)perf ··· 320 325 ifndef NO_GTK2 321 326 ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so 322 327 GTK_IN := $(OUTPUT)gtk-in.o 323 - 324 - install-gtk: $(OUTPUT)libperf-gtk.so 325 - $(call QUIET_INSTALL, 'GTK UI') \ 326 - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \ 327 - $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)' 328 328 endif 329 329 330 330 ifdef ASCIIDOC8 ··· 328 338 329 339 LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group 330 340 341 + ifeq ($(USE_CLANG), 1) 342 + CLANGLIBS_LIST = AST Basic CodeGen Driver Frontend Lex Tooling Edit Sema Analysis Parse Serialization 343 + LIBCLANG = $(foreach l,$(CLANGLIBS_LIST),$(wildcard $(shell $(LLVM_CONFIG) --libdir)/libclang$(l).a)) 344 + LIBS += -Wl,--start-group $(LIBCLANG) -Wl,--end-group 345 + endif 346 + 347 + ifeq ($(USE_LLVM), 1) 348 + LIBLLVM = $(shell $(LLVM_CONFIG) --libs all) $(shell $(LLVM_CONFIG) --system-libs) 349 + LIBS += -L$(shell $(LLVM_CONFIG) --libdir) $(LIBLLVM) 350 + endif 351 + 352 + ifeq ($(USE_CXX), 1) 353 + LIBS += -lstdc++ 354 + endif 355 + 331 356 export INSTALL SHELL_PATH 332 357 333 358 ### Build rules ··· 350 345 SHELL = $(SHELL_PATH) 351 346 352 347 all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) 348 + 349 + $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) 350 + $(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \ 351 + CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \ 352 + $(PYTHON_WORD) util/setup.py \ 353 + --quiet build_ext; \ 354 + mkdir -p $(OUTPUT)python && \ 355 + cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/ 353 356 354 357 please_set_SHELL_PATH_to_a_more_modern_shell: 355 358 $(Q)$$(:) ··· 369 356 370 357 PERF_IN := $(OUTPUT)perf-in.o 371 358 372 - export srctree OUTPUT RM CC LD AR CFLAGS V BISON FLEX AWK 359 + export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK 373 360 export HOSTCC HOSTLD HOSTAR 374 361 include $(srctree)/tools/build/Makefile.include 375 362 ··· 704 691 705 692 ### Installation rules 706 693 694 + ifndef NO_GTK2 695 + install-gtk: $(OUTPUT)libperf-gtk.so 696 + $(call QUIET_INSTALL, 'GTK UI') \ 697 + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \ 698 + $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)' 699 + else 707 700 install-gtk: 701 + endif 708 702 709 703 install-tools: all install-gtk 710 704 $(call QUIET_INSTALL, binaries) \
+1
tools/perf/tests/Build
··· 43 43 perf-y += is_printable_array.o 44 44 perf-y += bitmap.o 45 45 perf-y += perf-hooks.o 46 + perf-y += clang.o 46 47 47 48 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build 48 49 $(call rule_mkdir)
+9
tools/perf/tests/builtin-test.c
··· 234 234 .func = test__perf_hooks, 235 235 }, 236 236 { 237 + .desc = "builtin clang support", 238 + .func = test__clang, 239 + .subtest = { 240 + .skip_if_fail = true, 241 + .get_nr = test__clang_subtest_get_nr, 242 + .get_desc = test__clang_subtest_get_desc, 243 + } 244 + }, 245 + { 237 246 .func = NULL, 238 247 }, 239 248 };
+46
tools/perf/tests/clang.c
··· 1 + #include "tests.h" 2 + #include "debug.h" 3 + #include "util.h" 4 + #include "c++/clang-c.h" 5 + 6 + static struct { 7 + int (*func)(void); 8 + const char *desc; 9 + } clang_testcase_table[] = { 10 + #ifdef HAVE_LIBCLANGLLVM_SUPPORT 11 + { 12 + .func = test__clang_to_IR, 13 + .desc = "builtin clang compile C source to IR", 14 + }, 15 + { 16 + .func = test__clang_to_obj, 17 + .desc = "builtin clang compile C source to ELF object", 18 + }, 19 + #endif 20 + }; 21 + 22 + int test__clang_subtest_get_nr(void) 23 + { 24 + return (int)ARRAY_SIZE(clang_testcase_table); 25 + } 26 + 27 + const char *test__clang_subtest_get_desc(int i) 28 + { 29 + if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) 30 + return NULL; 31 + return clang_testcase_table[i].desc; 32 + } 33 + 34 + #ifndef HAVE_LIBCLANGLLVM_SUPPORT 35 + int test__clang(int i __maybe_unused) 36 + { 37 + return TEST_SKIP; 38 + } 39 + #else 40 + int test__clang(int i) 41 + { 42 + if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) 43 + return TEST_FAIL; 44 + return clang_testcase_table[i].func(); 45 + } 46 + #endif
+7
tools/perf/tests/llvm.h
··· 1 1 #ifndef PERF_TEST_LLVM_H 2 2 #define PERF_TEST_LLVM_H 3 3 4 + #ifdef __cplusplus 5 + extern "C" { 6 + #endif 7 + 4 8 #include <stddef.h> /* for size_t */ 5 9 #include <stdbool.h> /* for bool */ 6 10 ··· 24 20 int test_llvm__fetch_bpf_obj(void **p_obj_buf, size_t *p_obj_buf_sz, 25 21 enum test_llvm__testcase index, bool force, 26 22 bool *should_load_fail); 23 + #ifdef __cplusplus 24 + } 25 + #endif 27 26 #endif
+3 -1
tools/perf/tests/make
··· 83 83 make_no_libcrypto := NO_LIBCRYPTO=1 84 84 make_with_babeltrace:= LIBBABELTRACE=1 85 85 make_no_sdt := NO_SDT=1 86 + make_with_clangllvm := LIBCLANGLLVM=1 86 87 make_tags := tags 87 88 make_cscope := cscope 88 89 make_help := help ··· 140 139 run += make_no_auxtrace 141 140 run += make_no_libbpf 142 141 run += make_with_babeltrace 142 + run += make_with_clangllvm 143 143 run += make_help 144 144 run += make_doc 145 145 run += make_perf_o ··· 280 278 281 279 MAKEFLAGS := --no-print-directory 282 280 283 - clean := @(cd $(PERF); $(MAKE_F) -s $(O_OPT) clean >/dev/null) 281 + clean := @(cd $(PERF); $(MAKE_F) -s $(O_OPT) clean >/dev/null && $(MAKE) -s $(O_OPT) -C ../build clean >/dev/null) 284 282 285 283 $(run): 286 284 $(call clean)
+9 -5
tools/perf/tests/perf-hooks.c
··· 15 15 exit(-1); 16 16 } 17 17 18 - static int hook_flags; 19 18 20 - static void the_hook(void) 19 + static void the_hook(void *_hook_flags) 21 20 { 21 + int *hook_flags = _hook_flags; 22 22 int *p = NULL; 23 23 24 - hook_flags = 1234; 24 + *hook_flags = 1234; 25 25 26 26 /* Generate a segfault, test perf_hooks__recover */ 27 27 *p = 0; ··· 29 29 30 30 int test__perf_hooks(int subtest __maybe_unused) 31 31 { 32 + int hook_flags = 0; 33 + 32 34 signal(SIGSEGV, sigsegv_handler); 33 - perf_hooks__set_hook("test", the_hook); 35 + perf_hooks__set_hook("test", the_hook, &hook_flags); 34 36 perf_hooks__invoke_test(); 35 37 36 38 /* hook is triggered? */ 37 - if (hook_flags != 1234) 39 + if (hook_flags != 1234) { 40 + pr_debug("Setting failed: %d (%p)\n", hook_flags, &hook_flags); 38 41 return TEST_FAIL; 42 + } 39 43 40 44 /* the buggy hook is removed? */ 41 45 if (perf_hooks__get_hook("test"))
+3
tools/perf/tests/tests.h
··· 92 92 int test__is_printable_array(int subtest); 93 93 int test__bitmap_print(int subtest); 94 94 int test__perf_hooks(int subtest); 95 + int test__clang(int subtest); 96 + const char *test__clang_subtest_get_desc(int subtest); 97 + int test__clang_subtest_get_nr(void); 95 98 96 99 #if defined(__arm__) || defined(__aarch64__) 97 100 #ifdef HAVE_DWARF_UNWIND_SUPPORT
+2
tools/perf/util/Build
··· 126 126 127 127 libperf-y += perf-hooks.o 128 128 129 + libperf-$(CONFIG_CXX) += c++/ 130 + 129 131 CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" 130 132 # avoid compiler warnings in 32-bit mode 131 133 CFLAGS_genelf_debug.o += -Wno-packed
+3
tools/perf/util/annotate.c
··· 237 237 static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 238 238 struct ins_operands *ops) 239 239 { 240 + if (!ops->target.addr) 241 + return ins__raw_scnprintf(ins, bf, size, ops); 242 + 240 243 return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset); 241 244 } 242 245
+15 -4
tools/perf/util/bpf-loader.c
··· 14 14 #include "debug.h" 15 15 #include "bpf-loader.h" 16 16 #include "bpf-prologue.h" 17 - #include "llvm-utils.h" 18 17 #include "probe-event.h" 19 18 #include "probe-finder.h" // for MAX_PROBES 20 19 #include "parse-events.h" 21 20 #include "llvm-utils.h" 21 + #include "c++/clang-c.h" 22 22 23 23 #define DEFINE_PRINT_FN(name, level) \ 24 24 static int libbpf_##name(const char *fmt, ...) \ ··· 86 86 void *obj_buf; 87 87 size_t obj_buf_sz; 88 88 89 - err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz); 90 - if (err) 91 - return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); 89 + perf_clang__init(); 90 + err = perf_clang__compile_bpf(filename, &obj_buf, &obj_buf_sz); 91 + perf_clang__cleanup(); 92 + if (err) { 93 + pr_warning("bpf: builtin compilation failed: %d, try external compiler\n", err); 94 + err = llvm__compile_bpf(filename, &obj_buf, &obj_buf_sz); 95 + if (err) 96 + return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); 97 + } else 98 + pr_debug("bpf: successfull builtin compilation\n"); 92 99 obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename); 100 + 101 + if (!IS_ERR(obj) && llvm_param.dump_obj) 102 + llvm__dump_obj(filename, obj_buf, obj_buf_sz); 103 + 93 104 free(obj_buf); 94 105 } else 95 106 obj = bpf_object__open(filename);
+2
tools/perf/util/c++/Build
··· 1 + libperf-$(CONFIG_CLANGLLVM) += clang.o 2 + libperf-$(CONFIG_CLANGLLVM) += clang-test.o
+43
tools/perf/util/c++/clang-c.h
··· 1 + #ifndef PERF_UTIL_CLANG_C_H 2 + #define PERF_UTIL_CLANG_C_H 3 + 4 + #include <stddef.h> /* for size_t */ 5 + #include <util-cxx.h> /* for __maybe_unused */ 6 + 7 + #ifdef __cplusplus 8 + extern "C" { 9 + #endif 10 + 11 + #ifdef HAVE_LIBCLANGLLVM_SUPPORT 12 + extern void perf_clang__init(void); 13 + extern void perf_clang__cleanup(void); 14 + 15 + extern int test__clang_to_IR(void); 16 + extern int test__clang_to_obj(void); 17 + 18 + extern int perf_clang__compile_bpf(const char *filename, 19 + void **p_obj_buf, 20 + size_t *p_obj_buf_sz); 21 + #else 22 + 23 + 24 + static inline void perf_clang__init(void) { } 25 + static inline void perf_clang__cleanup(void) { } 26 + 27 + static inline int test__clang_to_IR(void) { return -1; } 28 + static inline int test__clang_to_obj(void) { return -1;} 29 + 30 + static inline int 31 + perf_clang__compile_bpf(const char *filename __maybe_unused, 32 + void **p_obj_buf __maybe_unused, 33 + size_t *p_obj_buf_sz __maybe_unused) 34 + { 35 + return -ENOTSUP; 36 + } 37 + 38 + #endif 39 + 40 + #ifdef __cplusplus 41 + } 42 + #endif 43 + #endif
+62
tools/perf/util/c++/clang-test.cpp
··· 1 + #include "clang.h" 2 + #include "clang-c.h" 3 + #include "llvm/IR/Function.h" 4 + #include "llvm/IR/LLVMContext.h" 5 + 6 + #include <util-cxx.h> 7 + #include <tests/llvm.h> 8 + #include <string> 9 + 10 + class perf_clang_scope { 11 + public: 12 + explicit perf_clang_scope() {perf_clang__init();} 13 + ~perf_clang_scope() {perf_clang__cleanup();} 14 + }; 15 + 16 + static std::unique_ptr<llvm::Module> 17 + __test__clang_to_IR(void) 18 + { 19 + unsigned int kernel_version; 20 + 21 + if (fetch_kernel_version(&kernel_version, NULL, 0)) 22 + return std::unique_ptr<llvm::Module>(nullptr); 23 + 24 + std::string cflag_kver("-DLINUX_VERSION_CODE=" + 25 + std::to_string(kernel_version)); 26 + 27 + std::unique_ptr<llvm::Module> M = 28 + perf::getModuleFromSource({cflag_kver.c_str()}, 29 + "perf-test.c", 30 + test_llvm__bpf_base_prog); 31 + return M; 32 + } 33 + 34 + extern "C" { 35 + int test__clang_to_IR(void) 36 + { 37 + perf_clang_scope _scope; 38 + 39 + auto M = __test__clang_to_IR(); 40 + if (!M) 41 + return -1; 42 + for (llvm::Function& F : *M) 43 + if (F.getName() == "bpf_func__SyS_epoll_wait") 44 + return 0; 45 + return -1; 46 + } 47 + 48 + int test__clang_to_obj(void) 49 + { 50 + perf_clang_scope _scope; 51 + 52 + auto M = __test__clang_to_IR(); 53 + if (!M) 54 + return -1; 55 + 56 + auto Buffer = perf::getBPFObjectFromModule(&*M); 57 + if (!Buffer) 58 + return -1; 59 + return 0; 60 + } 61 + 62 + }
+195
tools/perf/util/c++/clang.cpp
··· 1 + /* 2 + * llvm C frontend for perf. Support dynamically compile C file 3 + * 4 + * Inspired by clang example code: 5 + * http://llvm.org/svn/llvm-project/cfe/trunk/examples/clang-interpreter/main.cpp 6 + * 7 + * Copyright (C) 2016 Wang Nan <wangnan0@huawei.com> 8 + * Copyright (C) 2016 Huawei Inc. 9 + */ 10 + 11 + #include "clang/CodeGen/CodeGenAction.h" 12 + #include "clang/Frontend/CompilerInvocation.h" 13 + #include "clang/Frontend/CompilerInstance.h" 14 + #include "clang/Frontend/TextDiagnosticPrinter.h" 15 + #include "clang/Tooling/Tooling.h" 16 + #include "llvm/IR/LegacyPassManager.h" 17 + #include "llvm/IR/Module.h" 18 + #include "llvm/Option/Option.h" 19 + #include "llvm/Support/FileSystem.h" 20 + #include "llvm/Support/ManagedStatic.h" 21 + #include "llvm/Support/TargetRegistry.h" 22 + #include "llvm/Support/TargetSelect.h" 23 + #include "llvm/Target/TargetMachine.h" 24 + #include "llvm/Target/TargetOptions.h" 25 + #include <memory> 26 + 27 + #include "clang.h" 28 + #include "clang-c.h" 29 + 30 + namespace perf { 31 + 32 + static std::unique_ptr<llvm::LLVMContext> LLVMCtx; 33 + 34 + using namespace clang; 35 + 36 + static CompilerInvocation * 37 + createCompilerInvocation(llvm::opt::ArgStringList CFlags, StringRef& Path, 38 + DiagnosticsEngine& Diags) 39 + { 40 + llvm::opt::ArgStringList CCArgs { 41 + "-cc1", 42 + "-triple", "bpf-pc-linux", 43 + "-fsyntax-only", 44 + "-ferror-limit", "19", 45 + "-fmessage-length", "127", 46 + "-O2", 47 + "-nostdsysteminc", 48 + "-nobuiltininc", 49 + "-vectorize-loops", 50 + "-vectorize-slp", 51 + "-Wno-unused-value", 52 + "-Wno-pointer-sign", 53 + "-x", "c"}; 54 + 55 + CCArgs.append(CFlags.begin(), CFlags.end()); 56 + CompilerInvocation *CI = tooling::newInvocation(&Diags, CCArgs); 57 + 58 + FrontendOptions& Opts = CI->getFrontendOpts(); 59 + Opts.Inputs.clear(); 60 + Opts.Inputs.emplace_back(Path, IK_C); 61 + return CI; 62 + } 63 + 64 + static std::unique_ptr<llvm::Module> 65 + getModuleFromSource(llvm::opt::ArgStringList CFlags, 66 + StringRef Path, IntrusiveRefCntPtr<vfs::FileSystem> VFS) 67 + { 68 + CompilerInstance Clang; 69 + Clang.createDiagnostics(); 70 + 71 + Clang.setVirtualFileSystem(&*VFS); 72 + 73 + IntrusiveRefCntPtr<CompilerInvocation> CI = 74 + createCompilerInvocation(std::move(CFlags), Path, 75 + Clang.getDiagnostics()); 76 + Clang.setInvocation(&*CI); 77 + 78 + std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction(&*LLVMCtx)); 79 + if (!Clang.ExecuteAction(*Act)) 80 + return std::unique_ptr<llvm::Module>(nullptr); 81 + 82 + return Act->takeModule(); 83 + } 84 + 85 + std::unique_ptr<llvm::Module> 86 + getModuleFromSource(llvm::opt::ArgStringList CFlags, 87 + StringRef Name, StringRef Content) 88 + { 89 + using namespace vfs; 90 + 91 + llvm::IntrusiveRefCntPtr<OverlayFileSystem> OverlayFS( 92 + new OverlayFileSystem(getRealFileSystem())); 93 + llvm::IntrusiveRefCntPtr<InMemoryFileSystem> MemFS( 94 + new InMemoryFileSystem(true)); 95 + 96 + /* 97 + * pushOverlay helps setting working dir for MemFS. Must call 98 + * before addFile. 99 + */ 100 + OverlayFS->pushOverlay(MemFS); 101 + MemFS->addFile(Twine(Name), 0, llvm::MemoryBuffer::getMemBuffer(Content)); 102 + 103 + return getModuleFromSource(std::move(CFlags), Name, OverlayFS); 104 + } 105 + 106 + std::unique_ptr<llvm::Module> 107 + getModuleFromSource(llvm::opt::ArgStringList CFlags, StringRef Path) 108 + { 109 + IntrusiveRefCntPtr<vfs::FileSystem> VFS(vfs::getRealFileSystem()); 110 + return getModuleFromSource(std::move(CFlags), Path, VFS); 111 + } 112 + 113 + std::unique_ptr<llvm::SmallVectorImpl<char>> 114 + getBPFObjectFromModule(llvm::Module *Module) 115 + { 116 + using namespace llvm; 117 + 118 + std::string TargetTriple("bpf-pc-linux"); 119 + std::string Error; 120 + const Target* Target = TargetRegistry::lookupTarget(TargetTriple, Error); 121 + if (!Target) { 122 + llvm::errs() << Error; 123 + return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr); 124 + } 125 + 126 + llvm::TargetOptions Opt; 127 + TargetMachine *TargetMachine = 128 + Target->createTargetMachine(TargetTriple, 129 + "generic", "", 130 + Opt, Reloc::Static); 131 + 132 + Module->setDataLayout(TargetMachine->createDataLayout()); 133 + Module->setTargetTriple(TargetTriple); 134 + 135 + std::unique_ptr<SmallVectorImpl<char>> Buffer(new SmallVector<char, 0>()); 136 + raw_svector_ostream ostream(*Buffer); 137 + 138 + legacy::PassManager PM; 139 + if (TargetMachine->addPassesToEmitFile(PM, ostream, 140 + TargetMachine::CGFT_ObjectFile)) { 141 + llvm::errs() << "TargetMachine can't emit a file of this type\n"; 142 + return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);; 143 + } 144 + PM.run(*Module); 145 + 146 + return std::move(Buffer); 147 + } 148 + 149 + } 150 + 151 + extern "C" { 152 + void perf_clang__init(void) 153 + { 154 + perf::LLVMCtx.reset(new llvm::LLVMContext()); 155 + LLVMInitializeBPFTargetInfo(); 156 + LLVMInitializeBPFTarget(); 157 + LLVMInitializeBPFTargetMC(); 158 + LLVMInitializeBPFAsmPrinter(); 159 + } 160 + 161 + void perf_clang__cleanup(void) 162 + { 163 + perf::LLVMCtx.reset(nullptr); 164 + llvm::llvm_shutdown(); 165 + } 166 + 167 + int perf_clang__compile_bpf(const char *filename, 168 + void **p_obj_buf, 169 + size_t *p_obj_buf_sz) 170 + { 171 + using namespace perf; 172 + 173 + if (!p_obj_buf || !p_obj_buf_sz) 174 + return -EINVAL; 175 + 176 + llvm::opt::ArgStringList CFlags; 177 + auto M = getModuleFromSource(std::move(CFlags), filename); 178 + if (!M) 179 + return -EINVAL; 180 + auto O = getBPFObjectFromModule(&*M); 181 + if (!O) 182 + return -EINVAL; 183 + 184 + size_t size = O->size_in_bytes(); 185 + void *buffer; 186 + 187 + buffer = malloc(size); 188 + if (!buffer) 189 + return -ENOMEM; 190 + memcpy(buffer, O->data(), size); 191 + *p_obj_buf = buffer; 192 + *p_obj_buf_sz = size; 193 + return 0; 194 + } 195 + }
+26
tools/perf/util/c++/clang.h
··· 1 + #ifndef PERF_UTIL_CLANG_H 2 + #define PERF_UTIL_CLANG_H 3 + 4 + #include "llvm/ADT/StringRef.h" 5 + #include "llvm/IR/LLVMContext.h" 6 + #include "llvm/IR/Module.h" 7 + #include "llvm/Option/Option.h" 8 + #include <memory> 9 + 10 + namespace perf { 11 + 12 + using namespace llvm; 13 + 14 + std::unique_ptr<Module> 15 + getModuleFromSource(opt::ArgStringList CFlags, 16 + StringRef Name, StringRef Content); 17 + 18 + std::unique_ptr<Module> 19 + getModuleFromSource(opt::ArgStringList CFlags, 20 + StringRef Path); 21 + 22 + std::unique_ptr<llvm::SmallVectorImpl<char>> 23 + getBPFObjectFromModule(llvm::Module *Module); 24 + 25 + } 26 + #endif
+58 -18
tools/perf/util/llvm-utils.c
··· 7 7 #include <limits.h> 8 8 #include <stdio.h> 9 9 #include <stdlib.h> 10 + #include <linux/err.h> 10 11 #include "debug.h" 11 12 #include "llvm-utils.h" 12 13 #include "config.h" ··· 283 282 "rm -rf $TMPDIR\n" 284 283 "exit $RET\n"; 285 284 286 - static inline void 287 - get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts) 285 + void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts) 288 286 { 287 + static char *saved_kbuild_dir; 288 + static char *saved_kbuild_include_opts; 289 289 int err; 290 290 291 291 if (!kbuild_dir || !kbuild_include_opts) ··· 295 293 *kbuild_dir = NULL; 296 294 *kbuild_include_opts = NULL; 297 295 296 + if (saved_kbuild_dir && saved_kbuild_include_opts && 297 + !IS_ERR(saved_kbuild_dir) && !IS_ERR(saved_kbuild_include_opts)) { 298 + *kbuild_dir = strdup(saved_kbuild_dir); 299 + *kbuild_include_opts = strdup(saved_kbuild_include_opts); 300 + 301 + if (*kbuild_dir && *kbuild_include_opts) 302 + return; 303 + 304 + zfree(kbuild_dir); 305 + zfree(kbuild_include_opts); 306 + /* 307 + * Don't fall through: it may breaks saved_kbuild_dir and 308 + * saved_kbuild_include_opts if detect them again when 309 + * memory is low. 310 + */ 311 + return; 312 + } 313 + 298 314 if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) { 299 315 pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.\n"); 300 316 pr_debug("Skip kbuild options detection.\n"); 301 - return; 317 + goto errout; 302 318 } 303 319 304 320 err = detect_kbuild_dir(kbuild_dir); ··· 326 306 "Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]\n" 327 307 " \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild\n" 328 308 " \tdetection.\n\n"); 329 - return; 309 + goto errout; 330 310 } 331 311 332 312 pr_debug("Kernel build dir is set to %s\n", *kbuild_dir); ··· 345 325 346 326 free(*kbuild_dir); 347 327 *kbuild_dir = NULL; 348 - return; 328 + goto errout; 349 329 } 350 330 351 331 pr_debug("include option is set to %s\n", *kbuild_include_opts); 332 + 333 + saved_kbuild_dir = strdup(*kbuild_dir); 334 + saved_kbuild_include_opts = strdup(*kbuild_include_opts); 335 + 336 + if (!saved_kbuild_dir || !saved_kbuild_include_opts) { 337 + zfree(&saved_kbuild_dir); 338 + zfree(&saved_kbuild_include_opts); 339 + } 340 + return; 341 + errout: 342 + saved_kbuild_dir = ERR_PTR(-EINVAL); 343 + saved_kbuild_include_opts = ERR_PTR(-EINVAL); 352 344 } 353 345 354 - static void 355 - dump_obj(const char *path, void *obj_buf, size_t size) 346 + int llvm__get_nr_cpus(void) 347 + { 348 + static int nr_cpus_avail = 0; 349 + char serr[STRERR_BUFSIZE]; 350 + 351 + if (nr_cpus_avail > 0) 352 + return nr_cpus_avail; 353 + 354 + nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); 355 + if (nr_cpus_avail <= 0) { 356 + pr_err( 357 + "WARNING:\tunable to get available CPUs in this system: %s\n" 358 + " \tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr))); 359 + nr_cpus_avail = 128; 360 + } 361 + return nr_cpus_avail; 362 + } 363 + 364 + void llvm__dump_obj(const char *path, void *obj_buf, size_t size) 356 365 { 357 366 char *obj_path = strdup(path); 358 367 FILE *fp; ··· 455 406 * This is an optional work. Even it fail we can continue our 456 407 * work. Needn't to check error return. 457 408 */ 458 - get_kbuild_opts(&kbuild_dir, &kbuild_include_opts); 409 + llvm__get_kbuild_opts(&kbuild_dir, &kbuild_include_opts); 459 410 460 - nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); 461 - if (nr_cpus_avail <= 0) { 462 - pr_err( 463 - "WARNING:\tunable to get available CPUs in this system: %s\n" 464 - " \tUse 128 instead.\n", str_error_r(errno, serr, sizeof(serr))); 465 - nr_cpus_avail = 128; 466 - } 411 + nr_cpus_avail = llvm__get_nr_cpus(); 467 412 snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d", 468 413 nr_cpus_avail); 469 414 ··· 495 452 496 453 free(kbuild_dir); 497 454 free(kbuild_include_opts); 498 - 499 - if (llvm_param.dump_obj) 500 - dump_obj(path, obj_buf, obj_buf_sz); 501 455 502 456 if (!p_obj_buf) 503 457 free(obj_buf);
+6
tools/perf/util/llvm-utils.h
··· 50 50 51 51 /* This function is for test__llvm() use only */ 52 52 int llvm__search_clang(void); 53 + 54 + /* Following functions are reused by builtin clang support */ 55 + void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts); 56 + int llvm__get_nr_cpus(void); 57 + 58 + void llvm__dump_obj(const char *path, void *obj_buf, size_t size); 53 59 #endif
+7 -3
tools/perf/util/perf-hooks.c
··· 27 27 *(current_perf_hook->p_hook_func) = NULL; 28 28 } else { 29 29 current_perf_hook = desc; 30 - (**desc->p_hook_func)(); 30 + (**desc->p_hook_func)(desc->hook_ctx); 31 31 } 32 32 current_perf_hook = NULL; 33 33 } ··· 41 41 #define PERF_HOOK(name) \ 42 42 perf_hook_func_t __perf_hook_func_##name = NULL; \ 43 43 struct perf_hook_desc __perf_hook_desc_##name = \ 44 - {.hook_name = #name, .p_hook_func = &__perf_hook_func_##name}; 44 + {.hook_name = #name, \ 45 + .p_hook_func = &__perf_hook_func_##name, \ 46 + .hook_ctx = NULL}; 45 47 #include "perf-hooks-list.h" 46 48 #undef PERF_HOOK 47 49 ··· 56 54 #undef PERF_HOOK 57 55 58 56 int perf_hooks__set_hook(const char *hook_name, 59 - perf_hook_func_t hook_func) 57 + perf_hook_func_t hook_func, 58 + void *hook_ctx) 60 59 { 61 60 unsigned int i; 62 61 ··· 68 65 if (*(perf_hooks[i]->p_hook_func)) 69 66 pr_warning("Overwrite existing hook: %s\n", hook_name); 70 67 *(perf_hooks[i]->p_hook_func) = hook_func; 68 + perf_hooks[i]->hook_ctx = hook_ctx; 71 69 return 0; 72 70 } 73 71 return -ENOENT;
+4 -2
tools/perf/util/perf-hooks.h
··· 5 5 extern "C" { 6 6 #endif 7 7 8 - typedef void (*perf_hook_func_t)(void); 8 + typedef void (*perf_hook_func_t)(void *ctx); 9 9 struct perf_hook_desc { 10 10 const char * const hook_name; 11 11 perf_hook_func_t * const p_hook_func; 12 + void *hook_ctx; 12 13 }; 13 14 14 15 extern void perf_hooks__invoke(const struct perf_hook_desc *); ··· 27 26 28 27 extern int 29 28 perf_hooks__set_hook(const char *hook_name, 30 - perf_hook_func_t hook_func); 29 + perf_hook_func_t hook_func, 30 + void *hook_ctx); 31 31 32 32 extern perf_hook_func_t 33 33 perf_hooks__get_hook(const char *hook_name);
+26
tools/perf/util/util-cxx.h
··· 1 + /* 2 + * Support C++ source use utilities defined in util.h 3 + */ 4 + 5 + #ifndef PERF_UTIL_UTIL_CXX_H 6 + #define PERF_UTIL_UTIL_CXX_H 7 + 8 + #ifdef __cplusplus 9 + extern "C" { 10 + #endif 11 + 12 + /* 13 + * Now 'new' is the only C++ keyword found in util.h: 14 + * in tools/include/linux/rbtree.h 15 + * 16 + * Other keywords, like class and delete, should be 17 + * redefined if necessary. 18 + */ 19 + #define new _new 20 + #include "util.h" 21 + #undef new 22 + 23 + #ifdef __cplusplus 24 + } 25 + #endif 26 + #endif