.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
---|
2 | | -#include "../../util/util.h" |
---|
3 | 2 | #include "../browser.h" |
---|
4 | 3 | #include "../helpline.h" |
---|
5 | 4 | #include "../ui.h" |
---|
6 | | -#include "../util.h" |
---|
7 | 5 | #include "../../util/annotate.h" |
---|
| 6 | +#include "../../util/debug.h" |
---|
| 7 | +#include "../../util/dso.h" |
---|
8 | 8 | #include "../../util/hist.h" |
---|
9 | 9 | #include "../../util/sort.h" |
---|
| 10 | +#include "../../util/map.h" |
---|
10 | 11 | #include "../../util/symbol.h" |
---|
11 | 12 | #include "../../util/evsel.h" |
---|
12 | 13 | #include "../../util/evlist.h" |
---|
.. | .. |
---|
14 | 15 | #include <pthread.h> |
---|
15 | 16 | #include <linux/kernel.h> |
---|
16 | 17 | #include <linux/string.h> |
---|
| 18 | +#include <linux/zalloc.h> |
---|
17 | 19 | #include <sys/ttydefaults.h> |
---|
18 | 20 | #include <asm/bug.h> |
---|
19 | 21 | |
---|
.. | .. |
---|
207 | 209 | ui_browser__mark_fused(browser, |
---|
208 | 210 | pcnt_width + 3 + notes->widths.addr + width, |
---|
209 | 211 | from - 1, |
---|
210 | | - to > from ? true : false); |
---|
| 212 | + to > from); |
---|
211 | 213 | } |
---|
212 | 214 | } |
---|
213 | 215 | |
---|
.. | .. |
---|
225 | 227 | return ret; |
---|
226 | 228 | } |
---|
227 | 229 | |
---|
228 | | -static int disasm__cmp(struct annotation_line *a, struct annotation_line *b) |
---|
| 230 | +static double disasm__cmp(struct annotation_line *a, struct annotation_line *b, |
---|
| 231 | + int percent_type) |
---|
229 | 232 | { |
---|
230 | 233 | int i; |
---|
231 | 234 | |
---|
232 | 235 | for (i = 0; i < a->data_nr; i++) { |
---|
233 | | - if (a->data[i].percent == b->data[i].percent) |
---|
| 236 | + if (a->data[i].percent[percent_type] == b->data[i].percent[percent_type]) |
---|
234 | 237 | continue; |
---|
235 | | - return a->data[i].percent < b->data[i].percent; |
---|
| 238 | + return a->data[i].percent[percent_type] - |
---|
| 239 | + b->data[i].percent[percent_type]; |
---|
236 | 240 | } |
---|
237 | 241 | return 0; |
---|
238 | 242 | } |
---|
239 | 243 | |
---|
240 | | -static void disasm_rb_tree__insert(struct rb_root *root, struct annotation_line *al) |
---|
| 244 | +static void disasm_rb_tree__insert(struct annotate_browser *browser, |
---|
| 245 | + struct annotation_line *al) |
---|
241 | 246 | { |
---|
| 247 | + struct rb_root *root = &browser->entries; |
---|
242 | 248 | struct rb_node **p = &root->rb_node; |
---|
243 | 249 | struct rb_node *parent = NULL; |
---|
244 | 250 | struct annotation_line *l; |
---|
.. | .. |
---|
247 | 253 | parent = *p; |
---|
248 | 254 | l = rb_entry(parent, struct annotation_line, rb_node); |
---|
249 | 255 | |
---|
250 | | - if (disasm__cmp(al, l)) |
---|
| 256 | + if (disasm__cmp(al, l, browser->opts->percent_type) < 0) |
---|
251 | 257 | p = &(*p)->rb_left; |
---|
252 | 258 | else |
---|
253 | 259 | p = &(*p)->rb_right; |
---|
.. | .. |
---|
294 | 300 | } |
---|
295 | 301 | |
---|
296 | 302 | static void annotate_browser__calc_percent(struct annotate_browser *browser, |
---|
297 | | - struct perf_evsel *evsel) |
---|
| 303 | + struct evsel *evsel) |
---|
298 | 304 | { |
---|
299 | 305 | struct map_symbol *ms = browser->b.priv; |
---|
300 | 306 | struct symbol *sym = ms->sym; |
---|
.. | .. |
---|
330 | 336 | RB_CLEAR_NODE(&pos->al.rb_node); |
---|
331 | 337 | continue; |
---|
332 | 338 | } |
---|
333 | | - disasm_rb_tree__insert(&browser->entries, &pos->al); |
---|
| 339 | + disasm_rb_tree__insert(browser, &pos->al); |
---|
334 | 340 | } |
---|
335 | 341 | pthread_mutex_unlock(¬es->lock); |
---|
336 | 342 | |
---|
.. | .. |
---|
401 | 407 | * to the calling function. |
---|
402 | 408 | */ |
---|
403 | 409 | static bool annotate_browser__callq(struct annotate_browser *browser, |
---|
404 | | - struct perf_evsel *evsel, |
---|
| 410 | + struct evsel *evsel, |
---|
405 | 411 | struct hist_browser_timer *hbt) |
---|
406 | 412 | { |
---|
407 | | - struct map_symbol *ms = browser->b.priv; |
---|
| 413 | + struct map_symbol *ms = browser->b.priv, target_ms; |
---|
408 | 414 | struct disasm_line *dl = disasm_line(browser->selection); |
---|
409 | 415 | struct annotation *notes; |
---|
410 | 416 | char title[SYM_TITLE_MAX_SIZE]; |
---|
.. | .. |
---|
417 | 423 | notes = symbol__annotation(dl->ops.target.sym); |
---|
418 | 424 | pthread_mutex_lock(¬es->lock); |
---|
419 | 425 | |
---|
420 | | - if (!symbol__hists(dl->ops.target.sym, evsel->evlist->nr_entries)) { |
---|
| 426 | + if (!symbol__hists(dl->ops.target.sym, evsel->evlist->core.nr_entries)) { |
---|
421 | 427 | pthread_mutex_unlock(¬es->lock); |
---|
422 | 428 | ui__warning("Not enough memory for annotating '%s' symbol!\n", |
---|
423 | 429 | dl->ops.target.sym->name); |
---|
424 | 430 | return true; |
---|
425 | 431 | } |
---|
426 | 432 | |
---|
| 433 | + target_ms.maps = ms->maps; |
---|
| 434 | + target_ms.map = ms->map; |
---|
| 435 | + target_ms.sym = dl->ops.target.sym; |
---|
427 | 436 | pthread_mutex_unlock(¬es->lock); |
---|
428 | | - symbol__tui_annotate(dl->ops.target.sym, ms->map, evsel, hbt, browser->opts); |
---|
| 437 | + symbol__tui_annotate(&target_ms, evsel, hbt, browser->opts); |
---|
429 | 438 | sym_title(ms->sym, ms->map, title, sizeof(title), browser->opts->percent_type); |
---|
430 | 439 | ui_browser__show_title(&browser->b, title); |
---|
431 | 440 | return true; |
---|
.. | .. |
---|
450 | 459 | } |
---|
451 | 460 | |
---|
452 | 461 | static bool annotate_browser__jump(struct annotate_browser *browser, |
---|
453 | | - struct perf_evsel *evsel, |
---|
| 462 | + struct evsel *evsel, |
---|
454 | 463 | struct hist_browser_timer *hbt) |
---|
455 | 464 | { |
---|
456 | 465 | struct disasm_line *dl = disasm_line(browser->selection); |
---|
.. | .. |
---|
651 | 660 | } |
---|
652 | 661 | |
---|
653 | 662 | static int annotate_browser__run(struct annotate_browser *browser, |
---|
654 | | - struct perf_evsel *evsel, |
---|
| 663 | + struct evsel *evsel, |
---|
655 | 664 | struct hist_browser_timer *hbt) |
---|
656 | 665 | { |
---|
657 | 666 | struct rb_node *nd = NULL; |
---|
.. | .. |
---|
745 | 754 | "? Search string backwards\n"); |
---|
746 | 755 | continue; |
---|
747 | 756 | case 'r': |
---|
748 | | - { |
---|
749 | | - script_browse(NULL); |
---|
750 | | - continue; |
---|
751 | | - } |
---|
| 757 | + script_browse(NULL, NULL); |
---|
| 758 | + annotate_browser__show(&browser->b, title, help); |
---|
| 759 | + continue; |
---|
752 | 760 | case 'k': |
---|
753 | 761 | notes->options->show_linenr = !notes->options->show_linenr; |
---|
754 | 762 | break; |
---|
.. | .. |
---|
825 | 833 | map_symbol__annotation_dump(ms, evsel, browser->opts); |
---|
826 | 834 | continue; |
---|
827 | 835 | case 't': |
---|
828 | | - if (notes->options->show_total_period) { |
---|
829 | | - notes->options->show_total_period = false; |
---|
830 | | - notes->options->show_nr_samples = true; |
---|
831 | | - } else if (notes->options->show_nr_samples) |
---|
832 | | - notes->options->show_nr_samples = false; |
---|
| 836 | + if (symbol_conf.show_total_period) { |
---|
| 837 | + symbol_conf.show_total_period = false; |
---|
| 838 | + symbol_conf.show_nr_samples = true; |
---|
| 839 | + } else if (symbol_conf.show_nr_samples) |
---|
| 840 | + symbol_conf.show_nr_samples = false; |
---|
833 | 841 | else |
---|
834 | | - notes->options->show_total_period = true; |
---|
| 842 | + symbol_conf.show_total_period = true; |
---|
835 | 843 | annotation__update_column_widths(notes); |
---|
836 | 844 | continue; |
---|
837 | 845 | case 'c': |
---|
.. | .. |
---|
864 | 872 | return key; |
---|
865 | 873 | } |
---|
866 | 874 | |
---|
867 | | -int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, |
---|
| 875 | +int map_symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel, |
---|
868 | 876 | struct hist_browser_timer *hbt, |
---|
869 | 877 | struct annotation_options *opts) |
---|
870 | 878 | { |
---|
871 | | - return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt, opts); |
---|
| 879 | + return symbol__tui_annotate(ms, evsel, hbt, opts); |
---|
872 | 880 | } |
---|
873 | 881 | |
---|
874 | | -int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, |
---|
| 882 | +int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel, |
---|
875 | 883 | struct hist_browser_timer *hbt, |
---|
876 | 884 | struct annotation_options *opts) |
---|
877 | 885 | { |
---|
.. | .. |
---|
882 | 890 | return map_symbol__tui_annotate(&he->ms, evsel, hbt, opts); |
---|
883 | 891 | } |
---|
884 | 892 | |
---|
885 | | -int symbol__tui_annotate(struct symbol *sym, struct map *map, |
---|
886 | | - struct perf_evsel *evsel, |
---|
| 893 | +int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel, |
---|
887 | 894 | struct hist_browser_timer *hbt, |
---|
888 | 895 | struct annotation_options *opts) |
---|
889 | 896 | { |
---|
| 897 | + struct symbol *sym = ms->sym; |
---|
890 | 898 | struct annotation *notes = symbol__annotation(sym); |
---|
891 | | - struct map_symbol ms = { |
---|
892 | | - .map = map, |
---|
893 | | - .sym = sym, |
---|
894 | | - }; |
---|
895 | 899 | struct annotate_browser browser = { |
---|
896 | 900 | .b = { |
---|
897 | 901 | .refresh = annotate_browser__refresh, |
---|
.. | .. |
---|
899 | 903 | .write = annotate_browser__write, |
---|
900 | 904 | .filter = disasm_line__filter, |
---|
901 | 905 | .extra_title_lines = 1, /* for hists__scnprintf_title() */ |
---|
902 | | - .priv = &ms, |
---|
| 906 | + .priv = ms, |
---|
903 | 907 | .use_navkeypressed = true, |
---|
904 | 908 | }, |
---|
905 | 909 | .opts = opts, |
---|
.. | .. |
---|
909 | 913 | if (sym == NULL) |
---|
910 | 914 | return -1; |
---|
911 | 915 | |
---|
912 | | - if (map->dso->annotate_warned) |
---|
| 916 | + if (ms->map->dso->annotate_warned) |
---|
913 | 917 | return -1; |
---|
914 | 918 | |
---|
915 | | - err = symbol__annotate2(sym, map, evsel, opts, &browser.arch); |
---|
| 919 | + err = symbol__annotate2(ms, evsel, opts, &browser.arch); |
---|
916 | 920 | if (err) { |
---|
917 | 921 | char msg[BUFSIZ]; |
---|
918 | | - symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); |
---|
| 922 | + symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); |
---|
919 | 923 | ui__error("Couldn't annotate %s:\n%s", sym->name, msg); |
---|
920 | 924 | goto out_free_offsets; |
---|
921 | 925 | } |
---|