diff options
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 561db6361f57..2ea1a2e4c0c2 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -22,6 +22,10 @@ | |||
22 | #include <limits.h> | 22 | #include <limits.h> |
23 | #include <sys/utsname.h> | 23 | #include <sys/utsname.h> |
24 | 24 | ||
25 | #ifndef KSYM_NAME_LEN | ||
26 | #define KSYM_NAME_LEN 128 | ||
27 | #endif | ||
28 | |||
25 | #ifndef NT_GNU_BUILD_ID | 29 | #ifndef NT_GNU_BUILD_ID |
26 | #define NT_GNU_BUILD_ID 3 | 30 | #define NT_GNU_BUILD_ID 3 |
27 | #endif | 31 | #endif |
@@ -93,7 +97,7 @@ static void symbols__fixup_end(struct rb_root *self) | |||
93 | prev = curr; | 97 | prev = curr; |
94 | curr = rb_entry(nd, struct symbol, rb_node); | 98 | curr = rb_entry(nd, struct symbol, rb_node); |
95 | 99 | ||
96 | if (prev->end == prev->start) | 100 | if (prev->end == prev->start && prev->end != curr->start) |
97 | prev->end = curr->start - 1; | 101 | prev->end = curr->start - 1; |
98 | } | 102 | } |
99 | 103 | ||
@@ -426,16 +430,25 @@ size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp) | |||
426 | 430 | ||
427 | int kallsyms__parse(const char *filename, void *arg, | 431 | int kallsyms__parse(const char *filename, void *arg, |
428 | int (*process_symbol)(void *arg, const char *name, | 432 | int (*process_symbol)(void *arg, const char *name, |
429 | char type, u64 start)) | 433 | char type, u64 start, u64 end)) |
430 | { | 434 | { |
431 | char *line = NULL; | 435 | char *line = NULL; |
432 | size_t n; | 436 | size_t n; |
433 | int err = 0; | 437 | int err = -1; |
438 | u64 prev_start = 0; | ||
439 | char prev_symbol_type = 0; | ||
440 | char *prev_symbol_name; | ||
434 | FILE *file = fopen(filename, "r"); | 441 | FILE *file = fopen(filename, "r"); |
435 | 442 | ||
436 | if (file == NULL) | 443 | if (file == NULL) |
437 | goto out_failure; | 444 | goto out_failure; |
438 | 445 | ||
446 | prev_symbol_name = malloc(KSYM_NAME_LEN); | ||
447 | if (prev_symbol_name == NULL) | ||
448 | goto out_close; | ||
449 | |||
450 | err = 0; | ||
451 | |||
439 | while (!feof(file)) { | 452 | while (!feof(file)) { |
440 | u64 start; | 453 | u64 start; |
441 | int line_len, len; | 454 | int line_len, len; |
@@ -455,14 +468,33 @@ int kallsyms__parse(const char *filename, void *arg, | |||
455 | continue; | 468 | continue; |
456 | 469 | ||
457 | symbol_type = toupper(line[len]); | 470 | symbol_type = toupper(line[len]); |
458 | symbol_name = line + len + 2; | 471 | len += 2; |
472 | symbol_name = line + len; | ||
473 | len = line_len - len; | ||
459 | 474 | ||
460 | err = process_symbol(arg, symbol_name, symbol_type, start); | 475 | if (len >= KSYM_NAME_LEN) { |
461 | if (err) | 476 | err = -1; |
462 | break; | 477 | break; |
478 | } | ||
479 | |||
480 | if (prev_symbol_type) { | ||
481 | u64 end = start; | ||
482 | if (end != prev_start) | ||
483 | --end; | ||
484 | err = process_symbol(arg, prev_symbol_name, | ||
485 | prev_symbol_type, prev_start, end); | ||
486 | if (err) | ||
487 | break; | ||
488 | } | ||
489 | |||
490 | memcpy(prev_symbol_name, symbol_name, len + 1); | ||
491 | prev_symbol_type = symbol_type; | ||
492 | prev_start = start; | ||
463 | } | 493 | } |
464 | 494 | ||
495 | free(prev_symbol_name); | ||
465 | free(line); | 496 | free(line); |
497 | out_close: | ||
466 | fclose(file); | 498 | fclose(file); |
467 | return err; | 499 | return err; |
468 | 500 | ||
@@ -484,7 +516,7 @@ static u8 kallsyms2elf_type(char type) | |||
484 | } | 516 | } |
485 | 517 | ||
486 | static int map__process_kallsym_symbol(void *arg, const char *name, | 518 | static int map__process_kallsym_symbol(void *arg, const char *name, |
487 | char type, u64 start) | 519 | char type, u64 start, u64 end) |
488 | { | 520 | { |
489 | struct symbol *sym; | 521 | struct symbol *sym; |
490 | struct process_kallsyms_args *a = arg; | 522 | struct process_kallsyms_args *a = arg; |
@@ -493,11 +525,8 @@ static int map__process_kallsym_symbol(void *arg, const char *name, | |||
493 | if (!symbol_type__is_a(type, a->map->type)) | 525 | if (!symbol_type__is_a(type, a->map->type)) |
494 | return 0; | 526 | return 0; |
495 | 527 | ||
496 | /* | 528 | sym = symbol__new(start, end - start + 1, |
497 | * Will fix up the end later, when we have all symbols sorted. | 529 | kallsyms2elf_type(type), name); |
498 | */ | ||
499 | sym = symbol__new(start, 0, kallsyms2elf_type(type), name); | ||
500 | |||
501 | if (sym == NULL) | 530 | if (sym == NULL) |
502 | return -ENOMEM; | 531 | return -ENOMEM; |
503 | /* | 532 | /* |
@@ -650,7 +679,6 @@ int dso__load_kallsyms(struct dso *self, const char *filename, | |||
650 | if (dso__load_all_kallsyms(self, filename, map) < 0) | 679 | if (dso__load_all_kallsyms(self, filename, map) < 0) |
651 | return -1; | 680 | return -1; |
652 | 681 | ||
653 | symbols__fixup_end(&self->symbols[map->type]); | ||
654 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) | 682 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) |
655 | self->origin = DSO__ORIG_GUEST_KERNEL; | 683 | self->origin = DSO__ORIG_GUEST_KERNEL; |
656 | else | 684 | else |
@@ -2162,7 +2190,7 @@ struct process_args { | |||
2162 | }; | 2190 | }; |
2163 | 2191 | ||
2164 | static int symbol__in_kernel(void *arg, const char *name, | 2192 | static int symbol__in_kernel(void *arg, const char *name, |
2165 | char type __used, u64 start) | 2193 | char type __used, u64 start, u64 end __used) |
2166 | { | 2194 | { |
2167 | struct process_args *args = arg; | 2195 | struct process_args *args = arg; |
2168 | 2196 | ||