aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-04-03 12:16:42 -0400
committerIngo Molnar <mingo@elte.hu>2010-04-03 12:16:42 -0400
commit70a7c1271e2bfca8ad2bf71f44c516ea2763b9ed (patch)
treeeaac85de741bc558529eccaefc372ff1e90ff425 /tools/perf
parent40b91cd10f000b4c4934e48e2e5c0bec66def144 (diff)
parent533c46c31c0e82f19dbb087c77d85eaccd6fefdb (diff)
Merge branch 'perf' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Makefile325
-rw-r--r--tools/perf/bench/mem-memcpy.c1
-rw-r--r--tools/perf/builtin-annotate.c1
-rw-r--r--tools/perf/builtin-kmem.c9
-rw-r--r--tools/perf/builtin-record.c4
-rw-r--r--tools/perf/builtin-report.c23
-rw-r--r--tools/perf/builtin-timechart.c1
-rw-r--r--tools/perf/perf.c1
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN6
-rw-r--r--tools/perf/util/color.c53
-rw-r--r--tools/perf/util/color.h4
-rw-r--r--tools/perf/util/debug.h16
-rw-r--r--tools/perf/util/event.c9
-rw-r--r--tools/perf/util/hist.c66
-rw-r--r--tools/perf/util/hist.h9
-rw-r--r--tools/perf/util/map.c196
-rw-r--r--tools/perf/util/map.h34
-rw-r--r--tools/perf/util/newt.c298
-rw-r--r--tools/perf/util/session.c22
-rw-r--r--tools/perf/util/session.h19
-rw-r--r--tools/perf/util/sort.c93
-rw-r--r--tools/perf/util/sort.h6
-rw-r--r--tools/perf/util/string.h16
-rw-r--r--tools/perf/util/thread.c169
-rw-r--r--tools/perf/util/util.h12
25 files changed, 806 insertions, 587 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 690364577611..9f5a47e5c07e 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -1,3 +1,7 @@
1ifeq ("$(origin O)", "command line")
2 OUTPUT := $(O)/
3endif
4
1# The default target of this Makefile is... 5# The default target of this Makefile is...
2all:: 6all::
3 7
@@ -153,9 +157,13 @@ all::
153# 157#
154# Define NO_DWARF if you do not want debug-info analysis feature at all. 158# Define NO_DWARF if you do not want debug-info analysis feature at all.
155 159
156PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE 160$(shell sh -c 'mkdir -p $(OUTPUT)scripts/python/Perf-Trace-Util/' 2> /dev/null)
157 @$(SHELL_PATH) util/PERF-VERSION-GEN 161$(shell sh -c 'mkdir -p $(OUTPUT)util/scripting-engines/' 2> /dev/null)
158-include PERF-VERSION-FILE 162$(shell sh -c 'mkdir $(OUTPUT)bench' 2> /dev/null)
163
164$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
165 @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
166-include $(OUTPUT)PERF-VERSION-FILE
159 167
160uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 168uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
161uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not') 169uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
@@ -310,7 +318,7 @@ PROGRAMS += $(EXTRA_PROGRAMS)
310# 318#
311# Single 'perf' binary right now: 319# Single 'perf' binary right now:
312# 320#
313PROGRAMS += perf 321PROGRAMS += $(OUTPUT)perf
314 322
315# List built-in command $C whose implementation cmd_$C() is not in 323# List built-in command $C whose implementation cmd_$C() is not in
316# builtin-$C.o but is linked in as part of some other command. 324# builtin-$C.o but is linked in as part of some other command.
@@ -320,7 +328,7 @@ PROGRAMS += perf
320ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) 328ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
321 329
322# what 'all' will build but not install in perfexecdir 330# what 'all' will build but not install in perfexecdir
323OTHER_PROGRAMS = perf$X 331OTHER_PROGRAMS = $(OUTPUT)perf$X
324 332
325# Set paths to tools early so that they can be used for version tests. 333# Set paths to tools early so that they can be used for version tests.
326ifndef SHELL_PATH 334ifndef SHELL_PATH
@@ -332,7 +340,7 @@ endif
332 340
333export PERL_PATH 341export PERL_PATH
334 342
335LIB_FILE=libperf.a 343LIB_FILE=$(OUTPUT)libperf.a
336 344
337LIB_H += ../../include/linux/perf_event.h 345LIB_H += ../../include/linux/perf_event.h
338LIB_H += ../../include/linux/rbtree.h 346LIB_H += ../../include/linux/rbtree.h
@@ -377,7 +385,6 @@ LIB_H += util/header.h
377LIB_H += util/help.h 385LIB_H += util/help.h
378LIB_H += util/session.h 386LIB_H += util/session.h
379LIB_H += util/strbuf.h 387LIB_H += util/strbuf.h
380LIB_H += util/string.h
381LIB_H += util/strlist.h 388LIB_H += util/strlist.h
382LIB_H += util/svghelper.h 389LIB_H += util/svghelper.h
383LIB_H += util/run-command.h 390LIB_H += util/run-command.h
@@ -393,77 +400,77 @@ LIB_H += util/probe-finder.h
393LIB_H += util/probe-event.h 400LIB_H += util/probe-event.h
394LIB_H += util/cpumap.h 401LIB_H += util/cpumap.h
395 402
396LIB_OBJS += util/abspath.o 403LIB_OBJS += $(OUTPUT)util/abspath.o
397LIB_OBJS += util/alias.o 404LIB_OBJS += $(OUTPUT)util/alias.o
398LIB_OBJS += util/build-id.o 405LIB_OBJS += $(OUTPUT)util/build-id.o
399LIB_OBJS += util/config.o 406LIB_OBJS += $(OUTPUT)util/config.o
400LIB_OBJS += util/ctype.o 407LIB_OBJS += $(OUTPUT)util/ctype.o
401LIB_OBJS += util/debugfs.o 408LIB_OBJS += $(OUTPUT)util/debugfs.o
402LIB_OBJS += util/environment.o 409LIB_OBJS += $(OUTPUT)util/environment.o
403LIB_OBJS += util/event.o 410LIB_OBJS += $(OUTPUT)util/event.o
404LIB_OBJS += util/exec_cmd.o 411LIB_OBJS += $(OUTPUT)util/exec_cmd.o
405LIB_OBJS += util/help.o 412LIB_OBJS += $(OUTPUT)util/help.o
406LIB_OBJS += util/levenshtein.o 413LIB_OBJS += $(OUTPUT)util/levenshtein.o
407LIB_OBJS += util/parse-options.o 414LIB_OBJS += $(OUTPUT)util/parse-options.o
408LIB_OBJS += util/parse-events.o 415LIB_OBJS += $(OUTPUT)util/parse-events.o
409LIB_OBJS += util/path.o 416LIB_OBJS += $(OUTPUT)util/path.o
410LIB_OBJS += util/rbtree.o 417LIB_OBJS += $(OUTPUT)util/rbtree.o
411LIB_OBJS += util/bitmap.o 418LIB_OBJS += $(OUTPUT)util/bitmap.o
412LIB_OBJS += util/hweight.o 419LIB_OBJS += $(OUTPUT)util/hweight.o
413LIB_OBJS += util/find_next_bit.o 420LIB_OBJS += $(OUTPUT)util/find_next_bit.o
414LIB_OBJS += util/run-command.o 421LIB_OBJS += $(OUTPUT)util/run-command.o
415LIB_OBJS += util/quote.o 422LIB_OBJS += $(OUTPUT)util/quote.o
416LIB_OBJS += util/strbuf.o 423LIB_OBJS += $(OUTPUT)util/strbuf.o
417LIB_OBJS += util/string.o 424LIB_OBJS += $(OUTPUT)util/string.o
418LIB_OBJS += util/strlist.o 425LIB_OBJS += $(OUTPUT)util/strlist.o
419LIB_OBJS += util/usage.o 426LIB_OBJS += $(OUTPUT)util/usage.o
420LIB_OBJS += util/wrapper.o 427LIB_OBJS += $(OUTPUT)util/wrapper.o
421LIB_OBJS += util/sigchain.o 428LIB_OBJS += $(OUTPUT)util/sigchain.o
422LIB_OBJS += util/symbol.o 429LIB_OBJS += $(OUTPUT)util/symbol.o
423LIB_OBJS += util/color.o 430LIB_OBJS += $(OUTPUT)util/color.o
424LIB_OBJS += util/pager.o 431LIB_OBJS += $(OUTPUT)util/pager.o
425LIB_OBJS += util/header.o 432LIB_OBJS += $(OUTPUT)util/header.o
426LIB_OBJS += util/callchain.o 433LIB_OBJS += $(OUTPUT)util/callchain.o
427LIB_OBJS += util/values.o 434LIB_OBJS += $(OUTPUT)util/values.o
428LIB_OBJS += util/debug.o 435LIB_OBJS += $(OUTPUT)util/debug.o
429LIB_OBJS += util/map.o 436LIB_OBJS += $(OUTPUT)util/map.o
430LIB_OBJS += util/session.o 437LIB_OBJS += $(OUTPUT)util/session.o
431LIB_OBJS += util/thread.o 438LIB_OBJS += $(OUTPUT)util/thread.o
432LIB_OBJS += util/trace-event-parse.o 439LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
433LIB_OBJS += util/trace-event-read.o 440LIB_OBJS += $(OUTPUT)util/trace-event-read.o
434LIB_OBJS += util/trace-event-info.o 441LIB_OBJS += $(OUTPUT)util/trace-event-info.o
435LIB_OBJS += util/trace-event-scripting.o 442LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
436LIB_OBJS += util/svghelper.o 443LIB_OBJS += $(OUTPUT)util/svghelper.o
437LIB_OBJS += util/sort.o 444LIB_OBJS += $(OUTPUT)util/sort.o
438LIB_OBJS += util/hist.o 445LIB_OBJS += $(OUTPUT)util/hist.o
439LIB_OBJS += util/probe-event.o 446LIB_OBJS += $(OUTPUT)util/probe-event.o
440LIB_OBJS += util/util.o 447LIB_OBJS += $(OUTPUT)util/util.o
441LIB_OBJS += util/cpumap.o 448LIB_OBJS += $(OUTPUT)util/cpumap.o
442 449
443BUILTIN_OBJS += builtin-annotate.o 450BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
444 451
445BUILTIN_OBJS += builtin-bench.o 452BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
446 453
447# Benchmark modules 454# Benchmark modules
448BUILTIN_OBJS += bench/sched-messaging.o 455BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
449BUILTIN_OBJS += bench/sched-pipe.o 456BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
450BUILTIN_OBJS += bench/mem-memcpy.o 457BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
451 458
452BUILTIN_OBJS += builtin-diff.o 459BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
453BUILTIN_OBJS += builtin-help.o 460BUILTIN_OBJS += $(OUTPUT)builtin-help.o
454BUILTIN_OBJS += builtin-sched.o 461BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
455BUILTIN_OBJS += builtin-buildid-list.o 462BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
456BUILTIN_OBJS += builtin-buildid-cache.o 463BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
457BUILTIN_OBJS += builtin-list.o 464BUILTIN_OBJS += $(OUTPUT)builtin-list.o
458BUILTIN_OBJS += builtin-record.o 465BUILTIN_OBJS += $(OUTPUT)builtin-record.o
459BUILTIN_OBJS += builtin-report.o 466BUILTIN_OBJS += $(OUTPUT)builtin-report.o
460BUILTIN_OBJS += builtin-stat.o 467BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
461BUILTIN_OBJS += builtin-timechart.o 468BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
462BUILTIN_OBJS += builtin-top.o 469BUILTIN_OBJS += $(OUTPUT)builtin-top.o
463BUILTIN_OBJS += builtin-trace.o 470BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
464BUILTIN_OBJS += builtin-probe.o 471BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
465BUILTIN_OBJS += builtin-kmem.o 472BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
466BUILTIN_OBJS += builtin-lock.o 473BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
467 474
468PERFLIBS = $(LIB_FILE) 475PERFLIBS = $(LIB_FILE)
469 476
@@ -494,6 +501,10 @@ ifeq ($(uname_S),Darwin)
494 PTHREAD_LIBS = 501 PTHREAD_LIBS =
495endif 502endif
496 503
504ifneq ($(OUTPUT),)
505 BASIC_CFLAGS += -I$(OUTPUT)
506endif
507
497ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) 508ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
498ifneq ($(shell sh -c "(echo '\#include <gnu/libc-version.h>'; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y) 509ifneq ($(shell sh -c "(echo '\#include <gnu/libc-version.h>'; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
499 msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); 510 msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
@@ -512,7 +523,7 @@ else
512ifndef NO_DWARF 523ifndef NO_DWARF
513 BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT 524 BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
514 EXTLIBS += -lelf -ldw 525 EXTLIBS += -lelf -ldw
515 LIB_OBJS += util/probe-finder.o 526 LIB_OBJS += $(OUTPUT)util/probe-finder.o
516endif 527endif
517endif 528endif
518 529
@@ -521,7 +532,7 @@ ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtIni
521 BASIC_CFLAGS += -DNO_NEWT_SUPPORT 532 BASIC_CFLAGS += -DNO_NEWT_SUPPORT
522else 533else
523 EXTLIBS += -lnewt 534 EXTLIBS += -lnewt
524 LIB_OBJS += util/newt.o 535 LIB_OBJS += $(OUTPUT)util/newt.o
525endif 536endif
526 537
527ifndef NO_LIBPERL 538ifndef NO_LIBPERL
@@ -533,8 +544,8 @@ ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; e
533 BASIC_CFLAGS += -DNO_LIBPERL 544 BASIC_CFLAGS += -DNO_LIBPERL
534else 545else
535 ALL_LDFLAGS += $(PERL_EMBED_LDOPTS) 546 ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
536 LIB_OBJS += util/scripting-engines/trace-event-perl.o 547 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
537 LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o 548 LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
538endif 549endif
539 550
540ifndef NO_LIBPYTHON 551ifndef NO_LIBPYTHON
@@ -542,12 +553,12 @@ PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null`
542PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null` 553PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null`
543endif 554endif
544 555
545ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o /dev/null $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y) 556ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o $(BITBUCKET) $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
546 BASIC_CFLAGS += -DNO_LIBPYTHON 557 BASIC_CFLAGS += -DNO_LIBPYTHON
547else 558else
548 ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS) 559 ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS)
549 LIB_OBJS += util/scripting-engines/trace-event-python.o 560 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
550 LIB_OBJS += scripts/python/Perf-Trace-Util/Context.o 561 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
551endif 562endif
552 563
553ifdef NO_DEMANGLE 564ifdef NO_DEMANGLE
@@ -618,53 +629,53 @@ ifdef NO_C99_FORMAT
618endif 629endif
619ifdef SNPRINTF_RETURNS_BOGUS 630ifdef SNPRINTF_RETURNS_BOGUS
620 COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS 631 COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS
621 COMPAT_OBJS += compat/snprintf.o 632 COMPAT_OBJS += $(OUTPUT)compat/snprintf.o
622endif 633endif
623ifdef FREAD_READS_DIRECTORIES 634ifdef FREAD_READS_DIRECTORIES
624 COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES 635 COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
625 COMPAT_OBJS += compat/fopen.o 636 COMPAT_OBJS += $(OUTPUT)compat/fopen.o
626endif 637endif
627ifdef NO_SYMLINK_HEAD 638ifdef NO_SYMLINK_HEAD
628 BASIC_CFLAGS += -DNO_SYMLINK_HEAD 639 BASIC_CFLAGS += -DNO_SYMLINK_HEAD
629endif 640endif
630ifdef NO_STRCASESTR 641ifdef NO_STRCASESTR
631 COMPAT_CFLAGS += -DNO_STRCASESTR 642 COMPAT_CFLAGS += -DNO_STRCASESTR
632 COMPAT_OBJS += compat/strcasestr.o 643 COMPAT_OBJS += $(OUTPUT)compat/strcasestr.o
633endif 644endif
634ifdef NO_STRTOUMAX 645ifdef NO_STRTOUMAX
635 COMPAT_CFLAGS += -DNO_STRTOUMAX 646 COMPAT_CFLAGS += -DNO_STRTOUMAX
636 COMPAT_OBJS += compat/strtoumax.o 647 COMPAT_OBJS += $(OUTPUT)compat/strtoumax.o
637endif 648endif
638ifdef NO_STRTOULL 649ifdef NO_STRTOULL
639 COMPAT_CFLAGS += -DNO_STRTOULL 650 COMPAT_CFLAGS += -DNO_STRTOULL
640endif 651endif
641ifdef NO_SETENV 652ifdef NO_SETENV
642 COMPAT_CFLAGS += -DNO_SETENV 653 COMPAT_CFLAGS += -DNO_SETENV
643 COMPAT_OBJS += compat/setenv.o 654 COMPAT_OBJS += $(OUTPUT)compat/setenv.o
644endif 655endif
645ifdef NO_MKDTEMP 656ifdef NO_MKDTEMP
646 COMPAT_CFLAGS += -DNO_MKDTEMP 657 COMPAT_CFLAGS += -DNO_MKDTEMP
647 COMPAT_OBJS += compat/mkdtemp.o 658 COMPAT_OBJS += $(OUTPUT)compat/mkdtemp.o
648endif 659endif
649ifdef NO_UNSETENV 660ifdef NO_UNSETENV
650 COMPAT_CFLAGS += -DNO_UNSETENV 661 COMPAT_CFLAGS += -DNO_UNSETENV
651 COMPAT_OBJS += compat/unsetenv.o 662 COMPAT_OBJS += $(OUTPUT)compat/unsetenv.o
652endif 663endif
653ifdef NO_SYS_SELECT_H 664ifdef NO_SYS_SELECT_H
654 BASIC_CFLAGS += -DNO_SYS_SELECT_H 665 BASIC_CFLAGS += -DNO_SYS_SELECT_H
655endif 666endif
656ifdef NO_MMAP 667ifdef NO_MMAP
657 COMPAT_CFLAGS += -DNO_MMAP 668 COMPAT_CFLAGS += -DNO_MMAP
658 COMPAT_OBJS += compat/mmap.o 669 COMPAT_OBJS += $(OUTPUT)compat/mmap.o
659else 670else
660 ifdef USE_WIN32_MMAP 671 ifdef USE_WIN32_MMAP
661 COMPAT_CFLAGS += -DUSE_WIN32_MMAP 672 COMPAT_CFLAGS += -DUSE_WIN32_MMAP
662 COMPAT_OBJS += compat/win32mmap.o 673 COMPAT_OBJS += $(OUTPUT)compat/win32mmap.o
663 endif 674 endif
664endif 675endif
665ifdef NO_PREAD 676ifdef NO_PREAD
666 COMPAT_CFLAGS += -DNO_PREAD 677 COMPAT_CFLAGS += -DNO_PREAD
667 COMPAT_OBJS += compat/pread.o 678 COMPAT_OBJS += $(OUTPUT)compat/pread.o
668endif 679endif
669ifdef NO_FAST_WORKING_DIRECTORY 680ifdef NO_FAST_WORKING_DIRECTORY
670 BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY 681 BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
@@ -686,10 +697,10 @@ else
686endif 697endif
687endif 698endif
688ifdef NO_INET_NTOP 699ifdef NO_INET_NTOP
689 LIB_OBJS += compat/inet_ntop.o 700 LIB_OBJS += $(OUTPUT)compat/inet_ntop.o
690endif 701endif
691ifdef NO_INET_PTON 702ifdef NO_INET_PTON
692 LIB_OBJS += compat/inet_pton.o 703 LIB_OBJS += $(OUTPUT)compat/inet_pton.o
693endif 704endif
694 705
695ifdef NO_ICONV 706ifdef NO_ICONV
@@ -706,15 +717,15 @@ endif
706 717
707ifdef PPC_SHA1 718ifdef PPC_SHA1
708 SHA1_HEADER = "ppc/sha1.h" 719 SHA1_HEADER = "ppc/sha1.h"
709 LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o 720 LIB_OBJS += $(OUTPUT)ppc/sha1.o ppc/sha1ppc.o
710else 721else
711ifdef ARM_SHA1 722ifdef ARM_SHA1
712 SHA1_HEADER = "arm/sha1.h" 723 SHA1_HEADER = "arm/sha1.h"
713 LIB_OBJS += arm/sha1.o arm/sha1_arm.o 724 LIB_OBJS += $(OUTPUT)arm/sha1.o $(OUTPUT)arm/sha1_arm.o
714else 725else
715ifdef MOZILLA_SHA1 726ifdef MOZILLA_SHA1
716 SHA1_HEADER = "mozilla-sha1/sha1.h" 727 SHA1_HEADER = "mozilla-sha1/sha1.h"
717 LIB_OBJS += mozilla-sha1/sha1.o 728 LIB_OBJS += $(OUTPUT)mozilla-sha1/sha1.o
718else 729else
719 SHA1_HEADER = <openssl/sha.h> 730 SHA1_HEADER = <openssl/sha.h>
720 EXTLIBS += $(LIB_4_CRYPTO) 731 EXTLIBS += $(LIB_4_CRYPTO)
@@ -726,15 +737,15 @@ ifdef NO_PERL_MAKEMAKER
726endif 737endif
727ifdef NO_HSTRERROR 738ifdef NO_HSTRERROR
728 COMPAT_CFLAGS += -DNO_HSTRERROR 739 COMPAT_CFLAGS += -DNO_HSTRERROR
729 COMPAT_OBJS += compat/hstrerror.o 740 COMPAT_OBJS += $(OUTPUT)compat/hstrerror.o
730endif 741endif
731ifdef NO_MEMMEM 742ifdef NO_MEMMEM
732 COMPAT_CFLAGS += -DNO_MEMMEM 743 COMPAT_CFLAGS += -DNO_MEMMEM
733 COMPAT_OBJS += compat/memmem.o 744 COMPAT_OBJS += $(OUTPUT)compat/memmem.o
734endif 745endif
735ifdef INTERNAL_QSORT 746ifdef INTERNAL_QSORT
736 COMPAT_CFLAGS += -DINTERNAL_QSORT 747 COMPAT_CFLAGS += -DINTERNAL_QSORT
737 COMPAT_OBJS += compat/qsort.o 748 COMPAT_OBJS += $(OUTPUT)compat/qsort.o
738endif 749endif
739ifdef RUNTIME_PREFIX 750ifdef RUNTIME_PREFIX
740 COMPAT_CFLAGS += -DRUNTIME_PREFIX 751 COMPAT_CFLAGS += -DRUNTIME_PREFIX
@@ -814,7 +825,7 @@ export TAR INSTALL DESTDIR SHELL_PATH
814 825
815SHELL = $(SHELL_PATH) 826SHELL = $(SHELL_PATH)
816 827
817all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS 828all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) $(OUTPUT)PERF-BUILD-OPTIONS
818ifneq (,$X) 829ifneq (,$X)
819 $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';) 830 $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
820endif 831endif
@@ -826,39 +837,39 @@ please_set_SHELL_PATH_to_a_more_modern_shell:
826 837
827shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell 838shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
828 839
829strip: $(PROGRAMS) perf$X 840strip: $(PROGRAMS) $(OUTPUT)perf$X
830 $(STRIP) $(STRIP_OPTS) $(PROGRAMS) perf$X 841 $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf$X
831 842
832perf.o: perf.c common-cmds.h PERF-CFLAGS 843$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
833 $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \ 844 $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \
834 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 845 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
835 $(ALL_CFLAGS) -c $(filter %.c,$^) 846 $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@
836 847
837perf$X: perf.o $(BUILTIN_OBJS) $(PERFLIBS) 848$(OUTPUT)perf$X: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
838 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ perf.o \ 849 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(OUTPUT)perf.o \
839 $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) 850 $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
840 851
841builtin-help.o: builtin-help.c common-cmds.h PERF-CFLAGS 852$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
842 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ 853 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
843 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 854 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
844 '-DPERF_MAN_PATH="$(mandir_SQ)"' \ 855 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
845 '-DPERF_INFO_PATH="$(infodir_SQ)"' $< 856 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
846 857
847builtin-timechart.o: builtin-timechart.c common-cmds.h PERF-CFLAGS 858$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
848 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ 859 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
849 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 860 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
850 '-DPERF_MAN_PATH="$(mandir_SQ)"' \ 861 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
851 '-DPERF_INFO_PATH="$(infodir_SQ)"' $< 862 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
852 863
853$(BUILT_INS): perf$X 864$(BUILT_INS): $(OUTPUT)perf$X
854 $(QUIET_BUILT_IN)$(RM) $@ && \ 865 $(QUIET_BUILT_IN)$(RM) $@ && \
855 ln perf$X $@ 2>/dev/null || \ 866 ln perf$X $@ 2>/dev/null || \
856 ln -s perf$X $@ 2>/dev/null || \ 867 ln -s perf$X $@ 2>/dev/null || \
857 cp perf$X $@ 868 cp perf$X $@
858 869
859common-cmds.h: util/generate-cmdlist.sh command-list.txt 870$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
860 871
861common-cmds.h: $(wildcard Documentation/perf-*.txt) 872$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
862 $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ 873 $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
863 874
864$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh 875$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
@@ -870,7 +881,7 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
870 -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ 881 -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
871 $@.sh >$@+ && \ 882 $@.sh >$@+ && \
872 chmod +x $@+ && \ 883 chmod +x $@+ && \
873 mv $@+ $@ 884 mv $@+ $(OUTPUT)$@
874 885
875configure: configure.ac 886configure: configure.ac
876 $(QUIET_GEN)$(RM) $@ $<+ && \ 887 $(QUIET_GEN)$(RM) $@ $<+ && \
@@ -880,60 +891,60 @@ configure: configure.ac
880 $(RM) $<+ 891 $(RM) $<+
881 892
882# These can record PERF_VERSION 893# These can record PERF_VERSION
883perf.o perf.spec \ 894$(OUTPUT)perf.o perf.spec \
884 $(patsubst %.sh,%,$(SCRIPT_SH)) \ 895 $(patsubst %.sh,%,$(SCRIPT_SH)) \
885 $(patsubst %.perl,%,$(SCRIPT_PERL)) \ 896 $(patsubst %.perl,%,$(SCRIPT_PERL)) \
886 : PERF-VERSION-FILE 897 : $(OUTPUT)PERF-VERSION-FILE
887 898
888%.o: %.c PERF-CFLAGS 899$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
889 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< 900 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
890%.s: %.c PERF-CFLAGS 901$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
891 $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< 902 $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
892%.o: %.S 903$(OUTPUT)%.o: %.S
893 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< 904 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
894 905
895util/exec_cmd.o: util/exec_cmd.c PERF-CFLAGS 906$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
896 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ 907 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
897 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ 908 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
898 '-DBINDIR="$(bindir_relative_SQ)"' \ 909 '-DBINDIR="$(bindir_relative_SQ)"' \
899 '-DPREFIX="$(prefix_SQ)"' \ 910 '-DPREFIX="$(prefix_SQ)"' \
900 $< 911 $<
901 912
902builtin-init-db.o: builtin-init-db.c PERF-CFLAGS 913$(OUTPUT)builtin-init-db.o: builtin-init-db.c $(OUTPUT)PERF-CFLAGS
903 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $< 914 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
904 915
905util/config.o: util/config.c PERF-CFLAGS 916$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
906 $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 917 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
907 918
908util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS 919$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
909 $(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 920 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
910 921
911# some perf warning policies can't fit to lib/bitmap.c, eg: it warns about variable shadowing 922# some perf warning policies can't fit to lib/bitmap.c, eg: it warns about variable shadowing
912# from <string.h> that comes from kernel headers wrapping. 923# from <string.h> that comes from kernel headers wrapping.
913KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//` 924KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//`
914 925
915util/bitmap.o: ../../lib/bitmap.c PERF-CFLAGS 926$(OUTPUT)util/bitmap.o: ../../lib/bitmap.c $(OUTPUT)PERF-CFLAGS
916 $(QUIET_CC)$(CC) -o util/bitmap.o -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 927 $(QUIET_CC)$(CC) -o $@ -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
917 928
918util/hweight.o: ../../lib/hweight.c PERF-CFLAGS 929$(OUTPUT)util/hweight.o: ../../lib/hweight.c $(OUTPUT)PERF-CFLAGS
919 $(QUIET_CC)$(CC) -o util/hweight.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 930 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
920 931
921util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS 932$(OUTPUT)util/find_next_bit.o: ../../lib/find_next_bit.c $(OUTPUT)PERF-CFLAGS
922 $(QUIET_CC)$(CC) -o util/find_next_bit.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 933 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
923 934
924util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c PERF-CFLAGS 935$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
925 $(QUIET_CC)$(CC) -o util/scripting-engines/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< 936 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
926 937
927scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c PERF-CFLAGS 938$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
928 $(QUIET_CC)$(CC) -o scripts/perl/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< 939 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
929 940
930util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c PERF-CFLAGS 941$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
931 $(QUIET_CC)$(CC) -o util/scripting-engines/trace-event-python.o -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< 942 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
932 943
933scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c PERF-CFLAGS 944$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
934 $(QUIET_CC)$(CC) -o scripts/python/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< 945 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
935 946
936perf-%$X: %.o $(PERFLIBS) 947$(OUTPUT)perf-%$X: %.o $(PERFLIBS)
937 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) 948 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
938 949
939$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) 950$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
@@ -974,17 +985,17 @@ cscope:
974TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\ 985TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
975 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ) 986 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
976 987
977PERF-CFLAGS: .FORCE-PERF-CFLAGS 988$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
978 @FLAGS='$(TRACK_CFLAGS)'; \ 989 @FLAGS='$(TRACK_CFLAGS)'; \
979 if test x"$$FLAGS" != x"`cat PERF-CFLAGS 2>/dev/null`" ; then \ 990 if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
980 echo 1>&2 " * new build flags or prefix"; \ 991 echo 1>&2 " * new build flags or prefix"; \
981 echo "$$FLAGS" >PERF-CFLAGS; \ 992 echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
982 fi 993 fi
983 994
984# We need to apply sq twice, once to protect from the shell 995# We need to apply sq twice, once to protect from the shell
985# that runs PERF-BUILD-OPTIONS, and then again to protect it 996# that runs $(OUTPUT)PERF-BUILD-OPTIONS, and then again to protect it
986# and the first level quoting from the shell that runs "echo". 997# and the first level quoting from the shell that runs "echo".
987PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS 998$(OUTPUT)PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS
988 @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@ 999 @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
989 @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@ 1000 @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
990 @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@ 1001 @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
@@ -1005,7 +1016,7 @@ all:: $(TEST_PROGRAMS)
1005 1016
1006export NO_SVN_TESTS 1017export NO_SVN_TESTS
1007 1018
1008check: common-cmds.h 1019check: $(OUTPUT)common-cmds.h
1009 if sparse; \ 1020 if sparse; \
1010 then \ 1021 then \
1011 for i in *.c */*.c; \ 1022 for i in *.c */*.c; \
@@ -1039,10 +1050,10 @@ export perfexec_instdir
1039 1050
1040install: all 1051install: all
1041 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' 1052 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
1042 $(INSTALL) perf$X '$(DESTDIR_SQ)$(bindir_SQ)' 1053 $(INSTALL) $(OUTPUT)perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
1043 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' 1054 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
1044 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' 1055 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
1045 $(INSTALL) perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 1056 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
1046 $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' 1057 $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
1047 $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl' 1058 $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
1048 $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' 1059 $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
@@ -1056,7 +1067,7 @@ ifdef BUILT_INS
1056 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 1067 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
1057 $(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 1068 $(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
1058ifneq (,$X) 1069ifneq (,$X)
1059 $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';) 1070 $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) $(OUTPUT)perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';)
1060endif 1071endif
1061endif 1072endif
1062 1073
@@ -1140,14 +1151,14 @@ clean:
1140 $(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE) 1151 $(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE)
1141 $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X 1152 $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X
1142 $(RM) $(TEST_PROGRAMS) 1153 $(RM) $(TEST_PROGRAMS)
1143 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope* 1154 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
1144 $(RM) -r autom4te.cache 1155 $(RM) -r autom4te.cache
1145 $(RM) config.log config.mak.autogen config.mak.append config.status config.cache 1156 $(RM) config.log config.mak.autogen config.mak.append config.status config.cache
1146 $(RM) -r $(PERF_TARNAME) .doc-tmp-dir 1157 $(RM) -r $(PERF_TARNAME) .doc-tmp-dir
1147 $(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz 1158 $(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz
1148 $(RM) $(htmldocs).tar.gz $(manpages).tar.gz 1159 $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
1149 $(MAKE) -C Documentation/ clean 1160 $(MAKE) -C Documentation/ clean
1150 $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS 1161 $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-BUILD-OPTIONS
1151 1162
1152.PHONY: all install clean strip 1163.PHONY: all install clean strip
1153.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 1164.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 89773178e894..52e646e3e873 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -10,7 +10,6 @@
10#include "../perf.h" 10#include "../perf.h"
11#include "../util/util.h" 11#include "../util/util.h"
12#include "../util/parse-options.h" 12#include "../util/parse-options.h"
13#include "../util/string.h"
14#include "../util/header.h" 13#include "../util/header.h"
15#include "bench.h" 14#include "bench.h"
16 15
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 887e8e04a6f9..ee0d91726991 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -14,7 +14,6 @@
14#include "util/cache.h" 14#include "util/cache.h"
15#include <linux/rbtree.h> 15#include <linux/rbtree.h>
16#include "util/symbol.h" 16#include "util/symbol.h"
17#include "util/string.h"
18 17
19#include "perf.h" 18#include "perf.h"
20#include "util/debug.h" 19#include "util/debug.h"
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 924a9518931a..513aa8a55db6 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -363,19 +363,21 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
363 struct alloc_stat *data = rb_entry(next, struct alloc_stat, 363 struct alloc_stat *data = rb_entry(next, struct alloc_stat,
364 node); 364 node);
365 struct symbol *sym = NULL; 365 struct symbol *sym = NULL;
366 struct map *map;
366 char buf[BUFSIZ]; 367 char buf[BUFSIZ];
367 u64 addr; 368 u64 addr;
368 369
369 if (is_caller) { 370 if (is_caller) {
370 addr = data->call_site; 371 addr = data->call_site;
371 if (!raw_ip) 372 if (!raw_ip)
372 sym = map_groups__find_function(&session->kmaps, addr, NULL); 373 sym = map_groups__find_function(&session->kmaps,
374 addr, &map, NULL);
373 } else 375 } else
374 addr = data->ptr; 376 addr = data->ptr;
375 377
376 if (sym != NULL) 378 if (sym != NULL)
377 snprintf(buf, sizeof(buf), "%s+%Lx", sym->name, 379 snprintf(buf, sizeof(buf), "%s+%Lx", sym->name,
378 addr - sym->start); 380 addr - map->unmap_ip(map, sym->start));
379 else 381 else
380 snprintf(buf, sizeof(buf), "%#Lx", addr); 382 snprintf(buf, sizeof(buf), "%#Lx", addr);
381 printf(" %-34s |", buf); 383 printf(" %-34s |", buf);
@@ -488,6 +490,9 @@ static int __cmd_kmem(void)
488 if (session == NULL) 490 if (session == NULL)
489 return -ENOMEM; 491 return -ENOMEM;
490 492
493 if (perf_session__create_kernel_maps(session) < 0)
494 goto out_delete;
495
491 if (!perf_session__has_traces(session, "kmem record")) 496 if (!perf_session__has_traces(session, "kmem record"))
492 goto out_delete; 497 goto out_delete;
493 498
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 60ecdd3dd26d..dc61f1b68b40 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -15,7 +15,6 @@
15#include "util/util.h" 15#include "util/util.h"
16#include "util/parse-options.h" 16#include "util/parse-options.h"
17#include "util/parse-events.h" 17#include "util/parse-events.h"
18#include "util/string.h"
19 18
20#include "util/header.h" 19#include "util/header.h"
21#include "util/event.h" 20#include "util/event.h"
@@ -575,6 +574,9 @@ static int __cmd_record(int argc, const char **argv)
575 574
576 err = event__synthesize_kernel_mmap(process_synthesized_event, 575 err = event__synthesize_kernel_mmap(process_synthesized_event,
577 session, "_text"); 576 session, "_text");
577 if (err < 0)
578 err = event__synthesize_kernel_mmap(process_synthesized_event,
579 session, "_stext");
578 if (err < 0) { 580 if (err < 0) {
579 pr_err("Couldn't record kernel reference relocation symbol.\n"); 581 pr_err("Couldn't record kernel reference relocation symbol.\n");
580 return err; 582 return err;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 6ab16980dd66..e93c69a8e720 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -14,7 +14,6 @@
14#include "util/cache.h" 14#include "util/cache.h"
15#include <linux/rbtree.h> 15#include <linux/rbtree.h>
16#include "util/symbol.h" 16#include "util/symbol.h"
17#include "util/string.h"
18#include "util/callchain.h" 17#include "util/callchain.h"
19#include "util/strlist.h" 18#include "util/strlist.h"
20#include "util/values.h" 19#include "util/values.h"
@@ -89,9 +88,12 @@ static int perf_session__add_hist_entry(struct perf_session *self,
89 struct event_stat_id *stats; 88 struct event_stat_id *stats;
90 struct perf_event_attr *attr; 89 struct perf_event_attr *attr;
91 90
92 if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) 91 if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) {
93 syms = perf_session__resolve_callchain(self, al->thread, 92 syms = perf_session__resolve_callchain(self, al->thread,
94 data->callchain, &parent); 93 data->callchain, &parent);
94 if (syms == NULL)
95 return -ENOMEM;
96 }
95 97
96 attr = perf_header__find_attr(data->id, &self->header); 98 attr = perf_header__find_attr(data->id, &self->header);
97 if (attr) 99 if (attr)
@@ -110,8 +112,8 @@ static int perf_session__add_hist_entry(struct perf_session *self,
110 112
111 if (symbol_conf.use_callchain) { 113 if (symbol_conf.use_callchain) {
112 if (!hit) 114 if (!hit)
113 callchain_init(&he->callchain); 115 callchain_init(he->callchain);
114 err = append_chain(&he->callchain, data->callchain, syms); 116 err = append_chain(he->callchain, data->callchain, syms);
115 free(syms); 117 free(syms);
116 118
117 if (err) 119 if (err)
@@ -303,14 +305,16 @@ static int __cmd_report(void)
303 next = rb_first(&session->stats_by_id); 305 next = rb_first(&session->stats_by_id);
304 while (next) { 306 while (next) {
305 struct event_stat_id *stats; 307 struct event_stat_id *stats;
308 u64 nr_hists;
306 309
307 stats = rb_entry(next, struct event_stat_id, rb_node); 310 stats = rb_entry(next, struct event_stat_id, rb_node);
308 perf_session__collapse_resort(&stats->hists); 311 perf_session__collapse_resort(&stats->hists);
309 perf_session__output_resort(&stats->hists, stats->stats.total); 312 nr_hists = perf_session__output_resort(&stats->hists,
310 313 stats->stats.total);
311 if (use_browser) 314 if (use_browser)
312 perf_session__browse_hists(&stats->hists, 315 perf_session__browse_hists(&stats->hists, nr_hists,
313 stats->stats.total, help); 316 stats->stats.total, help,
317 input_name);
314 else { 318 else {
315 if (rb_first(&session->stats_by_id) == 319 if (rb_first(&session->stats_by_id) ==
316 rb_last(&session->stats_by_id)) 320 rb_last(&session->stats_by_id))
@@ -469,7 +473,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
469 setup_sorting(report_usage, options); 473 setup_sorting(report_usage, options);
470 474
471 if (parent_pattern != default_parent_pattern) { 475 if (parent_pattern != default_parent_pattern) {
472 sort_dimension__add("parent"); 476 if (sort_dimension__add("parent") < 0)
477 return -1;
473 sort_parent.elide = 1; 478 sort_parent.elide = 1;
474 } else 479 } else
475 symbol_conf.exclude_other = false; 480 symbol_conf.exclude_other = false;
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 0d4d8ff7914b..266e7aa996d3 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -21,7 +21,6 @@
21#include "util/cache.h" 21#include "util/cache.h"
22#include <linux/rbtree.h> 22#include <linux/rbtree.h>
23#include "util/symbol.h" 23#include "util/symbol.h"
24#include "util/string.h"
25#include "util/callchain.h" 24#include "util/callchain.h"
26#include "util/strlist.h" 25#include "util/strlist.h"
27 26
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 2826e702986e..d4be55b6cd34 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -13,7 +13,6 @@
13#include "util/quote.h" 13#include "util/quote.h"
14#include "util/run-command.h" 14#include "util/run-command.h"
15#include "util/parse-events.h" 15#include "util/parse-events.h"
16#include "util/string.h"
17#include "util/debugfs.h" 16#include "util/debugfs.h"
18 17
19bool use_browser; 18bool use_browser;
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index 54552a00a117..49ece7921914 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -1,6 +1,10 @@
1#!/bin/sh 1#!/bin/sh
2 2
3GVF=PERF-VERSION-FILE 3if [ $# -eq 1 ] ; then
4 OUTPUT=$1
5fi
6
7GVF=${OUTPUT}PERF-VERSION-FILE
4DEF_VER=v0.0.2.PERF 8DEF_VER=v0.0.2.PERF
5 9
6LF=' 10LF='
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 9da01914e0af..e191eb9a667f 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -166,6 +166,31 @@ int perf_color_default_config(const char *var, const char *value, void *cb)
166 return perf_default_config(var, value, cb); 166 return perf_default_config(var, value, cb);
167} 167}
168 168
169static int __color_vsnprintf(char *bf, size_t size, const char *color,
170 const char *fmt, va_list args, const char *trail)
171{
172 int r = 0;
173
174 /*
175 * Auto-detect:
176 */
177 if (perf_use_color_default < 0) {
178 if (isatty(1) || pager_in_use())
179 perf_use_color_default = 1;
180 else
181 perf_use_color_default = 0;
182 }
183
184 if (perf_use_color_default && *color)
185 r += snprintf(bf, size, "%s", color);
186 r += vsnprintf(bf + r, size - r, fmt, args);
187 if (perf_use_color_default && *color)
188 r += snprintf(bf + r, size - r, "%s", PERF_COLOR_RESET);
189 if (trail)
190 r += snprintf(bf + r, size - r, "%s", trail);
191 return r;
192}
193
169static int __color_vfprintf(FILE *fp, const char *color, const char *fmt, 194static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
170 va_list args, const char *trail) 195 va_list args, const char *trail)
171{ 196{
@@ -191,11 +216,28 @@ static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
191 return r; 216 return r;
192} 217}
193 218
219int color_vsnprintf(char *bf, size_t size, const char *color,
220 const char *fmt, va_list args)
221{
222 return __color_vsnprintf(bf, size, color, fmt, args, NULL);
223}
224
194int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args) 225int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args)
195{ 226{
196 return __color_vfprintf(fp, color, fmt, args, NULL); 227 return __color_vfprintf(fp, color, fmt, args, NULL);
197} 228}
198 229
230int color_snprintf(char *bf, size_t size, const char *color,
231 const char *fmt, ...)
232{
233 va_list args;
234 int r;
235
236 va_start(args, fmt);
237 r = color_vsnprintf(bf, size, color, fmt, args);
238 va_end(args);
239 return r;
240}
199 241
200int color_fprintf(FILE *fp, const char *color, const char *fmt, ...) 242int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
201{ 243{
@@ -203,10 +245,7 @@ int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
203 int r; 245 int r;
204 246
205 va_start(args, fmt); 247 va_start(args, fmt);
206 if (use_browser) 248 r = color_vfprintf(fp, color, fmt, args);
207 r = vfprintf(fp, fmt, args);
208 else
209 r = color_vfprintf(fp, color, fmt, args);
210 va_end(args); 249 va_end(args);
211 return r; 250 return r;
212} 251}
@@ -277,3 +316,9 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
277 316
278 return r; 317 return r;
279} 318}
319
320int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent)
321{
322 const char *color = get_percent_color(percent);
323 return color_snprintf(bf, size, color, fmt, percent);
324}
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h
index 24e8809210bb..dea082b79602 100644
--- a/tools/perf/util/color.h
+++ b/tools/perf/util/color.h
@@ -32,10 +32,14 @@ int perf_color_default_config(const char *var, const char *value, void *cb);
32int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty); 32int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty);
33void color_parse(const char *value, const char *var, char *dst); 33void color_parse(const char *value, const char *var, char *dst);
34void color_parse_mem(const char *value, int len, const char *var, char *dst); 34void color_parse_mem(const char *value, int len, const char *var, char *dst);
35int color_vsnprintf(char *bf, size_t size, const char *color,
36 const char *fmt, va_list args);
35int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args); 37int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args);
36int color_fprintf(FILE *fp, const char *color, const char *fmt, ...); 38int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
39int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...);
37int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); 40int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
38int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf); 41int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
42int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent);
39int percent_color_fprintf(FILE *fp, const char *fmt, double percent); 43int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
40const char *get_percent_color(double percent); 44const char *get_percent_color(double percent);
41 45
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 0172edf3f153..5cb0a1b1401a 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -10,13 +10,29 @@ extern int dump_trace;
10int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); 10int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
11void trace_event(event_t *event); 11void trace_event(event_t *event);
12 12
13struct ui_progress;
14
13#ifdef NO_NEWT_SUPPORT 15#ifdef NO_NEWT_SUPPORT
14static inline int browser__show_help(const char *format __used, va_list ap __used) 16static inline int browser__show_help(const char *format __used, va_list ap __used)
15{ 17{
16 return 0; 18 return 0;
17} 19}
20
21static inline struct ui_progress *ui_progress__new(const char *title __used,
22 u64 total __used)
23{
24 return (struct ui_progress *)1;
25}
26
27static inline void ui_progress__update(struct ui_progress *self __used,
28 u64 curr __used) {}
29
30static inline void ui_progress__delete(struct ui_progress *self __used) {}
18#else 31#else
19int browser__show_help(const char *format, va_list ap); 32int browser__show_help(const char *format, va_list ap);
33struct ui_progress *ui_progress__new(const char *title, u64 total);
34void ui_progress__update(struct ui_progress *self, u64 curr);
35void ui_progress__delete(struct ui_progress *self);
20#endif 36#endif
21 37
22#endif /* __PERF_DEBUG_H */ 38#endif /* __PERF_DEBUG_H */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 052eaeccc202..571fb25f7eb9 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -130,6 +130,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
130 continue; 130 continue;
131 pbf += n + 3; 131 pbf += n + 3;
132 if (*pbf == 'x') { /* vm_exec */ 132 if (*pbf == 'x') { /* vm_exec */
133 u64 vm_pgoff;
133 char *execname = strchr(bf, '/'); 134 char *execname = strchr(bf, '/');
134 135
135 /* Catch VDSO */ 136 /* Catch VDSO */
@@ -139,6 +140,14 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
139 if (execname == NULL) 140 if (execname == NULL)
140 continue; 141 continue;
141 142
143 pbf += 3;
144 n = hex2u64(pbf, &vm_pgoff);
145 /* pgoff is in bytes, not pages */
146 if (n >= 0)
147 ev.mmap.pgoff = vm_pgoff << getpagesize();
148 else
149 ev.mmap.pgoff = 0;
150
142 size = strlen(execname); 151 size = strlen(execname);
143 execname[size - 1] = '\0'; /* Remove \n */ 152 execname[size - 1] = '\0'; /* Remove \n */
144 memcpy(ev.mmap.filename, execname, size); 153 memcpy(ev.mmap.filename, execname, size);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 09e09e78cb62..18cf8b321608 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -50,7 +50,8 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
50 p = &(*p)->rb_right; 50 p = &(*p)->rb_right;
51 } 51 }
52 52
53 he = malloc(sizeof(*he)); 53 he = malloc(sizeof(*he) + (symbol_conf.use_callchain ?
54 sizeof(struct callchain_node) : 0));
54 if (!he) 55 if (!he)
55 return NULL; 56 return NULL;
56 *he = entry; 57 *he = entry;
@@ -168,7 +169,7 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
168 struct hist_entry *iter; 169 struct hist_entry *iter;
169 170
170 if (symbol_conf.use_callchain) 171 if (symbol_conf.use_callchain)
171 callchain_param.sort(&he->sorted_chain, &he->callchain, 172 callchain_param.sort(&he->sorted_chain, he->callchain,
172 min_callchain_hits, &callchain_param); 173 min_callchain_hits, &callchain_param);
173 174
174 while (*p != NULL) { 175 while (*p != NULL) {
@@ -185,12 +186,13 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
185 rb_insert_color(&he->rb_node, root); 186 rb_insert_color(&he->rb_node, root);
186} 187}
187 188
188void perf_session__output_resort(struct rb_root *hists, u64 total_samples) 189u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples)
189{ 190{
190 struct rb_root tmp; 191 struct rb_root tmp;
191 struct rb_node *next; 192 struct rb_node *next;
192 struct hist_entry *n; 193 struct hist_entry *n;
193 u64 min_callchain_hits; 194 u64 min_callchain_hits;
195 u64 nr_hists = 0;
194 196
195 min_callchain_hits = 197 min_callchain_hits =
196 total_samples * (callchain_param.min_percent / 100); 198 total_samples * (callchain_param.min_percent / 100);
@@ -205,9 +207,11 @@ void perf_session__output_resort(struct rb_root *hists, u64 total_samples)
205 rb_erase(&n->rb_node, hists); 207 rb_erase(&n->rb_node, hists);
206 perf_session__insert_output_hist_entry(&tmp, n, 208 perf_session__insert_output_hist_entry(&tmp, n,
207 min_callchain_hits); 209 min_callchain_hits);
210 ++nr_hists;
208 } 211 }
209 212
210 *hists = tmp; 213 *hists = tmp;
214 return nr_hists;
211} 215}
212 216
213static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) 217static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
@@ -452,16 +456,17 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
452 return ret; 456 return ret;
453} 457}
454 458
455size_t hist_entry__fprintf(struct hist_entry *self, 459int hist_entry__snprintf(struct hist_entry *self,
460 char *s, size_t size,
456 struct perf_session *pair_session, 461 struct perf_session *pair_session,
457 bool show_displacement, 462 bool show_displacement,
458 long displacement, FILE *fp, 463 long displacement, bool color,
459 u64 session_total) 464 u64 session_total)
460{ 465{
461 struct sort_entry *se; 466 struct sort_entry *se;
462 u64 count, total; 467 u64 count, total;
463 const char *sep = symbol_conf.field_sep; 468 const char *sep = symbol_conf.field_sep;
464 size_t ret; 469 int ret;
465 470
466 if (symbol_conf.exclude_other && !self->parent) 471 if (symbol_conf.exclude_other && !self->parent)
467 return 0; 472 return 0;
@@ -474,17 +479,22 @@ size_t hist_entry__fprintf(struct hist_entry *self,
474 total = session_total; 479 total = session_total;
475 } 480 }
476 481
477 if (total) 482 if (total) {
478 ret = percent_color_fprintf(fp, sep ? "%.2f" : " %6.2f%%", 483 if (color)
479 (count * 100.0) / total); 484 ret = percent_color_snprintf(s, size,
480 else 485 sep ? "%.2f" : " %6.2f%%",
481 ret = fprintf(fp, sep ? "%lld" : "%12lld ", count); 486 (count * 100.0) / total);
487 else
488 ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%",
489 (count * 100.0) / total);
490 } else
491 ret = snprintf(s, size, sep ? "%lld" : "%12lld ", count);
482 492
483 if (symbol_conf.show_nr_samples) { 493 if (symbol_conf.show_nr_samples) {
484 if (sep) 494 if (sep)
485 ret += fprintf(fp, "%c%lld", *sep, count); 495 ret += snprintf(s + ret, size - ret, "%c%lld", *sep, count);
486 else 496 else
487 ret += fprintf(fp, "%11lld", count); 497 ret += snprintf(s + ret, size - ret, "%11lld", count);
488 } 498 }
489 499
490 if (pair_session) { 500 if (pair_session) {
@@ -504,9 +514,9 @@ size_t hist_entry__fprintf(struct hist_entry *self,
504 snprintf(bf, sizeof(bf), " "); 514 snprintf(bf, sizeof(bf), " ");
505 515
506 if (sep) 516 if (sep)
507 ret += fprintf(fp, "%c%s", *sep, bf); 517 ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
508 else 518 else
509 ret += fprintf(fp, "%11.11s", bf); 519 ret += snprintf(s + ret, size - ret, "%11.11s", bf);
510 520
511 if (show_displacement) { 521 if (show_displacement) {
512 if (displacement) 522 if (displacement)
@@ -515,9 +525,9 @@ size_t hist_entry__fprintf(struct hist_entry *self,
515 snprintf(bf, sizeof(bf), " "); 525 snprintf(bf, sizeof(bf), " ");
516 526
517 if (sep) 527 if (sep)
518 ret += fprintf(fp, "%c%s", *sep, bf); 528 ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
519 else 529 else
520 ret += fprintf(fp, "%6.6s", bf); 530 ret += snprintf(s + ret, size - ret, "%6.6s", bf);
521 } 531 }
522 } 532 }
523 533
@@ -525,11 +535,25 @@ size_t hist_entry__fprintf(struct hist_entry *self,
525 if (se->elide) 535 if (se->elide)
526 continue; 536 continue;
527 537
528 ret += fprintf(fp, "%s", sep ?: " "); 538 ret += snprintf(s + ret, size - ret, "%s", sep ?: " ");
529 ret += se->print(fp, self, se->width ? *se->width : 0); 539 ret += se->snprintf(self, s + ret, size - ret,
540 se->width ? *se->width : 0);
530 } 541 }
531 542
532 return ret + fprintf(fp, "\n"); 543 return ret;
544}
545
546int hist_entry__fprintf(struct hist_entry *self,
547 struct perf_session *pair_session,
548 bool show_displacement,
549 long displacement, FILE *fp,
550 u64 session_total)
551{
552 char bf[512];
553 hist_entry__snprintf(self, bf, sizeof(bf), pair_session,
554 show_displacement, displacement,
555 true, session_total);
556 return fprintf(fp, "%s\n", bf);
533} 557}
534 558
535static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, 559static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
@@ -658,7 +682,7 @@ print_entries:
658 682
659 if (h->ms.map == NULL && verbose > 1) { 683 if (h->ms.map == NULL && verbose > 1) {
660 __map_groups__fprintf_maps(&h->thread->mg, 684 __map_groups__fprintf_maps(&h->thread->mg,
661 MAP__FUNCTION, fp); 685 MAP__FUNCTION, verbose, fp);
662 fprintf(fp, "%.10s end\n", graph_dotted_line); 686 fprintf(fp, "%.10s end\n", graph_dotted_line);
663 } 687 }
664 } 688 }
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index fe366ce5db45..ad17f0ad798b 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -18,14 +18,19 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
18 u64 count, bool *hit); 18 u64 count, bool *hit);
19extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); 19extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
20extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); 20extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
21size_t hist_entry__fprintf(struct hist_entry *self, 21int hist_entry__fprintf(struct hist_entry *self,
22 struct perf_session *pair_session, 22 struct perf_session *pair_session,
23 bool show_displacement, 23 bool show_displacement,
24 long displacement, FILE *fp, 24 long displacement, FILE *fp,
25 u64 session_total); 25 u64 session_total);
26int hist_entry__snprintf(struct hist_entry *self,
27 char *bf, size_t size,
28 struct perf_session *pair_session,
29 bool show_displacement, long displacement,
30 bool color, u64 session_total);
26void hist_entry__free(struct hist_entry *); 31void hist_entry__free(struct hist_entry *);
27 32
28void perf_session__output_resort(struct rb_root *hists, u64 total_samples); 33u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples);
29void perf_session__collapse_resort(struct rb_root *hists); 34void perf_session__collapse_resort(struct rb_root *hists);
30size_t perf_session__fprintf_hists(struct rb_root *hists, 35size_t perf_session__fprintf_hists(struct rb_root *hists,
31 struct perf_session *pair, 36 struct perf_session *pair,
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 9f2963f9ee9a..37913b241bdf 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -1,4 +1,5 @@
1#include "symbol.h" 1#include "symbol.h"
2#include <errno.h>
2#include <limits.h> 3#include <limits.h>
3#include <stdlib.h> 4#include <stdlib.h>
4#include <string.h> 5#include <string.h>
@@ -234,18 +235,211 @@ u64 map__objdump_2ip(struct map *map, u64 addr)
234 return ip; 235 return ip;
235} 236}
236 237
238void map_groups__init(struct map_groups *self)
239{
240 int i;
241 for (i = 0; i < MAP__NR_TYPES; ++i) {
242 self->maps[i] = RB_ROOT;
243 INIT_LIST_HEAD(&self->removed_maps[i]);
244 }
245}
246
247void map_groups__flush(struct map_groups *self)
248{
249 int type;
250
251 for (type = 0; type < MAP__NR_TYPES; type++) {
252 struct rb_root *root = &self->maps[type];
253 struct rb_node *next = rb_first(root);
254
255 while (next) {
256 struct map *pos = rb_entry(next, struct map, rb_node);
257 next = rb_next(&pos->rb_node);
258 rb_erase(&pos->rb_node, root);
259 /*
260 * We may have references to this map, for
261 * instance in some hist_entry instances, so
262 * just move them to a separate list.
263 */
264 list_add_tail(&pos->node, &self->removed_maps[pos->type]);
265 }
266 }
267}
268
237struct symbol *map_groups__find_symbol(struct map_groups *self, 269struct symbol *map_groups__find_symbol(struct map_groups *self,
238 enum map_type type, u64 addr, 270 enum map_type type, u64 addr,
271 struct map **mapp,
239 symbol_filter_t filter) 272 symbol_filter_t filter)
240{ 273{
241 struct map *map = map_groups__find(self, type, addr); 274 struct map *map = map_groups__find(self, type, addr);
242 275
243 if (map != NULL) 276 if (map != NULL) {
277 if (mapp != NULL)
278 *mapp = map;
244 return map__find_symbol(map, map->map_ip(map, addr), filter); 279 return map__find_symbol(map, map->map_ip(map, addr), filter);
280 }
245 281
246 return NULL; 282 return NULL;
247} 283}
248 284
285struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
286 enum map_type type,
287 const char *name,
288 struct map **mapp,
289 symbol_filter_t filter)
290{
291 struct rb_node *nd;
292
293 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
294 struct map *pos = rb_entry(nd, struct map, rb_node);
295 struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
296
297 if (sym == NULL)
298 continue;
299 if (mapp != NULL)
300 *mapp = pos;
301 return sym;
302 }
303
304 return NULL;
305}
306
307size_t __map_groups__fprintf_maps(struct map_groups *self,
308 enum map_type type, int verbose, FILE *fp)
309{
310 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
311 struct rb_node *nd;
312
313 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
314 struct map *pos = rb_entry(nd, struct map, rb_node);
315 printed += fprintf(fp, "Map:");
316 printed += map__fprintf(pos, fp);
317 if (verbose > 2) {
318 printed += dso__fprintf(pos->dso, type, fp);
319 printed += fprintf(fp, "--\n");
320 }
321 }
322
323 return printed;
324}
325
326size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp)
327{
328 size_t printed = 0, i;
329 for (i = 0; i < MAP__NR_TYPES; ++i)
330 printed += __map_groups__fprintf_maps(self, i, verbose, fp);
331 return printed;
332}
333
334static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
335 enum map_type type,
336 int verbose, FILE *fp)
337{
338 struct map *pos;
339 size_t printed = 0;
340
341 list_for_each_entry(pos, &self->removed_maps[type], node) {
342 printed += fprintf(fp, "Map:");
343 printed += map__fprintf(pos, fp);
344 if (verbose > 1) {
345 printed += dso__fprintf(pos->dso, type, fp);
346 printed += fprintf(fp, "--\n");
347 }
348 }
349 return printed;
350}
351
352static size_t map_groups__fprintf_removed_maps(struct map_groups *self,
353 int verbose, FILE *fp)
354{
355 size_t printed = 0, i;
356 for (i = 0; i < MAP__NR_TYPES; ++i)
357 printed += __map_groups__fprintf_removed_maps(self, i, verbose, fp);
358 return printed;
359}
360
361size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp)
362{
363 size_t printed = map_groups__fprintf_maps(self, verbose, fp);
364 printed += fprintf(fp, "Removed maps:\n");
365 return printed + map_groups__fprintf_removed_maps(self, verbose, fp);
366}
367
368int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
369 int verbose, FILE *fp)
370{
371 struct rb_root *root = &self->maps[map->type];
372 struct rb_node *next = rb_first(root);
373
374 while (next) {
375 struct map *pos = rb_entry(next, struct map, rb_node);
376 next = rb_next(&pos->rb_node);
377
378 if (!map__overlap(pos, map))
379 continue;
380
381 if (verbose >= 2) {
382 fputs("overlapping maps:\n", fp);
383 map__fprintf(map, fp);
384 map__fprintf(pos, fp);
385 }
386
387 rb_erase(&pos->rb_node, root);
388 /*
389 * We may have references to this map, for instance in some
390 * hist_entry instances, so just move them to a separate
391 * list.
392 */
393 list_add_tail(&pos->node, &self->removed_maps[map->type]);
394 /*
395 * Now check if we need to create new maps for areas not
396 * overlapped by the new map:
397 */
398 if (map->start > pos->start) {
399 struct map *before = map__clone(pos);
400
401 if (before == NULL)
402 return -ENOMEM;
403
404 before->end = map->start - 1;
405 map_groups__insert(self, before);
406 if (verbose >= 2)
407 map__fprintf(before, fp);
408 }
409
410 if (map->end < pos->end) {
411 struct map *after = map__clone(pos);
412
413 if (after == NULL)
414 return -ENOMEM;
415
416 after->start = map->end + 1;
417 map_groups__insert(self, after);
418 if (verbose >= 2)
419 map__fprintf(after, fp);
420 }
421 }
422
423 return 0;
424}
425
426/*
427 * XXX This should not really _copy_ te maps, but refcount them.
428 */
429int map_groups__clone(struct map_groups *self,
430 struct map_groups *parent, enum map_type type)
431{
432 struct rb_node *nd;
433 for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
434 struct map *map = rb_entry(nd, struct map, rb_node);
435 struct map *new = map__clone(map);
436 if (new == NULL)
437 return -ENOMEM;
438 map_groups__insert(self, new);
439 }
440 return 0;
441}
442
249static u64 map__reloc_map_ip(struct map *map, u64 ip) 443static u64 map__reloc_map_ip(struct map *map, u64 ip)
250{ 444{
251 return ip + (s64)map->pgoff; 445 return ip + (s64)map->pgoff;
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 6a703fa74707..2031278cc06a 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -97,11 +97,14 @@ struct map_groups {
97}; 97};
98 98
99size_t __map_groups__fprintf_maps(struct map_groups *self, 99size_t __map_groups__fprintf_maps(struct map_groups *self,
100 enum map_type type, FILE *fp); 100 enum map_type type, int verbose, FILE *fp);
101void maps__insert(struct rb_root *maps, struct map *map); 101void maps__insert(struct rb_root *maps, struct map *map);
102struct map *maps__find(struct rb_root *maps, u64 addr); 102struct map *maps__find(struct rb_root *maps, u64 addr);
103void map_groups__init(struct map_groups *self); 103void map_groups__init(struct map_groups *self);
104size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp); 104int map_groups__clone(struct map_groups *self,
105 struct map_groups *parent, enum map_type type);
106size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp);
107size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp);
105 108
106static inline void map_groups__insert(struct map_groups *self, struct map *map) 109static inline void map_groups__insert(struct map_groups *self, struct map *map)
107{ 110{
@@ -116,15 +119,33 @@ static inline struct map *map_groups__find(struct map_groups *self,
116 119
117struct symbol *map_groups__find_symbol(struct map_groups *self, 120struct symbol *map_groups__find_symbol(struct map_groups *self,
118 enum map_type type, u64 addr, 121 enum map_type type, u64 addr,
122 struct map **mapp,
119 symbol_filter_t filter); 123 symbol_filter_t filter);
120 124
121static inline struct symbol *map_groups__find_function(struct map_groups *self, 125struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
122 u64 addr, 126 enum map_type type,
123 symbol_filter_t filter) 127 const char *name,
128 struct map **mapp,
129 symbol_filter_t filter);
130
131static inline
132struct symbol *map_groups__find_function(struct map_groups *self, u64 addr,
133 struct map **mapp, symbol_filter_t filter)
124{ 134{
125 return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter); 135 return map_groups__find_symbol(self, MAP__FUNCTION, addr, mapp, filter);
126} 136}
127 137
138static inline
139struct symbol *map_groups__find_function_by_name(struct map_groups *self,
140 const char *name, struct map **mapp,
141 symbol_filter_t filter)
142{
143 return map_groups__find_symbol_by_name(self, MAP__FUNCTION, name, mapp, filter);
144}
145
146int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
147 int verbose, FILE *fp);
148
128struct map *map_groups__find_by_name(struct map_groups *self, 149struct map *map_groups__find_by_name(struct map_groups *self,
129 enum map_type type, const char *name); 150 enum map_type type, const char *name);
130int __map_groups__create_kernel_maps(struct map_groups *self, 151int __map_groups__create_kernel_maps(struct map_groups *self,
@@ -134,5 +155,6 @@ int map_groups__create_kernel_maps(struct map_groups *self,
134 struct map *vmlinux_maps[MAP__NR_TYPES]); 155 struct map *vmlinux_maps[MAP__NR_TYPES]);
135struct map *map_groups__new_module(struct map_groups *self, u64 start, 156struct map *map_groups__new_module(struct map_groups *self, u64 start,
136 const char *filename); 157 const char *filename);
158void map_groups__flush(struct map_groups *self);
137 159
138#endif /* __PERF_MAP_H */ 160#endif /* __PERF_MAP_H */
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index e99bcc8d1939..c93bc2a2d137 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -12,6 +12,72 @@
12#include "sort.h" 12#include "sort.h"
13#include "symbol.h" 13#include "symbol.h"
14 14
15struct ui_progress {
16 newtComponent form, scale;
17};
18
19struct ui_progress *ui_progress__new(const char *title, u64 total)
20{
21 struct ui_progress *self = malloc(sizeof(*self));
22
23 if (self != NULL) {
24 int cols;
25 newtGetScreenSize(&cols, NULL);
26 cols -= 4;
27 newtCenteredWindow(cols, 1, title);
28 self->form = newtForm(NULL, NULL, 0);
29 if (self->form == NULL)
30 goto out_free_self;
31 self->scale = newtScale(0, 0, cols, total);
32 if (self->scale == NULL)
33 goto out_free_form;
34 newtFormAddComponents(self->form, self->scale, NULL);
35 newtRefresh();
36 }
37
38 return self;
39
40out_free_form:
41 newtFormDestroy(self->form);
42out_free_self:
43 free(self);
44 return NULL;
45}
46
47void ui_progress__update(struct ui_progress *self, u64 curr)
48{
49 newtScaleSet(self->scale, curr);
50 newtRefresh();
51}
52
53void ui_progress__delete(struct ui_progress *self)
54{
55 newtFormDestroy(self->form);
56 newtPopWindow();
57 free(self);
58}
59
60static char browser__last_msg[1024];
61
62int browser__show_help(const char *format, va_list ap)
63{
64 int ret;
65 static int backlog;
66
67 ret = vsnprintf(browser__last_msg + backlog,
68 sizeof(browser__last_msg) - backlog, format, ap);
69 backlog += ret;
70
71 if (browser__last_msg[backlog - 1] == '\n') {
72 newtPopHelpLine();
73 newtPushHelpLine(browser__last_msg);
74 newtRefresh();
75 backlog = 0;
76 }
77
78 return ret;
79}
80
15static void newt_form__set_exit_keys(newtComponent self) 81static void newt_form__set_exit_keys(newtComponent self)
16{ 82{
17 newtFormAddHotKey(self, NEWT_KEY_ESCAPE); 83 newtFormAddHotKey(self, NEWT_KEY_ESCAPE);
@@ -228,60 +294,17 @@ static void hist_entry__append_callchain_browser(struct hist_entry *self,
228 } 294 }
229} 295}
230 296
231/*
232 * FIXME: get lib/string.c linked with perf somehow
233 */
234static char *skip_spaces(const char *str)
235{
236 while (isspace(*str))
237 ++str;
238 return (char *)str;
239}
240
241static char *strim(char *s)
242{
243 size_t size;
244 char *end;
245
246 s = skip_spaces(s);
247 size = strlen(s);
248 if (!size)
249 return s;
250
251 end = s + size - 1;
252 while (end >= s && isspace(*end))
253 end--;
254 *(end + 1) = '\0';
255
256 return s;
257}
258
259static size_t hist_entry__append_browser(struct hist_entry *self, 297static size_t hist_entry__append_browser(struct hist_entry *self,
260 newtComponent tree, u64 total) 298 newtComponent tree, u64 total)
261{ 299{
262 char bf[1024], *s; 300 char s[256];
263 FILE *fp; 301 size_t ret;
264 302
265 if (symbol_conf.exclude_other && !self->parent) 303 if (symbol_conf.exclude_other && !self->parent)
266 return 0; 304 return 0;
267 305
268 fp = fmemopen(bf, sizeof(bf), "w"); 306 ret = hist_entry__snprintf(self, s, sizeof(s), NULL,
269 if (fp == NULL) 307 false, 0, false, total);
270 return 0;
271
272 hist_entry__fprintf(self, NULL, false, 0, fp, total);
273 fclose(fp);
274
275 /*
276 * FIXME: We shouldn't need to trim, as the printing routines shouldn't
277 * add spaces it in the first place, the stdio output routines should
278 * call a __snprintf method instead of the current __print (that
279 * actually is a __fprintf) one, but get the raw string and _then_ add
280 * the newline, as this is a detail of stdio printing, not needed in
281 * other UIs, e.g. newt.
282 */
283 s = strim(bf);
284
285 if (symbol_conf.use_callchain) { 308 if (symbol_conf.use_callchain) {
286 int indexes[2]; 309 int indexes[2];
287 310
@@ -291,10 +314,11 @@ static size_t hist_entry__append_browser(struct hist_entry *self,
291 } else 314 } else
292 newtListboxAppendEntry(tree, s, &self->ms); 315 newtListboxAppendEntry(tree, s, &self->ms);
293 316
294 return strlen(s); 317 return ret;
295} 318}
296 319
297static void map_symbol__annotate_browser(const struct map_symbol *self) 320static void map_symbol__annotate_browser(const struct map_symbol *self,
321 const char *input_name)
298{ 322{
299 FILE *fp; 323 FILE *fp;
300 int cols, rows; 324 int cols, rows;
@@ -308,8 +332,8 @@ static void map_symbol__annotate_browser(const struct map_symbol *self)
308 if (self->sym == NULL) 332 if (self->sym == NULL)
309 return; 333 return;
310 334
311 if (asprintf(&str, "perf annotate -d \"%s\" %s 2>&1 | expand", 335 if (asprintf(&str, "perf annotate -i \"%s\" -d \"%s\" %s 2>&1 | expand",
312 self->map->dso->name, self->sym->name) < 0) 336 input_name, self->map->dso->name, self->sym->name) < 0)
313 return; 337 return;
314 338
315 fp = popen(str, "r"); 339 fp = popen(str, "r");
@@ -358,90 +382,121 @@ static const void *newt__symbol_tree_get_current(newtComponent self)
358 return newtListboxGetCurrent(self); 382 return newtListboxGetCurrent(self);
359} 383}
360 384
361static void perf_session__selection(newtComponent self, void *data) 385static void hist_browser__selection(newtComponent self, void *data)
362{ 386{
363 const struct map_symbol **symbol_ptr = data; 387 const struct map_symbol **symbol_ptr = data;
364 *symbol_ptr = newt__symbol_tree_get_current(self); 388 *symbol_ptr = newt__symbol_tree_get_current(self);
365} 389}
366 390
367void perf_session__browse_hists(struct rb_root *hists, u64 session_total, 391struct hist_browser {
368 const char *helpline) 392 newtComponent form, tree;
369{
370 struct sort_entry *se;
371 struct rb_node *nd;
372 char seq[] = ".";
373 unsigned int width;
374 char *col_width = symbol_conf.col_width_list_str;
375 int rows, cols, idx;
376 int max_len = 0;
377 char str[1024];
378 newtComponent form, tree;
379 struct newtExitStruct es;
380 const struct map_symbol *selection; 393 const struct map_symbol *selection;
394};
381 395
382 snprintf(str, sizeof(str), "Samples: %Ld", session_total); 396static struct hist_browser *hist_browser__new(void)
383 newtDrawRootText(0, 0, str); 397{
384 newtPushHelpLine(helpline); 398 struct hist_browser *self = malloc(sizeof(*self));
385
386 newtGetScreenSize(&cols, &rows);
387 399
388 if (symbol_conf.use_callchain) 400 if (self != NULL) {
389 tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq, 401 char seq[] = ".";
390 NEWT_FLAG_SCROLL); 402 int rows;
391 else
392 tree = newtListbox(0, 0, rows - 5, (NEWT_FLAG_SCROLL |
393 NEWT_FLAG_RETURNEXIT));
394 403
395 newtComponentAddCallback(tree, perf_session__selection, &selection); 404 newtGetScreenSize(NULL, &rows);
396 405
397 list_for_each_entry(se, &hist_entry__sort_list, list) { 406 if (symbol_conf.use_callchain)
398 if (se->elide) 407 self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
399 continue; 408 NEWT_FLAG_SCROLL);
400 width = strlen(se->header); 409 else
401 if (se->width) { 410 self->tree = newtListbox(0, 0, rows - 5,
402 if (symbol_conf.col_width_list_str) { 411 (NEWT_FLAG_SCROLL |
403 if (col_width) { 412 NEWT_FLAG_RETURNEXIT));
404 *se->width = atoi(col_width); 413 newtComponentAddCallback(self->tree, hist_browser__selection,
405 col_width = strchr(col_width, ','); 414 &self->selection);
406 if (col_width)
407 ++col_width;
408 }
409 }
410 *se->width = max(*se->width, width);
411 }
412 } 415 }
413 416
417 return self;
418}
419
420static void hist_browser__delete(struct hist_browser *self)
421{
422 newtFormDestroy(self->form);
423 newtPopWindow();
424 free(self);
425}
426
427static int hist_browser__populate(struct hist_browser *self, struct rb_root *hists,
428 u64 nr_hists, u64 session_total)
429{
430 int max_len = 0, idx, cols, rows;
431 struct ui_progress *progress;
432 struct rb_node *nd;
433 u64 curr_hist = 0;
434
435 progress = ui_progress__new("Adding entries to the browser...", nr_hists);
436 if (progress == NULL)
437 return -1;
438
414 idx = 0; 439 idx = 0;
415 for (nd = rb_first(hists); nd; nd = rb_next(nd)) { 440 for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
416 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 441 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
417 int len = hist_entry__append_browser(h, tree, session_total); 442 int len = hist_entry__append_browser(h, self->tree, session_total);
418 if (len > max_len) 443 if (len > max_len)
419 max_len = len; 444 max_len = len;
420 if (symbol_conf.use_callchain) 445 if (symbol_conf.use_callchain)
421 hist_entry__append_callchain_browser(h, tree, session_total, idx++); 446 hist_entry__append_callchain_browser(h, self->tree,
447 session_total, idx++);
448 ++curr_hist;
449 if (curr_hist % 5)
450 ui_progress__update(progress, curr_hist);
422 } 451 }
423 452
453 ui_progress__delete(progress);
454
455 newtGetScreenSize(&cols, &rows);
456
424 if (max_len > cols) 457 if (max_len > cols)
425 max_len = cols - 3; 458 max_len = cols - 3;
426 459
427 if (!symbol_conf.use_callchain) 460 if (!symbol_conf.use_callchain)
428 newtListboxSetWidth(tree, max_len); 461 newtListboxSetWidth(self->tree, max_len);
429 462
430 newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0), 463 newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0),
431 rows - 5, "Report"); 464 rows - 5, "Report");
432 form = newt_form__new(); 465 self->form = newt_form__new();
433 newtFormAddHotKey(form, 'A'); 466 newtFormAddHotKey(self->form, 'A');
434 newtFormAddHotKey(form, 'a'); 467 newtFormAddHotKey(self->form, 'a');
435 newtFormAddHotKey(form, NEWT_KEY_RIGHT); 468 newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
436 newtFormAddComponents(form, tree, NULL); 469 newtFormAddComponents(self->form, self->tree, NULL);
437 selection = newt__symbol_tree_get_current(tree); 470 self->selection = newt__symbol_tree_get_current(self->tree);
471
472 return 0;
473}
474
475int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
476 u64 session_total, const char *helpline,
477 const char *input_name)
478{
479 struct newtExitStruct es;
480 char str[1024];
481 int err = -1;
482 struct hist_browser *browser = hist_browser__new();
483
484 if (browser == NULL)
485 return -1;
486
487 snprintf(str, sizeof(str), "Samples: %Ld", session_total);
488 newtDrawRootText(0, 0, str);
489 newtPushHelpLine(helpline);
490
491 if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0)
492 goto out;
438 493
439 while (1) { 494 while (1) {
440 char annotate[512]; 495 char annotate[512];
441 const char *options[2]; 496 const char *options[2];
442 int nr_options = 0, choice = 0; 497 int nr_options = 0, choice = 0;
443 498
444 newtFormRun(form, &es); 499 newtFormRun(browser->form, &es);
445 if (es.reason == NEWT_EXIT_HOTKEY) { 500 if (es.reason == NEWT_EXIT_HOTKEY) {
446 if (toupper(es.u.key) == 'A') 501 if (toupper(es.u.key) == 'A')
447 goto do_annotate; 502 goto do_annotate;
@@ -455,9 +510,9 @@ void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
455 } 510 }
456 } 511 }
457 512
458 if (selection->sym != NULL) { 513 if (browser->selection->sym != NULL) {
459 snprintf(annotate, sizeof(annotate), 514 snprintf(annotate, sizeof(annotate),
460 "Annotate %s", selection->sym->name); 515 "Annotate %s", browser->selection->sym->name);
461 options[nr_options++] = annotate; 516 options[nr_options++] = annotate;
462 } 517 }
463 518
@@ -466,41 +521,22 @@ void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
466 if (choice == nr_options - 1) 521 if (choice == nr_options - 1)
467 break; 522 break;
468do_annotate: 523do_annotate:
469 if (selection->sym != NULL && choice >= 0) { 524 if (browser->selection->sym != NULL && choice >= 0) {
470 if (selection->map->dso->origin == DSO__ORIG_KERNEL) { 525 if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
471 newtPopHelpLine(); 526 newtPopHelpLine();
472 newtPushHelpLine("No vmlinux file found, can't " 527 newtPushHelpLine("No vmlinux file found, can't "
473 "annotate with just a " 528 "annotate with just a "
474 "kallsyms file"); 529 "kallsyms file");
475 continue; 530 continue;
476 } 531 }
477 map_symbol__annotate_browser(selection); 532 map_symbol__annotate_browser(browser->selection,
533 input_name);
478 } 534 }
479 } 535 }
480 536 err = 0;
481 newtFormDestroy(form); 537out:
482 newtPopWindow(); 538 hist_browser__delete(browser);
483} 539 return err;
484
485static char browser__last_msg[1024];
486
487int browser__show_help(const char *format, va_list ap)
488{
489 int ret;
490 static int backlog;
491
492 ret = vsnprintf(browser__last_msg + backlog,
493 sizeof(browser__last_msg) - backlog, format, ap);
494 backlog += ret;
495
496 if (browser__last_msg[backlog - 1] == '\n') {
497 newtPopHelpLine();
498 newtPushHelpLine(browser__last_msg);
499 newtRefresh();
500 backlog = 0;
501 }
502
503 return ret;
504} 540}
505 541
506void setup_browser(void) 542void setup_browser(void)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 76b4ac689df9..ddf288fca3eb 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -52,11 +52,6 @@ out_close:
52 return -1; 52 return -1;
53} 53}
54 54
55static inline int perf_session__create_kernel_maps(struct perf_session *self)
56{
57 return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
58}
59
60struct perf_session *perf_session__new(const char *filename, int mode, bool force) 55struct perf_session *perf_session__new(const char *filename, int mode, bool force)
61{ 56{
62 size_t len = filename ? strlen(filename) + 1 : 0; 57 size_t len = filename ? strlen(filename) + 1 : 0;
@@ -123,16 +118,11 @@ struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
123 struct symbol **parent) 118 struct symbol **parent)
124{ 119{
125 u8 cpumode = PERF_RECORD_MISC_USER; 120 u8 cpumode = PERF_RECORD_MISC_USER;
126 struct map_symbol *syms = NULL;
127 unsigned int i; 121 unsigned int i;
122 struct map_symbol *syms = calloc(chain->nr, sizeof(*syms));
128 123
129 if (symbol_conf.use_callchain) { 124 if (!syms)
130 syms = calloc(chain->nr, sizeof(*syms)); 125 return NULL;
131 if (!syms) {
132 fprintf(stderr, "Can't allocate memory for symbols\n");
133 exit(-1);
134 }
135 }
136 126
137 for (i = 0; i < chain->nr; i++) { 127 for (i = 0; i < chain->nr; i++) {
138 u64 ip = chain->ips[i]; 128 u64 ip = chain->ips[i];
@@ -397,6 +387,10 @@ int __perf_session__process_events(struct perf_session *self,
397 event_t *event; 387 event_t *event;
398 uint32_t size; 388 uint32_t size;
399 char *buf; 389 char *buf;
390 struct ui_progress *progress = ui_progress__new("Processing events...",
391 self->size);
392 if (progress == NULL)
393 return -1;
400 394
401 perf_event_ops__fill_defaults(ops); 395 perf_event_ops__fill_defaults(ops);
402 396
@@ -425,6 +419,7 @@ remap:
425 419
426more: 420more:
427 event = (event_t *)(buf + head); 421 event = (event_t *)(buf + head);
422 ui_progress__update(progress, offset);
428 423
429 if (self->header.needs_swap) 424 if (self->header.needs_swap)
430 perf_event_header__bswap(&event->header); 425 perf_event_header__bswap(&event->header);
@@ -475,6 +470,7 @@ more:
475done: 470done:
476 err = 0; 471 err = 0;
477out_err: 472out_err:
473 ui_progress__delete(progress);
478 return err; 474 return err;
479} 475}
480 476
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 631f8157fc17..27f4c2dc715b 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -80,6 +80,11 @@ static inline int __perf_session__create_kernel_maps(struct perf_session *self,
80 self->vmlinux_maps, kernel); 80 self->vmlinux_maps, kernel);
81} 81}
82 82
83static inline int perf_session__create_kernel_maps(struct perf_session *self)
84{
85 return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
86}
87
83static inline struct map * 88static inline struct map *
84 perf_session__new_module_map(struct perf_session *self, 89 perf_session__new_module_map(struct perf_session *self,
85 u64 start, const char *filename) 90 u64 start, const char *filename)
@@ -88,11 +93,17 @@ static inline struct map *
88} 93}
89 94
90#ifdef NO_NEWT_SUPPORT 95#ifdef NO_NEWT_SUPPORT
91static inline void perf_session__browse_hists(struct rb_root *hists __used, 96static inline int perf_session__browse_hists(struct rb_root *hists __used,
97 u64 nr_hists __used,
92 u64 session_total __used, 98 u64 session_total __used,
93 const char *helpline __used) {} 99 const char *helpline __used,
100 const char *input_name __used)
101{
102 return 0;
103}
94#else 104#else
95void perf_session__browse_hists(struct rb_root *hists, u64 session_total, 105int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
96 const char *helpline); 106 u64 session_total, const char *helpline,
107 const char *input_name);
97#endif 108#endif
98#endif /* __PERF_SESSION_H */ 109#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9b80c13cae46..9d24d4b2c8fb 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -18,10 +18,21 @@ char * field_sep;
18 18
19LIST_HEAD(hist_entry__sort_list); 19LIST_HEAD(hist_entry__sort_list);
20 20
21static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
22 size_t size, unsigned int width);
23static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
24 size_t size, unsigned int width);
25static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
26 size_t size, unsigned int width);
27static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
28 size_t size, unsigned int width);
29static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
30 size_t size, unsigned int width);
31
21struct sort_entry sort_thread = { 32struct sort_entry sort_thread = {
22 .header = "Command: Pid", 33 .header = "Command: Pid",
23 .cmp = sort__thread_cmp, 34 .cmp = sort__thread_cmp,
24 .print = sort__thread_print, 35 .snprintf = hist_entry__thread_snprintf,
25 .width = &threads__col_width, 36 .width = &threads__col_width,
26}; 37};
27 38
@@ -29,27 +40,27 @@ struct sort_entry sort_comm = {
29 .header = "Command", 40 .header = "Command",
30 .cmp = sort__comm_cmp, 41 .cmp = sort__comm_cmp,
31 .collapse = sort__comm_collapse, 42 .collapse = sort__comm_collapse,
32 .print = sort__comm_print, 43 .snprintf = hist_entry__comm_snprintf,
33 .width = &comms__col_width, 44 .width = &comms__col_width,
34}; 45};
35 46
36struct sort_entry sort_dso = { 47struct sort_entry sort_dso = {
37 .header = "Shared Object", 48 .header = "Shared Object",
38 .cmp = sort__dso_cmp, 49 .cmp = sort__dso_cmp,
39 .print = sort__dso_print, 50 .snprintf = hist_entry__dso_snprintf,
40 .width = &dsos__col_width, 51 .width = &dsos__col_width,
41}; 52};
42 53
43struct sort_entry sort_sym = { 54struct sort_entry sort_sym = {
44 .header = "Symbol", 55 .header = "Symbol",
45 .cmp = sort__sym_cmp, 56 .cmp = sort__sym_cmp,
46 .print = sort__sym_print, 57 .snprintf = hist_entry__sym_snprintf,
47}; 58};
48 59
49struct sort_entry sort_parent = { 60struct sort_entry sort_parent = {
50 .header = "Parent symbol", 61 .header = "Parent symbol",
51 .cmp = sort__parent_cmp, 62 .cmp = sort__parent_cmp,
52 .print = sort__parent_print, 63 .snprintf = hist_entry__parent_snprintf,
53 .width = &parent_symbol__col_width, 64 .width = &parent_symbol__col_width,
54}; 65};
55 66
@@ -85,45 +96,38 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
85 return right->thread->pid - left->thread->pid; 96 return right->thread->pid - left->thread->pid;
86} 97}
87 98
88int repsep_fprintf(FILE *fp, const char *fmt, ...) 99static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
89{ 100{
90 int n; 101 int n;
91 va_list ap; 102 va_list ap;
92 103
93 va_start(ap, fmt); 104 va_start(ap, fmt);
94 if (!field_sep) 105 n = vsnprintf(bf, size, fmt, ap);
95 n = vfprintf(fp, fmt, ap); 106 if (field_sep && n > 0) {
96 else { 107 char *sep = bf;
97 char *bf = NULL; 108
98 n = vasprintf(&bf, fmt, ap); 109 while (1) {
99 if (n > 0) { 110 sep = strchr(sep, *field_sep);
100 char *sep = bf; 111 if (sep == NULL)
101 112 break;
102 while (1) { 113 *sep = '.';
103 sep = strchr(sep, *field_sep);
104 if (sep == NULL)
105 break;
106 *sep = '.';
107 }
108 } 114 }
109 fputs(bf, fp);
110 free(bf);
111 } 115 }
112 va_end(ap); 116 va_end(ap);
113 return n; 117 return n;
114} 118}
115 119
116size_t 120static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
117sort__thread_print(FILE *fp, struct hist_entry *self, unsigned int width) 121 size_t size, unsigned int width)
118{ 122{
119 return repsep_fprintf(fp, "%*s:%5d", width - 6, 123 return repsep_snprintf(bf, size, "%*s:%5d", width,
120 self->thread->comm ?: "", self->thread->pid); 124 self->thread->comm ?: "", self->thread->pid);
121} 125}
122 126
123size_t 127static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
124sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width) 128 size_t size, unsigned int width)
125{ 129{
126 return repsep_fprintf(fp, "%*s", width, self->thread->comm); 130 return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
127} 131}
128 132
129/* --sort dso */ 133/* --sort dso */
@@ -149,16 +153,16 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
149 return strcmp(dso_name_l, dso_name_r); 153 return strcmp(dso_name_l, dso_name_r);
150} 154}
151 155
152size_t 156static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
153sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width) 157 size_t size, unsigned int width)
154{ 158{
155 if (self->ms.map && self->ms.map->dso) { 159 if (self->ms.map && self->ms.map->dso) {
156 const char *dso_name = !verbose ? self->ms.map->dso->short_name : 160 const char *dso_name = !verbose ? self->ms.map->dso->short_name :
157 self->ms.map->dso->long_name; 161 self->ms.map->dso->long_name;
158 return repsep_fprintf(fp, "%-*s", width, dso_name); 162 return repsep_snprintf(bf, size, "%-*s", width, dso_name);
159 } 163 }
160 164
161 return repsep_fprintf(fp, "%*llx", width, (u64)self->ip); 165 return repsep_snprintf(bf, size, "%*Lx", width, self->ip);
162} 166}
163 167
164/* --sort symbol */ 168/* --sort symbol */
@@ -177,22 +181,22 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
177 return (int64_t)(ip_r - ip_l); 181 return (int64_t)(ip_r - ip_l);
178} 182}
179 183
180 184static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
181size_t 185 size_t size, unsigned int width __used)
182sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used)
183{ 186{
184 size_t ret = 0; 187 size_t ret = 0;
185 188
186 if (verbose) { 189 if (verbose) {
187 char o = self->ms.map ? dso__symtab_origin(self->ms.map->dso) : '!'; 190 char o = self->ms.map ? dso__symtab_origin(self->ms.map->dso) : '!';
188 ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip, o); 191 ret += repsep_snprintf(bf, size, "%#018llx %c ", self->ip, o);
189 } 192 }
190 193
191 ret += repsep_fprintf(fp, "[%c] ", self->level); 194 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level);
192 if (self->ms.sym) 195 if (self->ms.sym)
193 ret += repsep_fprintf(fp, "%s", self->ms.sym->name); 196 ret += repsep_snprintf(bf + ret, size - ret, "%s",
197 self->ms.sym->name);
194 else 198 else
195 ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip); 199 ret += repsep_snprintf(bf + ret, size - ret, "%#016llx", self->ip);
196 200
197 return ret; 201 return ret;
198} 202}
@@ -231,10 +235,10 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
231 return strcmp(sym_l->name, sym_r->name); 235 return strcmp(sym_l->name, sym_r->name);
232} 236}
233 237
234size_t 238static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
235sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width) 239 size_t size, unsigned int width)
236{ 240{
237 return repsep_fprintf(fp, "%-*s", width, 241 return repsep_snprintf(bf, size, "%-*s", width,
238 self->parent ? self->parent->name : "[other]"); 242 self->parent ? self->parent->name : "[other]");
239} 243}
240 244
@@ -260,9 +264,8 @@ int sort_dimension__add(const char *tok)
260 char err[BUFSIZ]; 264 char err[BUFSIZ];
261 265
262 regerror(ret, &parent_regex, err, sizeof(err)); 266 regerror(ret, &parent_regex, err, sizeof(err));
263 fprintf(stderr, "Invalid regex: %s\n%s", 267 pr_err("Invalid regex: %s\n%s", parent_pattern, err);
264 parent_pattern, err); 268 return -EINVAL;
265 exit(-1);
266 } 269 }
267 sort__has_parent = 1; 270 sort__has_parent = 1;
268 } 271 }
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 598568696f97..5bf2b744e7b2 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -49,12 +49,12 @@ struct hist_entry {
49 u64 ip; 49 u64 ip;
50 char level; 50 char level;
51 struct symbol *parent; 51 struct symbol *parent;
52 struct callchain_node callchain;
53 union { 52 union {
54 unsigned long position; 53 unsigned long position;
55 struct hist_entry *pair; 54 struct hist_entry *pair;
56 struct rb_root sorted_chain; 55 struct rb_root sorted_chain;
57 }; 56 };
57 struct callchain_node callchain[0];
58}; 58};
59 59
60enum sort_type { 60enum sort_type {
@@ -76,7 +76,8 @@ struct sort_entry {
76 76
77 int64_t (*cmp)(struct hist_entry *, struct hist_entry *); 77 int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
78 int64_t (*collapse)(struct hist_entry *, struct hist_entry *); 78 int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
79 size_t (*print)(FILE *fp, struct hist_entry *, unsigned int width); 79 int (*snprintf)(struct hist_entry *self, char *bf, size_t size,
80 unsigned int width);
80 unsigned int *width; 81 unsigned int *width;
81 bool elide; 82 bool elide;
82}; 83};
@@ -86,7 +87,6 @@ extern struct list_head hist_entry__sort_list;
86 87
87void setup_sorting(const char * const usagestr[], const struct option *opts); 88void setup_sorting(const char * const usagestr[], const struct option *opts);
88 89
89extern int repsep_fprintf(FILE *fp, const char *fmt, ...);
90extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int); 90extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int);
91extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int); 91extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int);
92extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int); 92extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int);
diff --git a/tools/perf/util/string.h b/tools/perf/util/string.h
deleted file mode 100644
index 700582416664..000000000000
--- a/tools/perf/util/string.h
+++ /dev/null
@@ -1,16 +0,0 @@
1#ifndef __PERF_STRING_H_
2#define __PERF_STRING_H_
3
4#include <stdbool.h>
5#include "types.h"
6
7s64 perf_atoll(const char *str);
8char **argv_split(const char *str, int *argcp);
9void argv_free(char **argv);
10bool strglobmatch(const char *str, const char *pat);
11bool strlazymatch(const char *str, const char *pat);
12
13#define _STR(x) #x
14#define STR(x) _STR(x)
15
16#endif /* __PERF_STRING_H */
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 9bbe27d75306..1f7ecd47f499 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -38,15 +38,6 @@ failure:
38 return ret; 38 return ret;
39} 39}
40 40
41void map_groups__init(struct map_groups *self)
42{
43 int i;
44 for (i = 0; i < MAP__NR_TYPES; ++i) {
45 self->maps[i] = RB_ROOT;
46 INIT_LIST_HEAD(&self->removed_maps[i]);
47 }
48}
49
50static struct thread *thread__new(pid_t pid) 41static struct thread *thread__new(pid_t pid)
51{ 42{
52 struct thread *self = zalloc(sizeof(*self)); 43 struct thread *self = zalloc(sizeof(*self));
@@ -62,28 +53,6 @@ static struct thread *thread__new(pid_t pid)
62 return self; 53 return self;
63} 54}
64 55
65static void map_groups__flush(struct map_groups *self)
66{
67 int type;
68
69 for (type = 0; type < MAP__NR_TYPES; type++) {
70 struct rb_root *root = &self->maps[type];
71 struct rb_node *next = rb_first(root);
72
73 while (next) {
74 struct map *pos = rb_entry(next, struct map, rb_node);
75 next = rb_next(&pos->rb_node);
76 rb_erase(&pos->rb_node, root);
77 /*
78 * We may have references to this map, for
79 * instance in some hist_entry instances, so
80 * just move them to a separate list.
81 */
82 list_add_tail(&pos->node, &self->removed_maps[pos->type]);
83 }
84 }
85}
86
87int thread__set_comm(struct thread *self, const char *comm) 56int thread__set_comm(struct thread *self, const char *comm)
88{ 57{
89 int err; 58 int err;
@@ -110,69 +79,10 @@ int thread__comm_len(struct thread *self)
110 return self->comm_len; 79 return self->comm_len;
111} 80}
112 81
113size_t __map_groups__fprintf_maps(struct map_groups *self,
114 enum map_type type, FILE *fp)
115{
116 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
117 struct rb_node *nd;
118
119 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
120 struct map *pos = rb_entry(nd, struct map, rb_node);
121 printed += fprintf(fp, "Map:");
122 printed += map__fprintf(pos, fp);
123 if (verbose > 2) {
124 printed += dso__fprintf(pos->dso, type, fp);
125 printed += fprintf(fp, "--\n");
126 }
127 }
128
129 return printed;
130}
131
132size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp)
133{
134 size_t printed = 0, i;
135 for (i = 0; i < MAP__NR_TYPES; ++i)
136 printed += __map_groups__fprintf_maps(self, i, fp);
137 return printed;
138}
139
140static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
141 enum map_type type, FILE *fp)
142{
143 struct map *pos;
144 size_t printed = 0;
145
146 list_for_each_entry(pos, &self->removed_maps[type], node) {
147 printed += fprintf(fp, "Map:");
148 printed += map__fprintf(pos, fp);
149 if (verbose > 1) {
150 printed += dso__fprintf(pos->dso, type, fp);
151 printed += fprintf(fp, "--\n");
152 }
153 }
154 return printed;
155}
156
157static size_t map_groups__fprintf_removed_maps(struct map_groups *self, FILE *fp)
158{
159 size_t printed = 0, i;
160 for (i = 0; i < MAP__NR_TYPES; ++i)
161 printed += __map_groups__fprintf_removed_maps(self, i, fp);
162 return printed;
163}
164
165static size_t map_groups__fprintf(struct map_groups *self, FILE *fp)
166{
167 size_t printed = map_groups__fprintf_maps(self, fp);
168 printed += fprintf(fp, "Removed maps:\n");
169 return printed + map_groups__fprintf_removed_maps(self, fp);
170}
171
172static size_t thread__fprintf(struct thread *self, FILE *fp) 82static size_t thread__fprintf(struct thread *self, FILE *fp)
173{ 83{
174 return fprintf(fp, "Thread %d %s\n", self->pid, self->comm) + 84 return fprintf(fp, "Thread %d %s\n", self->pid, self->comm) +
175 map_groups__fprintf(&self->mg, fp); 85 map_groups__fprintf(&self->mg, verbose, fp);
176} 86}
177 87
178struct thread *perf_session__findnew(struct perf_session *self, pid_t pid) 88struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
@@ -214,87 +124,12 @@ struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
214 return th; 124 return th;
215} 125}
216 126
217static int map_groups__fixup_overlappings(struct map_groups *self,
218 struct map *map)
219{
220 struct rb_root *root = &self->maps[map->type];
221 struct rb_node *next = rb_first(root);
222
223 while (next) {
224 struct map *pos = rb_entry(next, struct map, rb_node);
225 next = rb_next(&pos->rb_node);
226
227 if (!map__overlap(pos, map))
228 continue;
229
230 if (verbose >= 2) {
231 fputs("overlapping maps:\n", stderr);
232 map__fprintf(map, stderr);
233 map__fprintf(pos, stderr);
234 }
235
236 rb_erase(&pos->rb_node, root);
237 /*
238 * We may have references to this map, for instance in some
239 * hist_entry instances, so just move them to a separate
240 * list.
241 */
242 list_add_tail(&pos->node, &self->removed_maps[map->type]);
243 /*
244 * Now check if we need to create new maps for areas not
245 * overlapped by the new map:
246 */
247 if (map->start > pos->start) {
248 struct map *before = map__clone(pos);
249
250 if (before == NULL)
251 return -ENOMEM;
252
253 before->end = map->start - 1;
254 map_groups__insert(self, before);
255 if (verbose >= 2)
256 map__fprintf(before, stderr);
257 }
258
259 if (map->end < pos->end) {
260 struct map *after = map__clone(pos);
261
262 if (after == NULL)
263 return -ENOMEM;
264
265 after->start = map->end + 1;
266 map_groups__insert(self, after);
267 if (verbose >= 2)
268 map__fprintf(after, stderr);
269 }
270 }
271
272 return 0;
273}
274
275void thread__insert_map(struct thread *self, struct map *map) 127void thread__insert_map(struct thread *self, struct map *map)
276{ 128{
277 map_groups__fixup_overlappings(&self->mg, map); 129 map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
278 map_groups__insert(&self->mg, map); 130 map_groups__insert(&self->mg, map);
279} 131}
280 132
281/*
282 * XXX This should not really _copy_ te maps, but refcount them.
283 */
284static int map_groups__clone(struct map_groups *self,
285 struct map_groups *parent, enum map_type type)
286{
287 struct rb_node *nd;
288 for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
289 struct map *map = rb_entry(nd, struct map, rb_node);
290 struct map *new = map__clone(map);
291 if (new == NULL)
292 return -ENOMEM;
293 map_groups__insert(self, new);
294 }
295 return 0;
296}
297
298int thread__fork(struct thread *self, struct thread *parent) 133int thread__fork(struct thread *self, struct thread *parent)
299{ 134{
300 int i; 135 int i;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 52701087ce04..fbf45d1b26f7 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -42,12 +42,14 @@
42#define _ALL_SOURCE 1 42#define _ALL_SOURCE 1
43#define _GNU_SOURCE 1 43#define _GNU_SOURCE 1
44#define _BSD_SOURCE 1 44#define _BSD_SOURCE 1
45#define HAS_BOOL
45 46
46#include <unistd.h> 47#include <unistd.h>
47#include <stdio.h> 48#include <stdio.h>
48#include <sys/stat.h> 49#include <sys/stat.h>
49#include <sys/statfs.h> 50#include <sys/statfs.h>
50#include <fcntl.h> 51#include <fcntl.h>
52#include <stdbool.h>
51#include <stddef.h> 53#include <stddef.h>
52#include <stdlib.h> 54#include <stdlib.h>
53#include <stdarg.h> 55#include <stdarg.h>
@@ -78,6 +80,7 @@
78#include <pwd.h> 80#include <pwd.h>
79#include <inttypes.h> 81#include <inttypes.h>
80#include "../../../include/linux/magic.h" 82#include "../../../include/linux/magic.h"
83#include "types.h"
81 84
82 85
83#ifndef NO_ICONV 86#ifndef NO_ICONV
@@ -415,4 +418,13 @@ void git_qsort(void *base, size_t nmemb, size_t size,
415int mkdir_p(char *path, mode_t mode); 418int mkdir_p(char *path, mode_t mode);
416int copyfile(const char *from, const char *to); 419int copyfile(const char *from, const char *to);
417 420
421s64 perf_atoll(const char *str);
422char **argv_split(const char *str, int *argcp);
423void argv_free(char **argv);
424bool strglobmatch(const char *str, const char *pat);
425bool strlazymatch(const char *str, const char *pat);
426
427#define _STR(x) #x
428#define STR(x) _STR(x)
429
418#endif 430#endif