From 31d68e7b66f168e623902e194af1e52b8cf75d71 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 27 Mar 2012 12:55:57 -0300 Subject: perf annotate: Validate addr in symbol__inc_addr_samples This routine was checking only if the provided address was after sym->end, not if it was before sym->start. Fix that by checking for both and return in both cases -ERANGE, so that tools can communicate this to the user properly, or if they chose so, to abort. This problem was reported previously but the fixes involved either doing what was being done for the > end case, i.e. silently drop the sample, returning 0, or aborting at this function, which is in a lib (or better, is slated to be at some point) and shouldn't abort. The 'report' tool already checks this value and uses pr_debug to warn the user. This patch makes the 'top' tool check it too and warn once per map where such range problem takes place. Reported-by: David Miller Reported-by: Sorin Dumitru Reported-by: Stephane Eranian Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-lw8gs7p9i9nhldilo82tzpne@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 4 ++-- tools/perf/util/map.c | 1 + tools/perf/util/map.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'tools/perf/util') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 70f5a4dc17e9..08c6d138a655 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -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); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index dea6d1c1a954..35ae56864e4f 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -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, diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index b100c20b7f94..81371bad4ef0 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -33,6 +33,7 @@ struct map { u64 end; u8 /* enum map_type */ type; bool referenced; + bool erange_warned; u32 priv; u64 pgoff; -- cgit v1.2.3-59-g8ed1b