diff options
-rw-r--r-- | tools/perf/util/annotate.c | 65 | ||||
-rw-r--r-- | tools/perf/util/annotate.h | 3 |
2 files changed, 67 insertions, 1 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index ef1d57def76d..a72585ab52e8 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -80,16 +80,50 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
80 | 80 | ||
81 | static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privsize) | 81 | static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privsize) |
82 | { | 82 | { |
83 | struct disasm_line *dl = malloc(sizeof(*dl) + privsize); | 83 | struct disasm_line *dl = zalloc(sizeof(*dl) + privsize); |
84 | 84 | ||
85 | if (dl != NULL) { | 85 | if (dl != NULL) { |
86 | dl->offset = offset; | 86 | dl->offset = offset; |
87 | dl->line = strdup(line); | 87 | dl->line = strdup(line); |
88 | if (dl->line == NULL) | 88 | if (dl->line == NULL) |
89 | goto out_delete; | 89 | goto out_delete; |
90 | |||
91 | if (offset != -1) { | ||
92 | char *name = dl->line, tmp; | ||
93 | |||
94 | while (isspace(name[0])) | ||
95 | ++name; | ||
96 | |||
97 | if (name[0] == '\0') | ||
98 | goto out_delete; | ||
99 | |||
100 | dl->operands = name + 1; | ||
101 | |||
102 | while (dl->operands[0] != '\0' && | ||
103 | !isspace(dl->operands[0])) | ||
104 | ++dl->operands; | ||
105 | |||
106 | tmp = dl->operands[0]; | ||
107 | dl->operands[0] = '\0'; | ||
108 | dl->name = strdup(name); | ||
109 | |||
110 | if (dl->name == NULL) | ||
111 | goto out_free_line; | ||
112 | |||
113 | dl->operands[0] = tmp; | ||
114 | |||
115 | if (dl->operands[0] != '\0') { | ||
116 | dl->operands++; | ||
117 | while (isspace(dl->operands[0])) | ||
118 | ++dl->operands; | ||
119 | } | ||
120 | } | ||
90 | } | 121 | } |
91 | 122 | ||
92 | return dl; | 123 | return dl; |
124 | |||
125 | out_free_line: | ||
126 | free(dl->line); | ||
93 | out_delete: | 127 | out_delete: |
94 | free(dl); | 128 | free(dl); |
95 | return NULL; | 129 | return NULL; |
@@ -98,6 +132,7 @@ out_delete: | |||
98 | void disasm_line__free(struct disasm_line *dl) | 132 | void disasm_line__free(struct disasm_line *dl) |
99 | { | 133 | { |
100 | free(dl->line); | 134 | free(dl->line); |
135 | free(dl->name); | ||
101 | free(dl); | 136 | free(dl); |
102 | } | 137 | } |
103 | 138 | ||
@@ -591,6 +626,34 @@ void disasm__purge(struct list_head *head) | |||
591 | } | 626 | } |
592 | } | 627 | } |
593 | 628 | ||
629 | static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp) | ||
630 | { | ||
631 | size_t printed; | ||
632 | |||
633 | if (dl->offset == -1) | ||
634 | return fprintf(fp, "%s\n", dl->line); | ||
635 | |||
636 | printed = fprintf(fp, "%#" PRIx64 " %s", dl->offset, dl->name); | ||
637 | |||
638 | if (dl->operands[0] != '\0') { | ||
639 | printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ", | ||
640 | dl->operands); | ||
641 | } | ||
642 | |||
643 | return printed + fprintf(fp, "\n"); | ||
644 | } | ||
645 | |||
646 | size_t disasm__fprintf(struct list_head *head, FILE *fp) | ||
647 | { | ||
648 | struct disasm_line *pos; | ||
649 | size_t printed = 0; | ||
650 | |||
651 | list_for_each_entry(pos, head, node) | ||
652 | printed += disasm_line__fprintf(pos, fp); | ||
653 | |||
654 | return printed; | ||
655 | } | ||
656 | |||
594 | int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, | 657 | int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, |
595 | bool print_lines, bool full_paths, int min_pcnt, | 658 | bool print_lines, bool full_paths, int min_pcnt, |
596 | int max_lines) | 659 | int max_lines) |
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 8bb68bb2a04a..dd7636d24133 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
@@ -11,10 +11,13 @@ struct disasm_line { | |||
11 | struct list_head node; | 11 | struct list_head node; |
12 | s64 offset; | 12 | s64 offset; |
13 | char *line; | 13 | char *line; |
14 | char *name; | ||
15 | char *operands; | ||
14 | }; | 16 | }; |
15 | 17 | ||
16 | void disasm_line__free(struct disasm_line *dl); | 18 | void disasm_line__free(struct disasm_line *dl); |
17 | struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos); | 19 | struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos); |
20 | size_t disasm__fprintf(struct list_head *head, FILE *fp); | ||
18 | 21 | ||
19 | struct sym_hist { | 22 | struct sym_hist { |
20 | u64 sum; | 23 | u64 sum; |