diff options
| -rw-r--r-- | tools/perf/builtin-annotate.c | 109 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/data_map.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/event.h | 8 | ||||
| -rw-r--r-- | tools/perf/util/map.c | 21 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 56 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 17 |
7 files changed, 132 insertions, 83 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 06f10278b28e..245692530de1 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -37,12 +37,44 @@ static int print_line; | |||
| 37 | static unsigned long page_size; | 37 | static unsigned long page_size; |
| 38 | static unsigned long mmap_window = 32; | 38 | static unsigned long mmap_window = 32; |
| 39 | 39 | ||
| 40 | struct sym_hist { | ||
| 41 | u64 sum; | ||
| 42 | u64 ip[0]; | ||
| 43 | }; | ||
| 44 | |||
| 40 | struct sym_ext { | 45 | struct sym_ext { |
| 41 | struct rb_node node; | 46 | struct rb_node node; |
| 42 | double percent; | 47 | double percent; |
| 43 | char *path; | 48 | char *path; |
| 44 | }; | 49 | }; |
| 45 | 50 | ||
| 51 | struct sym_priv { | ||
| 52 | struct sym_hist *hist; | ||
| 53 | struct sym_ext *ext; | ||
| 54 | }; | ||
| 55 | |||
| 56 | static const char *sym_hist_filter; | ||
| 57 | |||
| 58 | static int symbol_filter(struct map *map, struct symbol *sym) | ||
| 59 | { | ||
| 60 | if (strcmp(sym->name, sym_hist_filter) == 0) { | ||
| 61 | struct sym_priv *priv = dso__sym_priv(map->dso, sym); | ||
| 62 | const int size = (sizeof(*priv->hist) + | ||
| 63 | (sym->end - sym->start) * sizeof(u64)); | ||
| 64 | |||
| 65 | priv->hist = malloc(size); | ||
| 66 | if (priv->hist) | ||
| 67 | memset(priv->hist, 0, size); | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | /* | ||
| 71 | * FIXME: We should really filter it out, as we don't want to go thru symbols | ||
| 72 | * we're not interested, and if a DSO ends up with no symbols, delete it too, | ||
| 73 | * but right now the kernel loading routines in symbol.c bail out if no symbols | ||
| 74 | * are found, fix it later. | ||
| 75 | */ | ||
| 76 | return 0; | ||
| 77 | } | ||
| 46 | 78 | ||
| 47 | /* | 79 | /* |
| 48 | * collect histogram counts | 80 | * collect histogram counts |
| @@ -51,10 +83,16 @@ static void hist_hit(struct hist_entry *he, u64 ip) | |||
| 51 | { | 83 | { |
| 52 | unsigned int sym_size, offset; | 84 | unsigned int sym_size, offset; |
| 53 | struct symbol *sym = he->sym; | 85 | struct symbol *sym = he->sym; |
| 86 | struct sym_priv *priv; | ||
| 87 | struct sym_hist *h; | ||
| 54 | 88 | ||
| 55 | he->count++; | 89 | he->count++; |
| 56 | 90 | ||
| 57 | if (!sym || !sym->hist) | 91 | if (!sym || !he->map) |
| 92 | return; | ||
| 93 | |||
| 94 | priv = dso__sym_priv(he->map->dso, sym); | ||
| 95 | if (!priv->hist) | ||
| 58 | return; | 96 | return; |
| 59 | 97 | ||
| 60 | sym_size = sym->end - sym->start; | 98 | sym_size = sym->end - sym->start; |
| @@ -67,15 +105,16 @@ static void hist_hit(struct hist_entry *he, u64 ip) | |||
| 67 | if (offset >= sym_size) | 105 | if (offset >= sym_size) |
| 68 | return; | 106 | return; |
| 69 | 107 | ||
| 70 | sym->hist_sum++; | 108 | h = priv->hist; |
| 71 | sym->hist[offset]++; | 109 | h->sum++; |
| 110 | h->ip[offset]++; | ||
| 72 | 111 | ||
| 73 | if (verbose >= 3) | 112 | if (verbose >= 3) |
| 74 | printf("%p %s: count++ [ip: %p, %08Lx] => %Ld\n", | 113 | printf("%p %s: count++ [ip: %p, %08Lx] => %Ld\n", |
| 75 | (void *)(unsigned long)he->sym->start, | 114 | (void *)(unsigned long)he->sym->start, |
| 76 | he->sym->name, | 115 | he->sym->name, |
| 77 | (void *)(unsigned long)ip, ip - he->sym->start, | 116 | (void *)(unsigned long)ip, ip - he->sym->start, |
| 78 | sym->hist[offset]); | 117 | h->ip[offset]); |
| 79 | } | 118 | } |
| 80 | 119 | ||
| 81 | static int hist_entry__add(struct thread *thread, struct map *map, | 120 | static int hist_entry__add(struct thread *thread, struct map *map, |
| @@ -162,7 +201,9 @@ got_map: | |||
| 162 | static int | 201 | static int |
| 163 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | 202 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) |
| 164 | { | 203 | { |
| 165 | struct map *map = map__new(&event->mmap, NULL, 0); | 204 | struct map *map = map__new(&event->mmap, NULL, 0, |
| 205 | sizeof(struct sym_priv), symbol_filter, | ||
| 206 | verbose); | ||
| 166 | struct thread *thread = threads__findnew(event->mmap.pid); | 207 | struct thread *thread = threads__findnew(event->mmap.pid); |
| 167 | 208 | ||
| 168 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n", | 209 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n", |
| @@ -314,17 +355,19 @@ static int parse_line(FILE *file, struct hist_entry *he, u64 len) | |||
| 314 | unsigned int hits = 0; | 355 | unsigned int hits = 0; |
| 315 | double percent = 0.0; | 356 | double percent = 0.0; |
| 316 | const char *color; | 357 | const char *color; |
| 317 | struct sym_ext *sym_ext = sym->priv; | 358 | struct sym_priv *priv = dso__sym_priv(he->map->dso, sym); |
| 359 | struct sym_ext *sym_ext = priv->ext; | ||
| 360 | struct sym_hist *h = priv->hist; | ||
| 318 | 361 | ||
| 319 | offset = line_ip - start; | 362 | offset = line_ip - start; |
| 320 | if (offset < len) | 363 | if (offset < len) |
| 321 | hits = sym->hist[offset]; | 364 | hits = h->ip[offset]; |
| 322 | 365 | ||
| 323 | if (offset < len && sym_ext) { | 366 | if (offset < len && sym_ext) { |
| 324 | path = sym_ext[offset].path; | 367 | path = sym_ext[offset].path; |
| 325 | percent = sym_ext[offset].percent; | 368 | percent = sym_ext[offset].percent; |
| 326 | } else if (sym->hist_sum) | 369 | } else if (h->sum) |
| 327 | percent = 100.0 * hits / sym->hist_sum; | 370 | percent = 100.0 * hits / h->sum; |
| 328 | 371 | ||
| 329 | color = get_percent_color(percent); | 372 | color = get_percent_color(percent); |
| 330 | 373 | ||
| @@ -377,9 +420,10 @@ static void insert_source_line(struct sym_ext *sym_ext) | |||
| 377 | rb_insert_color(&sym_ext->node, &root_sym_ext); | 420 | rb_insert_color(&sym_ext->node, &root_sym_ext); |
| 378 | } | 421 | } |
| 379 | 422 | ||
| 380 | static void free_source_line(struct symbol *sym, int len) | 423 | static void free_source_line(struct hist_entry *he, int len) |
| 381 | { | 424 | { |
| 382 | struct sym_ext *sym_ext = sym->priv; | 425 | struct sym_priv *priv = dso__sym_priv(he->map->dso, he->sym); |
| 426 | struct sym_ext *sym_ext = priv->ext; | ||
| 383 | int i; | 427 | int i; |
| 384 | 428 | ||
| 385 | if (!sym_ext) | 429 | if (!sym_ext) |
| @@ -389,7 +433,7 @@ static void free_source_line(struct symbol *sym, int len) | |||
| 389 | free(sym_ext[i].path); | 433 | free(sym_ext[i].path); |
| 390 | free(sym_ext); | 434 | free(sym_ext); |
| 391 | 435 | ||
| 392 | sym->priv = NULL; | 436 | priv->ext = NULL; |
| 393 | root_sym_ext = RB_ROOT; | 437 | root_sym_ext = RB_ROOT; |
| 394 | } | 438 | } |
| 395 | 439 | ||
| @@ -402,15 +446,16 @@ get_source_line(struct hist_entry *he, int len, const char *filename) | |||
| 402 | int i; | 446 | int i; |
| 403 | char cmd[PATH_MAX * 2]; | 447 | char cmd[PATH_MAX * 2]; |
| 404 | struct sym_ext *sym_ext; | 448 | struct sym_ext *sym_ext; |
| 449 | struct sym_priv *priv = dso__sym_priv(he->map->dso, sym); | ||
| 450 | struct sym_hist *h = priv->hist; | ||
| 405 | 451 | ||
| 406 | if (!sym->hist_sum) | 452 | if (!h->sum) |
| 407 | return; | 453 | return; |
| 408 | 454 | ||
| 409 | sym->priv = calloc(len, sizeof(struct sym_ext)); | 455 | sym_ext = priv->ext = calloc(len, sizeof(struct sym_ext)); |
| 410 | if (!sym->priv) | 456 | if (!priv->ext) |
| 411 | return; | 457 | return; |
| 412 | 458 | ||
| 413 | sym_ext = sym->priv; | ||
| 414 | start = he->map->unmap_ip(he->map, sym->start); | 459 | start = he->map->unmap_ip(he->map, sym->start); |
| 415 | 460 | ||
| 416 | for (i = 0; i < len; i++) { | 461 | for (i = 0; i < len; i++) { |
| @@ -419,7 +464,7 @@ get_source_line(struct hist_entry *he, int len, const char *filename) | |||
| 419 | u64 offset; | 464 | u64 offset; |
| 420 | FILE *fp; | 465 | FILE *fp; |
| 421 | 466 | ||
| 422 | sym_ext[i].percent = 100.0 * sym->hist[i] / sym->hist_sum; | 467 | sym_ext[i].percent = 100.0 * h->ip[i] / h->sum; |
| 423 | if (sym_ext[i].percent <= 0.5) | 468 | if (sym_ext[i].percent <= 0.5) |
| 424 | continue; | 469 | continue; |
| 425 | 470 | ||
| @@ -530,7 +575,7 @@ static void annotate_sym(struct hist_entry *he) | |||
| 530 | 575 | ||
| 531 | pclose(file); | 576 | pclose(file); |
| 532 | if (print_line) | 577 | if (print_line) |
| 533 | free_source_line(sym, len); | 578 | free_source_line(he, len); |
| 534 | } | 579 | } |
| 535 | 580 | ||
| 536 | static void find_annotations(void) | 581 | static void find_annotations(void) |
| @@ -540,19 +585,23 @@ static void find_annotations(void) | |||
| 540 | 585 | ||
| 541 | for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) { | 586 | for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) { |
| 542 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); | 587 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); |
| 588 | struct sym_priv *priv; | ||
| 543 | 589 | ||
| 544 | if (he->sym && he->sym->hist) { | 590 | if (he->sym == NULL) |
| 545 | annotate_sym(he); | 591 | continue; |
| 546 | count++; | ||
| 547 | /* | ||
| 548 | * Since we have a hist_entry per IP for the same | ||
| 549 | * symbol, free he->sym->hist to signal we already | ||
| 550 | * processed this symbol. | ||
| 551 | */ | ||
| 552 | free(he->sym->hist); | ||
| 553 | he->sym->hist = NULL; | ||
| 554 | 592 | ||
| 555 | } | 593 | priv = dso__sym_priv(he->map->dso, he->sym); |
| 594 | if (priv->hist == NULL) | ||
| 595 | continue; | ||
| 596 | |||
| 597 | annotate_sym(he); | ||
| 598 | count++; | ||
| 599 | /* | ||
| 600 | * Since we have a hist_entry per IP for the same symbol, free | ||
| 601 | * he->sym->hist to signal we already processed this symbol. | ||
| 602 | */ | ||
| 603 | free(priv->hist); | ||
| 604 | priv->hist = NULL; | ||
| 556 | } | 605 | } |
| 557 | 606 | ||
| 558 | if (!count) | 607 | if (!count) |
| @@ -593,7 +642,7 @@ static int __cmd_annotate(void) | |||
| 593 | exit(0); | 642 | exit(0); |
| 594 | } | 643 | } |
| 595 | 644 | ||
| 596 | if (load_kernel() < 0) { | 645 | if (load_kernel(sizeof(struct sym_priv), symbol_filter) < 0) { |
| 597 | perror("failed to load kernel symbols"); | 646 | perror("failed to load kernel symbols"); |
| 598 | return EXIT_FAILURE; | 647 | return EXIT_FAILURE; |
| 599 | } | 648 | } |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index a4f8cc209151..bee207ce589a 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -680,7 +680,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
| 680 | static int | 680 | static int |
| 681 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | 681 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) |
| 682 | { | 682 | { |
| 683 | struct map *map = map__new(&event->mmap, cwd, cwdlen); | 683 | struct map *map = map__new(&event->mmap, cwd, cwdlen, 0, NULL, verbose); |
| 684 | struct thread *thread = threads__findnew(event->mmap.pid); | 684 | struct thread *thread = threads__findnew(event->mmap.pid); |
| 685 | 685 | ||
| 686 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n", | 686 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n", |
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c index 242b0555ab91..18accb8fee4d 100644 --- a/tools/perf/util/data_map.c +++ b/tools/perf/util/data_map.c | |||
| @@ -130,7 +130,7 @@ int mmap_dispatch_perf_file(struct perf_header **pheader, | |||
| 130 | if (curr_handler->sample_type_check(sample_type) < 0) | 130 | if (curr_handler->sample_type_check(sample_type) < 0) |
| 131 | exit(-1); | 131 | exit(-1); |
| 132 | 132 | ||
| 133 | if (load_kernel() < 0) { | 133 | if (load_kernel(0, NULL) < 0) { |
| 134 | perror("failed to load kernel symbols"); | 134 | perror("failed to load kernel symbols"); |
| 135 | return EXIT_FAILURE; | 135 | return EXIT_FAILURE; |
| 136 | } | 136 | } |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 6b5be56a8271..db59c8bbe49a 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -101,7 +101,13 @@ static inline u64 identity__map_ip(struct map *map __used, u64 ip) | |||
| 101 | return ip; | 101 | return ip; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen); | 104 | struct symbol; |
| 105 | |||
| 106 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); | ||
| 107 | |||
| 108 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, | ||
| 109 | unsigned int sym_priv_size, symbol_filter_t filter, | ||
| 110 | int v); | ||
| 105 | struct map *map__clone(struct map *self); | 111 | struct map *map__clone(struct map *self); |
| 106 | int map__overlap(struct map *l, struct map *r); | 112 | int map__overlap(struct map *l, struct map *r); |
| 107 | size_t map__fprintf(struct map *self, FILE *fp); | 113 | size_t map__fprintf(struct map *self, FILE *fp); |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 4e203d144f9e..55079c0200e0 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
| 4 | #include <string.h> | 4 | #include <string.h> |
| 5 | #include <stdio.h> | 5 | #include <stdio.h> |
| 6 | #include "debug.h" | ||
| 6 | 7 | ||
| 7 | static inline int is_anon_memory(const char *filename) | 8 | static inline int is_anon_memory(const char *filename) |
| 8 | { | 9 | { |
| @@ -19,7 +20,9 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen) | |||
| 19 | return n; | 20 | return n; |
| 20 | } | 21 | } |
| 21 | 22 | ||
| 22 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen) | 23 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, |
| 24 | unsigned int sym_priv_size, symbol_filter_t filter, | ||
| 25 | int v) | ||
| 23 | { | 26 | { |
| 24 | struct map *self = malloc(sizeof(*self)); | 27 | struct map *self = malloc(sizeof(*self)); |
| 25 | 28 | ||
| @@ -27,6 +30,7 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen) | |||
| 27 | const char *filename = event->filename; | 30 | const char *filename = event->filename; |
| 28 | char newfilename[PATH_MAX]; | 31 | char newfilename[PATH_MAX]; |
| 29 | int anon; | 32 | int anon; |
| 33 | bool new_dso; | ||
| 30 | 34 | ||
| 31 | if (cwd) { | 35 | if (cwd) { |
| 32 | int n = strcommon(filename, cwd, cwdlen); | 36 | int n = strcommon(filename, cwd, cwdlen); |
| @@ -49,10 +53,23 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen) | |||
| 49 | self->end = event->start + event->len; | 53 | self->end = event->start + event->len; |
| 50 | self->pgoff = event->pgoff; | 54 | self->pgoff = event->pgoff; |
| 51 | 55 | ||
| 52 | self->dso = dsos__findnew(filename); | 56 | self->dso = dsos__findnew(filename, sym_priv_size, &new_dso); |
| 53 | if (self->dso == NULL) | 57 | if (self->dso == NULL) |
| 54 | goto out_delete; | 58 | goto out_delete; |
| 55 | 59 | ||
| 60 | if (new_dso) { | ||
| 61 | int nr = dso__load(self->dso, self, filter, v); | ||
| 62 | |||
| 63 | if (nr < 0) | ||
| 64 | eprintf("Failed to open %s, continuing " | ||
| 65 | "without symbols\n", | ||
| 66 | self->dso->long_name); | ||
| 67 | else if (nr == 0) | ||
| 68 | eprintf("No symbols found in %s, maybe " | ||
| 69 | "install a debug package?\n", | ||
| 70 | self->dso->long_name); | ||
| 71 | } | ||
| 72 | |||
| 56 | if (self->dso == vdso || anon) | 73 | if (self->dso == vdso || anon) |
| 57 | self->map_ip = self->unmap_ip = identity__map_ip; | 74 | self->map_ip = self->unmap_ip = identity__map_ip; |
| 58 | else { | 75 | else { |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 3350119f6909..0a4898480d6d 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -11,8 +11,6 @@ | |||
| 11 | #include <elf.h> | 11 | #include <elf.h> |
| 12 | #include <sys/utsname.h> | 12 | #include <sys/utsname.h> |
| 13 | 13 | ||
| 14 | const char *sym_hist_filter; | ||
| 15 | |||
| 16 | enum dso_origin { | 14 | enum dso_origin { |
| 17 | DSO__ORIG_KERNEL = 0, | 15 | DSO__ORIG_KERNEL = 0, |
| 18 | DSO__ORIG_JAVA_JIT, | 16 | DSO__ORIG_JAVA_JIT, |
| @@ -86,22 +84,16 @@ static struct symbol *symbol__new(u64 start, u64 len, const char *name, | |||
| 86 | if (!self) | 84 | if (!self) |
| 87 | return NULL; | 85 | return NULL; |
| 88 | 86 | ||
| 89 | if (v > 2) | ||
| 90 | printf("new symbol: %016Lx [%08lx]: %s, hist: %p\n", | ||
| 91 | start, (unsigned long)len, name, self->hist); | ||
| 92 | |||
| 93 | self->hist = NULL; | ||
| 94 | self->hist_sum = 0; | ||
| 95 | |||
| 96 | if (sym_hist_filter && !strcmp(name, sym_hist_filter)) | ||
| 97 | self->hist = calloc(sizeof(u64), len); | ||
| 98 | |||
| 99 | if (priv_size) { | 87 | if (priv_size) { |
| 100 | memset(self, 0, priv_size); | 88 | memset(self, 0, priv_size); |
| 101 | self = ((void *)self) + priv_size; | 89 | self = ((void *)self) + priv_size; |
| 102 | } | 90 | } |
| 103 | self->start = start; | 91 | self->start = start; |
| 104 | self->end = len ? start + len - 1 : start; | 92 | self->end = len ? start + len - 1 : start; |
| 93 | |||
| 94 | if (v > 2) | ||
| 95 | printf("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end); | ||
| 96 | |||
| 105 | memcpy(self->name, name, namelen); | 97 | memcpy(self->name, name, namelen); |
| 106 | 98 | ||
| 107 | return self; | 99 | return self; |
| @@ -919,7 +911,8 @@ char dso__symtab_origin(const struct dso *self) | |||
| 919 | return origin[self->origin]; | 911 | return origin[self->origin]; |
| 920 | } | 912 | } |
| 921 | 913 | ||
| 922 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter, int v) | 914 | int dso__load(struct dso *self, struct map *map, |
| 915 | symbol_filter_t filter, int v) | ||
| 923 | { | 916 | { |
| 924 | int size = PATH_MAX; | 917 | int size = PATH_MAX; |
| 925 | char *name = malloc(size), *build_id = NULL; | 918 | char *name = malloc(size), *build_id = NULL; |
| @@ -1335,33 +1328,21 @@ static struct dso *dsos__find(const char *name) | |||
| 1335 | return NULL; | 1328 | return NULL; |
| 1336 | } | 1329 | } |
| 1337 | 1330 | ||
| 1338 | struct dso *dsos__findnew(const char *name) | 1331 | struct dso *dsos__findnew(const char *name, unsigned int sym_priv_size, |
| 1332 | bool *is_new) | ||
| 1339 | { | 1333 | { |
| 1340 | struct dso *dso = dsos__find(name); | 1334 | struct dso *dso = dsos__find(name); |
| 1341 | int nr; | ||
| 1342 | |||
| 1343 | if (dso) | ||
| 1344 | return dso; | ||
| 1345 | |||
| 1346 | dso = dso__new(name, 0); | ||
| 1347 | if (!dso) | ||
| 1348 | goto out_delete_dso; | ||
| 1349 | 1335 | ||
| 1350 | nr = dso__load(dso, NULL, NULL, verbose); | 1336 | if (!dso) { |
| 1351 | if (nr < 0) { | 1337 | dso = dso__new(name, sym_priv_size); |
| 1352 | eprintf("Failed to open: %s\n", name); | 1338 | if (dso) { |
| 1353 | goto out_delete_dso; | 1339 | dsos__add(dso); |
| 1354 | } | 1340 | *is_new = true; |
| 1355 | if (!nr) | 1341 | } |
| 1356 | eprintf("No symbols found in: %s, maybe install a debug package?\n", name); | 1342 | } else |
| 1357 | 1343 | *is_new = false; | |
| 1358 | dsos__add(dso); | ||
| 1359 | 1344 | ||
| 1360 | return dso; | 1345 | return dso; |
| 1361 | |||
| 1362 | out_delete_dso: | ||
| 1363 | dso__delete(dso); | ||
| 1364 | return NULL; | ||
| 1365 | } | 1346 | } |
| 1366 | 1347 | ||
| 1367 | void dsos__fprintf(FILE *fp) | 1348 | void dsos__fprintf(FILE *fp) |
| @@ -1372,9 +1353,10 @@ void dsos__fprintf(FILE *fp) | |||
| 1372 | dso__fprintf(pos, fp); | 1353 | dso__fprintf(pos, fp); |
| 1373 | } | 1354 | } |
| 1374 | 1355 | ||
| 1375 | int load_kernel(void) | 1356 | int load_kernel(unsigned int sym_priv_size, symbol_filter_t filter) |
| 1376 | { | 1357 | { |
| 1377 | if (dsos__load_kernel(vmlinux_name, 0, NULL, verbose, modules) <= 0) | 1358 | if (dsos__load_kernel(vmlinux_name, sym_priv_size, |
| 1359 | filter, verbose, modules) <= 0) | ||
| 1378 | return -1; | 1360 | return -1; |
| 1379 | 1361 | ||
| 1380 | vdso = dso__new("[vdso]", 0); | 1362 | vdso = dso__new("[vdso]", 0); |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2e4522edeb07..c2a777de9b7e 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define __PERF_SYMBOL 1 | 2 | #define __PERF_SYMBOL 1 |
| 3 | 3 | ||
| 4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 5 | #include <stdbool.h> | ||
| 5 | #include "types.h" | 6 | #include "types.h" |
| 6 | #include <linux/list.h> | 7 | #include <linux/list.h> |
| 7 | #include <linux/rbtree.h> | 8 | #include <linux/rbtree.h> |
| @@ -35,9 +36,6 @@ struct symbol { | |||
| 35 | struct rb_node rb_node; | 36 | struct rb_node rb_node; |
| 36 | u64 start; | 37 | u64 start; |
| 37 | u64 end; | 38 | u64 end; |
| 38 | u64 hist_sum; | ||
| 39 | u64 *hist; | ||
| 40 | void *priv; | ||
| 41 | char name[0]; | 39 | char name[0]; |
| 42 | }; | 40 | }; |
| 43 | 41 | ||
| @@ -54,10 +52,6 @@ struct dso { | |||
| 54 | char name[0]; | 52 | char name[0]; |
| 55 | }; | 53 | }; |
| 56 | 54 | ||
| 57 | extern const char *sym_hist_filter; | ||
| 58 | |||
| 59 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); | ||
| 60 | |||
| 61 | struct dso *dso__new(const char *name, unsigned int sym_priv_size); | 55 | struct dso *dso__new(const char *name, unsigned int sym_priv_size); |
| 62 | void dso__delete(struct dso *self); | 56 | void dso__delete(struct dso *self); |
| 63 | 57 | ||
| @@ -70,15 +64,16 @@ struct symbol *dso__find_symbol(struct dso *self, u64 ip); | |||
| 70 | 64 | ||
| 71 | int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size, | 65 | int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size, |
| 72 | symbol_filter_t filter, int verbose, int modules); | 66 | symbol_filter_t filter, int verbose, int modules); |
| 73 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter, | 67 | struct dso *dsos__findnew(const char *name, unsigned int sym_priv_size, |
| 74 | int verbose); | 68 | bool *is_new); |
| 75 | struct dso *dsos__findnew(const char *name); | 69 | int dso__load(struct dso *self, struct map *map, |
| 70 | symbol_filter_t filter, int v); | ||
| 76 | void dsos__fprintf(FILE *fp); | 71 | void dsos__fprintf(FILE *fp); |
| 77 | 72 | ||
| 78 | size_t dso__fprintf(struct dso *self, FILE *fp); | 73 | size_t dso__fprintf(struct dso *self, FILE *fp); |
| 79 | char dso__symtab_origin(const struct dso *self); | 74 | char dso__symtab_origin(const struct dso *self); |
| 80 | 75 | ||
| 81 | int load_kernel(void); | 76 | int load_kernel(unsigned int sym_priv_size, symbol_filter_t filter); |
| 82 | 77 | ||
| 83 | void symbol__init(void); | 78 | void symbol__init(void); |
| 84 | 79 | ||
