#include "gtk.h" #include "util/debug.h" #include "util/annotate.h" #include "util/evsel.h" #include "ui/helpline.h" enum { ANN_COL__PERCENT, ANN_COL__OFFSET, ANN_COL__LINE, MAX_ANN_COLS }; static const char *const col_names[] = { "Overhead", "Offset", "Line" }; static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym, struct disasm_line *dl, int evidx) { struct sym_hist *symhist; double percent = 0.0; const char *markup; int ret = 0; strcpy(buf, ""); if (dl->offset == (s64) -1) return 0; symhist = annotation__histogram(symbol__annotation(sym), evidx); if (!symbol_conf.event_group && !symhist->addr[dl->offset]) return 0; percent = 100.0 * symhist->addr[dl->offset] / symhist->sum; markup = perf_gtk__get_percent_color(percent); if (markup) ret += scnprintf(buf, size, "%s", markup); ret += scnprintf(buf + ret, size - ret, "%6.2f%%", percent); if (markup) ret += scnprintf(buf + ret, size - ret, ""); return ret; } static int perf_gtk__get_offset(char *buf, size_t size, struct symbol *sym, struct map *map, struct disasm_line *dl) { u64 start = map__rip_2objdump(map, sym->start); strcpy(buf, ""); if (dl->offset == (s64) -1) return 0; return scnprintf(buf, size, "%"PRIx64, start + dl->offset); } static int perf_gtk__get_line(char *buf, size_t size, struct disasm_line *dl) { int ret = 0; char *line = g_markup_escape_text(dl->line, -1); const char *markup = ""; strcpy(buf, ""); if (!line) return 0; if (dl->offset != (s64) -1) markup = NULL; if (markup) ret += scnprintf(buf, size, "%s", markup); ret += scnprintf(buf + ret, size - ret, "%s", line); if (markup) ret += scnprintf(buf + ret, size - ret, ""); g_free(line); return ret; } static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct hist_browser_timer *hbt __maybe_unused) { struct disasm_line *pos, *n; struct annotation *notes; GType col_types[MAX_ANN_COLS]; GtkCellRenderer *renderer; GtkListStore *store; GtkWidget *view; int i; char s[512]; notes = symbol__annotation(sym); for (i = 0; i < MAX_ANN_COLS; i++) { col_types[i] = G_TYPE_STRING; } store = gtk_list_store_newv(MAX_ANN_COLS, col_types); view = gtk_tree_view_new(); renderer = gtk_cell_renderer_text_new(); for (i = 0; i < MAX_ANN_COLS; i++) { gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, col_names[i], renderer, "markup", i, NULL); } gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); g_object_unref(GTK_TREE_MODEL(store)); list_for_each_entry(pos, ¬es->src->source, node) { GtkTreeIter iter; int ret = 0; gtk_list_store_append(store, &iter); if (perf_evsel__is_group_event(evsel)) { for (i = 0; i < evsel->nr_members; i++) { ret += perf_gtk__get_percent(s + ret, sizeof(s) - ret, sym, pos, evsel->idx + i); ret += scnprintf(s + ret, sizeof(s) - ret, " "); } } else { ret = perf_gtk__get_percent(s, sizeof(s), sym, pos, evsel->idx); } if (ret) gtk_list_store_set(store, &iter, ANN_COL__PERCENT, s, -1); if (perf_gtk__get_offset(s, sizeof(s), sym, map, pos)) gtk_list_store_set(store, &iter, ANN_COL__OFFSET, s, -1); if (perf_gtk__get_line(s, sizeof(s), pos)) gtk_list_store_set(store, &iter, ANN_COL__LINE, s, -1); } gtk_container_add(GTK_CONTAINER(window), view); list_for_each_entry_safe(pos, n, ¬es->src->source, node) { list_del(&pos->node); disasm_line__free(pos); } return 0; } static int symbol__gtk_annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct hist_browser_timer *hbt) { GtkWidget *window; GtkWidget *notebook; GtkWidget *scrolled_window; GtkWidget *tab_label; int err; if (map->dso->annotate_warned) return -1; err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), 0); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s: %s\n", sym->name, msg); return -1; } if (perf_gtk__is_active_context(pgctx)) { window = pgctx->main_window; notebook = pgctx->notebook; } else { GtkWidget *vbox; GtkWidget *infobar; GtkWidget *statbar; signal(SIGSEGV, perf_gtk__signal); signal(SIGFPE, perf_gtk__signal); signal(SIGINT, perf_gtk__signal); signal(SIGQUIT, perf_gtk__signal); signal(SIGTERM, perf_gtk__signal); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "perf annotate"); g_signal_connect(window, "delete_event", gtk_main_quit, NULL); pgctx = perf_gtk__activate_context(window); if (!pgctx) return -1; vbox = gtk_vbox_new(FALSE, 0); notebook = gtk_notebook_new(); pgctx->notebook = notebook; gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); infobar = perf_gtk__setup_info_bar(); if (infobar) { gtk_box_pack_start(GTK_BOX(vbox), infobar, FALSE, FALSE, 0); } statbar = perf_gtk__setup_statusbar(); gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(window), vbox); } scrolled_window = gtk_scrolled_window_new(NULL, NULL); tab_label = gtk_label_new(sym->name); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label); perf_gtk__annotate_symbol(scrolled_window, sym, map, evsel, hbt); return 0; } int hist_entry__gtk_annotate(struct hist_entry *he, struct perf_evsel *evsel, struct hist_browser_timer *hbt) { return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt); } void perf_gtk__show_annotations(void) { GtkWidget *window; if (!perf_gtk__is_active_context(pgctx)) return; window = pgctx->main_window; gtk_widget_show_all(window); perf_gtk__resize_window(window); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_main(); perf_gtk__deactivate_context(&pgctx); } f='/cgit.cgi/linux/net-next.git/log/tools/perf/util/annotate.h?h=nds-private-remove&id=e9f7f17d53003ee46ccbaf057f7820bfb6e76b9d'>logplain -rw-r--r--auxtrace.c47774logplain -rw-r--r--auxtrace.h22142logplain -rw-r--r--block-range.c6948logplain -rw-r--r--block-range.h1607logplain -rw-r--r--bpf-loader.c40787logplain -rw-r--r--bpf-loader.h6215logplain -rw-r--r--bpf-prologue.c11226logplain -rw-r--r--bpf-prologue.h847logplain -rw-r--r--build-id.c19054logplain -rw-r--r--build-id.h1859logplain d---------c++184logplain -rw-r--r--cache.h733logplain -rw-r--r--call-path.c2893logplain -rw-r--r--call-path.h2203logplain -rw-r--r--callchain.c29332logplain -rw-r--r--callchain.h7881logplain -rw-r--r--cgroup.c3195logplain -rw-r--r--cgroup.h359logplain -rw-r--r--cloexec.c1950logplain -rw-r--r--cloexec.h251logplain -rw-r--r--color.c4787logplain -rw-r--r--color.h1647logplain -rw-r--r--comm.c2239logplain -rw-r--r--comm.h561logplain -rw-r--r--config.c16262logplain -rw-r--r--config.h2113logplain -rw-r--r--counts.c1026logplain -rw-r--r--counts.h790logplain -rw-r--r--cpumap.c12627logplain -rw-r--r--cpumap.h1954logplain -rw-r--r--cs-etm.h2061logplain -rw-r--r--ctype.c2018logplain -rw-r--r--data-convert-bt.c36671logplain -rw-r--r--data-convert-bt.h302logplain -rw-r--r--data-convert.h141logplain -rw-r--r--data.c3459logplain -rw-r--r--data.h1369logplain -rw-r--r--db-export.c11434logplain -rw-r--r--db-export.h3816logplain -rw-r--r--debug.c4417logplain -rw-r--r--debug.h2023logplain -rw-r--r--demangle-java.c4219logplain -rw-r--r--demangle-java.h249logplain -rw-r--r--demangle-rust.c6602logplain -rw-r--r--demangle-rust.h170logplain -rw-r--r--drv_configs.c1834logplain -rw-r--r--drv_configs.h844logplain -rw-r--r--dso.c31994logplain -rw-r--r--dso.h10399logplain -rw-r--r--dwarf-aux.c33828logplain -rw-r--r--dwarf-aux.h5101logplain -rw-r--r--dwarf-regs.c1816logplain -rw-r--r--env.c1884logplain -rw-r--r--env.h1268logplain -rw-r--r--event.c36670logplain -rw-r--r--event.h15997logplain -rw-r--r--evlist.c47104logplain -rw-r--r--evlist.h12584logplain -rw-r--r--evsel.c63917logplain -rw-r--r--evsel.h13041logplain -rw-r--r--evsel_fprintf.c5831logplain -rw-r--r--find-vdso-map.c581logplain -rw-r--r--genelf.c11653logplain -rw-r--r--genelf.h1814logplain -rw-r--r--genelf_debug.c14374logplain -rwxr-xr-xgenerate-cmdlist.sh1141logplain -rw-r--r--group.h122logplain -rw-r--r--header.c73410logplain -rw-r--r--header.h4365logplain -rw-r--r--help-unknown-cmd.c3221logplain