diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-04-03 12:16:42 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-04-03 12:16:42 -0400 |
commit | 70a7c1271e2bfca8ad2bf71f44c516ea2763b9ed (patch) | |
tree | eaac85de741bc558529eccaefc372ff1e90ff425 /tools/perf | |
parent | 40b91cd10f000b4c4934e48e2e5c0bec66def144 (diff) | |
parent | 533c46c31c0e82f19dbb087c77d85eaccd6fefdb (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/Makefile | 325 | ||||
-rw-r--r-- | tools/perf/bench/mem-memcpy.c | 1 | ||||
-rw-r--r-- | tools/perf/builtin-annotate.c | 1 | ||||
-rw-r--r-- | tools/perf/builtin-kmem.c | 9 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 4 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 23 | ||||
-rw-r--r-- | tools/perf/builtin-timechart.c | 1 | ||||
-rw-r--r-- | tools/perf/perf.c | 1 | ||||
-rwxr-xr-x | tools/perf/util/PERF-VERSION-GEN | 6 | ||||
-rw-r--r-- | tools/perf/util/color.c | 53 | ||||
-rw-r--r-- | tools/perf/util/color.h | 4 | ||||
-rw-r--r-- | tools/perf/util/debug.h | 16 | ||||
-rw-r--r-- | tools/perf/util/event.c | 9 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 66 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 9 | ||||
-rw-r--r-- | tools/perf/util/map.c | 196 | ||||
-rw-r--r-- | tools/perf/util/map.h | 34 | ||||
-rw-r--r-- | tools/perf/util/newt.c | 298 | ||||
-rw-r--r-- | tools/perf/util/session.c | 22 | ||||
-rw-r--r-- | tools/perf/util/session.h | 19 | ||||
-rw-r--r-- | tools/perf/util/sort.c | 93 | ||||
-rw-r--r-- | tools/perf/util/sort.h | 6 | ||||
-rw-r--r-- | tools/perf/util/string.h | 16 | ||||
-rw-r--r-- | tools/perf/util/thread.c | 169 | ||||
-rw-r--r-- | tools/perf/util/util.h | 12 |
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 @@ | |||
1 | ifeq ("$(origin O)", "command line") | ||
2 | OUTPUT := $(O)/ | ||
3 | endif | ||
4 | |||
1 | # The default target of this Makefile is... | 5 | # The default target of this Makefile is... |
2 | all:: | 6 | all:: |
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 | ||
156 | PERF-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 | ||
160 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') | 168 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') |
161 | uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not') | 169 | uname_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 | # |
313 | PROGRAMS += perf | 321 | PROGRAMS += $(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 | |||
320 | ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) | 328 | ALL_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 |
323 | OTHER_PROGRAMS = perf$X | 331 | OTHER_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. |
326 | ifndef SHELL_PATH | 334 | ifndef SHELL_PATH |
@@ -332,7 +340,7 @@ endif | |||
332 | 340 | ||
333 | export PERL_PATH | 341 | export PERL_PATH |
334 | 342 | ||
335 | LIB_FILE=libperf.a | 343 | LIB_FILE=$(OUTPUT)libperf.a |
336 | 344 | ||
337 | LIB_H += ../../include/linux/perf_event.h | 345 | LIB_H += ../../include/linux/perf_event.h |
338 | LIB_H += ../../include/linux/rbtree.h | 346 | LIB_H += ../../include/linux/rbtree.h |
@@ -377,7 +385,6 @@ LIB_H += util/header.h | |||
377 | LIB_H += util/help.h | 385 | LIB_H += util/help.h |
378 | LIB_H += util/session.h | 386 | LIB_H += util/session.h |
379 | LIB_H += util/strbuf.h | 387 | LIB_H += util/strbuf.h |
380 | LIB_H += util/string.h | ||
381 | LIB_H += util/strlist.h | 388 | LIB_H += util/strlist.h |
382 | LIB_H += util/svghelper.h | 389 | LIB_H += util/svghelper.h |
383 | LIB_H += util/run-command.h | 390 | LIB_H += util/run-command.h |
@@ -393,77 +400,77 @@ LIB_H += util/probe-finder.h | |||
393 | LIB_H += util/probe-event.h | 400 | LIB_H += util/probe-event.h |
394 | LIB_H += util/cpumap.h | 401 | LIB_H += util/cpumap.h |
395 | 402 | ||
396 | LIB_OBJS += util/abspath.o | 403 | LIB_OBJS += $(OUTPUT)util/abspath.o |
397 | LIB_OBJS += util/alias.o | 404 | LIB_OBJS += $(OUTPUT)util/alias.o |
398 | LIB_OBJS += util/build-id.o | 405 | LIB_OBJS += $(OUTPUT)util/build-id.o |
399 | LIB_OBJS += util/config.o | 406 | LIB_OBJS += $(OUTPUT)util/config.o |
400 | LIB_OBJS += util/ctype.o | 407 | LIB_OBJS += $(OUTPUT)util/ctype.o |
401 | LIB_OBJS += util/debugfs.o | 408 | LIB_OBJS += $(OUTPUT)util/debugfs.o |
402 | LIB_OBJS += util/environment.o | 409 | LIB_OBJS += $(OUTPUT)util/environment.o |
403 | LIB_OBJS += util/event.o | 410 | LIB_OBJS += $(OUTPUT)util/event.o |
404 | LIB_OBJS += util/exec_cmd.o | 411 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o |
405 | LIB_OBJS += util/help.o | 412 | LIB_OBJS += $(OUTPUT)util/help.o |
406 | LIB_OBJS += util/levenshtein.o | 413 | LIB_OBJS += $(OUTPUT)util/levenshtein.o |
407 | LIB_OBJS += util/parse-options.o | 414 | LIB_OBJS += $(OUTPUT)util/parse-options.o |
408 | LIB_OBJS += util/parse-events.o | 415 | LIB_OBJS += $(OUTPUT)util/parse-events.o |
409 | LIB_OBJS += util/path.o | 416 | LIB_OBJS += $(OUTPUT)util/path.o |
410 | LIB_OBJS += util/rbtree.o | 417 | LIB_OBJS += $(OUTPUT)util/rbtree.o |
411 | LIB_OBJS += util/bitmap.o | 418 | LIB_OBJS += $(OUTPUT)util/bitmap.o |
412 | LIB_OBJS += util/hweight.o | 419 | LIB_OBJS += $(OUTPUT)util/hweight.o |
413 | LIB_OBJS += util/find_next_bit.o | 420 | LIB_OBJS += $(OUTPUT)util/find_next_bit.o |
414 | LIB_OBJS += util/run-command.o | 421 | LIB_OBJS += $(OUTPUT)util/run-command.o |
415 | LIB_OBJS += util/quote.o | 422 | LIB_OBJS += $(OUTPUT)util/quote.o |
416 | LIB_OBJS += util/strbuf.o | 423 | LIB_OBJS += $(OUTPUT)util/strbuf.o |
417 | LIB_OBJS += util/string.o | 424 | LIB_OBJS += $(OUTPUT)util/string.o |
418 | LIB_OBJS += util/strlist.o | 425 | LIB_OBJS += $(OUTPUT)util/strlist.o |
419 | LIB_OBJS += util/usage.o | 426 | LIB_OBJS += $(OUTPUT)util/usage.o |
420 | LIB_OBJS += util/wrapper.o | 427 | LIB_OBJS += $(OUTPUT)util/wrapper.o |
421 | LIB_OBJS += util/sigchain.o | 428 | LIB_OBJS += $(OUTPUT)util/sigchain.o |
422 | LIB_OBJS += util/symbol.o | 429 | LIB_OBJS += $(OUTPUT)util/symbol.o |
423 | LIB_OBJS += util/color.o | 430 | LIB_OBJS += $(OUTPUT)util/color.o |
424 | LIB_OBJS += util/pager.o | 431 | LIB_OBJS += $(OUTPUT)util/pager.o |
425 | LIB_OBJS += util/header.o | 432 | LIB_OBJS += $(OUTPUT)util/header.o |
426 | LIB_OBJS += util/callchain.o | 433 | LIB_OBJS += $(OUTPUT)util/callchain.o |
427 | LIB_OBJS += util/values.o | 434 | LIB_OBJS += $(OUTPUT)util/values.o |
428 | LIB_OBJS += util/debug.o | 435 | LIB_OBJS += $(OUTPUT)util/debug.o |
429 | LIB_OBJS += util/map.o | 436 | LIB_OBJS += $(OUTPUT)util/map.o |
430 | LIB_OBJS += util/session.o | 437 | LIB_OBJS += $(OUTPUT)util/session.o |
431 | LIB_OBJS += util/thread.o | 438 | LIB_OBJS += $(OUTPUT)util/thread.o |
432 | LIB_OBJS += util/trace-event-parse.o | 439 | LIB_OBJS += $(OUTPUT)util/trace-event-parse.o |
433 | LIB_OBJS += util/trace-event-read.o | 440 | LIB_OBJS += $(OUTPUT)util/trace-event-read.o |
434 | LIB_OBJS += util/trace-event-info.o | 441 | LIB_OBJS += $(OUTPUT)util/trace-event-info.o |
435 | LIB_OBJS += util/trace-event-scripting.o | 442 | LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o |
436 | LIB_OBJS += util/svghelper.o | 443 | LIB_OBJS += $(OUTPUT)util/svghelper.o |
437 | LIB_OBJS += util/sort.o | 444 | LIB_OBJS += $(OUTPUT)util/sort.o |
438 | LIB_OBJS += util/hist.o | 445 | LIB_OBJS += $(OUTPUT)util/hist.o |
439 | LIB_OBJS += util/probe-event.o | 446 | LIB_OBJS += $(OUTPUT)util/probe-event.o |
440 | LIB_OBJS += util/util.o | 447 | LIB_OBJS += $(OUTPUT)util/util.o |
441 | LIB_OBJS += util/cpumap.o | 448 | LIB_OBJS += $(OUTPUT)util/cpumap.o |
442 | 449 | ||
443 | BUILTIN_OBJS += builtin-annotate.o | 450 | BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o |
444 | 451 | ||
445 | BUILTIN_OBJS += builtin-bench.o | 452 | BUILTIN_OBJS += $(OUTPUT)builtin-bench.o |
446 | 453 | ||
447 | # Benchmark modules | 454 | # Benchmark modules |
448 | BUILTIN_OBJS += bench/sched-messaging.o | 455 | BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o |
449 | BUILTIN_OBJS += bench/sched-pipe.o | 456 | BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o |
450 | BUILTIN_OBJS += bench/mem-memcpy.o | 457 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o |
451 | 458 | ||
452 | BUILTIN_OBJS += builtin-diff.o | 459 | BUILTIN_OBJS += $(OUTPUT)builtin-diff.o |
453 | BUILTIN_OBJS += builtin-help.o | 460 | BUILTIN_OBJS += $(OUTPUT)builtin-help.o |
454 | BUILTIN_OBJS += builtin-sched.o | 461 | BUILTIN_OBJS += $(OUTPUT)builtin-sched.o |
455 | BUILTIN_OBJS += builtin-buildid-list.o | 462 | BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o |
456 | BUILTIN_OBJS += builtin-buildid-cache.o | 463 | BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o |
457 | BUILTIN_OBJS += builtin-list.o | 464 | BUILTIN_OBJS += $(OUTPUT)builtin-list.o |
458 | BUILTIN_OBJS += builtin-record.o | 465 | BUILTIN_OBJS += $(OUTPUT)builtin-record.o |
459 | BUILTIN_OBJS += builtin-report.o | 466 | BUILTIN_OBJS += $(OUTPUT)builtin-report.o |
460 | BUILTIN_OBJS += builtin-stat.o | 467 | BUILTIN_OBJS += $(OUTPUT)builtin-stat.o |
461 | BUILTIN_OBJS += builtin-timechart.o | 468 | BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o |
462 | BUILTIN_OBJS += builtin-top.o | 469 | BUILTIN_OBJS += $(OUTPUT)builtin-top.o |
463 | BUILTIN_OBJS += builtin-trace.o | 470 | BUILTIN_OBJS += $(OUTPUT)builtin-trace.o |
464 | BUILTIN_OBJS += builtin-probe.o | 471 | BUILTIN_OBJS += $(OUTPUT)builtin-probe.o |
465 | BUILTIN_OBJS += builtin-kmem.o | 472 | BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o |
466 | BUILTIN_OBJS += builtin-lock.o | 473 | BUILTIN_OBJS += $(OUTPUT)builtin-lock.o |
467 | 474 | ||
468 | PERFLIBS = $(LIB_FILE) | 475 | PERFLIBS = $(LIB_FILE) |
469 | 476 | ||
@@ -494,6 +501,10 @@ ifeq ($(uname_S),Darwin) | |||
494 | PTHREAD_LIBS = | 501 | PTHREAD_LIBS = |
495 | endif | 502 | endif |
496 | 503 | ||
504 | ifneq ($(OUTPUT),) | ||
505 | BASIC_CFLAGS += -I$(OUTPUT) | ||
506 | endif | ||
507 | |||
497 | ifeq ($(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) | 508 | ifeq ($(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) |
498 | ifneq ($(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) | 509 | ifneq ($(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 | |||
512 | ifndef NO_DWARF | 523 | ifndef 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 |
516 | endif | 527 | endif |
517 | endif | 528 | endif |
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 |
522 | else | 533 | else |
523 | EXTLIBS += -lnewt | 534 | EXTLIBS += -lnewt |
524 | LIB_OBJS += util/newt.o | 535 | LIB_OBJS += $(OUTPUT)util/newt.o |
525 | endif | 536 | endif |
526 | 537 | ||
527 | ifndef NO_LIBPERL | 538 | ifndef 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 |
534 | else | 545 | else |
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 |
538 | endif | 549 | endif |
539 | 550 | ||
540 | ifndef NO_LIBPYTHON | 551 | ifndef NO_LIBPYTHON |
@@ -542,12 +553,12 @@ PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null` | |||
542 | PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null` | 553 | PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null` |
543 | endif | 554 | endif |
544 | 555 | ||
545 | ifneq ($(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) | 556 | ifneq ($(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 |
547 | else | 558 | else |
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 |
551 | endif | 562 | endif |
552 | 563 | ||
553 | ifdef NO_DEMANGLE | 564 | ifdef NO_DEMANGLE |
@@ -618,53 +629,53 @@ ifdef NO_C99_FORMAT | |||
618 | endif | 629 | endif |
619 | ifdef SNPRINTF_RETURNS_BOGUS | 630 | ifdef 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 |
622 | endif | 633 | endif |
623 | ifdef FREAD_READS_DIRECTORIES | 634 | ifdef 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 |
626 | endif | 637 | endif |
627 | ifdef NO_SYMLINK_HEAD | 638 | ifdef NO_SYMLINK_HEAD |
628 | BASIC_CFLAGS += -DNO_SYMLINK_HEAD | 639 | BASIC_CFLAGS += -DNO_SYMLINK_HEAD |
629 | endif | 640 | endif |
630 | ifdef NO_STRCASESTR | 641 | ifdef 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 |
633 | endif | 644 | endif |
634 | ifdef NO_STRTOUMAX | 645 | ifdef 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 |
637 | endif | 648 | endif |
638 | ifdef NO_STRTOULL | 649 | ifdef NO_STRTOULL |
639 | COMPAT_CFLAGS += -DNO_STRTOULL | 650 | COMPAT_CFLAGS += -DNO_STRTOULL |
640 | endif | 651 | endif |
641 | ifdef NO_SETENV | 652 | ifdef 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 |
644 | endif | 655 | endif |
645 | ifdef NO_MKDTEMP | 656 | ifdef 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 |
648 | endif | 659 | endif |
649 | ifdef NO_UNSETENV | 660 | ifdef 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 |
652 | endif | 663 | endif |
653 | ifdef NO_SYS_SELECT_H | 664 | ifdef NO_SYS_SELECT_H |
654 | BASIC_CFLAGS += -DNO_SYS_SELECT_H | 665 | BASIC_CFLAGS += -DNO_SYS_SELECT_H |
655 | endif | 666 | endif |
656 | ifdef NO_MMAP | 667 | ifdef 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 |
659 | else | 670 | else |
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 |
664 | endif | 675 | endif |
665 | ifdef NO_PREAD | 676 | ifdef 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 |
668 | endif | 679 | endif |
669 | ifdef NO_FAST_WORKING_DIRECTORY | 680 | ifdef NO_FAST_WORKING_DIRECTORY |
670 | BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY | 681 | BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY |
@@ -686,10 +697,10 @@ else | |||
686 | endif | 697 | endif |
687 | endif | 698 | endif |
688 | ifdef NO_INET_NTOP | 699 | ifdef NO_INET_NTOP |
689 | LIB_OBJS += compat/inet_ntop.o | 700 | LIB_OBJS += $(OUTPUT)compat/inet_ntop.o |
690 | endif | 701 | endif |
691 | ifdef NO_INET_PTON | 702 | ifdef NO_INET_PTON |
692 | LIB_OBJS += compat/inet_pton.o | 703 | LIB_OBJS += $(OUTPUT)compat/inet_pton.o |
693 | endif | 704 | endif |
694 | 705 | ||
695 | ifdef NO_ICONV | 706 | ifdef NO_ICONV |
@@ -706,15 +717,15 @@ endif | |||
706 | 717 | ||
707 | ifdef PPC_SHA1 | 718 | ifdef 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 |
710 | else | 721 | else |
711 | ifdef ARM_SHA1 | 722 | ifdef 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 |
714 | else | 725 | else |
715 | ifdef MOZILLA_SHA1 | 726 | ifdef 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 |
718 | else | 729 | else |
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 | |||
726 | endif | 737 | endif |
727 | ifdef NO_HSTRERROR | 738 | ifdef 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 |
730 | endif | 741 | endif |
731 | ifdef NO_MEMMEM | 742 | ifdef 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 |
734 | endif | 745 | endif |
735 | ifdef INTERNAL_QSORT | 746 | ifdef 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 |
738 | endif | 749 | endif |
739 | ifdef RUNTIME_PREFIX | 750 | ifdef RUNTIME_PREFIX |
740 | COMPAT_CFLAGS += -DRUNTIME_PREFIX | 751 | COMPAT_CFLAGS += -DRUNTIME_PREFIX |
@@ -814,7 +825,7 @@ export TAR INSTALL DESTDIR SHELL_PATH | |||
814 | 825 | ||
815 | SHELL = $(SHELL_PATH) | 826 | SHELL = $(SHELL_PATH) |
816 | 827 | ||
817 | all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS | 828 | all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) $(OUTPUT)PERF-BUILD-OPTIONS |
818 | ifneq (,$X) | 829 | ifneq (,$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';) |
820 | endif | 831 | endif |
@@ -826,39 +837,39 @@ please_set_SHELL_PATH_to_a_more_modern_shell: | |||
826 | 837 | ||
827 | shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell | 838 | shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell |
828 | 839 | ||
829 | strip: $(PROGRAMS) perf$X | 840 | strip: $(PROGRAMS) $(OUTPUT)perf$X |
830 | $(STRIP) $(STRIP_OPTS) $(PROGRAMS) perf$X | 841 | $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf$X |
831 | 842 | ||
832 | perf.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 | ||
837 | perf$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 | ||
841 | builtin-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 | ||
847 | builtin-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 | ||
859 | common-cmds.h: util/generate-cmdlist.sh command-list.txt | 870 | $(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt |
860 | 871 | ||
861 | common-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 | ||
875 | configure: configure.ac | 886 | configure: 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 |
883 | perf.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 | ||
895 | util/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 | ||
902 | builtin-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 | ||
905 | util/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 | ||
908 | util/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. |
913 | KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//` | 924 | KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//` |
914 | 925 | ||
915 | util/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 | ||
918 | util/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 | ||
921 | util/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 | ||
924 | util/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 | ||
927 | scripts/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 | ||
930 | util/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 | ||
933 | scripts/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 | ||
936 | perf-%$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: | |||
974 | TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\ | 985 | TRACK_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 | ||
977 | PERF-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". |
987 | PERF-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 | ||
1006 | export NO_SVN_TESTS | 1017 | export NO_SVN_TESTS |
1007 | 1018 | ||
1008 | check: common-cmds.h | 1019 | check: $(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 | ||
1040 | install: all | 1051 | install: 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)' |
1058 | ifneq (,$X) | 1069 | ifneq (,$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';) |
1060 | endif | 1071 | endif |
1061 | endif | 1072 | endif |
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 | ||
19 | bool use_browser; | 18 | bool 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 | ||
3 | GVF=PERF-VERSION-FILE | 3 | if [ $# -eq 1 ] ; then |
4 | OUTPUT=$1 | ||
5 | fi | ||
6 | |||
7 | GVF=${OUTPUT}PERF-VERSION-FILE | ||
4 | DEF_VER=v0.0.2.PERF | 8 | DEF_VER=v0.0.2.PERF |
5 | 9 | ||
6 | LF=' | 10 | LF=' |
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 | ||
169 | static 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 | |||
169 | static int __color_vfprintf(FILE *fp, const char *color, const char *fmt, | 194 | static 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 | ||
219 | int 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 | |||
194 | int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args) | 225 | int 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 | ||
230 | int 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 | ||
200 | int color_fprintf(FILE *fp, const char *color, const char *fmt, ...) | 242 | int 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 | |||
320 | int 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); | |||
32 | int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty); | 32 | int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty); |
33 | void color_parse(const char *value, const char *var, char *dst); | 33 | void color_parse(const char *value, const char *var, char *dst); |
34 | void color_parse_mem(const char *value, int len, const char *var, char *dst); | 34 | void color_parse_mem(const char *value, int len, const char *var, char *dst); |
35 | int color_vsnprintf(char *bf, size_t size, const char *color, | ||
36 | const char *fmt, va_list args); | ||
35 | int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args); | 37 | int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args); |
36 | int color_fprintf(FILE *fp, const char *color, const char *fmt, ...); | 38 | int color_fprintf(FILE *fp, const char *color, const char *fmt, ...); |
39 | int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...); | ||
37 | int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); | 40 | int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); |
38 | int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf); | 41 | int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf); |
42 | int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent); | ||
39 | int percent_color_fprintf(FILE *fp, const char *fmt, double percent); | 43 | int percent_color_fprintf(FILE *fp, const char *fmt, double percent); |
40 | const char *get_percent_color(double percent); | 44 | const 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; | |||
10 | int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); | 10 | int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); |
11 | void trace_event(event_t *event); | 11 | void trace_event(event_t *event); |
12 | 12 | ||
13 | struct ui_progress; | ||
14 | |||
13 | #ifdef NO_NEWT_SUPPORT | 15 | #ifdef NO_NEWT_SUPPORT |
14 | static inline int browser__show_help(const char *format __used, va_list ap __used) | 16 | static inline int browser__show_help(const char *format __used, va_list ap __used) |
15 | { | 17 | { |
16 | return 0; | 18 | return 0; |
17 | } | 19 | } |
20 | |||
21 | static inline struct ui_progress *ui_progress__new(const char *title __used, | ||
22 | u64 total __used) | ||
23 | { | ||
24 | return (struct ui_progress *)1; | ||
25 | } | ||
26 | |||
27 | static inline void ui_progress__update(struct ui_progress *self __used, | ||
28 | u64 curr __used) {} | ||
29 | |||
30 | static inline void ui_progress__delete(struct ui_progress *self __used) {} | ||
18 | #else | 31 | #else |
19 | int browser__show_help(const char *format, va_list ap); | 32 | int browser__show_help(const char *format, va_list ap); |
33 | struct ui_progress *ui_progress__new(const char *title, u64 total); | ||
34 | void ui_progress__update(struct ui_progress *self, u64 curr); | ||
35 | void 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 | ||
188 | void perf_session__output_resort(struct rb_root *hists, u64 total_samples) | 189 | u64 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 | ||
213 | static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) | 217 | static 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 | ||
455 | size_t hist_entry__fprintf(struct hist_entry *self, | 459 | int 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 | |||
546 | int 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 | ||
535 | static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, | 559 | static 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); |
19 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); | 19 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); |
20 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); | 20 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); |
21 | size_t hist_entry__fprintf(struct hist_entry *self, | 21 | int 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); |
26 | int 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); | ||
26 | void hist_entry__free(struct hist_entry *); | 31 | void hist_entry__free(struct hist_entry *); |
27 | 32 | ||
28 | void perf_session__output_resort(struct rb_root *hists, u64 total_samples); | 33 | u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples); |
29 | void perf_session__collapse_resort(struct rb_root *hists); | 34 | void perf_session__collapse_resort(struct rb_root *hists); |
30 | size_t perf_session__fprintf_hists(struct rb_root *hists, | 35 | size_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 | ||
238 | void 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 | |||
247 | void 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 | |||
237 | struct symbol *map_groups__find_symbol(struct map_groups *self, | 269 | struct 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 | ||
285 | struct 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 | |||
307 | size_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 | |||
326 | size_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 | |||
334 | static 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 | |||
352 | static 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 | |||
361 | size_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 | |||
368 | int 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 | */ | ||
429 | int 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 | |||
249 | static u64 map__reloc_map_ip(struct map *map, u64 ip) | 443 | static 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 | ||
99 | size_t __map_groups__fprintf_maps(struct map_groups *self, | 99 | size_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); |
101 | void maps__insert(struct rb_root *maps, struct map *map); | 101 | void maps__insert(struct rb_root *maps, struct map *map); |
102 | struct map *maps__find(struct rb_root *maps, u64 addr); | 102 | struct map *maps__find(struct rb_root *maps, u64 addr); |
103 | void map_groups__init(struct map_groups *self); | 103 | void map_groups__init(struct map_groups *self); |
104 | size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp); | 104 | int map_groups__clone(struct map_groups *self, |
105 | struct map_groups *parent, enum map_type type); | ||
106 | size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp); | ||
107 | size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp); | ||
105 | 108 | ||
106 | static inline void map_groups__insert(struct map_groups *self, struct map *map) | 109 | static 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 | ||
117 | struct symbol *map_groups__find_symbol(struct map_groups *self, | 120 | struct 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 | ||
121 | static inline struct symbol *map_groups__find_function(struct map_groups *self, | 125 | struct 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 | |||
131 | static inline | ||
132 | struct 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 | ||
138 | static inline | ||
139 | struct 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 | |||
146 | int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, | ||
147 | int verbose, FILE *fp); | ||
148 | |||
128 | struct map *map_groups__find_by_name(struct map_groups *self, | 149 | struct 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); |
130 | int __map_groups__create_kernel_maps(struct map_groups *self, | 151 | int __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]); |
135 | struct map *map_groups__new_module(struct map_groups *self, u64 start, | 156 | struct map *map_groups__new_module(struct map_groups *self, u64 start, |
136 | const char *filename); | 157 | const char *filename); |
158 | void 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 | ||
15 | struct ui_progress { | ||
16 | newtComponent form, scale; | ||
17 | }; | ||
18 | |||
19 | struct 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 | |||
40 | out_free_form: | ||
41 | newtFormDestroy(self->form); | ||
42 | out_free_self: | ||
43 | free(self); | ||
44 | return NULL; | ||
45 | } | ||
46 | |||
47 | void ui_progress__update(struct ui_progress *self, u64 curr) | ||
48 | { | ||
49 | newtScaleSet(self->scale, curr); | ||
50 | newtRefresh(); | ||
51 | } | ||
52 | |||
53 | void ui_progress__delete(struct ui_progress *self) | ||
54 | { | ||
55 | newtFormDestroy(self->form); | ||
56 | newtPopWindow(); | ||
57 | free(self); | ||
58 | } | ||
59 | |||
60 | static char browser__last_msg[1024]; | ||
61 | |||
62 | int 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 | |||
15 | static void newt_form__set_exit_keys(newtComponent self) | 81 | static 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 | */ | ||
234 | static char *skip_spaces(const char *str) | ||
235 | { | ||
236 | while (isspace(*str)) | ||
237 | ++str; | ||
238 | return (char *)str; | ||
239 | } | ||
240 | |||
241 | static 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 | |||
259 | static size_t hist_entry__append_browser(struct hist_entry *self, | 297 | static 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 | ||
297 | static void map_symbol__annotate_browser(const struct map_symbol *self) | 320 | static 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 | ||
361 | static void perf_session__selection(newtComponent self, void *data) | 385 | static 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 | ||
367 | void perf_session__browse_hists(struct rb_root *hists, u64 session_total, | 391 | struct 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); | 396 | static 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 | |||
420 | static void hist_browser__delete(struct hist_browser *self) | ||
421 | { | ||
422 | newtFormDestroy(self->form); | ||
423 | newtPopWindow(); | ||
424 | free(self); | ||
425 | } | ||
426 | |||
427 | static 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 | |||
475 | int 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; |
468 | do_annotate: | 523 | do_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); | 537 | out: |
482 | newtPopWindow(); | 538 | hist_browser__delete(browser); |
483 | } | 539 | return err; |
484 | |||
485 | static char browser__last_msg[1024]; | ||
486 | |||
487 | int 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 | ||
506 | void setup_browser(void) | 542 | void 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 | ||
55 | static 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 | |||
60 | struct perf_session *perf_session__new(const char *filename, int mode, bool force) | 55 | struct 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 | ||
426 | more: | 420 | more: |
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: | |||
475 | done: | 470 | done: |
476 | err = 0; | 471 | err = 0; |
477 | out_err: | 472 | out_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 | ||
83 | static 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 | |||
83 | static inline struct map * | 88 | static 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 |
91 | static inline void perf_session__browse_hists(struct rb_root *hists __used, | 96 | static 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 |
95 | void perf_session__browse_hists(struct rb_root *hists, u64 session_total, | 105 | int 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 | ||
19 | LIST_HEAD(hist_entry__sort_list); | 19 | LIST_HEAD(hist_entry__sort_list); |
20 | 20 | ||
21 | static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf, | ||
22 | size_t size, unsigned int width); | ||
23 | static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf, | ||
24 | size_t size, unsigned int width); | ||
25 | static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf, | ||
26 | size_t size, unsigned int width); | ||
27 | static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf, | ||
28 | size_t size, unsigned int width); | ||
29 | static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf, | ||
30 | size_t size, unsigned int width); | ||
31 | |||
21 | struct sort_entry sort_thread = { | 32 | struct 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 | ||
36 | struct sort_entry sort_dso = { | 47 | struct 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 | ||
43 | struct sort_entry sort_sym = { | 54 | struct 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 | ||
49 | struct sort_entry sort_parent = { | 60 | struct 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 | ||
88 | int repsep_fprintf(FILE *fp, const char *fmt, ...) | 99 | static 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 | ||
116 | size_t | 120 | static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf, |
117 | sort__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 | ||
123 | size_t | 127 | static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf, |
124 | sort__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 | ||
152 | size_t | 156 | static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf, |
153 | sort__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 | 184 | static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf, | |
181 | size_t | 185 | size_t size, unsigned int width __used) |
182 | sort__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 | ||
234 | size_t | 238 | static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf, |
235 | sort__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 | ||
60 | enum sort_type { | 60 | enum 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 | ||
87 | void setup_sorting(const char * const usagestr[], const struct option *opts); | 88 | void setup_sorting(const char * const usagestr[], const struct option *opts); |
88 | 89 | ||
89 | extern int repsep_fprintf(FILE *fp, const char *fmt, ...); | ||
90 | extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int); | 90 | extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int); |
91 | extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int); | 91 | extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int); |
92 | extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int); | 92 | extern 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 | |||
7 | s64 perf_atoll(const char *str); | ||
8 | char **argv_split(const char *str, int *argcp); | ||
9 | void argv_free(char **argv); | ||
10 | bool strglobmatch(const char *str, const char *pat); | ||
11 | bool 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 | ||
41 | void 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 | |||
50 | static struct thread *thread__new(pid_t pid) | 41 | static 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 | ||
65 | static 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 | |||
87 | int thread__set_comm(struct thread *self, const char *comm) | 56 | int 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 | ||
113 | size_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 | |||
132 | size_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 | |||
140 | static 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 | |||
157 | static 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 | |||
165 | static 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 | |||
172 | static size_t thread__fprintf(struct thread *self, FILE *fp) | 82 | static 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 | ||
178 | struct thread *perf_session__findnew(struct perf_session *self, pid_t pid) | 88 | struct 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 | ||
217 | static 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 | |||
275 | void thread__insert_map(struct thread *self, struct map *map) | 127 | void 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 | */ | ||
284 | static 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 | |||
298 | int thread__fork(struct thread *self, struct thread *parent) | 133 | int 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, | |||
415 | int mkdir_p(char *path, mode_t mode); | 418 | int mkdir_p(char *path, mode_t mode); |
416 | int copyfile(const char *from, const char *to); | 419 | int copyfile(const char *from, const char *to); |
417 | 420 | ||
421 | s64 perf_atoll(const char *str); | ||
422 | char **argv_split(const char *str, int *argcp); | ||
423 | void argv_free(char **argv); | ||
424 | bool strglobmatch(const char *str, const char *pat); | ||
425 | bool strlazymatch(const char *str, const char *pat); | ||
426 | |||
427 | #define _STR(x) #x | ||
428 | #define STR(x) _STR(x) | ||
429 | |||
418 | #endif | 430 | #endif |