aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-08-06 03:00:32 -0400
committerIngo Molnar <mingo@elte.hu>2010-08-06 03:00:32 -0400
commite66b688c6456e6a607a1636e228fe0395d6c7214 (patch)
treebcdd5a9d23d78d91419b3b61de76a5b9fb955008 /tools
parenta7c55cbee0c1bae9bf5a15a08300e91d88706e45 (diff)
parent71e7cf3a37ba6189fa7215555e8e760b400fc23b (diff)
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-report.c31
-rw-r--r--tools/perf/builtin-timechart.c4
-rw-r--r--tools/perf/builtin-trace.c19
-rw-r--r--tools/perf/util/hist.c3
-rw-r--r--tools/perf/util/newt.c242
-rw-r--r--tools/perf/util/probe-finder.c1
-rw-r--r--tools/perf/util/sort.c6
-rw-r--r--tools/perf/util/symbol.c30
-rw-r--r--tools/perf/util/symbol.h1
9 files changed, 297 insertions, 40 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 2f4b92925b26..55fc1f46892a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -348,7 +348,18 @@ static int __cmd_report(void)
348 hists__tty_browse_tree(&session->hists_tree, help); 348 hists__tty_browse_tree(&session->hists_tree, help);
349 349
350out_delete: 350out_delete:
351 perf_session__delete(session); 351 /*
352 * Speed up the exit process, for large files this can
353 * take quite a while.
354 *
355 * XXX Enable this when using valgrind or if we ever
356 * librarize this command.
357 *
358 * Also experiment with obstacks to see how much speed
359 * up we'll get here.
360 *
361 * perf_session__delete(session);
362 */
352 return ret; 363 return ret;
353} 364}
354 365
@@ -478,8 +489,24 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
478 * so don't allocate extra space that won't be used in the stdio 489 * so don't allocate extra space that won't be used in the stdio
479 * implementation. 490 * implementation.
480 */ 491 */
481 if (use_browser > 0) 492 if (use_browser > 0) {
482 symbol_conf.priv_size = sizeof(struct sym_priv); 493 symbol_conf.priv_size = sizeof(struct sym_priv);
494 /*
495 * For searching by name on the "Browse map details".
496 * providing it only in verbose mode not to bloat too
497 * much struct symbol.
498 */
499 if (verbose) {
500 /*
501 * XXX: Need to provide a less kludgy way to ask for
502 * more space per symbol, the u32 is for the index on
503 * the ui browser.
504 * See symbol__browser_index.
505 */
506 symbol_conf.priv_size += sizeof(u32);
507 symbol_conf.sort_by_name = true;
508 }
509 }
483 510
484 if (symbol__init() < 0) 511 if (symbol__init() < 0)
485 return -1; 512 return -1;
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 5161619d4714..9bcc38f0b706 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -455,8 +455,8 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te)
455 if (p->current->state != TYPE_NONE) 455 if (p->current->state != TYPE_NONE)
456 pid_put_sample(sw->next_pid, p->current->state, cpu, p->current->state_since, timestamp); 456 pid_put_sample(sw->next_pid, p->current->state, cpu, p->current->state_since, timestamp);
457 457
458 p->current->state_since = timestamp; 458 p->current->state_since = timestamp;
459 p->current->state = TYPE_RUNNING; 459 p->current->state = TYPE_RUNNING;
460 } 460 }
461 461
462 if (prev_p->current) { 462 if (prev_p->current) {
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 294da725a57d..40a6a2992d15 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1,13 +1,16 @@
1#include "builtin.h" 1#include "builtin.h"
2 2
3#include "util/util.h" 3#include "perf.h"
4#include "util/cache.h" 4#include "util/cache.h"
5#include "util/debug.h"
6#include "util/exec_cmd.h"
7#include "util/header.h"
8#include "util/parse-options.h"
9#include "util/session.h"
5#include "util/symbol.h" 10#include "util/symbol.h"
6#include "util/thread.h" 11#include "util/thread.h"
7#include "util/header.h"
8#include "util/exec_cmd.h"
9#include "util/trace-event.h" 12#include "util/trace-event.h"
10#include "util/session.h" 13#include "util/util.h"
11 14
12static char const *script_name; 15static char const *script_name;
13static char const *generate_script_lang; 16static char const *generate_script_lang;
@@ -59,14 +62,6 @@ static int cleanup_scripting(void)
59 return scripting_ops->stop_script(); 62 return scripting_ops->stop_script();
60} 63}
61 64
62#include "util/parse-options.h"
63
64#include "perf.h"
65#include "util/debug.h"
66
67#include "util/trace-event.h"
68#include "util/exec_cmd.h"
69
70static char const *input_name = "perf.data"; 65static char const *input_name = "perf.data";
71 66
72static int process_sample_event(event_t *event, struct perf_session *session) 67static int process_sample_event(event_t *event, struct perf_session *session)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index e7263d49bcf0..62ec9b0e4b9a 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -876,6 +876,9 @@ unsigned int hists__sort_list_width(struct hists *self)
876 if (!se->elide) 876 if (!se->elide)
877 ret += 2 + hists__col_len(self, se->se_width_idx); 877 ret += 2 + hists__col_len(self, se->se_width_idx);
878 878
879 if (verbose) /* Addr + origin */
880 ret += 3 + BITS_PER_LONG / 4;
881
879 return ret; 882 return ret;
880} 883}
881 884
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index 91de99b58445..e2deae0704d7 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -13,6 +13,7 @@
13#include <slang.h> 13#include <slang.h>
14#include <signal.h> 14#include <signal.h>
15#include <stdlib.h> 15#include <stdlib.h>
16#include <elf.h>
16#include <newt.h> 17#include <newt.h>
17#include <sys/ttydefaults.h> 18#include <sys/ttydefaults.h>
18 19
@@ -127,6 +128,39 @@ static void ui_helpline__puts(const char *msg)
127 ui_helpline__push(msg); 128 ui_helpline__push(msg);
128} 129}
129 130
131static int ui_entry__read(const char *title, char *bf, size_t size, int width)
132{
133 struct newtExitStruct es;
134 newtComponent form, entry;
135 const char *result;
136 int err = -1;
137
138 newtCenteredWindow(width, 1, title);
139 form = newtForm(NULL, NULL, 0);
140 if (form == NULL)
141 return -1;
142
143 entry = newtEntry(0, 0, "0x", width, &result, NEWT_FLAG_SCROLL);
144 if (entry == NULL)
145 goto out_free_form;
146
147 newtFormAddComponent(form, entry);
148 newtFormAddHotKey(form, NEWT_KEY_ENTER);
149 newtFormAddHotKey(form, NEWT_KEY_ESCAPE);
150 newtFormAddHotKey(form, NEWT_KEY_LEFT);
151 newtFormAddHotKey(form, CTRL('c'));
152 newtFormRun(form, &es);
153
154 if (result != NULL) {
155 strncpy(bf, result, size);
156 err = 0;
157 }
158out_free_form:
159 newtPopWindow();
160 newtFormDestroy(form);
161 return 0;
162}
163
130static char browser__last_msg[1024]; 164static char browser__last_msg[1024];
131 165
132int browser__show_help(const char *format, va_list ap) 166int browser__show_help(const char *format, va_list ap)
@@ -279,7 +313,8 @@ struct ui_browser {
279 void *first_visible_entry, *entries; 313 void *first_visible_entry, *entries;
280 u16 top, left, width, height; 314 u16 top, left, width, height;
281 void *priv; 315 void *priv;
282 unsigned int (*refresh_entries)(struct ui_browser *self); 316 unsigned int (*refresh)(struct ui_browser *self);
317 void (*write)(struct ui_browser *self, void *entry, int row);
283 void (*seek)(struct ui_browser *self, 318 void (*seek)(struct ui_browser *self,
284 off_t offset, int whence); 319 off_t offset, int whence);
285 u32 nr_entries; 320 u32 nr_entries;
@@ -316,6 +351,58 @@ static void ui_browser__list_head_seek(struct ui_browser *self,
316 self->first_visible_entry = pos; 351 self->first_visible_entry = pos;
317} 352}
318 353
354static void ui_browser__rb_tree_seek(struct ui_browser *self,
355 off_t offset, int whence)
356{
357 struct rb_root *root = self->entries;
358 struct rb_node *nd;
359
360 switch (whence) {
361 case SEEK_SET:
362 nd = rb_first(root);
363 break;
364 case SEEK_CUR:
365 nd = self->first_visible_entry;
366 break;
367 case SEEK_END:
368 nd = rb_last(root);
369 break;
370 default:
371 return;
372 }
373
374 if (offset > 0) {
375 while (offset-- != 0)
376 nd = rb_next(nd);
377 } else {
378 while (offset++ != 0)
379 nd = rb_prev(nd);
380 }
381
382 self->first_visible_entry = nd;
383}
384
385static unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self)
386{
387 struct rb_node *nd;
388 int row = 0;
389
390 if (self->first_visible_entry == NULL)
391 self->first_visible_entry = rb_first(self->entries);
392
393 nd = self->first_visible_entry;
394
395 while (nd != NULL) {
396 SLsmg_gotorc(self->top + row, self->left);
397 self->write(self, nd, row);
398 if (++row == self->height)
399 break;
400 nd = rb_next(nd);
401 }
402
403 return row;
404}
405
319static bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row) 406static bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row)
320{ 407{
321 return (self->first_visible_entry_idx + row) == self->index; 408 return (self->first_visible_entry_idx + row) == self->index;
@@ -418,12 +505,12 @@ static int objdump_line__show(struct objdump_line *self, struct list_head *head,
418 return 0; 505 return 0;
419} 506}
420 507
421static int ui_browser__refresh_entries(struct ui_browser *self) 508static int ui_browser__refresh(struct ui_browser *self)
422{ 509{
423 int row; 510 int row;
424 511
425 newtScrollbarSet(self->sb, self->index, self->nr_entries - 1); 512 newtScrollbarSet(self->sb, self->index, self->nr_entries - 1);
426 row = self->refresh_entries(self); 513 row = self->refresh(self);
427 SLsmg_set_color(HE_COLORSET_NORMAL); 514 SLsmg_set_color(HE_COLORSET_NORMAL);
428 SLsmg_fill_region(self->top + row, self->left, 515 SLsmg_fill_region(self->top + row, self->left,
429 self->height - row, self->width, ' '); 516 self->height - row, self->width, ' ');
@@ -433,7 +520,7 @@ static int ui_browser__refresh_entries(struct ui_browser *self)
433 520
434static int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es) 521static int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es)
435{ 522{
436 if (ui_browser__refresh_entries(self) < 0) 523 if (ui_browser__refresh(self) < 0)
437 return -1; 524 return -1;
438 525
439 while (1) { 526 while (1) {
@@ -504,7 +591,7 @@ static int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es)
504 default: 591 default:
505 return es->u.key; 592 return es->u.key;
506 } 593 }
507 if (ui_browser__refresh_entries(self) < 0) 594 if (ui_browser__refresh(self) < 0)
508 return -1; 595 return -1;
509 } 596 }
510 return 0; 597 return 0;
@@ -567,9 +654,9 @@ int hist_entry__tui_annotate(struct hist_entry *self)
567 ui_helpline__push("Press <- or ESC to exit"); 654 ui_helpline__push("Press <- or ESC to exit");
568 655
569 memset(&browser, 0, sizeof(browser)); 656 memset(&browser, 0, sizeof(browser));
570 browser.entries = &head; 657 browser.entries = &head;
571 browser.refresh_entries = hist_entry__annotate_browser_refresh; 658 browser.refresh = hist_entry__annotate_browser_refresh;
572 browser.seek = ui_browser__list_head_seek; 659 browser.seek = ui_browser__list_head_seek;
573 browser.priv = self; 660 browser.priv = self;
574 list_for_each_entry(pos, &head, node) { 661 list_for_each_entry(pos, &head, node) {
575 size_t line_len = strlen(pos->line); 662 size_t line_len = strlen(pos->line);
@@ -592,6 +679,128 @@ int hist_entry__tui_annotate(struct hist_entry *self)
592 return ret; 679 return ret;
593} 680}
594 681
682/* -------------------------------------------------------------------- */
683
684struct map_browser {
685 struct ui_browser b;
686 struct map *map;
687 u16 namelen;
688 u8 addrlen;
689};
690
691static void map_browser__write(struct ui_browser *self, void *nd, int row)
692{
693 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
694 struct map_browser *mb = container_of(self, struct map_browser, b);
695 bool current_entry = ui_browser__is_current_entry(self, row);
696 int color = ui_browser__percent_color(0, current_entry);
697
698 SLsmg_set_color(color);
699 slsmg_printf("%*llx %*llx %c ",
700 mb->addrlen, sym->start, mb->addrlen, sym->end,
701 sym->binding == STB_GLOBAL ? 'g' :
702 sym->binding == STB_LOCAL ? 'l' : 'w');
703 slsmg_write_nstring(sym->name, mb->namelen);
704}
705
706/* FIXME uber-kludgy, see comment on cmd_report... */
707static u32 *symbol__browser_index(struct symbol *self)
708{
709 return ((void *)self) - sizeof(struct rb_node) - sizeof(u32);
710}
711
712static int map_browser__search(struct map_browser *self)
713{
714 char target[512];
715 struct symbol *sym;
716 int err = ui_entry__read("Search by name/addr", target, sizeof(target), 40);
717
718 if (err)
719 return err;
720
721 if (target[0] == '0' && tolower(target[1]) == 'x') {
722 u64 addr = strtoull(target, NULL, 16);
723 sym = map__find_symbol(self->map, addr, NULL);
724 } else
725 sym = map__find_symbol_by_name(self->map, target, NULL);
726
727 if (sym != NULL) {
728 u32 *idx = symbol__browser_index(sym);
729
730 self->b.first_visible_entry = &sym->rb_node;
731 self->b.index = self->b.first_visible_entry_idx = *idx;
732 } else
733 ui_helpline__fpush("%s not found!", target);
734
735 return 0;
736}
737
738static int map_browser__run(struct map_browser *self, struct newtExitStruct *es)
739{
740 if (ui_browser__show(&self->b, self->map->dso->long_name) < 0)
741 return -1;
742
743 ui_helpline__fpush("Press <- or ESC to exit, %s / to search",
744 verbose ? "" : "restart with -v to use");
745 newtFormAddHotKey(self->b.form, NEWT_KEY_LEFT);
746 newtFormAddHotKey(self->b.form, NEWT_KEY_ENTER);
747 if (verbose)
748 newtFormAddHotKey(self->b.form, '/');
749
750 while (1) {
751 ui_browser__run(&self->b, es);
752
753 if (es->reason != NEWT_EXIT_HOTKEY)
754 break;
755 if (verbose && es->u.key == '/')
756 map_browser__search(self);
757 else
758 break;
759 }
760
761 newtFormDestroy(self->b.form);
762 newtPopWindow();
763 ui_helpline__pop();
764 return 0;
765}
766
767static int map__browse(struct map *self)
768{
769 struct map_browser mb = {
770 .b = {
771 .entries = &self->dso->symbols[self->type],
772 .refresh = ui_browser__rb_tree_refresh,
773 .seek = ui_browser__rb_tree_seek,
774 .write = map_browser__write,
775 },
776 .map = self,
777 };
778 struct newtExitStruct es;
779 struct rb_node *nd;
780 char tmp[BITS_PER_LONG / 4];
781 u64 maxaddr = 0;
782
783 for (nd = rb_first(mb.b.entries); nd; nd = rb_next(nd)) {
784 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
785
786 if (mb.namelen < pos->namelen)
787 mb.namelen = pos->namelen;
788 if (maxaddr < pos->end)
789 maxaddr = pos->end;
790 if (verbose) {
791 u32 *idx = symbol__browser_index(pos);
792 *idx = mb.b.nr_entries;
793 }
794 ++mb.b.nr_entries;
795 }
796
797 mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr);
798 mb.b.width += mb.addrlen * 2 + 4 + mb.namelen;
799 return map_browser__run(&mb, &es);
800}
801
802/* -------------------------------------------------------------------- */
803
595struct hist_browser { 804struct hist_browser {
596 struct ui_browser b; 805 struct ui_browser b;
597 struct hists *hists; 806 struct hists *hists;
@@ -602,7 +811,7 @@ struct hist_browser {
602static void hist_browser__reset(struct hist_browser *self); 811static void hist_browser__reset(struct hist_browser *self);
603static int hist_browser__run(struct hist_browser *self, const char *title, 812static int hist_browser__run(struct hist_browser *self, const char *title,
604 struct newtExitStruct *es); 813 struct newtExitStruct *es);
605static unsigned int hist_browser__refresh_entries(struct ui_browser *self); 814static unsigned int hist_browser__refresh(struct ui_browser *self);
606static void ui_browser__hists_seek(struct ui_browser *self, 815static void ui_browser__hists_seek(struct ui_browser *self,
607 off_t offset, int whence); 816 off_t offset, int whence);
608 817
@@ -612,7 +821,7 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
612 821
613 if (self) { 822 if (self) {
614 self->hists = hists; 823 self->hists = hists;
615 self->b.refresh_entries = hist_browser__refresh_entries; 824 self->b.refresh = hist_browser__refresh;
616 self->b.seek = ui_browser__hists_seek; 825 self->b.seek = ui_browser__hists_seek;
617 } 826 }
618 827
@@ -680,7 +889,8 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name)
680 const struct dso *dso; 889 const struct dso *dso;
681 char *options[16]; 890 char *options[16];
682 int nr_options = 0, choice = 0, i, 891 int nr_options = 0, choice = 0, i,
683 annotate = -2, zoom_dso = -2, zoom_thread = -2; 892 annotate = -2, zoom_dso = -2, zoom_thread = -2,
893 browse_map = -2;
684 894
685 if (hist_browser__run(browser, msg, &es)) 895 if (hist_browser__run(browser, msg, &es))
686 break; 896 break;
@@ -771,6 +981,10 @@ do_help:
771 (dso->kernel ? "the Kernel" : dso->short_name)) > 0) 981 (dso->kernel ? "the Kernel" : dso->short_name)) > 0)
772 zoom_dso = nr_options++; 982 zoom_dso = nr_options++;
773 983
984 if (browser->selection->map != NULL &&
985 asprintf(&options[nr_options], "Browse map details") > 0)
986 browse_map = nr_options++;
987
774 options[nr_options++] = (char *)"Exit"; 988 options[nr_options++] = (char *)"Exit";
775 989
776 choice = popup_menu(nr_options, options); 990 choice = popup_menu(nr_options, options);
@@ -800,7 +1014,9 @@ do_annotate:
800 continue; 1014 continue;
801 1015
802 hist_entry__tui_annotate(he); 1016 hist_entry__tui_annotate(he);
803 } else if (choice == zoom_dso) { 1017 } else if (choice == browse_map)
1018 map__browse(browser->selection->map);
1019 else if (choice == zoom_dso) {
804zoom_dso: 1020zoom_dso:
805 if (dso_filter) { 1021 if (dso_filter) {
806 pstack__remove(fstack, &dso_filter); 1022 pstack__remove(fstack, &dso_filter);
@@ -1213,7 +1429,7 @@ static int hist_browser__show_entry(struct hist_browser *self,
1213 return printed; 1429 return printed;
1214} 1430}
1215 1431
1216static unsigned int hist_browser__refresh_entries(struct ui_browser *self) 1432static unsigned int hist_browser__refresh(struct ui_browser *self)
1217{ 1433{
1218 unsigned row = 0; 1434 unsigned row = 0;
1219 struct rb_node *nd; 1435 struct rb_node *nd;
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 840f1aabbb74..6c7750da43d7 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -33,7 +33,6 @@
33#include <ctype.h> 33#include <ctype.h>
34#include <dwarf-regs.h> 34#include <dwarf-regs.h>
35 35
36#include "string.h"
37#include "event.h" 36#include "event.h"
38#include "debug.h" 37#include "debug.h"
39#include "util.h" 38#include "util.h"
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 1c61a4f4aa8a..b62a553cc67d 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -196,7 +196,8 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
196 196
197 if (verbose) { 197 if (verbose) {
198 char o = self->ms.map ? dso__symtab_origin(self->ms.map->dso) : '!'; 198 char o = self->ms.map ? dso__symtab_origin(self->ms.map->dso) : '!';
199 ret += repsep_snprintf(bf, size, "%#018llx %c ", self->ip, o); 199 ret += repsep_snprintf(bf, size, "%*Lx %c ",
200 BITS_PER_LONG / 4, self->ip, o);
200 } 201 }
201 202
202 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level); 203 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level);
@@ -204,7 +205,8 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
204 ret += repsep_snprintf(bf + ret, size - ret, "%s", 205 ret += repsep_snprintf(bf + ret, size - ret, "%s",
205 self->ms.sym->name); 206 self->ms.sym->name);
206 else 207 else
207 ret += repsep_snprintf(bf + ret, size - ret, "%#016llx", self->ip); 208 ret += repsep_snprintf(bf + ret, size - ret, "%*Lx",
209 BITS_PER_LONG / 4, self->ip);
208 210
209 return ret; 211 return ret;
210} 212}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 6f0dd90c36ce..b6f5970f9106 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -131,7 +131,8 @@ static void map_groups__fixup_end(struct map_groups *self)
131 __map_groups__fixup_end(self, i); 131 __map_groups__fixup_end(self, i);
132} 132}
133 133
134static struct symbol *symbol__new(u64 start, u64 len, const char *name) 134static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
135 const char *name)
135{ 136{
136 size_t namelen = strlen(name) + 1; 137 size_t namelen = strlen(name) + 1;
137 struct symbol *self = calloc(1, (symbol_conf.priv_size + 138 struct symbol *self = calloc(1, (symbol_conf.priv_size +
@@ -144,6 +145,7 @@ static struct symbol *symbol__new(u64 start, u64 len, const char *name)
144 145
145 self->start = start; 146 self->start = start;
146 self->end = len ? start + len - 1 : start; 147 self->end = len ? start + len - 1 : start;
148 self->binding = binding;
147 self->namelen = namelen - 1; 149 self->namelen = namelen - 1;
148 150
149 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end); 151 pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
@@ -160,8 +162,11 @@ void symbol__delete(struct symbol *self)
160 162
161static size_t symbol__fprintf(struct symbol *self, FILE *fp) 163static size_t symbol__fprintf(struct symbol *self, FILE *fp)
162{ 164{
163 return fprintf(fp, " %llx-%llx %s\n", 165 return fprintf(fp, " %llx-%llx %c %s\n",
164 self->start, self->end, self->name); 166 self->start, self->end,
167 self->binding == STB_GLOBAL ? 'g' :
168 self->binding == STB_LOCAL ? 'l' : 'w',
169 self->name);
165} 170}
166 171
167void dso__set_long_name(struct dso *self, char *name) 172void dso__set_long_name(struct dso *self, char *name)
@@ -453,6 +458,14 @@ struct process_kallsyms_args {
453 struct dso *dso; 458 struct dso *dso;
454}; 459};
455 460
461static u8 kallsyms2elf_type(char type)
462{
463 if (type == 'W')
464 return STB_WEAK;
465
466 return isupper(type) ? STB_GLOBAL : STB_LOCAL;
467}
468
456static int map__process_kallsym_symbol(void *arg, const char *name, 469static int map__process_kallsym_symbol(void *arg, const char *name,
457 char type, u64 start) 470 char type, u64 start)
458{ 471{
@@ -466,7 +479,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
466 /* 479 /*
467 * Will fix up the end later, when we have all symbols sorted. 480 * Will fix up the end later, when we have all symbols sorted.
468 */ 481 */
469 sym = symbol__new(start, 0, name); 482 sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
470 483
471 if (sym == NULL) 484 if (sym == NULL)
472 return -ENOMEM; 485 return -ENOMEM;
@@ -661,7 +674,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map,
661 if (len + 2 >= line_len) 674 if (len + 2 >= line_len)
662 continue; 675 continue;
663 676
664 sym = symbol__new(start, size, line + len); 677 sym = symbol__new(start, size, STB_GLOBAL, line + len);
665 678
666 if (sym == NULL) 679 if (sym == NULL)
667 goto out_delete_line; 680 goto out_delete_line;
@@ -873,7 +886,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
873 "%s@plt", elf_sym__name(&sym, symstrs)); 886 "%s@plt", elf_sym__name(&sym, symstrs));
874 887
875 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 888 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
876 sympltname); 889 STB_GLOBAL, sympltname);
877 if (!f) 890 if (!f)
878 goto out_elf_end; 891 goto out_elf_end;
879 892
@@ -895,7 +908,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map,
895 "%s@plt", elf_sym__name(&sym, symstrs)); 908 "%s@plt", elf_sym__name(&sym, symstrs));
896 909
897 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 910 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
898 sympltname); 911 STB_GLOBAL, sympltname);
899 if (!f) 912 if (!f)
900 goto out_elf_end; 913 goto out_elf_end;
901 914
@@ -1146,7 +1159,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1146 if (demangled != NULL) 1159 if (demangled != NULL)
1147 elf_name = demangled; 1160 elf_name = demangled;
1148new_symbol: 1161new_symbol:
1149 f = symbol__new(sym.st_value, sym.st_size, elf_name); 1162 f = symbol__new(sym.st_value, sym.st_size,
1163 GELF_ST_BIND(sym.st_info), elf_name);
1150 free(demangled); 1164 free(demangled);
1151 if (!f) 1165 if (!f)
1152 goto out_elf_end; 1166 goto out_elf_end;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 906be20011d9..b7a8da4af5a0 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -53,6 +53,7 @@ struct symbol {
53 u64 start; 53 u64 start;
54 u64 end; 54 u64 end;
55 u16 namelen; 55 u16 namelen;
56 u8 binding;
56 char name[0]; 57 char name[0];
57}; 58};
58 59