diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
| -rw-r--r-- | tools/perf/util/annotate.c | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index d102716c43a1..7eae5488ecea 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -110,10 +110,10 @@ static int jump__parse(struct ins_operands *ops) | |||
| 110 | { | 110 | { |
| 111 | const char *s = strchr(ops->raw, '+'); | 111 | const char *s = strchr(ops->raw, '+'); |
| 112 | 112 | ||
| 113 | ops->target.addr = strtoll(ops->raw, NULL, 16); | 113 | ops->target.addr = strtoull(ops->raw, NULL, 16); |
| 114 | 114 | ||
| 115 | if (s++ != NULL) | 115 | if (s++ != NULL) |
| 116 | ops->target.offset = strtoll(s, NULL, 16); | 116 | ops->target.offset = strtoull(s, NULL, 16); |
| 117 | else | 117 | else |
| 118 | ops->target.offset = UINT64_MAX; | 118 | ops->target.offset = UINT64_MAX; |
| 119 | 119 | ||
| @@ -809,7 +809,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
| 809 | end = map__rip_2objdump(map, sym->end); | 809 | end = map__rip_2objdump(map, sym->end); |
| 810 | 810 | ||
| 811 | offset = line_ip - start; | 811 | offset = line_ip - start; |
| 812 | if (offset < 0 || (u64)line_ip > end) | 812 | if ((u64)line_ip < start || (u64)line_ip > end) |
| 813 | offset = -1; | 813 | offset = -1; |
| 814 | else | 814 | else |
| 815 | parsed_line = tmp2 + 1; | 815 | parsed_line = tmp2 + 1; |
| @@ -821,11 +821,55 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
| 821 | if (dl == NULL) | 821 | if (dl == NULL) |
| 822 | return -1; | 822 | return -1; |
| 823 | 823 | ||
| 824 | if (dl->ops.target.offset == UINT64_MAX) | ||
| 825 | dl->ops.target.offset = dl->ops.target.addr - | ||
| 826 | map__rip_2objdump(map, sym->start); | ||
| 827 | |||
| 828 | /* | ||
| 829 | * kcore has no symbols, so add the call target name if it is on the | ||
| 830 | * same map. | ||
| 831 | */ | ||
| 832 | if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) { | ||
| 833 | struct symbol *s; | ||
| 834 | u64 ip = dl->ops.target.addr; | ||
| 835 | |||
| 836 | if (ip >= map->start && ip <= map->end) { | ||
| 837 | ip = map->map_ip(map, ip); | ||
| 838 | s = map__find_symbol(map, ip, NULL); | ||
| 839 | if (s && s->start == ip) | ||
| 840 | dl->ops.target.name = strdup(s->name); | ||
| 841 | } | ||
| 842 | } | ||
| 843 | |||
| 824 | disasm__add(¬es->src->source, dl); | 844 | disasm__add(¬es->src->source, dl); |
| 825 | 845 | ||
| 826 | return 0; | 846 | return 0; |
| 827 | } | 847 | } |
| 828 | 848 | ||
| 849 | static void delete_last_nop(struct symbol *sym) | ||
| 850 | { | ||
| 851 | struct annotation *notes = symbol__annotation(sym); | ||
| 852 | struct list_head *list = ¬es->src->source; | ||
| 853 | struct disasm_line *dl; | ||
| 854 | |||
| 855 | while (!list_empty(list)) { | ||
| 856 | dl = list_entry(list->prev, struct disasm_line, node); | ||
| 857 | |||
| 858 | if (dl->ins && dl->ins->ops) { | ||
| 859 | if (dl->ins->ops != &nop_ops) | ||
| 860 | return; | ||
| 861 | } else { | ||
| 862 | if (!strstr(dl->line, " nop ") && | ||
| 863 | !strstr(dl->line, " nopl ") && | ||
| 864 | !strstr(dl->line, " nopw ")) | ||
| 865 | return; | ||
| 866 | } | ||
| 867 | |||
| 868 | list_del(&dl->node); | ||
| 869 | disasm_line__free(dl); | ||
| 870 | } | ||
| 871 | } | ||
| 872 | |||
| 829 | int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) | 873 | int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) |
| 830 | { | 874 | { |
| 831 | struct dso *dso = map->dso; | 875 | struct dso *dso = map->dso; |
| @@ -864,7 +908,8 @@ fallback: | |||
| 864 | free_filename = false; | 908 | free_filename = false; |
| 865 | } | 909 | } |
| 866 | 910 | ||
| 867 | if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) { | 911 | if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && |
| 912 | !dso__is_kcore(dso)) { | ||
| 868 | char bf[BUILD_ID_SIZE * 2 + 16] = " with build id "; | 913 | char bf[BUILD_ID_SIZE * 2 + 16] = " with build id "; |
| 869 | char *build_id_msg = NULL; | 914 | char *build_id_msg = NULL; |
| 870 | 915 | ||
| @@ -898,7 +943,7 @@ fallback: | |||
| 898 | snprintf(command, sizeof(command), | 943 | snprintf(command, sizeof(command), |
| 899 | "%s %s%s --start-address=0x%016" PRIx64 | 944 | "%s %s%s --start-address=0x%016" PRIx64 |
| 900 | " --stop-address=0x%016" PRIx64 | 945 | " --stop-address=0x%016" PRIx64 |
| 901 | " -d %s %s -C %s|grep -v %s|expand", | 946 | " -d %s %s -C %s 2>/dev/null|grep -v %s|expand", |
| 902 | objdump_path ? objdump_path : "objdump", | 947 | objdump_path ? objdump_path : "objdump", |
| 903 | disassembler_style ? "-M " : "", | 948 | disassembler_style ? "-M " : "", |
| 904 | disassembler_style ? disassembler_style : "", | 949 | disassembler_style ? disassembler_style : "", |
| @@ -918,6 +963,13 @@ fallback: | |||
| 918 | if (symbol__parse_objdump_line(sym, map, file, privsize) < 0) | 963 | if (symbol__parse_objdump_line(sym, map, file, privsize) < 0) |
| 919 | break; | 964 | break; |
| 920 | 965 | ||
| 966 | /* | ||
| 967 | * kallsyms does not have symbol sizes so there may a nop at the end. | ||
| 968 | * Remove it. | ||
| 969 | */ | ||
| 970 | if (dso__is_kcore(dso)) | ||
| 971 | delete_last_nop(sym); | ||
| 972 | |||
| 921 | pclose(file); | 973 | pclose(file); |
| 922 | out_free_filename: | 974 | out_free_filename: |
| 923 | if (free_filename) | 975 | if (free_filename) |
