aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui/browsers/annotate.c
diff options
context:
space:
mode:
authorFrederik Deweerdt <frederik.deweerdt@xprog.eu>2013-01-14 14:47:17 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-01-24 14:40:36 -0500
commit865c66c4183aab1d12522ca3ad3a3339d2437e5c (patch)
tree88c0059a6164b488b9d9d598faac8612fa925363 /tools/perf/ui/browsers/annotate.c
parent2c803e5248d038988ec7c52e8fd7c83130dd3c13 (diff)
perf annotate browser: Fix segfault when drawing out-of-bounds jumps
Factorize jump sanity checks from mark_jump_targets() and draw_current_jump() in an is_valid_jump() function. This fixes a segfault when moving the cursor over an invalid jump. Signed-off-by: Frederik Deweerdt <frederik.deweerdt@xprog.eu> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lkml.kernel.org/r/20130114194716.GA4973@ks398093.ip-192-95-24.net [ committer note: Make it a disasm_line method ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r--tools/perf/ui/browsers/annotate.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 5dab3ca96980..2fc7f04691cf 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -182,6 +182,16 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
182 ab->selection = dl; 182 ab->selection = dl;
183} 183}
184 184
185static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym)
186{
187 if (!dl || !dl->ins || !ins__is_jump(dl->ins)
188 || !disasm_line__has_offset(dl)
189 || dl->ops.target.offset >= symbol__size(sym))
190 return false;
191
192 return true;
193}
194
185static void annotate_browser__draw_current_jump(struct ui_browser *browser) 195static void annotate_browser__draw_current_jump(struct ui_browser *browser)
186{ 196{
187 struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); 197 struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
@@ -195,8 +205,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
195 if (strstr(sym->name, "@plt")) 205 if (strstr(sym->name, "@plt"))
196 return; 206 return;
197 207
198 if (!cursor || !cursor->ins || !ins__is_jump(cursor->ins) || 208 if (!disasm_line__is_valid_jump(cursor, sym))
199 !disasm_line__has_offset(cursor))
200 return; 209 return;
201 210
202 target = ab->offsets[cursor->ops.target.offset]; 211 target = ab->offsets[cursor->ops.target.offset];
@@ -788,17 +797,9 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser
788 struct disasm_line *dl = browser->offsets[offset], *dlt; 797 struct disasm_line *dl = browser->offsets[offset], *dlt;
789 struct browser_disasm_line *bdlt; 798 struct browser_disasm_line *bdlt;
790 799
791 if (!dl || !dl->ins || !ins__is_jump(dl->ins) || 800 if (!disasm_line__is_valid_jump(dl, sym))
792 !disasm_line__has_offset(dl))
793 continue; 801 continue;
794 802
795 if (dl->ops.target.offset >= size) {
796 ui__error("jump to after symbol!\n"
797 "size: %zx, jump target: %" PRIx64,
798 size, dl->ops.target.offset);
799 continue;
800 }
801
802 dlt = browser->offsets[dl->ops.target.offset]; 803 dlt = browser->offsets[dl->ops.target.offset];
803 /* 804 /*
804 * FIXME: Oops, no jump target? Buggy disassembler? Or do we 805 * FIXME: Oops, no jump target? Buggy disassembler? Or do we
@@ -921,7 +922,7 @@ out_free_offsets:
921 922
922#define ANNOTATE_CFG(n) \ 923#define ANNOTATE_CFG(n) \
923 { .name = #n, .value = &annotate_browser__opts.n, } 924 { .name = #n, .value = &annotate_browser__opts.n, }
924 925
925/* 926/*
926 * Keep the entries sorted, they are bsearch'ed 927 * Keep the entries sorted, they are bsearch'ed
927 */ 928 */