Merge tag 'v3.4-rc2' into perf/core
authorIngo Molnar <mingo@kernel.org>
Fri, 13 Apr 2012 07:57:10 +0000 (09:57 +0200)
committerIngo Molnar <mingo@kernel.org>
Fri, 13 Apr 2012 07:57:10 +0000 (09:57 +0200)
Merge Linux 3.4-rc2: we were on v3.3, update the base.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
36 files changed:
Makefile
tools/Makefile [new file with mode: 0644]
tools/perf/.gitignore
tools/perf/Documentation/perfconfig.example
tools/perf/Makefile
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-stat.c
tools/perf/builtin-top.c
tools/perf/ui/browser.c [moved from tools/perf/util/ui/browser.c with 98% similarity]
tools/perf/ui/browser.h [moved from tools/perf/util/ui/browser.h with 95% similarity]
tools/perf/ui/browsers/annotate.c [moved from tools/perf/util/ui/browsers/annotate.c with 54% similarity]
tools/perf/ui/browsers/hists.c [moved from tools/perf/util/ui/browsers/hists.c with 98% similarity]
tools/perf/ui/browsers/map.c [moved from tools/perf/util/ui/browsers/map.c with 97% similarity]
tools/perf/ui/browsers/map.h [moved from tools/perf/util/ui/browsers/map.h with 100% similarity]
tools/perf/ui/gtk/browser.c [moved from tools/perf/util/gtk/browser.c with 100% similarity]
tools/perf/ui/gtk/gtk.h [moved from tools/perf/util/gtk/gtk.h with 100% similarity]
tools/perf/ui/helpline.c [moved from tools/perf/util/ui/helpline.c with 100% similarity]
tools/perf/ui/helpline.h [moved from tools/perf/util/ui/helpline.h with 100% similarity]
tools/perf/ui/keysyms.h [moved from tools/perf/util/ui/keysyms.h with 100% similarity]
tools/perf/ui/libslang.h [moved from tools/perf/util/ui/libslang.h with 100% similarity]
tools/perf/ui/progress.c [moved from tools/perf/util/ui/progress.c with 100% similarity]
tools/perf/ui/progress.h [moved from tools/perf/util/ui/progress.h with 100% similarity]
tools/perf/ui/setup.c [moved from tools/perf/util/ui/setup.c with 100% similarity]
tools/perf/ui/ui.h [moved from tools/perf/util/ui/ui.h with 100% similarity]
tools/perf/ui/util.c [moved from tools/perf/util/ui/util.c with 100% similarity]
tools/perf/ui/util.h [moved from tools/perf/util/ui/util.h with 100% similarity]
tools/perf/util/annotate.c
tools/perf/util/debug.h
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/thread_map.h
tools/scripts/Makefile.include [new file with mode: 0644]

index 0df3d00..f7f7381 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1468,6 +1468,13 @@ kernelrelease:
 kernelversion:
        @echo $(KERNELVERSION)
 
+# Clear a bunch of variables before executing the submake
+tools/: FORCE
+       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/
+
+tools/%: FORCE
+       $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ $*
+
 # Single targets
 # ---------------------------------------------------------------------------
 # Single targets are compatible with:
diff --git a/tools/Makefile b/tools/Makefile
new file mode 100644 (file)
index 0000000..3ae4394
--- /dev/null
@@ -0,0 +1,77 @@
+include scripts/Makefile.include
+
+help:
+       @echo 'Possible targets:'
+       @echo ''
+       @echo '  cpupower   - a tool for all things x86 CPU power'
+       @echo '  firewire   - the userspace part of nosy, an IEEE-1394 traffic sniffer'
+       @echo '  lguest     - a minimal 32-bit x86 hypervisor'
+       @echo '  perf       - Linux performance measurement and analysis tool'
+       @echo '  selftests  - various kernel selftests'
+       @echo '  turbostat  - Intel CPU idle stats and freq reporting tool'
+       @echo '  usb        - USB testing tools'
+       @echo '  virtio     - vhost test module'
+       @echo '  vm         - misc vm tools'
+       @echo '  x86_energy_perf_policy - Intel energy policy tool'
+       @echo ''
+       @echo 'You can do:'
+       @echo ' $$ make -C tools/<tool>_install'
+       @echo ''
+       @echo '  from the kernel command line to build and install one of'
+       @echo '  the tools above'
+       @echo ''
+       @echo '  $$ make tools/install'
+       @echo ''
+       @echo '  installs all tools.'
+       @echo ''
+       @echo 'Cleaning targets:'
+       @echo ''
+       @echo '  all of the above with the "_clean" string appended cleans'
+       @echo '    the respective build directory.'
+       @echo '  clean: a summary clean target to clean _all_ folders'
+
+cpupower: FORCE
+       $(QUIET_SUBDIR0)power/$@/ $(QUIET_SUBDIR1)
+
+firewire lguest perf usb virtio vm: FORCE
+       $(QUIET_SUBDIR0)$@/ $(QUIET_SUBDIR1)
+
+selftests: FORCE
+       $(QUIET_SUBDIR0)testing/$@/ $(QUIET_SUBDIR1)
+
+turbostat x86_energy_perf_policy: FORCE
+       $(QUIET_SUBDIR0)power/x86/$@/ $(QUIET_SUBDIR1)
+
+cpupower_install:
+       $(QUIET_SUBDIR0)power/$(@:_install=)/ $(QUIET_SUBDIR1) install
+
+firewire_install lguest_install perf_install usb_install virtio_install vm_install:
+       $(QUIET_SUBDIR0)$(@:_install=)/ $(QUIET_SUBDIR1) install
+
+selftests_install:
+       $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) install
+
+turbostat_install x86_energy_perf_policy_install:
+       $(QUIET_SUBDIR0)power/x86/$(@:_install=)/ $(QUIET_SUBDIR1) install
+
+install: cpupower_install firewire_install lguest_install perf_install \
+               selftests_install turbostat_install usb_install virtio_install \
+               vm_install x86_energy_perf_policy_install
+
+cpupower_clean:
+       $(QUIET_SUBDIR0)power/cpupower/ $(QUIET_SUBDIR1) clean
+
+firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean:
+       $(QUIET_SUBDIR0)$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+
+selftests_clean:
+       $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+
+turbostat_clean x86_energy_perf_policy_clean:
+       $(QUIET_SUBDIR0)power/x86/$(@:_clean=)/ $(QUIET_SUBDIR1) clean
+
+clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \
+               turbostat_clean usb_clean virtio_clean vm_clean \
+               x86_energy_perf_policy_clean
+
+.PHONY: FORCE
index 416684b..26b823b 100644 (file)
@@ -19,3 +19,5 @@ TAGS
 cscope*
 config.mak
 config.mak.autogen
+*-bison.*
+*-flex.*
index d144866..42c6fd2 100644 (file)
@@ -6,6 +6,7 @@
        normal = black, lightgray
        selected = lightgray, magenta
        code = blue, lightgray
+       addr = magenta, lightgray
 
 [tui]
 
index 820371f..e98e14c 100644 (file)
@@ -1,18 +1,10 @@
-ifeq ("$(origin O)", "command line")
-       OUTPUT := $(O)/
-endif
+include ../scripts/Makefile.include
 
 # The default target of this Makefile is...
 all:
 
 include config/utilities.mak
 
-ifneq ($(OUTPUT),)
-# check that the output directory actually exists
-OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
-$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
-endif
-
 # Define V to have a more verbose compile.
 #
 # Define O to save output files in a separate directory.
@@ -84,31 +76,6 @@ ifneq ($(WERROR),0)
        CFLAGS_WERROR := -Werror
 endif
 
-#
-# Include saner warnings here, which can catch bugs:
-#
-
-EXTRA_WARNINGS := -Wformat
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-security
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-y2k
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Winit-self
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wpacked
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wredundant-decls
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-aliasing=3
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-default
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-enum
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wno-system-headers
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wundef
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wwrite-strings
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wbad-function-cast
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-declarations
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-prototypes
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wnested-externs
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wold-style-definition
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement
-
 ifeq ("$(origin DEBUG)", "command line")
   PERF_DEBUG = $(DEBUG)
 endif
@@ -237,21 +204,20 @@ export PERL_PATH
 FLEX = $(CROSS_COMPILE)flex
 BISON= $(CROSS_COMPILE)bison
 
-event-parser:
-       $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/parse-events-flex.c: util/parse-events.l
        $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
 
-$(OUTPUT)util/parse-events-flex.c: event-parser
-$(OUTPUT)util/parse-events-bison.c: event-parser
+$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
+       $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
 
-pmu-parser:
-       $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
+$(OUTPUT)util/pmu-flex.c: util/pmu.l
        $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
 
-$(OUTPUT)util/pmu-flex.c: pmu-parser
-$(OUTPUT)util/pmu-bison.c: pmu-parser
+$(OUTPUT)util/pmu-bison.c: util/pmu.y
+       $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
 
-$(OUTPUT)util/parse-events.o: event-parser pmu-parser
+$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
+$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
 
 LIB_FILE=$(OUTPUT)libperf.a
 
@@ -507,27 +473,27 @@ else
                # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
                BASIC_CFLAGS += -I/usr/include/slang
                EXTLIBS += -lnewt -lslang
-               LIB_OBJS += $(OUTPUT)util/ui/setup.o
-               LIB_OBJS += $(OUTPUT)util/ui/browser.o
-               LIB_OBJS += $(OUTPUT)util/ui/browsers/annotate.o
-               LIB_OBJS += $(OUTPUT)util/ui/browsers/hists.o
-               LIB_OBJS += $(OUTPUT)util/ui/browsers/map.o
-               LIB_OBJS += $(OUTPUT)util/ui/helpline.o
-               LIB_OBJS += $(OUTPUT)util/ui/progress.o
-               LIB_OBJS += $(OUTPUT)util/ui/util.o
-               LIB_H += util/ui/browser.h
-               LIB_H += util/ui/browsers/map.h
-               LIB_H += util/ui/helpline.h
-               LIB_H += util/ui/keysyms.h
-               LIB_H += util/ui/libslang.h
-               LIB_H += util/ui/progress.h
-               LIB_H += util/ui/util.h
-               LIB_H += util/ui/ui.h
+               LIB_OBJS += $(OUTPUT)ui/setup.o
+               LIB_OBJS += $(OUTPUT)ui/browser.o
+               LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
+               LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
+               LIB_OBJS += $(OUTPUT)ui/browsers/map.o
+               LIB_OBJS += $(OUTPUT)ui/helpline.o
+               LIB_OBJS += $(OUTPUT)ui/progress.o
+               LIB_OBJS += $(OUTPUT)ui/util.o
+               LIB_H += ui/browser.h
+               LIB_H += ui/browsers/map.h
+               LIB_H += ui/helpline.h
+               LIB_H += ui/keysyms.h
+               LIB_H += ui/libslang.h
+               LIB_H += ui/progress.h
+               LIB_H += ui/util.h
+               LIB_H += ui/ui.h
        endif
 endif
 
 ifdef NO_GTK2
-       BASIC_CFLAGS += -DNO_GTK2
+       BASIC_CFLAGS += -DNO_GTK2_SUPPORT
 else
        FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0)
        ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y)
@@ -536,7 +502,7 @@ else
        else
                BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0)
                EXTLIBS += $(shell pkg-config --libs gtk+-2.0)
-               LIB_OBJS += $(OUTPUT)util/gtk/browser.o
+               LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
        endif
 endif
 
@@ -679,18 +645,6 @@ else
        endif
 endif
 
-ifneq ($(findstring $(MAKEFLAGS),s),s)
-ifndef V
-       QUIET_CC       = @echo '   ' CC $@;
-       QUIET_AR       = @echo '   ' AR $@;
-       QUIET_LINK     = @echo '   ' LINK $@;
-       QUIET_MKDIR    = @echo '   ' MKDIR $@;
-       QUIET_GEN      = @echo '   ' GEN $@;
-       QUIET_FLEX     = @echo '   ' FLEX $@;
-       QUIET_BISON    = @echo '   ' BISON $@;
-endif
-endif
-
 ifdef ASCIIDOC8
        export ASCIIDOC8
 endif
@@ -801,16 +755,16 @@ $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
 $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
 
-$(OUTPUT)util/ui/browser.o: util/ui/browser.c $(OUTPUT)PERF-CFLAGS
+$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
 
-$(OUTPUT)util/ui/browsers/annotate.o: util/ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
+$(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
 
-$(OUTPUT)util/ui/browsers/hists.o: util/ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
+$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
 
-$(OUTPUT)util/ui/browsers/map.o: util/ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
+$(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
 
 $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
@@ -852,8 +806,6 @@ help:
        @echo '  html           - make html documentation'
        @echo '  info           - make GNU info documentation (access with info <foo>)'
        @echo '  pdf            - make pdf documentation'
-       @echo '  event-parser   - make event parser code'
-       @echo '  pmu-parser     - make pmu format parser code'
        @echo '  TAGS           - use etags to make tag information for source browsing'
        @echo '  tags           - use ctags to make tag information for source browsing'
        @echo '  cscope - use cscope to make interactive browsing database'
index be4e1ee..10b1f1f 100644 (file)
@@ -245,7 +245,7 @@ try_again:
                         * based cpu-clock-tick sw counter, which
                         * is always available even if no PMU support:
                         */
-                       if (attr->type == PERF_TYPE_HARDWARE
+                       if (err == ENOENT && attr->type == PERF_TYPE_HARDWARE
                                        && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
 
                                if (verbose)
index 2e31743..cec2b8c 100644 (file)
@@ -296,12 +296,15 @@ static size_t hists__fprintf_nr_sample_events(struct hists *self,
 {
        size_t ret;
        char unit;
-       unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE];
+       unsigned long nr_samples = self->stats.nr_events[PERF_RECORD_SAMPLE];
+       u64 nr_events = self->stats.total_period;
 
-       nr_events = convert_unit(nr_events, &unit);
-       ret = fprintf(fp, "# Events: %lu%c", nr_events, unit);
+       nr_samples = convert_unit(nr_samples, &unit);
+       ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
        if (evname != NULL)
-               ret += fprintf(fp, " %s", evname);
+               ret += fprintf(fp, " of event '%s'", evname);
+
+       ret += fprintf(fp, "\n# Event count (approx.): %lu", nr_events);
        return ret + fprintf(fp, "\n#\n");
 }
 
index fb8b5f8..1cad3af 100644 (file)
@@ -17,6 +17,7 @@
 #include "util/debug.h"
 
 #include <sys/prctl.h>
+#include <sys/resource.h>
 
 #include <semaphore.h>
 #include <pthread.h>
index c941bb6..dde9e17 100644 (file)
@@ -173,7 +173,7 @@ static struct perf_event_attr very_very_detailed_attrs[] = {
 
 
 
-struct perf_evlist             *evsel_list;
+static struct perf_evlist      *evsel_list;
 
 static bool                    system_wide                     =  false;
 static int                     run_idx                         =  0;
@@ -265,18 +265,18 @@ static double stddev_stats(struct stats *stats)
        return sqrt(variance_mean);
 }
 
-struct stats                   runtime_nsecs_stats[MAX_NR_CPUS];
-struct stats                   runtime_cycles_stats[MAX_NR_CPUS];
-struct stats                   runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
-struct stats                   runtime_stalled_cycles_back_stats[MAX_NR_CPUS];
-struct stats                   runtime_branches_stats[MAX_NR_CPUS];
-struct stats                   runtime_cacherefs_stats[MAX_NR_CPUS];
-struct stats                   runtime_l1_dcache_stats[MAX_NR_CPUS];
-struct stats                   runtime_l1_icache_stats[MAX_NR_CPUS];
-struct stats                   runtime_ll_cache_stats[MAX_NR_CPUS];
-struct stats                   runtime_itlb_cache_stats[MAX_NR_CPUS];
-struct stats                   runtime_dtlb_cache_stats[MAX_NR_CPUS];
-struct stats                   walltime_nsecs_stats;
+static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
+static struct stats runtime_cycles_stats[MAX_NR_CPUS];
+static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
+static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS];
+static struct stats runtime_branches_stats[MAX_NR_CPUS];
+static struct stats runtime_cacherefs_stats[MAX_NR_CPUS];
+static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS];
+static struct stats runtime_l1_icache_stats[MAX_NR_CPUS];
+static struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
+static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
+static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
+static struct stats walltime_nsecs_stats;
 
 static int create_perf_stat_counter(struct perf_evsel *evsel,
                                    struct perf_evsel *first)
index e3c63ae..8ef59f8 100644 (file)
@@ -42,6 +42,7 @@
 #include "util/debug.h"
 
 #include <assert.h>
+#include <elf.h>
 #include <fcntl.h>
 
 #include <stdio.h>
@@ -59,6 +60,7 @@
 #include <sys/prctl.h>
 #include <sys/wait.h>
 #include <sys/uio.h>
+#include <sys/utsname.h>
 #include <sys/mman.h>
 
 #include <linux/unistd.h>
@@ -162,12 +164,40 @@ static void __zero_source_counters(struct hist_entry *he)
        symbol__annotate_zero_histograms(sym);
 }
 
+static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
+{
+       struct utsname uts;
+       int err = uname(&uts);
+
+       ui__warning("Out of bounds address found:\n\n"
+                   "Addr:   %" PRIx64 "\n"
+                   "DSO:    %s %c\n"
+                   "Map:    %" PRIx64 "-%" PRIx64 "\n"
+                   "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n"
+                   "Arch:   %s\n"
+                   "Kernel: %s\n"
+                   "Tools:  %s\n\n"
+                   "Not all samples will be on the annotation output.\n\n"
+                   "Please report to linux-kernel@vger.kernel.org\n",
+                   ip, map->dso->long_name, dso__symtab_origin(map->dso),
+                   map->start, map->end, sym->start, sym->end,
+                   sym->binding == STB_GLOBAL ? 'g' :
+                   sym->binding == STB_LOCAL  ? 'l' : 'w', sym->name,
+                   err ? "[unknown]" : uts.machine,
+                   err ? "[unknown]" : uts.release, perf_version_string);
+       if (use_browser <= 0)
+               sleep(5);
+       
+       map->erange_warned = true;
+}
+
 static void perf_top__record_precise_ip(struct perf_top *top,
                                        struct hist_entry *he,
                                        int counter, u64 ip)
 {
        struct annotation *notes;
        struct symbol *sym;
+       int err;
 
        if (he == NULL || he->ms.sym == NULL ||
            ((top->sym_filter_entry == NULL ||
@@ -189,9 +219,12 @@ static void perf_top__record_precise_ip(struct perf_top *top,
        }
 
        ip = he->ms.map->map_ip(he->ms.map, ip);
-       symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
+       err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
 
        pthread_mutex_unlock(&notes->lock);
+
+       if (err == -ERANGE && !he->ms.map->erange_warned)
+               ui__warn_map_erange(he->ms.map, sym, ip);
 }
 
 static void perf_top__show_details(struct perf_top *top)
@@ -615,6 +648,7 @@ process_hotkey:
 
 /* Tag samples to be skipped. */
 static const char *skip_symbols[] = {
+       "intel_idle",
        "default_idle",
        "native_safe_halt",
        "cpu_idle",
similarity index 98%
rename from tools/perf/util/ui/browser.c
rename to tools/perf/ui/browser.c
index 5568291..a1b140c 100644 (file)
@@ -27,9 +27,12 @@ static int ui_browser__percent_color(struct ui_browser *browser,
        return HE_COLORSET_NORMAL;
 }
 
-void ui_browser__set_color(struct ui_browser *self __used, int color)
+int ui_browser__set_color(struct ui_browser *browser, int color)
 {
+       int ret = browser->current_color;
+       browser->current_color = color;
        SLsmg_set_color(color);
+       return ret;
 }
 
 void ui_browser__set_percent_color(struct ui_browser *self,
@@ -502,6 +505,12 @@ static struct ui_browser__colorset {
                .fg       = "blue",
                .bg       = "default",
        },
+       {
+               .colorset = HE_COLORSET_ADDR,
+               .name     = "addr",
+               .fg       = "magenta",
+               .bg       = "default",
+       },
        {
                .name = NULL,
        }
similarity index 95%
rename from tools/perf/util/ui/browser.h
rename to tools/perf/ui/browser.h
index 6ee82f6..2550277 100644 (file)
 #define HE_COLORSET_NORMAL     52
 #define HE_COLORSET_SELECTED   53
 #define HE_COLORSET_CODE       54
+#define HE_COLORSET_ADDR       55
 
 struct ui_browser {
        u64           index, top_idx;
        void          *top, *entries;
        u16           y, x, width, height;
+       int           current_color;
        void          *priv;
        const char    *title;
        char          *helpline;
@@ -27,7 +29,7 @@ struct ui_browser {
        bool          use_navkeypressed;
 };
 
-void ui_browser__set_color(struct ui_browser *self, int color);
+int  ui_browser__set_color(struct ui_browser *browser, int color);
 void ui_browser__set_percent_color(struct ui_browser *self,
                                   double percent, bool current);
 bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row);
similarity index 54%
rename from tools/perf/util/ui/browsers/annotate.c
rename to tools/perf/ui/browsers/annotate.c
index 57a4c6e..4db5186 100644 (file)
@@ -1,13 +1,13 @@
-#include "../../util.h"
+#include "../../util/util.h"
 #include "../browser.h"
 #include "../helpline.h"
 #include "../libslang.h"
 #include "../ui.h"
 #include "../util.h"
-#include "../../annotate.h"
-#include "../../hist.h"
-#include "../../sort.h"
-#include "../../symbol.h"
+#include "../../util/annotate.h"
+#include "../../util/hist.h"
+#include "../../util/sort.h"
+#include "../../util/symbol.h"
 #include <pthread.h>
 #include <newt.h>
 
@@ -16,9 +16,13 @@ struct annotate_browser {
        struct rb_root    entries;
        struct rb_node    *curr_hot;
        struct objdump_line *selection;
+       u64                 start;
        int                 nr_asm_entries;
        int                 nr_entries;
        bool                hide_src_code;
+       bool                use_offset;
+       bool                searching_backwards;
+       char                search_bf[128];
 };
 
 struct objdump_line_rb_node {
@@ -51,6 +55,9 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
        struct annotate_browser *ab = container_of(self, struct annotate_browser, b);
        struct objdump_line *ol = list_entry(entry, struct objdump_line, node);
        bool current_entry = ui_browser__is_current_entry(self, row);
+       bool change_color = (!ab->hide_src_code &&
+                            (!current_entry || (self->use_navkeypressed &&
+                                                !self->navkeypressed)));
        int width = self->width;
 
        if (ol->offset != -1) {
@@ -69,15 +76,29 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
        if (!self->navkeypressed)
                width += 1;
 
-       if (!ab->hide_src_code && ol->offset != -1)
-               if (!current_entry || (self->use_navkeypressed &&
-                                      !self->navkeypressed))
-                       ui_browser__set_color(self, HE_COLORSET_CODE);
+       if (ol->offset != -1 && change_color)
+               ui_browser__set_color(self, HE_COLORSET_CODE);
 
        if (!*ol->line)
                slsmg_write_nstring(" ", width - 18);
-       else
+       else if (ol->offset == -1)
                slsmg_write_nstring(ol->line, width - 18);
+       else {
+               char bf[64];
+               u64 addr = ol->offset;
+               int printed, color = -1;
+
+               if (!ab->use_offset)
+                       addr += ab->start;
+
+               printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr);
+               if (change_color)
+                       color = ui_browser__set_color(self, HE_COLORSET_ADDR);
+               slsmg_write_nstring(bf, printed);
+               if (change_color)
+                       ui_browser__set_color(self, color);
+               slsmg_write_nstring(ol->line, width - 18 - printed);
+       }
 
        if (current_entry)
                ab->selection = ol;
@@ -138,27 +159,38 @@ static void objdump__insert_line(struct rb_root *self,
 }
 
 static void annotate_browser__set_top(struct annotate_browser *self,
-                                     struct rb_node *nd)
+                                     struct objdump_line *pos, u32 idx)
 {
-       struct objdump_line_rb_node *rbpos;
-       struct objdump_line *pos;
        unsigned back;
 
        ui_browser__refresh_dimensions(&self->b);
        back = self->b.height / 2;
-       rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node);
-       pos = ((struct objdump_line *)rbpos) - 1;
-       self->b.top_idx = self->b.index = rbpos->idx;
+       self->b.top_idx = self->b.index = idx;
 
        while (self->b.top_idx != 0 && back != 0) {
                pos = list_entry(pos->node.prev, struct objdump_line, node);
 
+               if (objdump_line__filter(&self->b, &pos->node))
+                       continue;
+
                --self->b.top_idx;
                --back;
        }
 
        self->b.top = pos;
-       self->curr_hot = nd;
+       self->b.navkeypressed = true;
+}
+
+static void annotate_browser__set_rb_top(struct annotate_browser *browser,
+                                        struct rb_node *nd)
+{
+       struct objdump_line_rb_node *rbpos;
+       struct objdump_line *pos;
+
+       rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node);
+       pos = ((struct objdump_line *)rbpos) - 1;
+       annotate_browser__set_top(browser, pos, rbpos->idx);
+       browser->curr_hot = nd;
 }
 
 static void annotate_browser__calc_percent(struct annotate_browser *browser,
@@ -226,6 +258,231 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)
        return true;
 }
 
+static bool annotate_browser__callq(struct annotate_browser *browser,
+                                   int evidx, void (*timer)(void *arg),
+                                   void *arg, int delay_secs)
+{
+       struct map_symbol *ms = browser->b.priv;
+       struct symbol *sym = ms->sym;
+       struct annotation *notes;
+       struct symbol *target;
+       char *s = strstr(browser->selection->line, "callq ");
+       u64 ip;
+
+       if (s == NULL)
+               return false;
+
+       s = strchr(s, ' ');
+       if (s++ == NULL) {
+               ui_helpline__puts("Invallid callq instruction.");
+               return true;
+       }
+
+       ip = strtoull(s, NULL, 16);
+       ip = ms->map->map_ip(ms->map, ip);
+       target = map__find_symbol(ms->map, ip, NULL);
+       if (target == NULL) {
+               ui_helpline__puts("The called function was not found.");
+               return true;
+       }
+
+       notes = symbol__annotation(target);
+       pthread_mutex_lock(&notes->lock);
+
+       if (notes->src == NULL && symbol__alloc_hist(target) < 0) {
+               pthread_mutex_unlock(&notes->lock);
+               ui__warning("Not enough memory for annotating '%s' symbol!\n",
+                           target->name);
+               return true;
+       }
+
+       pthread_mutex_unlock(&notes->lock);
+       symbol__tui_annotate(target, ms->map, evidx, timer, arg, delay_secs);
+       ui_browser__show_title(&browser->b, sym->name);
+       return true;
+}
+
+static struct objdump_line *
+       annotate_browser__find_offset(struct annotate_browser *browser,
+                                     s64 offset, s64 *idx)
+{
+       struct map_symbol *ms = browser->b.priv;
+       struct symbol *sym = ms->sym;
+       struct annotation *notes = symbol__annotation(sym);
+       struct objdump_line *pos;
+
+       *idx = 0;
+       list_for_each_entry(pos, &notes->src->source, node) {
+               if (pos->offset == offset)
+                       return pos;
+               if (!objdump_line__filter(&browser->b, &pos->node))
+                       ++*idx;
+       }
+
+       return NULL;
+}
+
+static bool annotate_browser__jump(struct annotate_browser *browser)
+{
+       const char *jumps[] = { "je ", "jne ", "ja ", "jmpq ", "js ", "jmp ", NULL };
+       struct objdump_line *line;
+       s64 idx, offset;
+       char *s = NULL;
+       int i = 0;
+
+       while (jumps[i]) {
+               s = strstr(browser->selection->line, jumps[i++]);
+               if (s)
+                       break;
+       }
+
+       if (s == NULL)
+               return false;
+
+       s = strchr(s, '+');
+       if (s++ == NULL) {
+               ui_helpline__puts("Invallid jump instruction.");
+               return true;
+       }
+
+       offset = strtoll(s, NULL, 16);
+       line = annotate_browser__find_offset(browser, offset, &idx);
+       if (line == NULL) {
+               ui_helpline__puts("Invallid jump offset");
+               return true;
+       }
+
+       annotate_browser__set_top(browser, line, idx);
+       
+       return true;
+}
+
+static struct objdump_line *
+       annotate_browser__find_string(struct annotate_browser *browser,
+                                     char *s, s64 *idx)
+{
+       struct map_symbol *ms = browser->b.priv;
+       struct symbol *sym = ms->sym;
+       struct annotation *notes = symbol__annotation(sym);
+       struct objdump_line *pos = browser->selection;
+
+       *idx = browser->b.index;
+       list_for_each_entry_continue(pos, &notes->src->source, node) {
+               if (objdump_line__filter(&browser->b, &pos->node))
+                       continue;
+
+               ++*idx;
+
+               if (pos->line && strstr(pos->line, s) != NULL)
+                       return pos;
+       }
+
+       return NULL;
+}
+
+static bool __annotate_browser__search(struct annotate_browser *browser)
+{
+       struct objdump_line *line;
+       s64 idx;
+
+       line = annotate_browser__find_string(browser, browser->search_bf, &idx);
+       if (line == NULL) {
+               ui_helpline__puts("String not found!");
+               return false;
+       }
+
+       annotate_browser__set_top(browser, line, idx);
+       browser->searching_backwards = false;
+       return true;
+}
+
+static struct objdump_line *
+       annotate_browser__find_string_reverse(struct annotate_browser *browser,
+                                             char *s, s64 *idx)
+{
+       struct map_symbol *ms = browser->b.priv;
+       struct symbol *sym = ms->sym;
+       struct annotation *notes = symbol__annotation(sym);
+       struct objdump_line *pos = browser->selection;
+
+       *idx = browser->b.index;
+       list_for_each_entry_continue_reverse(pos, &notes->src->source, node) {
+               if (objdump_line__filter(&browser->b, &pos->node))
+                       continue;
+
+               --*idx;
+
+               if (pos->line && strstr(pos->line, s) != NULL)
+                       return pos;
+       }
+
+       return NULL;
+}
+
+static bool __annotate_browser__search_reverse(struct annotate_browser *browser)
+{
+       struct objdump_line *line;
+       s64 idx;
+
+       line = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx);
+       if (line == NULL) {
+               ui_helpline__puts("String not found!");
+               return false;
+       }
+
+       annotate_browser__set_top(browser, line, idx);
+       browser->searching_backwards = true;
+       return true;
+}
+
+static bool annotate_browser__search_window(struct annotate_browser *browser,
+                                           int delay_secs)
+{
+       if (ui_browser__input_window("Search", "String: ", browser->search_bf,
+                                    "ENTER: OK, ESC: Cancel",
+                                    delay_secs * 2) != K_ENTER ||
+           !*browser->search_bf)
+               return false;
+
+       return true;
+}
+
+static bool annotate_browser__search(struct annotate_browser *browser, int delay_secs)
+{
+       if (annotate_browser__search_window(browser, delay_secs))
+               return __annotate_browser__search(browser);
+
+       return false;
+}
+
+static bool annotate_browser__continue_search(struct annotate_browser *browser,
+                                             int delay_secs)
+{
+       if (!*browser->search_bf)
+               return annotate_browser__search(browser, delay_secs);
+
+       return __annotate_browser__search(browser);
+}
+
+static bool annotate_browser__search_reverse(struct annotate_browser *browser,
+                                          int delay_secs)
+{
+       if (annotate_browser__search_window(browser, delay_secs))
+               return __annotate_browser__search_reverse(browser);
+
+       return false;
+}
+
+static
+bool annotate_browser__continue_search_reverse(struct annotate_browser *browser,
+                                              int delay_secs)
+{
+       if (!*browser->search_bf)
+               return annotate_browser__search_reverse(browser, delay_secs);
+
+       return __annotate_browser__search_reverse(browser);
+}
+
 static int annotate_browser__run(struct annotate_browser *self, int evidx,
                                 void(*timer)(void *arg),
                                 void *arg, int delay_secs)
@@ -235,6 +492,7 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
        struct symbol *sym = ms->sym;
        const char *help = "<-/ESC: Exit, TAB/shift+TAB: Cycle hot lines, "
                           "H: Go to hottest line, ->/ENTER: Line action, "
+                          "O: Toggle offset view, "
                           "S: Toggle source code view";
        int key;
 
@@ -243,8 +501,10 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
 
        annotate_browser__calc_percent(self, evidx);
 
-       if (self->curr_hot)
-               annotate_browser__set_top(self, self->curr_hot);
+       if (self->curr_hot) {
+               annotate_browser__set_rb_top(self, self->curr_hot);
+               self->b.navkeypressed = false;
+       }
 
        nd = self->curr_hot;
 
@@ -295,56 +555,35 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
                        if (annotate_browser__toggle_source(self))
                                ui_helpline__puts(help);
                        continue;
+               case 'O':
+               case 'o':
+                       self->use_offset = !self->use_offset;
+                       continue;
+               case '/':
+                       if (annotate_browser__search(self, delay_secs)) {
+show_help:
+                               ui_helpline__puts(help);
+                       }
+                       continue;
+               case 'n':
+                       if (self->searching_backwards ?
+                           annotate_browser__continue_search_reverse(self, delay_secs) :
+                           annotate_browser__continue_search(self, delay_secs))
+                               goto show_help;
+                       continue;
+               case '?':
+                       if (annotate_browser__search_reverse(self, delay_secs))
+                               goto show_help;
+                       continue;
                case K_ENTER:
                case K_RIGHT:
-                       if (self->selection == NULL) {
+                       if (self->selection == NULL)
                                ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org");
-                               continue;
-                       }
-
-                       if (self->selection->offset == -1) {
+                       else if (self->selection->offset == -1)
                                ui_helpline__puts("Actions are only available for assembly lines.");
-                               continue;
-                       } else {
-                               char *s = strstr(self->selection->line, "callq ");
-                               struct annotation *notes;
-                               struct symbol *target;
-                               u64 ip;
-
-                               if (s == NULL) {
-                                       ui_helpline__puts("Actions are only available for the 'callq' instruction.");
-                                       continue;
-                               }
-
-                               s = strchr(s, ' ');
-                               if (s++ == NULL) {
-                                       ui_helpline__puts("Invallid callq instruction.");
-                                       continue;
-                               }
-
-                               ip = strtoull(s, NULL, 16);
-                               ip = ms->map->map_ip(ms->map, ip);
-                               target = map__find_symbol(ms->map, ip, NULL);
-                               if (target == NULL) {
-                                       ui_helpline__puts("The called function was not found.");
-                                       continue;
-                               }
-
-                               notes = symbol__annotation(target);
-                               pthread_mutex_lock(&notes->lock);
-
-                               if (notes->src == NULL && symbol__alloc_hist(target) < 0) {
-                                       pthread_mutex_unlock(&notes->lock);
-                                       ui__warning("Not enough memory for annotating '%s' symbol!\n",
-                                                   target->name);
-                                       continue;
-                               }
-
-                               pthread_mutex_unlock(&notes->lock);
-                               symbol__tui_annotate(target, ms->map, evidx,
-                                                    timer, arg, delay_secs);
-                               ui_browser__show_title(&self->b, sym->name);
-                       }
+                       else if (!(annotate_browser__jump(self) ||
+                                  annotate_browser__callq(self, evidx, timer, arg, delay_secs)))
+                               ui_helpline__puts("Actions are only available for the 'callq' and jump instructions.");
                        continue;
                case K_LEFT:
                case K_ESC:
@@ -356,7 +595,7 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
                }
 
                if (nd != NULL)
-                       annotate_browser__set_top(self, nd);
+                       annotate_browser__set_rb_top(self, nd);
        }
 out:
        ui_browser__hide(&self->b);
@@ -406,6 +645,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
        ui_helpline__push("Press <- or ESC to exit");
 
        notes = symbol__annotation(sym);
+       browser.start = map__rip_2objdump(map, sym->start);
 
        list_for_each_entry(pos, &notes->src->source, node) {
                struct objdump_line_rb_node *rbpos;
similarity index 98%
rename from tools/perf/util/ui/browsers/hists.c
rename to tools/perf/ui/browsers/hists.c
index d7a1c4a..466827e 100644 (file)
@@ -5,12 +5,12 @@
 #include <newt.h>
 #include <linux/rbtree.h>
 
-#include "../../evsel.h"
-#include "../../evlist.h"
-#include "../../hist.h"
-#include "../../pstack.h"
-#include "../../sort.h"
-#include "../../util.h"
+#include "../../util/evsel.h"
+#include "../../util/evlist.h"
+#include "../../util/hist.h"
+#include "../../util/pstack.h"
+#include "../../util/sort.h"
+#include "../../util/util.h"
 
 #include "../browser.h"
 #include "../helpline.h"
@@ -125,6 +125,9 @@ static int callchain__count_rows(struct rb_root *chain)
 
 static bool map_symbol__toggle_fold(struct map_symbol *self)
 {
+       if (!self)
+               return false;
+
        if (!self->has_children)
                return false;
 
@@ -837,10 +840,14 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size,
        int printed;
        const struct dso *dso = self->dso_filter;
        const struct thread *thread = self->thread_filter;
-       unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE];
+       unsigned long nr_samples = self->stats.nr_events[PERF_RECORD_SAMPLE];
+       u64 nr_events = self->stats.total_period;
+
+       nr_samples = convert_unit(nr_samples, &unit);
+       printed = scnprintf(bf, size,
+                          "Samples: %lu%c of event '%s', Event count (approx.): %lu",
+                          nr_samples, unit, ev_name, nr_events);
 
-       nr_events = convert_unit(nr_events, &unit);
-       printed = scnprintf(bf, size, "Events: %lu%c %s", nr_events, unit, ev_name);
 
        if (self->uid_filter_str)
                printed += snprintf(bf + printed, size - printed,
similarity index 97%
rename from tools/perf/util/ui/browsers/map.c
rename to tools/perf/ui/browsers/map.c
index eca6575..98851d5 100644 (file)
@@ -5,9 +5,9 @@
 #include <sys/ttydefaults.h>
 #include <string.h>
 #include <linux/bitops.h>
-#include "../../util.h"
-#include "../../debug.h"
-#include "../../symbol.h"
+#include "../../util/util.h"
+#include "../../util/debug.h"
+#include "../../util/symbol.h"
 #include "../browser.h"
 #include "../helpline.h"
 #include "map.h"
similarity index 100%
rename from tools/perf/util/ui/ui.h
rename to tools/perf/ui/ui.h
index 199f69e..1e7fd52 100644 (file)
@@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
 
        pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
 
-       if (addr > sym->end)
-               return 0;
+       if (addr < sym->start || addr > sym->end)
+               return -ERANGE;
 
        offset = addr - sym->start;
        h = annotation__histogram(notes, evidx);
@@ -84,10 +84,15 @@ static struct objdump_line *objdump_line__new(s64 offset, char *line, size_t pri
 
        if (self != NULL) {
                self->offset = offset;
-               self->line = line;
+               self->line = strdup(line);
+               if (self->line == NULL)
+                       goto out_delete;
        }
 
        return self;
+out_delete:
+       free(self);
+       return NULL;
 }
 
 void objdump_line__free(struct objdump_line *self)
@@ -112,7 +117,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
 }
 
 static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
-                              int evidx, u64 len, int min_pcnt,
+                              u64 start, int evidx, u64 len, int min_pcnt,
                               int printed, int max_lines,
                               struct objdump_line *queue)
 {
@@ -128,6 +133,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
                struct source_line *src_line = notes->src->lines;
                struct sym_hist *h = annotation__histogram(notes, evidx);
                s64 offset = oline->offset;
+               const u64 addr = start + offset;
                struct objdump_line *next;
 
                next = objdump__get_next_ip_line(&notes->src->source, oline);
@@ -157,7 +163,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
                        list_for_each_entry_from(queue, &notes->src->source, node) {
                                if (queue == oline)
                                        break;
-                               objdump_line__print(queue, sym, evidx, len,
+                               objdump_line__print(queue, sym, start, evidx, len,
                                                    0, 0, 1, NULL);
                        }
                }
@@ -180,6 +186,7 @@ static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
 
                color_fprintf(stdout, color, " %7.2f", percent);
                printf(" :      ");
+               color_fprintf(stdout, PERF_COLOR_MAGENTA, "  %" PRIx64 ":", addr);
                color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", oline->line);
        } else if (max_lines && printed >= max_lines)
                return 1;
@@ -201,7 +208,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
 {
        struct annotation *notes = symbol__annotation(sym);
        struct objdump_line *objdump_line;
-       char *line = NULL, *tmp, *tmp2, *c;
+       char *line = NULL, *parsed_line, *tmp, *tmp2, *c;
        size_t line_len;
        s64 line_ip, offset = -1;
 
@@ -219,6 +226,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
                *c = 0;
 
        line_ip = -1;
+       parsed_line = line;
 
        /*
         * Strip leading spaces:
@@ -246,13 +254,16 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
                offset = line_ip - start;
                if (offset < 0 || (u64)line_ip > end)
                        offset = -1;
+               else
+                       parsed_line = tmp2 + 1;
        }
 
-       objdump_line = objdump_line__new(offset, line, privsize);
-       if (objdump_line == NULL) {
-               free(line);
+       objdump_line = objdump_line__new(offset, parsed_line, privsize);
+       free(line);
+
+       if (objdump_line == NULL)
                return -1;
-       }
+
        objdump__add_line(&notes->src->source, objdump_line);
 
        return 0;
@@ -493,6 +504,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
        const char *filename = dso->long_name, *d_filename;
        struct annotation *notes = symbol__annotation(sym);
        struct objdump_line *pos, *queue = NULL;
+       u64 start = map__rip_2objdump(map, sym->start);
        int printed = 2, queue_len = 0;
        int more = 0;
        u64 len;
@@ -516,8 +528,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
                        queue_len = 0;
                }
 
-               switch (objdump_line__print(pos, sym, evidx, len, min_pcnt,
-                                           printed, max_lines, queue)) {
+               switch (objdump_line__print(pos, sym, start, evidx, len,
+                                           min_pcnt, printed, max_lines,
+                                           queue)) {
                case 0:
                        ++printed;
                        if (context) {
@@ -561,16 +574,12 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
 {
        struct annotation *notes = symbol__annotation(sym);
        struct sym_hist *h = annotation__histogram(notes, evidx);
-       struct objdump_line *pos;
-       int len = sym->end - sym->start;
+       int len = sym->end - sym->start, offset;
 
        h->sum = 0;
-
-       list_for_each_entry(pos, &notes->src->source, node) {
-               if (pos->offset != -1 && pos->offset < len) {
-                       h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8;
-                       h->sum += h->addr[pos->offset];
-               }
+       for (offset = 0; offset < len; ++offset) {
+               h->addr[offset] = h->addr[offset] * 7 / 8;
+               h->sum += h->addr[offset];
        }
 }
 
index f2ce88d..6bebe7f 100644 (file)
@@ -26,7 +26,7 @@ static inline void ui_progress__update(u64 curr __used, u64 total __used,
 #else
 extern char ui_helpline__last_msg[];
 int ui_helpline__show_help(const char *format, va_list ap);
-#include "ui/progress.h"
+#include "../ui/progress.h"
 int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
 #endif
 
index 2ec4b60..9f6d630 100644 (file)
@@ -256,6 +256,18 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
                if (!cmp) {
                        he->period += period;
                        ++he->nr_events;
+
+                       /* If the map of an existing hist_entry has
+                        * become out-of-date due to an exec() or
+                        * similar, update it.  Otherwise we will
+                        * mis-adjust symbol addresses when computing
+                        * the history counter to increment.
+                        */
+                       if (he->ms.map != entry->ms.map) {
+                               he->ms.map = entry->ms.map;
+                               if (he->ms.map)
+                                       he->ms.map->referenced = true;
+                       }
                        goto out;
                }
 
index 2cae9df..cfc64e2 100644 (file)
@@ -138,7 +138,7 @@ static inline int hist_entry__tui_annotate(struct hist_entry *self __used,
 #define K_LEFT -1
 #define K_RIGHT -2
 #else
-#include "ui/keysyms.h"
+#include "../ui/keysyms.h"
 int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
                             void(*timer)(void *arg), void *arg, int delay_secs);
 
index dea6d1c..35ae568 100644 (file)
@@ -38,6 +38,7 @@ void map__init(struct map *self, enum map_type type,
        RB_CLEAR_NODE(&self->rb_node);
        self->groups   = NULL;
        self->referenced = false;
+       self->erange_warned = false;
 }
 
 struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
index b100c20..81371ba 100644 (file)
@@ -33,6 +33,7 @@ struct map {
        u64                     end;
        u8 /* enum map_type */  type;
        bool                    referenced;
+       bool                    erange_warned;
        u32                     priv;
        u64                     pgoff;
 
index 7da80f1..f718df8 100644 (file)
@@ -6,7 +6,7 @@
 
 struct thread_map {
        int nr;
-       int map[];
+       pid_t map[];
 };
 
 struct thread_map *thread_map__new_by_pid(pid_t pid);
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
new file mode 100644 (file)
index 0000000..87b55a7
--- /dev/null
@@ -0,0 +1,57 @@
+ifeq ("$(origin O)", "command line")
+       OUTPUT := $(O)/
+endif
+
+ifneq ($(OUTPUT),)
+# check that the output directory actually exists
+OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
+$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
+endif
+
+#
+# Include saner warnings here, which can catch bugs:
+#
+EXTRA_WARNINGS := -Wbad-function-cast
+EXTRA_WARNINGS += -Wdeclaration-after-statement
+EXTRA_WARNINGS += -Wformat-security
+EXTRA_WARNINGS += -Wformat-y2k
+EXTRA_WARNINGS += -Winit-self
+EXTRA_WARNINGS += -Wmissing-declarations
+EXTRA_WARNINGS += -Wmissing-prototypes
+EXTRA_WARNINGS += -Wnested-externs
+EXTRA_WARNINGS += -Wno-system-headers
+EXTRA_WARNINGS += -Wold-style-definition
+EXTRA_WARNINGS += -Wpacked
+EXTRA_WARNINGS += -Wredundant-decls
+EXTRA_WARNINGS += -Wshadow
+EXTRA_WARNINGS += -Wstrict-aliasing=3
+EXTRA_WARNINGS += -Wstrict-prototypes
+EXTRA_WARNINGS += -Wswitch-default
+EXTRA_WARNINGS += -Wswitch-enum
+EXTRA_WARNINGS += -Wundef
+EXTRA_WARNINGS += -Wwrite-strings
+EXTRA_WARNINGS += -Wformat
+
+ifneq ($(findstring $(MAKEFLAGS), w),w)
+PRINT_DIR = --no-print-directory
+else
+NO_SUBDIR = :
+endif
+
+QUIET_SUBDIR0  = +$(MAKE) -C # space to separate -C and subdir
+QUIET_SUBDIR1  =
+
+ifneq ($(findstring $(MAKEFLAGS),s),s)
+ifndef V
+       QUIET_CC       = @echo '   ' CC $@;
+       QUIET_AR       = @echo '   ' AR $@;
+       QUIET_LINK     = @echo '   ' LINK $@;
+       QUIET_MKDIR    = @echo '   ' MKDIR $@;
+       QUIET_GEN      = @echo '   ' GEN $@;
+       QUIET_SUBDIR0  = +@subdir=
+       QUIET_SUBDIR1  = ;$(NO_SUBDIR) echo '   ' SUBDIR $$subdir; \
+                        $(MAKE) $(PRINT_DIR) -C $$subdir
+       QUIET_FLEX     = @echo '   ' FLEX $@;
+       QUIET_BISON    = @echo '   ' BISON $@;
+endif
+endif