1*2b676bf0SNamhyung Kim #include "gtk.h" 2*2b676bf0SNamhyung Kim #include "util/debug.h" 3*2b676bf0SNamhyung Kim #include "util/annotate.h" 4*2b676bf0SNamhyung Kim #include "ui/helpline.h" 5*2b676bf0SNamhyung Kim 6*2b676bf0SNamhyung Kim 7*2b676bf0SNamhyung Kim enum { 8*2b676bf0SNamhyung Kim ANN_COL__PERCENT, 9*2b676bf0SNamhyung Kim ANN_COL__OFFSET, 10*2b676bf0SNamhyung Kim ANN_COL__LINE, 11*2b676bf0SNamhyung Kim 12*2b676bf0SNamhyung Kim MAX_ANN_COLS 13*2b676bf0SNamhyung Kim }; 14*2b676bf0SNamhyung Kim 15*2b676bf0SNamhyung Kim static const char *const col_names[] = { 16*2b676bf0SNamhyung Kim "Overhead", 17*2b676bf0SNamhyung Kim "Offset", 18*2b676bf0SNamhyung Kim "Line" 19*2b676bf0SNamhyung Kim }; 20*2b676bf0SNamhyung Kim 21*2b676bf0SNamhyung Kim static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym, 22*2b676bf0SNamhyung Kim struct disasm_line *dl, int evidx) 23*2b676bf0SNamhyung Kim { 24*2b676bf0SNamhyung Kim struct sym_hist *symhist; 25*2b676bf0SNamhyung Kim double percent = 0.0; 26*2b676bf0SNamhyung Kim const char *markup; 27*2b676bf0SNamhyung Kim int ret = 0; 28*2b676bf0SNamhyung Kim 29*2b676bf0SNamhyung Kim strcpy(buf, ""); 30*2b676bf0SNamhyung Kim 31*2b676bf0SNamhyung Kim if (dl->offset == (s64) -1) 32*2b676bf0SNamhyung Kim return 0; 33*2b676bf0SNamhyung Kim 34*2b676bf0SNamhyung Kim symhist = annotation__histogram(symbol__annotation(sym), evidx); 35*2b676bf0SNamhyung Kim if (!symhist->addr[dl->offset]) 36*2b676bf0SNamhyung Kim return 0; 37*2b676bf0SNamhyung Kim 38*2b676bf0SNamhyung Kim percent = 100.0 * symhist->addr[dl->offset] / symhist->sum; 39*2b676bf0SNamhyung Kim 40*2b676bf0SNamhyung Kim markup = perf_gtk__get_percent_color(percent); 41*2b676bf0SNamhyung Kim if (markup) 42*2b676bf0SNamhyung Kim ret += scnprintf(buf, size, "%s", markup); 43*2b676bf0SNamhyung Kim ret += scnprintf(buf + ret, size - ret, "%6.2f%%", percent); 44*2b676bf0SNamhyung Kim if (markup) 45*2b676bf0SNamhyung Kim ret += scnprintf(buf + ret, size - ret, "</span>"); 46*2b676bf0SNamhyung Kim 47*2b676bf0SNamhyung Kim return ret; 48*2b676bf0SNamhyung Kim } 49*2b676bf0SNamhyung Kim 50*2b676bf0SNamhyung Kim static int perf_gtk__get_offset(char *buf, size_t size, struct symbol *sym, 51*2b676bf0SNamhyung Kim struct map *map, struct disasm_line *dl) 52*2b676bf0SNamhyung Kim { 53*2b676bf0SNamhyung Kim u64 start = map__rip_2objdump(map, sym->start); 54*2b676bf0SNamhyung Kim 55*2b676bf0SNamhyung Kim strcpy(buf, ""); 56*2b676bf0SNamhyung Kim 57*2b676bf0SNamhyung Kim if (dl->offset == (s64) -1) 58*2b676bf0SNamhyung Kim return 0; 59*2b676bf0SNamhyung Kim 60*2b676bf0SNamhyung Kim return scnprintf(buf, size, "%"PRIx64, start + dl->offset); 61*2b676bf0SNamhyung Kim } 62*2b676bf0SNamhyung Kim 63*2b676bf0SNamhyung Kim static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym, 64*2b676bf0SNamhyung Kim struct map *map, int evidx, 65*2b676bf0SNamhyung Kim struct hist_browser_timer *hbt __maybe_unused) 66*2b676bf0SNamhyung Kim { 67*2b676bf0SNamhyung Kim struct disasm_line *pos, *n; 68*2b676bf0SNamhyung Kim struct annotation *notes; 69*2b676bf0SNamhyung Kim GType col_types[MAX_ANN_COLS]; 70*2b676bf0SNamhyung Kim GtkCellRenderer *renderer; 71*2b676bf0SNamhyung Kim GtkListStore *store; 72*2b676bf0SNamhyung Kim GtkWidget *view; 73*2b676bf0SNamhyung Kim int i; 74*2b676bf0SNamhyung Kim char s[512]; 75*2b676bf0SNamhyung Kim 76*2b676bf0SNamhyung Kim if (map->dso->annotate_warned) 77*2b676bf0SNamhyung Kim return -1; 78*2b676bf0SNamhyung Kim 79*2b676bf0SNamhyung Kim if (symbol__annotate(sym, map, 0) < 0) { 80*2b676bf0SNamhyung Kim ui__error("%s", ui_helpline__current); 81*2b676bf0SNamhyung Kim return -1; 82*2b676bf0SNamhyung Kim } 83*2b676bf0SNamhyung Kim 84*2b676bf0SNamhyung Kim notes = symbol__annotation(sym); 85*2b676bf0SNamhyung Kim 86*2b676bf0SNamhyung Kim for (i = 0; i < MAX_ANN_COLS; i++) { 87*2b676bf0SNamhyung Kim col_types[i] = G_TYPE_STRING; 88*2b676bf0SNamhyung Kim } 89*2b676bf0SNamhyung Kim store = gtk_list_store_newv(MAX_ANN_COLS, col_types); 90*2b676bf0SNamhyung Kim 91*2b676bf0SNamhyung Kim view = gtk_tree_view_new(); 92*2b676bf0SNamhyung Kim renderer = gtk_cell_renderer_text_new(); 93*2b676bf0SNamhyung Kim 94*2b676bf0SNamhyung Kim for (i = 0; i < MAX_ANN_COLS; i++) { 95*2b676bf0SNamhyung Kim gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), 96*2b676bf0SNamhyung Kim -1, col_names[i], renderer, 97*2b676bf0SNamhyung Kim i == ANN_COL__PERCENT ? "markup" : "text", 98*2b676bf0SNamhyung Kim i, NULL); 99*2b676bf0SNamhyung Kim } 100*2b676bf0SNamhyung Kim 101*2b676bf0SNamhyung Kim gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); 102*2b676bf0SNamhyung Kim g_object_unref(GTK_TREE_MODEL(store)); 103*2b676bf0SNamhyung Kim 104*2b676bf0SNamhyung Kim list_for_each_entry(pos, ¬es->src->source, node) { 105*2b676bf0SNamhyung Kim GtkTreeIter iter; 106*2b676bf0SNamhyung Kim 107*2b676bf0SNamhyung Kim gtk_list_store_append(store, &iter); 108*2b676bf0SNamhyung Kim 109*2b676bf0SNamhyung Kim if (perf_gtk__get_percent(s, sizeof(s), sym, pos, evidx)) 110*2b676bf0SNamhyung Kim gtk_list_store_set(store, &iter, ANN_COL__PERCENT, s, -1); 111*2b676bf0SNamhyung Kim if (perf_gtk__get_offset(s, sizeof(s), sym, map, pos)) 112*2b676bf0SNamhyung Kim gtk_list_store_set(store, &iter, ANN_COL__OFFSET, s, -1); 113*2b676bf0SNamhyung Kim gtk_list_store_set(store, &iter, ANN_COL__LINE, pos->line, -1); 114*2b676bf0SNamhyung Kim } 115*2b676bf0SNamhyung Kim 116*2b676bf0SNamhyung Kim gtk_container_add(GTK_CONTAINER(window), view); 117*2b676bf0SNamhyung Kim 118*2b676bf0SNamhyung Kim list_for_each_entry_safe(pos, n, ¬es->src->source, node) { 119*2b676bf0SNamhyung Kim list_del(&pos->node); 120*2b676bf0SNamhyung Kim disasm_line__free(pos); 121*2b676bf0SNamhyung Kim } 122*2b676bf0SNamhyung Kim 123*2b676bf0SNamhyung Kim return 0; 124*2b676bf0SNamhyung Kim } 125*2b676bf0SNamhyung Kim 126*2b676bf0SNamhyung Kim int symbol__gtk_annotate(struct symbol *sym, struct map *map, int evidx, 127*2b676bf0SNamhyung Kim struct hist_browser_timer *hbt) 128*2b676bf0SNamhyung Kim { 129*2b676bf0SNamhyung Kim GtkWidget *vbox; 130*2b676bf0SNamhyung Kim GtkWidget *notebook; 131*2b676bf0SNamhyung Kim GtkWidget *infobar; 132*2b676bf0SNamhyung Kim GtkWidget *statbar; 133*2b676bf0SNamhyung Kim GtkWidget *window; 134*2b676bf0SNamhyung Kim GtkWidget *scrolled_window; 135*2b676bf0SNamhyung Kim GtkWidget *tab_label; 136*2b676bf0SNamhyung Kim 137*2b676bf0SNamhyung Kim signal(SIGSEGV, perf_gtk__signal); 138*2b676bf0SNamhyung Kim signal(SIGFPE, perf_gtk__signal); 139*2b676bf0SNamhyung Kim signal(SIGINT, perf_gtk__signal); 140*2b676bf0SNamhyung Kim signal(SIGQUIT, perf_gtk__signal); 141*2b676bf0SNamhyung Kim signal(SIGTERM, perf_gtk__signal); 142*2b676bf0SNamhyung Kim 143*2b676bf0SNamhyung Kim window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 144*2b676bf0SNamhyung Kim gtk_window_set_title(GTK_WINDOW(window), "perf annotate"); 145*2b676bf0SNamhyung Kim 146*2b676bf0SNamhyung Kim g_signal_connect(window, "delete_event", gtk_main_quit, NULL); 147*2b676bf0SNamhyung Kim 148*2b676bf0SNamhyung Kim pgctx = perf_gtk__activate_context(window); 149*2b676bf0SNamhyung Kim if (!pgctx) 150*2b676bf0SNamhyung Kim return -1; 151*2b676bf0SNamhyung Kim 152*2b676bf0SNamhyung Kim vbox = gtk_vbox_new(FALSE, 0); 153*2b676bf0SNamhyung Kim notebook = gtk_notebook_new(); 154*2b676bf0SNamhyung Kim scrolled_window = gtk_scrolled_window_new(NULL, NULL); 155*2b676bf0SNamhyung Kim tab_label = gtk_label_new(sym->name); 156*2b676bf0SNamhyung Kim 157*2b676bf0SNamhyung Kim gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), 158*2b676bf0SNamhyung Kim GTK_POLICY_AUTOMATIC, 159*2b676bf0SNamhyung Kim GTK_POLICY_AUTOMATIC); 160*2b676bf0SNamhyung Kim 161*2b676bf0SNamhyung Kim gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, 162*2b676bf0SNamhyung Kim tab_label); 163*2b676bf0SNamhyung Kim gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); 164*2b676bf0SNamhyung Kim 165*2b676bf0SNamhyung Kim infobar = perf_gtk__setup_info_bar(); 166*2b676bf0SNamhyung Kim if (infobar) 167*2b676bf0SNamhyung Kim gtk_box_pack_start(GTK_BOX(vbox), infobar, FALSE, FALSE, 0); 168*2b676bf0SNamhyung Kim 169*2b676bf0SNamhyung Kim statbar = perf_gtk__setup_statusbar(); 170*2b676bf0SNamhyung Kim gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0); 171*2b676bf0SNamhyung Kim 172*2b676bf0SNamhyung Kim gtk_container_add(GTK_CONTAINER(window), vbox); 173*2b676bf0SNamhyung Kim 174*2b676bf0SNamhyung Kim perf_gtk__annotate_symbol(scrolled_window, sym, map, evidx, hbt); 175*2b676bf0SNamhyung Kim 176*2b676bf0SNamhyung Kim gtk_widget_show_all(window); 177*2b676bf0SNamhyung Kim 178*2b676bf0SNamhyung Kim perf_gtk__resize_window(window); 179*2b676bf0SNamhyung Kim gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 180*2b676bf0SNamhyung Kim 181*2b676bf0SNamhyung Kim gtk_main(); 182*2b676bf0SNamhyung Kim 183*2b676bf0SNamhyung Kim perf_gtk__deactivate_context(&pgctx); 184*2b676bf0SNamhyung Kim return 0; 185*2b676bf0SNamhyung Kim } 186