Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf annotate: Implement code + data type annotation

Sometimes it's useful to see both instructions and their data type
together. Let's extend the annotate code to use data type profiling
functions.

To make it easy to pass more argument, introduce a struct to carry
necessary information together. Also add a new annotation_option called
'code_with_type' to control the behavior. This is not enabled yet but
it'll be set later from the command line.

For simplicity, this is implemented for --stdio only.

Reviewed-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250310224925.799005-7-namhyung@kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

+60 -14
+59 -14
tools/perf/util/annotate.c
··· 760 760 return 0; 761 761 } 762 762 763 + static struct annotated_data_type * 764 + __hist_entry__get_data_type(struct hist_entry *he, struct arch *arch, 765 + struct debuginfo *dbg, struct disasm_line *dl, 766 + int *type_offset); 767 + 768 + struct annotation_print_data { 769 + struct hist_entry *he; 770 + struct evsel *evsel; 771 + struct arch *arch; 772 + struct debuginfo *dbg; 773 + u64 start; 774 + int addr_fmt_width; 775 + }; 776 + 763 777 static int 764 - annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start, 765 - struct evsel *evsel, struct annotation_options *opts, 766 - int printed, struct annotation_line *queue, int addr_fmt_width) 778 + annotation_line__print(struct annotation_line *al, struct annotation_print_data *apd, 779 + struct annotation_options *opts, int printed, 780 + struct annotation_line *queue) 767 781 { 782 + struct symbol *sym = apd->he->ms.sym; 768 783 struct disasm_line *dl = container_of(al, struct disasm_line, al); 769 784 struct annotation *notes = symbol__annotation(sym); 770 785 static const char *prev_line; ··· 819 804 list_for_each_entry_from(queue, &notes->src->source, node) { 820 805 if (queue == al) 821 806 break; 822 - annotation_line__print(queue, sym, start, evsel, 823 - &queue_opts, /*printed=*/0, 824 - /*queue=*/NULL, 825 - addr_fmt_width); 807 + annotation_line__print(queue, apd, &queue_opts, 808 + /*printed=*/0, /*queue=*/NULL); 826 809 } 827 810 } 828 811 ··· 845 832 846 833 printf(" : "); 847 834 848 - disasm_line__print(dl, start, addr_fmt_width); 835 + disasm_line__print(dl, apd->start, apd->addr_fmt_width); 836 + 837 + if (opts->code_with_type && apd->dbg) { 838 + struct annotated_data_type *data_type; 839 + int offset = 0; 840 + 841 + data_type = __hist_entry__get_data_type(apd->he, apd->arch, 842 + apd->dbg, dl, &offset); 843 + if (data_type && data_type != NO_TYPE) { 844 + char buf[4096]; 845 + 846 + printf("\t\t# data-type: %s", 847 + data_type->self.type_name); 848 + 849 + if (data_type != &stackop_type && 850 + data_type != &canary_type) 851 + printf(" +%#x", offset); 852 + 853 + if (annotated_data_type__get_member_name(data_type, 854 + buf, 855 + sizeof(buf), 856 + offset)) 857 + printf(" (%s)", buf); 858 + } 859 + } 849 860 850 861 /* 851 862 * Also color the filename and line if needed, with ··· 895 858 if (!*al->line) 896 859 printf(" %*s:\n", width, " "); 897 860 else 898 - printf(" %*s: %-*d %s\n", width, " ", addr_fmt_width, al->line_nr, al->line); 861 + printf(" %*s: %-*d %s\n", width, " ", apd->addr_fmt_width, 862 + al->line_nr, al->line); 899 863 } 900 864 901 865 return 0; ··· 1227 1189 struct sym_hist *h = annotation__histogram(notes, evsel); 1228 1190 struct annotation_line *pos, *queue = NULL; 1229 1191 struct annotation_options *opts = &annotate_opts; 1230 - u64 start = map__rip_2objdump(map, sym->start); 1231 - int printed = 2, queue_len = 0, addr_fmt_width; 1192 + struct annotation_print_data apd = { 1193 + .he = he, 1194 + .evsel = evsel, 1195 + .start = map__rip_2objdump(map, sym->start), 1196 + }; 1197 + int printed = 2, queue_len = 0; 1232 1198 int more = 0; 1233 1199 bool context = opts->context; 1234 1200 int width = annotation__pcnt_width(notes); ··· 1266 1224 if (verbose > 0) 1267 1225 symbol__annotate_hits(sym, evsel); 1268 1226 1269 - addr_fmt_width = annotated_source__addr_fmt_width(&notes->src->source, start); 1227 + apd.addr_fmt_width = annotated_source__addr_fmt_width(&notes->src->source, 1228 + apd.start); 1229 + evsel__get_arch(evsel, &apd.arch); 1230 + apd.dbg = debuginfo__new(filename); 1270 1231 1271 1232 list_for_each_entry(pos, &notes->src->source, node) { 1272 1233 int err; ··· 1279 1234 queue_len = 0; 1280 1235 } 1281 1236 1282 - err = annotation_line__print(pos, sym, start, evsel, 1283 - opts, printed, queue, addr_fmt_width); 1237 + err = annotation_line__print(pos, &apd, opts, printed, queue); 1284 1238 1285 1239 switch (err) { 1286 1240 case 0: ··· 1310 1266 } 1311 1267 } 1312 1268 1269 + debuginfo__delete(apd.dbg); 1313 1270 free(filename); 1314 1271 1315 1272 return more;
+1
tools/perf/util/annotate.h
··· 55 55 show_asm_raw, 56 56 show_br_cntr, 57 57 annotate_src, 58 + code_with_type, 58 59 full_addr; 59 60 u8 offset_level; 60 61 u8 disassemblers[MAX_DISASSEMBLERS];