| .. | .. |
|---|
| 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 | } |
|---|