1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2aca7a94dSNamhyung Kim #include "../../util/util.h" 3aca7a94dSNamhyung Kim #include "../browser.h" 4aca7a94dSNamhyung Kim #include "../helpline.h" 5aca7a94dSNamhyung Kim #include "../ui.h" 6aca7a94dSNamhyung Kim #include "../util.h" 7aca7a94dSNamhyung Kim #include "../../util/annotate.h" 8aca7a94dSNamhyung Kim #include "../../util/hist.h" 9aca7a94dSNamhyung Kim #include "../../util/sort.h" 10aca7a94dSNamhyung Kim #include "../../util/symbol.h" 11db8fd07aSNamhyung Kim #include "../../util/evsel.h" 1241840d21STaeung Song #include "../../util/config.h" 1369fb09f6SJin Yao #include "../../util/evlist.h" 14fd20e811SArnaldo Carvalho de Melo #include <inttypes.h> 15aca7a94dSNamhyung Kim #include <pthread.h> 16877a7a11SArnaldo Carvalho de Melo #include <linux/kernel.h> 178e99b6d4SArnaldo Carvalho de Melo #include <linux/string.h> 18b0742e90SArnaldo Carvalho de Melo #include <sys/ttydefaults.h> 19aca7a94dSNamhyung Kim 200c4a5bceSMartin Liška struct disasm_line_samples { 210c4a5bceSMartin Liška double percent; 22bb79a232SArnaldo Carvalho de Melo struct sym_hist_entry he; 230c4a5bceSMartin Liška }; 240c4a5bceSMartin Liška 2598bc80b0SArnaldo Carvalho de Melo static struct annotation_options annotate_browser__opts = { 26e9823b21SArnaldo Carvalho de Melo .use_offset = true, 27e9823b21SArnaldo Carvalho de Melo .jump_arrows = true, 28e9823b21SArnaldo Carvalho de Melo }; 29e9823b21SArnaldo Carvalho de Melo 30dcaa3948SJin Yao struct arch; 31dcaa3948SJin Yao 32aca7a94dSNamhyung Kim struct annotate_browser { 33aca7a94dSNamhyung Kim struct ui_browser b; 34aca7a94dSNamhyung Kim struct rb_root entries; 35aca7a94dSNamhyung Kim struct rb_node *curr_hot; 367bcbcd58SJiri Olsa struct annotation_line *selection; 37dcaa3948SJin Yao struct arch *arch; 38aca7a94dSNamhyung Kim bool searching_backwards; 39aca7a94dSNamhyung Kim char search_bf[128]; 40aca7a94dSNamhyung Kim }; 41aca7a94dSNamhyung Kim 4295aa89d9SArnaldo Carvalho de Melo static inline struct annotation *browser__annotation(struct ui_browser *browser) 4395aa89d9SArnaldo Carvalho de Melo { 4495aa89d9SArnaldo Carvalho de Melo struct map_symbol *ms = browser->priv; 4595aa89d9SArnaldo Carvalho de Melo return symbol__annotation(ms->sym); 4695aa89d9SArnaldo Carvalho de Melo } 4795aa89d9SArnaldo Carvalho de Melo 4816932d77SArnaldo Carvalho de Melo static bool disasm_line__filter(struct ui_browser *browser, void *entry) 49aca7a94dSNamhyung Kim { 5095aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(browser); 5116932d77SArnaldo Carvalho de Melo 5216932d77SArnaldo Carvalho de Melo if (notes->options->hide_src_code) { 53d5490b96SJiri Olsa struct annotation_line *al = list_entry(entry, struct annotation_line, node); 54d5490b96SJiri Olsa 55d5490b96SJiri Olsa return al->offset == -1; 56aca7a94dSNamhyung Kim } 57aca7a94dSNamhyung Kim 58aca7a94dSNamhyung Kim return false; 59aca7a94dSNamhyung Kim } 60aca7a94dSNamhyung Kim 6127feb761SArnaldo Carvalho de Melo static int ui_browser__jumps_percent_color(struct ui_browser *browser, int nr, bool current) 622402e4a9SArnaldo Carvalho de Melo { 6327feb761SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(browser); 64bc1c0f3dSArnaldo Carvalho de Melo 6527feb761SArnaldo Carvalho de Melo if (current && (!browser->use_navkeypressed || browser->navkeypressed)) 662402e4a9SArnaldo Carvalho de Melo return HE_COLORSET_SELECTED; 67bc1c0f3dSArnaldo Carvalho de Melo if (nr == notes->max_jump_sources) 682402e4a9SArnaldo Carvalho de Melo return HE_COLORSET_TOP; 692402e4a9SArnaldo Carvalho de Melo if (nr > 1) 702402e4a9SArnaldo Carvalho de Melo return HE_COLORSET_MEDIUM; 712402e4a9SArnaldo Carvalho de Melo return HE_COLORSET_NORMAL; 722402e4a9SArnaldo Carvalho de Melo } 732402e4a9SArnaldo Carvalho de Melo 7427feb761SArnaldo Carvalho de Melo static int ui_browser__set_jumps_percent_color(struct ui_browser *browser, int nr, bool current) 752402e4a9SArnaldo Carvalho de Melo { 7627feb761SArnaldo Carvalho de Melo int color = ui_browser__jumps_percent_color(browser, nr, current); 7727feb761SArnaldo Carvalho de Melo return ui_browser__set_color(browser, color); 782402e4a9SArnaldo Carvalho de Melo } 792402e4a9SArnaldo Carvalho de Melo 80a5433b3eSJiri Olsa static void disasm_line__write(struct disasm_line *dl, struct ui_browser *browser, 81a5433b3eSJiri Olsa char *bf, size_t size) 82aca7a94dSNamhyung Kim { 8395aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(browser); 8416932d77SArnaldo Carvalho de Melo 8575b49202SArnaldo Carvalho de Melo if (dl->ins.ops && dl->ins.ops->scnprintf) { 8675b49202SArnaldo Carvalho de Melo if (ins__is_jump(&dl->ins)) { 87d5490b96SJiri Olsa bool fwd = dl->ops.target.offset > dl->al.offset; 8851a0d455SArnaldo Carvalho de Melo 8905e8b080SArnaldo Carvalho de Melo ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR : 9051a0d455SArnaldo Carvalho de Melo SLSMG_UARROW_CHAR); 9151a0d455SArnaldo Carvalho de Melo SLsmg_write_char(' '); 9275b49202SArnaldo Carvalho de Melo } else if (ins__is_call(&dl->ins)) { 9305e8b080SArnaldo Carvalho de Melo ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); 9488298f5aSArnaldo Carvalho de Melo SLsmg_write_char(' '); 9575b49202SArnaldo Carvalho de Melo } else if (ins__is_ret(&dl->ins)) { 9605e8b080SArnaldo Carvalho de Melo ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); 974ea08b52SArnaldo Carvalho de Melo SLsmg_write_char(' '); 986ef94929SNaveen N. Rao } else { 996ef94929SNaveen N. Rao ui_browser__write_nstring(browser, " ", 2); 1004ea08b52SArnaldo Carvalho de Melo } 1016ef94929SNaveen N. Rao } else { 1026ef94929SNaveen N. Rao ui_browser__write_nstring(browser, " ", 2); 1034ea08b52SArnaldo Carvalho de Melo } 1044ea08b52SArnaldo Carvalho de Melo 10516932d77SArnaldo Carvalho de Melo disasm_line__scnprintf(dl, bf, size, !notes->options->use_offset); 106a5433b3eSJiri Olsa } 107a5433b3eSJiri Olsa 108a5433b3eSJiri Olsa static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) 109a5433b3eSJiri Olsa { 110a5433b3eSJiri Olsa struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); 11195aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(browser); 112a5433b3eSJiri Olsa struct annotation_line *al = list_entry(entry, struct annotation_line, node); 113a5433b3eSJiri Olsa bool current_entry = ui_browser__is_current_entry(browser, row); 11416932d77SArnaldo Carvalho de Melo bool change_color = (!notes->options->hide_src_code && 115a5433b3eSJiri Olsa (!current_entry || (browser->use_navkeypressed && 116a5433b3eSJiri Olsa !browser->navkeypressed))); 117a5433b3eSJiri Olsa int width = browser->width, printed; 1186af612d2SArnaldo Carvalho de Melo int i, pcnt_width = annotation__pcnt_width(notes), 1190e83a7e9SArnaldo Carvalho de Melo cycles_width = annotation__cycles_width(notes); 120a5433b3eSJiri Olsa double percent_max = 0.0; 121a5433b3eSJiri Olsa char bf[256]; 122a5433b3eSJiri Olsa bool show_title = false; 123a5433b3eSJiri Olsa 1240553e83dSArnaldo Carvalho de Melo for (i = 0; i < notes->nr_events; i++) { 125a5433b3eSJiri Olsa if (al->samples[i].percent > percent_max) 126a5433b3eSJiri Olsa percent_max = al->samples[i].percent; 127a5433b3eSJiri Olsa } 128a5433b3eSJiri Olsa 129a5433b3eSJiri Olsa if ((row == 0) && (al->offset == -1 || percent_max == 0.0)) { 1300e83a7e9SArnaldo Carvalho de Melo if (notes->have_cycles) { 131a5433b3eSJiri Olsa if (al->ipc == 0.0 && al->cycles == 0) 132a5433b3eSJiri Olsa show_title = true; 133a5433b3eSJiri Olsa } else 134a5433b3eSJiri Olsa show_title = true; 135a5433b3eSJiri Olsa } 136a5433b3eSJiri Olsa 137a5433b3eSJiri Olsa if (al->offset != -1 && percent_max != 0.0) { 1380553e83dSArnaldo Carvalho de Melo for (i = 0; i < notes->nr_events; i++) { 139a5433b3eSJiri Olsa ui_browser__set_percent_color(browser, 140a5433b3eSJiri Olsa al->samples[i].percent, 141a5433b3eSJiri Olsa current_entry); 14216932d77SArnaldo Carvalho de Melo if (notes->options->show_total_period) { 143a5433b3eSJiri Olsa ui_browser__printf(browser, "%11" PRIu64 " ", 144a5433b3eSJiri Olsa al->samples[i].he.period); 14516932d77SArnaldo Carvalho de Melo } else if (notes->options->show_nr_samples) { 146a5433b3eSJiri Olsa ui_browser__printf(browser, "%6" PRIu64 " ", 147a5433b3eSJiri Olsa al->samples[i].he.nr_samples); 148a5433b3eSJiri Olsa } else { 149a5433b3eSJiri Olsa ui_browser__printf(browser, "%6.2f ", 150a5433b3eSJiri Olsa al->samples[i].percent); 151a5433b3eSJiri Olsa } 152a5433b3eSJiri Olsa } 153a5433b3eSJiri Olsa } else { 154a5433b3eSJiri Olsa ui_browser__set_percent_color(browser, 0, current_entry); 155a5433b3eSJiri Olsa 156a5433b3eSJiri Olsa if (!show_title) 157a5433b3eSJiri Olsa ui_browser__write_nstring(browser, " ", pcnt_width); 158a5433b3eSJiri Olsa else { 159a5433b3eSJiri Olsa ui_browser__printf(browser, "%*s", pcnt_width, 16016932d77SArnaldo Carvalho de Melo notes->options->show_total_period ? "Period" : 16116932d77SArnaldo Carvalho de Melo notes->options->show_nr_samples ? "Samples" : "Percent"); 162a5433b3eSJiri Olsa } 163a5433b3eSJiri Olsa } 1640e83a7e9SArnaldo Carvalho de Melo if (notes->have_cycles) { 165a5433b3eSJiri Olsa if (al->ipc) 166c426e584SArnaldo Carvalho de Melo ui_browser__printf(browser, "%*.2f ", ANNOTATION__IPC_WIDTH - 1, al->ipc); 167a5433b3eSJiri Olsa else if (!show_title) 168c426e584SArnaldo Carvalho de Melo ui_browser__write_nstring(browser, " ", ANNOTATION__IPC_WIDTH); 169a5433b3eSJiri Olsa else 170c426e584SArnaldo Carvalho de Melo ui_browser__printf(browser, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC"); 171a5433b3eSJiri Olsa 172a5433b3eSJiri Olsa if (al->cycles) 173a5433b3eSJiri Olsa ui_browser__printf(browser, "%*" PRIu64 " ", 174c426e584SArnaldo Carvalho de Melo ANNOTATION__CYCLES_WIDTH - 1, al->cycles); 175a5433b3eSJiri Olsa else if (!show_title) 176c426e584SArnaldo Carvalho de Melo ui_browser__write_nstring(browser, " ", ANNOTATION__CYCLES_WIDTH); 177a5433b3eSJiri Olsa else 178c426e584SArnaldo Carvalho de Melo ui_browser__printf(browser, "%*s ", ANNOTATION__CYCLES_WIDTH - 1, "Cycle"); 179a5433b3eSJiri Olsa } 180a5433b3eSJiri Olsa 181a5433b3eSJiri Olsa SLsmg_write_char(' '); 182a5433b3eSJiri Olsa 183a5433b3eSJiri Olsa /* The scroll bar isn't being used */ 184a5433b3eSJiri Olsa if (!browser->navkeypressed) 185a5433b3eSJiri Olsa width += 1; 186a5433b3eSJiri Olsa 187a5433b3eSJiri Olsa if (!*al->line) 188a5433b3eSJiri Olsa ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width); 189a5433b3eSJiri Olsa else if (al->offset == -1) { 19016932d77SArnaldo Carvalho de Melo if (al->line_nr && notes->options->show_linenr) 191a5433b3eSJiri Olsa printed = scnprintf(bf, sizeof(bf), "%-*d ", 192*9761e86eSArnaldo Carvalho de Melo notes->widths.addr + 1, al->line_nr); 193a5433b3eSJiri Olsa else 194a5433b3eSJiri Olsa printed = scnprintf(bf, sizeof(bf), "%*s ", 195*9761e86eSArnaldo Carvalho de Melo notes->widths.addr, " "); 196a5433b3eSJiri Olsa ui_browser__write_nstring(browser, bf, printed); 197a5433b3eSJiri Olsa ui_browser__write_nstring(browser, al->line, width - printed - pcnt_width - cycles_width + 1); 198a5433b3eSJiri Olsa } else { 199a5433b3eSJiri Olsa u64 addr = al->offset; 200a5433b3eSJiri Olsa int color = -1; 201a5433b3eSJiri Olsa 20216932d77SArnaldo Carvalho de Melo if (!notes->options->use_offset) 2030ca693b3SArnaldo Carvalho de Melo addr += notes->start; 204a5433b3eSJiri Olsa 20516932d77SArnaldo Carvalho de Melo if (!notes->options->use_offset) { 206a5433b3eSJiri Olsa printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); 207a5433b3eSJiri Olsa } else { 2080db45bcfSArnaldo Carvalho de Melo if (al->jump_sources) { 20916932d77SArnaldo Carvalho de Melo if (notes->options->show_nr_jumps) { 210a5433b3eSJiri Olsa int prev; 211a5433b3eSJiri Olsa printed = scnprintf(bf, sizeof(bf), "%*d ", 212*9761e86eSArnaldo Carvalho de Melo notes->widths.jumps, 2130db45bcfSArnaldo Carvalho de Melo al->jump_sources); 2140db45bcfSArnaldo Carvalho de Melo prev = ui_browser__set_jumps_percent_color(browser, al->jump_sources, 215a5433b3eSJiri Olsa current_entry); 216a5433b3eSJiri Olsa ui_browser__write_nstring(browser, bf, printed); 217a5433b3eSJiri Olsa ui_browser__set_color(browser, prev); 218a5433b3eSJiri Olsa } 219a5433b3eSJiri Olsa 220a5433b3eSJiri Olsa printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ", 221*9761e86eSArnaldo Carvalho de Melo notes->widths.target, addr); 222a5433b3eSJiri Olsa } else { 223a5433b3eSJiri Olsa printed = scnprintf(bf, sizeof(bf), "%*s ", 224*9761e86eSArnaldo Carvalho de Melo notes->widths.addr, " "); 225a5433b3eSJiri Olsa } 226a5433b3eSJiri Olsa } 227a5433b3eSJiri Olsa 228a5433b3eSJiri Olsa if (change_color) 229a5433b3eSJiri Olsa color = ui_browser__set_color(browser, HE_COLORSET_ADDR); 230a5433b3eSJiri Olsa ui_browser__write_nstring(browser, bf, printed); 231a5433b3eSJiri Olsa if (change_color) 232a5433b3eSJiri Olsa ui_browser__set_color(browser, color); 233a5433b3eSJiri Olsa 234a5433b3eSJiri Olsa disasm_line__write(disasm_line(al), browser, bf, sizeof(bf)); 235a5433b3eSJiri Olsa 236bc1e5d60SArnaldo Carvalho de Melo ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed); 237aca7a94dSNamhyung Kim } 238aca7a94dSNamhyung Kim 239aca7a94dSNamhyung Kim if (current_entry) 240a5433b3eSJiri Olsa ab->selection = al; 241aca7a94dSNamhyung Kim } 242aca7a94dSNamhyung Kim 2437e63a13aSJin Yao static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) 2447e63a13aSJin Yao { 245a17c4ca0SJiri Olsa struct disasm_line *pos = list_prev_entry(cursor, al.node); 2467e63a13aSJin Yao const char *name; 2477e63a13aSJin Yao 2487e63a13aSJin Yao if (!pos) 2497e63a13aSJin Yao return false; 2507e63a13aSJin Yao 2517e63a13aSJin Yao if (ins__is_lock(&pos->ins)) 2527e63a13aSJin Yao name = pos->ops.locked.ins.name; 2537e63a13aSJin Yao else 2547e63a13aSJin Yao name = pos->ins.name; 2557e63a13aSJin Yao 2567e63a13aSJin Yao if (!name || !cursor->ins.name) 2577e63a13aSJin Yao return false; 2587e63a13aSJin Yao 2597e63a13aSJin Yao return ins__is_fused(ab->arch, name, cursor->ins.name); 2607e63a13aSJin Yao } 2617e63a13aSJin Yao 2629d1ef56dSArnaldo Carvalho de Melo static void annotate_browser__draw_current_jump(struct ui_browser *browser) 263a3f895beSArnaldo Carvalho de Melo { 264a3f895beSArnaldo Carvalho de Melo struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); 2657bcbcd58SJiri Olsa struct disasm_line *cursor = disasm_line(ab->selection); 266a5ef2702SJiri Olsa struct annotation_line *target; 26783b1f2aaSArnaldo Carvalho de Melo unsigned int from, to; 26832ae1efdSNamhyung Kim struct map_symbol *ms = ab->b.priv; 26932ae1efdSNamhyung Kim struct symbol *sym = ms->sym; 2700e83a7e9SArnaldo Carvalho de Melo struct annotation *notes = symbol__annotation(sym); 2716af612d2SArnaldo Carvalho de Melo u8 pcnt_width = annotation__pcnt_width(notes); 27200ea0eb2SArnaldo Carvalho de Melo int width; 27332ae1efdSNamhyung Kim 27432ae1efdSNamhyung Kim /* PLT symbols contain external offsets */ 27532ae1efdSNamhyung Kim if (strstr(sym->name, "@plt")) 27632ae1efdSNamhyung Kim return; 277a3f895beSArnaldo Carvalho de Melo 278865c66c4SFrederik Deweerdt if (!disasm_line__is_valid_jump(cursor, sym)) 279a3f895beSArnaldo Carvalho de Melo return; 280a3f895beSArnaldo Carvalho de Melo 2819c04409dSArnaldo Carvalho de Melo /* 2829c04409dSArnaldo Carvalho de Melo * This first was seen with a gcc function, _cpp_lex_token, that 2839c04409dSArnaldo Carvalho de Melo * has the usual jumps: 2849c04409dSArnaldo Carvalho de Melo * 2859c04409dSArnaldo Carvalho de Melo * │1159e6c: ↓ jne 115aa32 <_cpp_lex_token@@Base+0xf92> 2869c04409dSArnaldo Carvalho de Melo * 2879c04409dSArnaldo Carvalho de Melo * I.e. jumps to a label inside that function (_cpp_lex_token), and 2889c04409dSArnaldo Carvalho de Melo * those works, but also this kind: 2899c04409dSArnaldo Carvalho de Melo * 2909c04409dSArnaldo Carvalho de Melo * │1159e8b: ↓ jne c469be <cpp_named_operator2name@@Base+0xa72> 2919c04409dSArnaldo Carvalho de Melo * 2929c04409dSArnaldo Carvalho de Melo * I.e. jumps to another function, outside _cpp_lex_token, which 2939c04409dSArnaldo Carvalho de Melo * are not being correctly handled generating as a side effect references 2949c04409dSArnaldo Carvalho de Melo * to ab->offset[] entries that are set to NULL, so to make this code 2959c04409dSArnaldo Carvalho de Melo * more robust, check that here. 2969c04409dSArnaldo Carvalho de Melo * 2979c04409dSArnaldo Carvalho de Melo * A proper fix for will be put in place, looking at the function 2989c04409dSArnaldo Carvalho de Melo * name right after the '<' token and probably treating this like a 2999c04409dSArnaldo Carvalho de Melo * 'call' instruction. 3009c04409dSArnaldo Carvalho de Melo */ 3019d6bb41dSArnaldo Carvalho de Melo target = notes->offsets[cursor->ops.target.offset]; 3029c04409dSArnaldo Carvalho de Melo if (target == NULL) { 3039d6bb41dSArnaldo Carvalho de Melo ui_helpline__printf("WARN: jump target inconsistency, press 'o', notes->offsets[%#x] = NULL\n", 3049c04409dSArnaldo Carvalho de Melo cursor->ops.target.offset); 3059c04409dSArnaldo Carvalho de Melo return; 3069c04409dSArnaldo Carvalho de Melo } 3079d1ef56dSArnaldo Carvalho de Melo 30816932d77SArnaldo Carvalho de Melo if (notes->options->hide_src_code) { 3094850c92eSArnaldo Carvalho de Melo from = cursor->al.idx_asm; 3104850c92eSArnaldo Carvalho de Melo to = target->idx_asm; 311a3f895beSArnaldo Carvalho de Melo } else { 3124850c92eSArnaldo Carvalho de Melo from = (u64)cursor->al.idx; 3134850c92eSArnaldo Carvalho de Melo to = (u64)target->idx; 314a3f895beSArnaldo Carvalho de Melo } 315a3f895beSArnaldo Carvalho de Melo 3160e83a7e9SArnaldo Carvalho de Melo width = annotation__cycles_width(notes); 317b40982e8SJin Yao 31878ce08dfSTaeung Song ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS); 319b40982e8SJin Yao __ui_browser__line_arrow(browser, 320*9761e86eSArnaldo Carvalho de Melo pcnt_width + 2 + notes->widths.addr + width, 321c7e7b610SNamhyung Kim from, to); 3227e63a13aSJin Yao 3237e63a13aSJin Yao if (is_fused(ab, cursor)) { 3247e63a13aSJin Yao ui_browser__mark_fused(browser, 325*9761e86eSArnaldo Carvalho de Melo pcnt_width + 3 + notes->widths.addr + width, 3267e63a13aSJin Yao from - 1, 3277e63a13aSJin Yao to > from ? true : false); 3287e63a13aSJin Yao } 329a3f895beSArnaldo Carvalho de Melo } 330a3f895beSArnaldo Carvalho de Melo 331a3f895beSArnaldo Carvalho de Melo static unsigned int annotate_browser__refresh(struct ui_browser *browser) 332a3f895beSArnaldo Carvalho de Melo { 33395aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(browser); 334a3f895beSArnaldo Carvalho de Melo int ret = ui_browser__list_head_refresh(browser); 3356af612d2SArnaldo Carvalho de Melo int pcnt_width = annotation__pcnt_width(notes); 336a3f895beSArnaldo Carvalho de Melo 33716932d77SArnaldo Carvalho de Melo if (notes->options->jump_arrows) 3389d1ef56dSArnaldo Carvalho de Melo annotate_browser__draw_current_jump(browser); 339a3f895beSArnaldo Carvalho de Melo 34083b1f2aaSArnaldo Carvalho de Melo ui_browser__set_color(browser, HE_COLORSET_NORMAL); 341c7e7b610SNamhyung Kim __ui_browser__vline(browser, pcnt_width, 0, browser->height - 1); 342a3f895beSArnaldo Carvalho de Melo return ret; 343a3f895beSArnaldo Carvalho de Melo } 344a3f895beSArnaldo Carvalho de Melo 345b15636c6SJiri Olsa static int disasm__cmp(struct annotation_line *a, struct annotation_line *b) 346c7e7b610SNamhyung Kim { 347c7e7b610SNamhyung Kim int i; 348c7e7b610SNamhyung Kim 349b15636c6SJiri Olsa for (i = 0; i < a->samples_nr; i++) { 3500c4a5bceSMartin Liška if (a->samples[i].percent == b->samples[i].percent) 351c7e7b610SNamhyung Kim continue; 3520c4a5bceSMartin Liška return a->samples[i].percent < b->samples[i].percent; 353c7e7b610SNamhyung Kim } 354c7e7b610SNamhyung Kim return 0; 355c7e7b610SNamhyung Kim } 356c7e7b610SNamhyung Kim 357b15636c6SJiri Olsa static void disasm_rb_tree__insert(struct rb_root *root, struct annotation_line *al) 358aca7a94dSNamhyung Kim { 35929ed6e76SArnaldo Carvalho de Melo struct rb_node **p = &root->rb_node; 360aca7a94dSNamhyung Kim struct rb_node *parent = NULL; 3613ab6db8dSJiri Olsa struct annotation_line *l; 362aca7a94dSNamhyung Kim 363aca7a94dSNamhyung Kim while (*p != NULL) { 364aca7a94dSNamhyung Kim parent = *p; 3653ab6db8dSJiri Olsa l = rb_entry(parent, struct annotation_line, rb_node); 366c7e7b610SNamhyung Kim 367b15636c6SJiri Olsa if (disasm__cmp(al, l)) 368aca7a94dSNamhyung Kim p = &(*p)->rb_left; 369aca7a94dSNamhyung Kim else 370aca7a94dSNamhyung Kim p = &(*p)->rb_right; 371aca7a94dSNamhyung Kim } 3723ab6db8dSJiri Olsa rb_link_node(&al->rb_node, parent, p); 3733ab6db8dSJiri Olsa rb_insert_color(&al->rb_node, root); 374aca7a94dSNamhyung Kim } 375aca7a94dSNamhyung Kim 37605e8b080SArnaldo Carvalho de Melo static void annotate_browser__set_top(struct annotate_browser *browser, 377ec03a77dSJiri Olsa struct annotation_line *pos, u32 idx) 378aca7a94dSNamhyung Kim { 379aca7a94dSNamhyung Kim unsigned back; 380aca7a94dSNamhyung Kim 38105e8b080SArnaldo Carvalho de Melo ui_browser__refresh_dimensions(&browser->b); 38205e8b080SArnaldo Carvalho de Melo back = browser->b.height / 2; 38305e8b080SArnaldo Carvalho de Melo browser->b.top_idx = browser->b.index = idx; 384aca7a94dSNamhyung Kim 38505e8b080SArnaldo Carvalho de Melo while (browser->b.top_idx != 0 && back != 0) { 386ec03a77dSJiri Olsa pos = list_entry(pos->node.prev, struct annotation_line, node); 387aca7a94dSNamhyung Kim 388ec03a77dSJiri Olsa if (disasm_line__filter(&browser->b, &pos->node)) 389aca7a94dSNamhyung Kim continue; 390aca7a94dSNamhyung Kim 39105e8b080SArnaldo Carvalho de Melo --browser->b.top_idx; 392aca7a94dSNamhyung Kim --back; 393aca7a94dSNamhyung Kim } 394aca7a94dSNamhyung Kim 395ec03a77dSJiri Olsa browser->b.top = pos; 39605e8b080SArnaldo Carvalho de Melo browser->b.navkeypressed = true; 397aca7a94dSNamhyung Kim } 398aca7a94dSNamhyung Kim 399aca7a94dSNamhyung Kim static void annotate_browser__set_rb_top(struct annotate_browser *browser, 400aca7a94dSNamhyung Kim struct rb_node *nd) 401aca7a94dSNamhyung Kim { 40295aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(&browser->b); 4034850c92eSArnaldo Carvalho de Melo struct annotation_line * pos = rb_entry(nd, struct annotation_line, rb_node); 4044850c92eSArnaldo Carvalho de Melo u32 idx = pos->idx; 405aca7a94dSNamhyung Kim 40616932d77SArnaldo Carvalho de Melo if (notes->options->hide_src_code) 4074850c92eSArnaldo Carvalho de Melo idx = pos->idx_asm; 408a44b45f2SArnaldo Carvalho de Melo annotate_browser__set_top(browser, pos, idx); 409aca7a94dSNamhyung Kim browser->curr_hot = nd; 410aca7a94dSNamhyung Kim } 411aca7a94dSNamhyung Kim 412aca7a94dSNamhyung Kim static void annotate_browser__calc_percent(struct annotate_browser *browser, 413db8fd07aSNamhyung Kim struct perf_evsel *evsel) 414aca7a94dSNamhyung Kim { 415aca7a94dSNamhyung Kim struct map_symbol *ms = browser->b.priv; 416aca7a94dSNamhyung Kim struct symbol *sym = ms->sym; 417aca7a94dSNamhyung Kim struct annotation *notes = symbol__annotation(sym); 418c4c72436SJiri Olsa struct disasm_line *pos; 419aca7a94dSNamhyung Kim 420aca7a94dSNamhyung Kim browser->entries = RB_ROOT; 421aca7a94dSNamhyung Kim 422aca7a94dSNamhyung Kim pthread_mutex_lock(¬es->lock); 423aca7a94dSNamhyung Kim 424e425da6cSJiri Olsa symbol__calc_percent(sym, evsel); 425e425da6cSJiri Olsa 426a17c4ca0SJiri Olsa list_for_each_entry(pos, ¬es->src->source, al.node) { 427c7e7b610SNamhyung Kim double max_percent = 0.0; 428c7e7b610SNamhyung Kim int i; 429e64aa75bSNamhyung Kim 430d5490b96SJiri Olsa if (pos->al.offset == -1) { 4315b12adc8SJiri Olsa RB_CLEAR_NODE(&pos->al.rb_node); 432e64aa75bSNamhyung Kim continue; 433e64aa75bSNamhyung Kim } 434e64aa75bSNamhyung Kim 435b15636c6SJiri Olsa for (i = 0; i < pos->al.samples_nr; i++) { 436e425da6cSJiri Olsa struct annotation_data *sample = &pos->al.samples[i]; 4370c4a5bceSMartin Liška 4383ab6db8dSJiri Olsa if (max_percent < sample->percent) 4393ab6db8dSJiri Olsa max_percent = sample->percent; 440c7e7b610SNamhyung Kim } 441c7e7b610SNamhyung Kim 44237236d5eSJiri Olsa if (max_percent < 0.01 && pos->al.ipc == 0) { 4435b12adc8SJiri Olsa RB_CLEAR_NODE(&pos->al.rb_node); 444aca7a94dSNamhyung Kim continue; 445aca7a94dSNamhyung Kim } 446b15636c6SJiri Olsa disasm_rb_tree__insert(&browser->entries, &pos->al); 447aca7a94dSNamhyung Kim } 448aca7a94dSNamhyung Kim pthread_mutex_unlock(¬es->lock); 449aca7a94dSNamhyung Kim 450aca7a94dSNamhyung Kim browser->curr_hot = rb_last(&browser->entries); 451aca7a94dSNamhyung Kim } 452aca7a94dSNamhyung Kim 453aca7a94dSNamhyung Kim static bool annotate_browser__toggle_source(struct annotate_browser *browser) 454aca7a94dSNamhyung Kim { 45595aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(&browser->b); 456ec03a77dSJiri Olsa struct annotation_line *al; 457aca7a94dSNamhyung Kim off_t offset = browser->b.index - browser->b.top_idx; 458aca7a94dSNamhyung Kim 459aca7a94dSNamhyung Kim browser->b.seek(&browser->b, offset, SEEK_CUR); 460ec03a77dSJiri Olsa al = list_entry(browser->b.top, struct annotation_line, node); 461aca7a94dSNamhyung Kim 46216932d77SArnaldo Carvalho de Melo if (notes->options->hide_src_code) { 4634850c92eSArnaldo Carvalho de Melo if (al->idx_asm < offset) 4644850c92eSArnaldo Carvalho de Melo offset = al->idx; 465aca7a94dSNamhyung Kim 4661cf5f98aSArnaldo Carvalho de Melo browser->b.nr_entries = notes->nr_entries; 46716932d77SArnaldo Carvalho de Melo notes->options->hide_src_code = false; 468aca7a94dSNamhyung Kim browser->b.seek(&browser->b, -offset, SEEK_CUR); 4694850c92eSArnaldo Carvalho de Melo browser->b.top_idx = al->idx - offset; 4704850c92eSArnaldo Carvalho de Melo browser->b.index = al->idx; 471aca7a94dSNamhyung Kim } else { 4724850c92eSArnaldo Carvalho de Melo if (al->idx_asm < 0) { 473aca7a94dSNamhyung Kim ui_helpline__puts("Only available for assembly lines."); 474aca7a94dSNamhyung Kim browser->b.seek(&browser->b, -offset, SEEK_CUR); 475aca7a94dSNamhyung Kim return false; 476aca7a94dSNamhyung Kim } 477aca7a94dSNamhyung Kim 4784850c92eSArnaldo Carvalho de Melo if (al->idx_asm < offset) 4794850c92eSArnaldo Carvalho de Melo offset = al->idx_asm; 480aca7a94dSNamhyung Kim 4811cf5f98aSArnaldo Carvalho de Melo browser->b.nr_entries = notes->nr_asm_entries; 48216932d77SArnaldo Carvalho de Melo notes->options->hide_src_code = true; 483aca7a94dSNamhyung Kim browser->b.seek(&browser->b, -offset, SEEK_CUR); 4844850c92eSArnaldo Carvalho de Melo browser->b.top_idx = al->idx_asm - offset; 4854850c92eSArnaldo Carvalho de Melo browser->b.index = al->idx_asm; 486aca7a94dSNamhyung Kim } 487aca7a94dSNamhyung Kim 488aca7a94dSNamhyung Kim return true; 489aca7a94dSNamhyung Kim } 490aca7a94dSNamhyung Kim 4911cf5f98aSArnaldo Carvalho de Melo static void ui_browser__init_asm_mode(struct ui_browser *browser) 492e9823b21SArnaldo Carvalho de Melo { 4931cf5f98aSArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(browser); 4941cf5f98aSArnaldo Carvalho de Melo ui_browser__reset_index(browser); 4951cf5f98aSArnaldo Carvalho de Melo browser->nr_entries = notes->nr_asm_entries; 496e9823b21SArnaldo Carvalho de Melo } 497e9823b21SArnaldo Carvalho de Melo 49834f77abcSAdrian Hunter #define SYM_TITLE_MAX_SIZE (PATH_MAX + 64) 49934f77abcSAdrian Hunter 50034f77abcSAdrian Hunter static int sym_title(struct symbol *sym, struct map *map, char *title, 50134f77abcSAdrian Hunter size_t sz) 50234f77abcSAdrian Hunter { 50334f77abcSAdrian Hunter return snprintf(title, sz, "%s %s", sym->name, map->dso->long_name); 50434f77abcSAdrian Hunter } 50534f77abcSAdrian Hunter 506db8fd07aSNamhyung Kim static bool annotate_browser__callq(struct annotate_browser *browser, 507db8fd07aSNamhyung Kim struct perf_evsel *evsel, 5089783adf7SNamhyung Kim struct hist_browser_timer *hbt) 509aca7a94dSNamhyung Kim { 510aca7a94dSNamhyung Kim struct map_symbol *ms = browser->b.priv; 5117bcbcd58SJiri Olsa struct disasm_line *dl = disasm_line(browser->selection); 512aca7a94dSNamhyung Kim struct annotation *notes; 51334f77abcSAdrian Hunter char title[SYM_TITLE_MAX_SIZE]; 514aca7a94dSNamhyung Kim 51575b49202SArnaldo Carvalho de Melo if (!ins__is_call(&dl->ins)) 516aca7a94dSNamhyung Kim return false; 517aca7a94dSNamhyung Kim 518696703afSArnaldo Carvalho de Melo if (!dl->ops.target.sym) { 519aca7a94dSNamhyung Kim ui_helpline__puts("The called function was not found."); 520aca7a94dSNamhyung Kim return true; 521aca7a94dSNamhyung Kim } 522aca7a94dSNamhyung Kim 523696703afSArnaldo Carvalho de Melo notes = symbol__annotation(dl->ops.target.sym); 524aca7a94dSNamhyung Kim pthread_mutex_lock(¬es->lock); 525aca7a94dSNamhyung Kim 526696703afSArnaldo Carvalho de Melo if (notes->src == NULL && symbol__alloc_hist(dl->ops.target.sym) < 0) { 527aca7a94dSNamhyung Kim pthread_mutex_unlock(¬es->lock); 528aca7a94dSNamhyung Kim ui__warning("Not enough memory for annotating '%s' symbol!\n", 529696703afSArnaldo Carvalho de Melo dl->ops.target.sym->name); 530aca7a94dSNamhyung Kim return true; 531aca7a94dSNamhyung Kim } 532aca7a94dSNamhyung Kim 533aca7a94dSNamhyung Kim pthread_mutex_unlock(¬es->lock); 534696703afSArnaldo Carvalho de Melo symbol__tui_annotate(dl->ops.target.sym, ms->map, evsel, hbt); 5351179e11bSAdrian Hunter sym_title(ms->sym, ms->map, title, sizeof(title)); 53634f77abcSAdrian Hunter ui_browser__show_title(&browser->b, title); 537aca7a94dSNamhyung Kim return true; 538aca7a94dSNamhyung Kim } 539aca7a94dSNamhyung Kim 54029ed6e76SArnaldo Carvalho de Melo static 54129ed6e76SArnaldo Carvalho de Melo struct disasm_line *annotate_browser__find_offset(struct annotate_browser *browser, 542aca7a94dSNamhyung Kim s64 offset, s64 *idx) 543aca7a94dSNamhyung Kim { 54495aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(&browser->b); 54529ed6e76SArnaldo Carvalho de Melo struct disasm_line *pos; 546aca7a94dSNamhyung Kim 547aca7a94dSNamhyung Kim *idx = 0; 548a17c4ca0SJiri Olsa list_for_each_entry(pos, ¬es->src->source, al.node) { 549d5490b96SJiri Olsa if (pos->al.offset == offset) 550aca7a94dSNamhyung Kim return pos; 551a17c4ca0SJiri Olsa if (!disasm_line__filter(&browser->b, &pos->al.node)) 552aca7a94dSNamhyung Kim ++*idx; 553aca7a94dSNamhyung Kim } 554aca7a94dSNamhyung Kim 555aca7a94dSNamhyung Kim return NULL; 556aca7a94dSNamhyung Kim } 557aca7a94dSNamhyung Kim 558aca7a94dSNamhyung Kim static bool annotate_browser__jump(struct annotate_browser *browser) 559aca7a94dSNamhyung Kim { 5607bcbcd58SJiri Olsa struct disasm_line *dl = disasm_line(browser->selection); 5615252b1aeSArnaldo Carvalho de Melo u64 offset; 5624f9d0325SArnaldo Carvalho de Melo s64 idx; 563aca7a94dSNamhyung Kim 56475b49202SArnaldo Carvalho de Melo if (!ins__is_jump(&dl->ins)) 565aca7a94dSNamhyung Kim return false; 566aca7a94dSNamhyung Kim 5675252b1aeSArnaldo Carvalho de Melo offset = dl->ops.target.offset; 5685252b1aeSArnaldo Carvalho de Melo dl = annotate_browser__find_offset(browser, offset, &idx); 56929ed6e76SArnaldo Carvalho de Melo if (dl == NULL) { 5705252b1aeSArnaldo Carvalho de Melo ui_helpline__printf("Invalid jump offset: %" PRIx64, offset); 571aca7a94dSNamhyung Kim return true; 572aca7a94dSNamhyung Kim } 573aca7a94dSNamhyung Kim 574ec03a77dSJiri Olsa annotate_browser__set_top(browser, &dl->al, idx); 575aca7a94dSNamhyung Kim 576aca7a94dSNamhyung Kim return true; 577aca7a94dSNamhyung Kim } 578aca7a94dSNamhyung Kim 57929ed6e76SArnaldo Carvalho de Melo static 5809213afbdSJiri Olsa struct annotation_line *annotate_browser__find_string(struct annotate_browser *browser, 581aca7a94dSNamhyung Kim char *s, s64 *idx) 582aca7a94dSNamhyung Kim { 58395aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(&browser->b); 5849213afbdSJiri Olsa struct annotation_line *al = browser->selection; 585aca7a94dSNamhyung Kim 586aca7a94dSNamhyung Kim *idx = browser->b.index; 5879213afbdSJiri Olsa list_for_each_entry_continue(al, ¬es->src->source, node) { 5889213afbdSJiri Olsa if (disasm_line__filter(&browser->b, &al->node)) 589aca7a94dSNamhyung Kim continue; 590aca7a94dSNamhyung Kim 591aca7a94dSNamhyung Kim ++*idx; 592aca7a94dSNamhyung Kim 5939213afbdSJiri Olsa if (al->line && strstr(al->line, s) != NULL) 5949213afbdSJiri Olsa return al; 595aca7a94dSNamhyung Kim } 596aca7a94dSNamhyung Kim 597aca7a94dSNamhyung Kim return NULL; 598aca7a94dSNamhyung Kim } 599aca7a94dSNamhyung Kim 600aca7a94dSNamhyung Kim static bool __annotate_browser__search(struct annotate_browser *browser) 601aca7a94dSNamhyung Kim { 6029213afbdSJiri Olsa struct annotation_line *al; 603aca7a94dSNamhyung Kim s64 idx; 604aca7a94dSNamhyung Kim 6059213afbdSJiri Olsa al = annotate_browser__find_string(browser, browser->search_bf, &idx); 6069213afbdSJiri Olsa if (al == NULL) { 607aca7a94dSNamhyung Kim ui_helpline__puts("String not found!"); 608aca7a94dSNamhyung Kim return false; 609aca7a94dSNamhyung Kim } 610aca7a94dSNamhyung Kim 611ec03a77dSJiri Olsa annotate_browser__set_top(browser, al, idx); 612aca7a94dSNamhyung Kim browser->searching_backwards = false; 613aca7a94dSNamhyung Kim return true; 614aca7a94dSNamhyung Kim } 615aca7a94dSNamhyung Kim 61629ed6e76SArnaldo Carvalho de Melo static 6179213afbdSJiri Olsa struct annotation_line *annotate_browser__find_string_reverse(struct annotate_browser *browser, 618aca7a94dSNamhyung Kim char *s, s64 *idx) 619aca7a94dSNamhyung Kim { 62095aa89d9SArnaldo Carvalho de Melo struct annotation *notes = browser__annotation(&browser->b); 6219213afbdSJiri Olsa struct annotation_line *al = browser->selection; 622aca7a94dSNamhyung Kim 623aca7a94dSNamhyung Kim *idx = browser->b.index; 6249213afbdSJiri Olsa list_for_each_entry_continue_reverse(al, ¬es->src->source, node) { 6259213afbdSJiri Olsa if (disasm_line__filter(&browser->b, &al->node)) 626aca7a94dSNamhyung Kim continue; 627aca7a94dSNamhyung Kim 628aca7a94dSNamhyung Kim --*idx; 629aca7a94dSNamhyung Kim 6309213afbdSJiri Olsa if (al->line && strstr(al->line, s) != NULL) 6319213afbdSJiri Olsa return al; 632aca7a94dSNamhyung Kim } 633aca7a94dSNamhyung Kim 634aca7a94dSNamhyung Kim return NULL; 635aca7a94dSNamhyung Kim } 636aca7a94dSNamhyung Kim 637aca7a94dSNamhyung Kim static bool __annotate_browser__search_reverse(struct annotate_browser *browser) 638aca7a94dSNamhyung Kim { 6399213afbdSJiri Olsa struct annotation_line *al; 640aca7a94dSNamhyung Kim s64 idx; 641aca7a94dSNamhyung Kim 6429213afbdSJiri Olsa al = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); 6439213afbdSJiri Olsa if (al == NULL) { 644aca7a94dSNamhyung Kim ui_helpline__puts("String not found!"); 645aca7a94dSNamhyung Kim return false; 646aca7a94dSNamhyung Kim } 647aca7a94dSNamhyung Kim 648ec03a77dSJiri Olsa annotate_browser__set_top(browser, al, idx); 649aca7a94dSNamhyung Kim browser->searching_backwards = true; 650aca7a94dSNamhyung Kim return true; 651aca7a94dSNamhyung Kim } 652aca7a94dSNamhyung Kim 653aca7a94dSNamhyung Kim static bool annotate_browser__search_window(struct annotate_browser *browser, 654aca7a94dSNamhyung Kim int delay_secs) 655aca7a94dSNamhyung Kim { 656aca7a94dSNamhyung Kim if (ui_browser__input_window("Search", "String: ", browser->search_bf, 657aca7a94dSNamhyung Kim "ENTER: OK, ESC: Cancel", 658aca7a94dSNamhyung Kim delay_secs * 2) != K_ENTER || 659aca7a94dSNamhyung Kim !*browser->search_bf) 660aca7a94dSNamhyung Kim return false; 661aca7a94dSNamhyung Kim 662aca7a94dSNamhyung Kim return true; 663aca7a94dSNamhyung Kim } 664aca7a94dSNamhyung Kim 665aca7a94dSNamhyung Kim static bool annotate_browser__search(struct annotate_browser *browser, int delay_secs) 666aca7a94dSNamhyung Kim { 667aca7a94dSNamhyung Kim if (annotate_browser__search_window(browser, delay_secs)) 668aca7a94dSNamhyung Kim return __annotate_browser__search(browser); 669aca7a94dSNamhyung Kim 670aca7a94dSNamhyung Kim return false; 671aca7a94dSNamhyung Kim } 672aca7a94dSNamhyung Kim 673aca7a94dSNamhyung Kim static bool annotate_browser__continue_search(struct annotate_browser *browser, 674aca7a94dSNamhyung Kim int delay_secs) 675aca7a94dSNamhyung Kim { 676aca7a94dSNamhyung Kim if (!*browser->search_bf) 677aca7a94dSNamhyung Kim return annotate_browser__search(browser, delay_secs); 678aca7a94dSNamhyung Kim 679aca7a94dSNamhyung Kim return __annotate_browser__search(browser); 680aca7a94dSNamhyung Kim } 681aca7a94dSNamhyung Kim 682aca7a94dSNamhyung Kim static bool annotate_browser__search_reverse(struct annotate_browser *browser, 683aca7a94dSNamhyung Kim int delay_secs) 684aca7a94dSNamhyung Kim { 685aca7a94dSNamhyung Kim if (annotate_browser__search_window(browser, delay_secs)) 686aca7a94dSNamhyung Kim return __annotate_browser__search_reverse(browser); 687aca7a94dSNamhyung Kim 688aca7a94dSNamhyung Kim return false; 689aca7a94dSNamhyung Kim } 690aca7a94dSNamhyung Kim 691aca7a94dSNamhyung Kim static 692aca7a94dSNamhyung Kim bool annotate_browser__continue_search_reverse(struct annotate_browser *browser, 693aca7a94dSNamhyung Kim int delay_secs) 694aca7a94dSNamhyung Kim { 695aca7a94dSNamhyung Kim if (!*browser->search_bf) 696aca7a94dSNamhyung Kim return annotate_browser__search_reverse(browser, delay_secs); 697aca7a94dSNamhyung Kim 698aca7a94dSNamhyung Kim return __annotate_browser__search_reverse(browser); 699aca7a94dSNamhyung Kim } 700aca7a94dSNamhyung Kim 701*9761e86eSArnaldo Carvalho de Melo static void annotation__update_column_widths(struct annotation *notes) 702e9823b21SArnaldo Carvalho de Melo { 70316932d77SArnaldo Carvalho de Melo if (notes->options->use_offset) 704*9761e86eSArnaldo Carvalho de Melo notes->widths.target = notes->widths.min_addr; 705e9823b21SArnaldo Carvalho de Melo else 706*9761e86eSArnaldo Carvalho de Melo notes->widths.target = notes->widths.max_addr; 707e9823b21SArnaldo Carvalho de Melo 708*9761e86eSArnaldo Carvalho de Melo notes->widths.addr = notes->widths.target; 709e9823b21SArnaldo Carvalho de Melo 71016932d77SArnaldo Carvalho de Melo if (notes->options->show_nr_jumps) 711*9761e86eSArnaldo Carvalho de Melo notes->widths.addr += notes->widths.jumps + 1; 712e9823b21SArnaldo Carvalho de Melo } 713e9823b21SArnaldo Carvalho de Melo 714db8fd07aSNamhyung Kim static int annotate_browser__run(struct annotate_browser *browser, 715db8fd07aSNamhyung Kim struct perf_evsel *evsel, 7169783adf7SNamhyung Kim struct hist_browser_timer *hbt) 717aca7a94dSNamhyung Kim { 718aca7a94dSNamhyung Kim struct rb_node *nd = NULL; 71905e8b080SArnaldo Carvalho de Melo struct map_symbol *ms = browser->b.priv; 720aca7a94dSNamhyung Kim struct symbol *sym = ms->sym; 72116932d77SArnaldo Carvalho de Melo struct annotation *notes = symbol__annotation(ms->sym); 72254e7a4e8SArnaldo Carvalho de Melo const char *help = "Press 'h' for help on key bindings"; 7239783adf7SNamhyung Kim int delay_secs = hbt ? hbt->refresh : 0; 724aca7a94dSNamhyung Kim int key; 72534f77abcSAdrian Hunter char title[SYM_TITLE_MAX_SIZE]; 726aca7a94dSNamhyung Kim 72734f77abcSAdrian Hunter sym_title(sym, ms->map, title, sizeof(title)); 72834f77abcSAdrian Hunter if (ui_browser__show(&browser->b, title, help) < 0) 729aca7a94dSNamhyung Kim return -1; 730aca7a94dSNamhyung Kim 731db8fd07aSNamhyung Kim annotate_browser__calc_percent(browser, evsel); 732aca7a94dSNamhyung Kim 73305e8b080SArnaldo Carvalho de Melo if (browser->curr_hot) { 73405e8b080SArnaldo Carvalho de Melo annotate_browser__set_rb_top(browser, browser->curr_hot); 73505e8b080SArnaldo Carvalho de Melo browser->b.navkeypressed = false; 736aca7a94dSNamhyung Kim } 737aca7a94dSNamhyung Kim 73805e8b080SArnaldo Carvalho de Melo nd = browser->curr_hot; 739aca7a94dSNamhyung Kim 740aca7a94dSNamhyung Kim while (1) { 74105e8b080SArnaldo Carvalho de Melo key = ui_browser__run(&browser->b, delay_secs); 742aca7a94dSNamhyung Kim 743aca7a94dSNamhyung Kim if (delay_secs != 0) { 744db8fd07aSNamhyung Kim annotate_browser__calc_percent(browser, evsel); 745aca7a94dSNamhyung Kim /* 746aca7a94dSNamhyung Kim * Current line focus got out of the list of most active 747aca7a94dSNamhyung Kim * lines, NULL it so that if TAB|UNTAB is pressed, we 748aca7a94dSNamhyung Kim * move to curr_hot (current hottest line). 749aca7a94dSNamhyung Kim */ 750aca7a94dSNamhyung Kim if (nd != NULL && RB_EMPTY_NODE(nd)) 751aca7a94dSNamhyung Kim nd = NULL; 752aca7a94dSNamhyung Kim } 753aca7a94dSNamhyung Kim 754aca7a94dSNamhyung Kim switch (key) { 755aca7a94dSNamhyung Kim case K_TIMER: 7569783adf7SNamhyung Kim if (hbt) 7579783adf7SNamhyung Kim hbt->timer(hbt->arg); 758aca7a94dSNamhyung Kim 759aca7a94dSNamhyung Kim if (delay_secs != 0) 760db8fd07aSNamhyung Kim symbol__annotate_decay_histogram(sym, evsel->idx); 761aca7a94dSNamhyung Kim continue; 762aca7a94dSNamhyung Kim case K_TAB: 763aca7a94dSNamhyung Kim if (nd != NULL) { 764aca7a94dSNamhyung Kim nd = rb_prev(nd); 765aca7a94dSNamhyung Kim if (nd == NULL) 76605e8b080SArnaldo Carvalho de Melo nd = rb_last(&browser->entries); 767aca7a94dSNamhyung Kim } else 76805e8b080SArnaldo Carvalho de Melo nd = browser->curr_hot; 769aca7a94dSNamhyung Kim break; 770aca7a94dSNamhyung Kim case K_UNTAB: 771d4913cbdSMarkus Trippelsdorf if (nd != NULL) { 772aca7a94dSNamhyung Kim nd = rb_next(nd); 773aca7a94dSNamhyung Kim if (nd == NULL) 77405e8b080SArnaldo Carvalho de Melo nd = rb_first(&browser->entries); 775d4913cbdSMarkus Trippelsdorf } else 77605e8b080SArnaldo Carvalho de Melo nd = browser->curr_hot; 777aca7a94dSNamhyung Kim break; 77854e7a4e8SArnaldo Carvalho de Melo case K_F1: 779aca7a94dSNamhyung Kim case 'h': 78005e8b080SArnaldo Carvalho de Melo ui_browser__help_window(&browser->b, 78154e7a4e8SArnaldo Carvalho de Melo "UP/DOWN/PGUP\n" 78254e7a4e8SArnaldo Carvalho de Melo "PGDN/SPACE Navigate\n" 78354e7a4e8SArnaldo Carvalho de Melo "q/ESC/CTRL+C Exit\n\n" 7847727a925SArnaldo Carvalho de Melo "ENTER Go to target\n" 7857727a925SArnaldo Carvalho de Melo "ESC Exit\n" 786eba9fac0SArnaldo Carvalho de Melo "H Go to hottest instruction\n" 787eba9fac0SArnaldo Carvalho de Melo "TAB/shift+TAB Cycle thru hottest instructions\n" 78854e7a4e8SArnaldo Carvalho de Melo "j Toggle showing jump to target arrows\n" 78954e7a4e8SArnaldo Carvalho de Melo "J Toggle showing number of jump sources on targets\n" 79054e7a4e8SArnaldo Carvalho de Melo "n Search next string\n" 79154e7a4e8SArnaldo Carvalho de Melo "o Toggle disassembler output/simplified view\n" 79254e7a4e8SArnaldo Carvalho de Melo "s Toggle source code view\n" 7933a555c77STaeung Song "t Circulate percent, total period, samples view\n" 79454e7a4e8SArnaldo Carvalho de Melo "/ Search string\n" 795e592488cSAndi Kleen "k Toggle line numbers\n" 79679ee47faSFeng Tang "r Run available scripts\n" 797fcd9fef9SArnaldo Carvalho de Melo "? Search string backwards\n"); 79854e7a4e8SArnaldo Carvalho de Melo continue; 79979ee47faSFeng Tang case 'r': 80079ee47faSFeng Tang { 80179ee47faSFeng Tang script_browse(NULL); 80279ee47faSFeng Tang continue; 80379ee47faSFeng Tang } 804e592488cSAndi Kleen case 'k': 80516932d77SArnaldo Carvalho de Melo notes->options->show_linenr = !notes->options->show_linenr; 806e592488cSAndi Kleen break; 80754e7a4e8SArnaldo Carvalho de Melo case 'H': 80805e8b080SArnaldo Carvalho de Melo nd = browser->curr_hot; 809aca7a94dSNamhyung Kim break; 810aca7a94dSNamhyung Kim case 's': 81105e8b080SArnaldo Carvalho de Melo if (annotate_browser__toggle_source(browser)) 812aca7a94dSNamhyung Kim ui_helpline__puts(help); 813aca7a94dSNamhyung Kim continue; 814aca7a94dSNamhyung Kim case 'o': 81516932d77SArnaldo Carvalho de Melo notes->options->use_offset = !notes->options->use_offset; 816*9761e86eSArnaldo Carvalho de Melo annotation__update_column_widths(notes); 817aca7a94dSNamhyung Kim continue; 8189d1ef56dSArnaldo Carvalho de Melo case 'j': 81916932d77SArnaldo Carvalho de Melo notes->options->jump_arrows = !notes->options->jump_arrows; 8209d1ef56dSArnaldo Carvalho de Melo continue; 8212402e4a9SArnaldo Carvalho de Melo case 'J': 82216932d77SArnaldo Carvalho de Melo notes->options->show_nr_jumps = !notes->options->show_nr_jumps; 823*9761e86eSArnaldo Carvalho de Melo annotation__update_column_widths(notes); 824e9823b21SArnaldo Carvalho de Melo continue; 825aca7a94dSNamhyung Kim case '/': 82605e8b080SArnaldo Carvalho de Melo if (annotate_browser__search(browser, delay_secs)) { 827aca7a94dSNamhyung Kim show_help: 828aca7a94dSNamhyung Kim ui_helpline__puts(help); 829aca7a94dSNamhyung Kim } 830aca7a94dSNamhyung Kim continue; 831aca7a94dSNamhyung Kim case 'n': 83205e8b080SArnaldo Carvalho de Melo if (browser->searching_backwards ? 83305e8b080SArnaldo Carvalho de Melo annotate_browser__continue_search_reverse(browser, delay_secs) : 83405e8b080SArnaldo Carvalho de Melo annotate_browser__continue_search(browser, delay_secs)) 835aca7a94dSNamhyung Kim goto show_help; 836aca7a94dSNamhyung Kim continue; 837aca7a94dSNamhyung Kim case '?': 83805e8b080SArnaldo Carvalho de Melo if (annotate_browser__search_reverse(browser, delay_secs)) 839aca7a94dSNamhyung Kim goto show_help; 840aca7a94dSNamhyung Kim continue; 841e9823b21SArnaldo Carvalho de Melo case 'D': { 842e9823b21SArnaldo Carvalho de Melo static int seq; 843e9823b21SArnaldo Carvalho de Melo ui_helpline__pop(); 844e9823b21SArnaldo Carvalho de Melo ui_helpline__fpush("%d: nr_ent=%d, height=%d, idx=%d, top_idx=%d, nr_asm_entries=%d", 84505e8b080SArnaldo Carvalho de Melo seq++, browser->b.nr_entries, 84605e8b080SArnaldo Carvalho de Melo browser->b.height, 84705e8b080SArnaldo Carvalho de Melo browser->b.index, 84805e8b080SArnaldo Carvalho de Melo browser->b.top_idx, 8491cf5f98aSArnaldo Carvalho de Melo notes->nr_asm_entries); 850e9823b21SArnaldo Carvalho de Melo } 851e9823b21SArnaldo Carvalho de Melo continue; 852aca7a94dSNamhyung Kim case K_ENTER: 853aca7a94dSNamhyung Kim case K_RIGHT: 8547bcbcd58SJiri Olsa { 8557bcbcd58SJiri Olsa struct disasm_line *dl = disasm_line(browser->selection); 8567bcbcd58SJiri Olsa 85705e8b080SArnaldo Carvalho de Melo if (browser->selection == NULL) 858aca7a94dSNamhyung Kim ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); 8597bcbcd58SJiri Olsa else if (browser->selection->offset == -1) 860aca7a94dSNamhyung Kim ui_helpline__puts("Actions are only available for assembly lines."); 8617bcbcd58SJiri Olsa else if (!dl->ins.ops) 862c4cceae3SArnaldo Carvalho de Melo goto show_sup_ins; 8637bcbcd58SJiri Olsa else if (ins__is_ret(&dl->ins)) 864c4cceae3SArnaldo Carvalho de Melo goto out; 8656ef94929SNaveen N. Rao else if (!(annotate_browser__jump(browser) || 866db8fd07aSNamhyung Kim annotate_browser__callq(browser, evsel, hbt))) { 867c4cceae3SArnaldo Carvalho de Melo show_sup_ins: 8686ef94929SNaveen N. Rao ui_helpline__puts("Actions are only available for function call/return & jump/branch instructions."); 869c4cceae3SArnaldo Carvalho de Melo } 870aca7a94dSNamhyung Kim continue; 8717bcbcd58SJiri Olsa } 8720c4a5bceSMartin Liška case 't': 87316932d77SArnaldo Carvalho de Melo if (notes->options->show_total_period) { 87416932d77SArnaldo Carvalho de Melo notes->options->show_total_period = false; 87516932d77SArnaldo Carvalho de Melo notes->options->show_nr_samples = true; 87616932d77SArnaldo Carvalho de Melo } else if (notes->options->show_nr_samples) 87716932d77SArnaldo Carvalho de Melo notes->options->show_nr_samples = false; 8783a555c77STaeung Song else 87916932d77SArnaldo Carvalho de Melo notes->options->show_total_period = true; 880*9761e86eSArnaldo Carvalho de Melo annotation__update_column_widths(notes); 8810c4a5bceSMartin Liška continue; 882aca7a94dSNamhyung Kim case K_LEFT: 883aca7a94dSNamhyung Kim case K_ESC: 884aca7a94dSNamhyung Kim case 'q': 885aca7a94dSNamhyung Kim case CTRL('c'): 886aca7a94dSNamhyung Kim goto out; 887aca7a94dSNamhyung Kim default: 888aca7a94dSNamhyung Kim continue; 889aca7a94dSNamhyung Kim } 890aca7a94dSNamhyung Kim 891aca7a94dSNamhyung Kim if (nd != NULL) 89205e8b080SArnaldo Carvalho de Melo annotate_browser__set_rb_top(browser, nd); 893aca7a94dSNamhyung Kim } 894aca7a94dSNamhyung Kim out: 89505e8b080SArnaldo Carvalho de Melo ui_browser__hide(&browser->b); 896aca7a94dSNamhyung Kim return key; 897aca7a94dSNamhyung Kim } 898aca7a94dSNamhyung Kim 899d5dbc518SArnaldo Carvalho de Melo int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, 900d5dbc518SArnaldo Carvalho de Melo struct hist_browser_timer *hbt) 901d5dbc518SArnaldo Carvalho de Melo { 9029cef4b0bSTaeung Song /* Set default value for show_total_period and show_nr_samples */ 9030c4a5bceSMartin Liška annotate_browser__opts.show_total_period = 9040c4a5bceSMartin Liška symbol_conf.show_total_period; 9059cef4b0bSTaeung Song annotate_browser__opts.show_nr_samples = 9069cef4b0bSTaeung Song symbol_conf.show_nr_samples; 9070c4a5bceSMartin Liška 908d5dbc518SArnaldo Carvalho de Melo return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt); 909d5dbc518SArnaldo Carvalho de Melo } 910d5dbc518SArnaldo Carvalho de Melo 911db8fd07aSNamhyung Kim int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, 9129783adf7SNamhyung Kim struct hist_browser_timer *hbt) 913aca7a94dSNamhyung Kim { 914ed426915SNamhyung Kim /* reset abort key so that it can get Ctrl-C as a key */ 915ed426915SNamhyung Kim SLang_reset_tty(); 916ed426915SNamhyung Kim SLang_init_tty(0, 0, 0); 917ed426915SNamhyung Kim 918d5dbc518SArnaldo Carvalho de Melo return map_symbol__tui_annotate(&he->ms, evsel, hbt); 919aca7a94dSNamhyung Kim } 920aca7a94dSNamhyung Kim 9212402e4a9SArnaldo Carvalho de Melo static inline int width_jumps(int n) 9222402e4a9SArnaldo Carvalho de Melo { 9232402e4a9SArnaldo Carvalho de Melo if (n >= 100) 9242402e4a9SArnaldo Carvalho de Melo return 5; 9252402e4a9SArnaldo Carvalho de Melo if (n / 10) 9262402e4a9SArnaldo Carvalho de Melo return 2; 9272402e4a9SArnaldo Carvalho de Melo return 1; 9282402e4a9SArnaldo Carvalho de Melo } 9292402e4a9SArnaldo Carvalho de Melo 930db8fd07aSNamhyung Kim int symbol__tui_annotate(struct symbol *sym, struct map *map, 931db8fd07aSNamhyung Kim struct perf_evsel *evsel, 9329783adf7SNamhyung Kim struct hist_browser_timer *hbt) 933aca7a94dSNamhyung Kim { 9349d6bb41dSArnaldo Carvalho de Melo struct annotation *notes = symbol__annotation(sym); 935c0a58fb2SSamuel Liao size_t size; 936aca7a94dSNamhyung Kim struct map_symbol ms = { 937aca7a94dSNamhyung Kim .map = map, 938aca7a94dSNamhyung Kim .sym = sym, 939aca7a94dSNamhyung Kim }; 940aca7a94dSNamhyung Kim struct annotate_browser browser = { 941aca7a94dSNamhyung Kim .b = { 942a3f895beSArnaldo Carvalho de Melo .refresh = annotate_browser__refresh, 943aca7a94dSNamhyung Kim .seek = ui_browser__list_head_seek, 944aca7a94dSNamhyung Kim .write = annotate_browser__write, 94529ed6e76SArnaldo Carvalho de Melo .filter = disasm_line__filter, 946aca7a94dSNamhyung Kim .priv = &ms, 947aca7a94dSNamhyung Kim .use_navkeypressed = true, 948aca7a94dSNamhyung Kim }, 949aca7a94dSNamhyung Kim }; 950ee51d851SArnaldo Carvalho de Melo int ret = -1, err; 951c7e7b610SNamhyung Kim int nr_pcnt = 1; 952aca7a94dSNamhyung Kim 953aca7a94dSNamhyung Kim if (sym == NULL) 954aca7a94dSNamhyung Kim return -1; 955aca7a94dSNamhyung Kim 956c0a58fb2SSamuel Liao size = symbol__size(sym); 957c0a58fb2SSamuel Liao 958aca7a94dSNamhyung Kim if (map->dso->annotate_warned) 959aca7a94dSNamhyung Kim return -1; 960aca7a94dSNamhyung Kim 96116932d77SArnaldo Carvalho de Melo notes->options = &annotate_browser__opts; 96216932d77SArnaldo Carvalho de Melo 9639d6bb41dSArnaldo Carvalho de Melo notes->offsets = zalloc(size * sizeof(struct annotation_line *)); 9649d6bb41dSArnaldo Carvalho de Melo if (notes->offsets == NULL) { 965b793a401SArnaldo Carvalho de Melo ui__error("Not enough memory!"); 966b793a401SArnaldo Carvalho de Melo return -1; 967b793a401SArnaldo Carvalho de Melo } 968b793a401SArnaldo Carvalho de Melo 9693ab6db8dSJiri Olsa if (perf_evsel__is_group_event(evsel)) 970c7e7b610SNamhyung Kim nr_pcnt = evsel->nr_members; 971c7e7b610SNamhyung Kim 9724850c92eSArnaldo Carvalho de Melo err = symbol__annotate(sym, map, evsel, 0, &browser.arch); 973ee51d851SArnaldo Carvalho de Melo if (err) { 974ee51d851SArnaldo Carvalho de Melo char msg[BUFSIZ]; 975ee51d851SArnaldo Carvalho de Melo symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); 976ee51d851SArnaldo Carvalho de Melo ui__error("Couldn't annotate %s:\n%s", sym->name, msg); 977b793a401SArnaldo Carvalho de Melo goto out_free_offsets; 978aca7a94dSNamhyung Kim } 979aca7a94dSNamhyung Kim 98005d3f1a1SJiri Olsa symbol__calc_percent(sym, evsel); 98105d3f1a1SJiri Olsa 9827727a925SArnaldo Carvalho de Melo ui_helpline__push("Press ESC to exit"); 983aca7a94dSNamhyung Kim 9840ca693b3SArnaldo Carvalho de Melo notes->start = map__rip_2objdump(map, sym->start); 985aca7a94dSNamhyung Kim 9865bc49f61SArnaldo Carvalho de Melo annotation__set_offsets(notes, size); 9875bc49f61SArnaldo Carvalho de Melo browser.b.width = notes->max_line_len; 9886dcd57e8SArnaldo Carvalho de Melo annotation__mark_jump_targets(notes, sym); 989f56c083bSArnaldo Carvalho de Melo annotation__compute_ipc(notes, size); 990b793a401SArnaldo Carvalho de Melo 991*9761e86eSArnaldo Carvalho de Melo notes->widths.addr = notes->widths.target = notes->widths.min_addr = hex_width(size); 992*9761e86eSArnaldo Carvalho de Melo notes->widths.max_addr = hex_width(sym->end); 993*9761e86eSArnaldo Carvalho de Melo notes->widths.jumps = width_jumps(notes->max_jump_sources); 9940553e83dSArnaldo Carvalho de Melo notes->nr_events = nr_pcnt; 9951cf5f98aSArnaldo Carvalho de Melo browser.b.nr_entries = notes->nr_entries; 996aca7a94dSNamhyung Kim browser.b.entries = ¬es->src->source, 997aca7a94dSNamhyung Kim browser.b.width += 18; /* Percentage */ 998e9823b21SArnaldo Carvalho de Melo 99916932d77SArnaldo Carvalho de Melo if (notes->options->hide_src_code) 10001cf5f98aSArnaldo Carvalho de Melo ui_browser__init_asm_mode(&browser.b); 1001e9823b21SArnaldo Carvalho de Melo 1002*9761e86eSArnaldo Carvalho de Melo annotation__update_column_widths(notes); 1003e9823b21SArnaldo Carvalho de Melo 1004db8fd07aSNamhyung Kim ret = annotate_browser__run(&browser, evsel, hbt); 1005f8eb37bdSJiri Olsa 1006f8eb37bdSJiri Olsa annotated_source__purge(notes->src); 1007b793a401SArnaldo Carvalho de Melo 1008b793a401SArnaldo Carvalho de Melo out_free_offsets: 10099d6bb41dSArnaldo Carvalho de Melo zfree(¬es->offsets); 1010aca7a94dSNamhyung Kim return ret; 1011aca7a94dSNamhyung Kim } 1012c323cf04SArnaldo Carvalho de Melo 1013c323cf04SArnaldo Carvalho de Melo #define ANNOTATE_CFG(n) \ 1014c323cf04SArnaldo Carvalho de Melo { .name = #n, .value = &annotate_browser__opts.n, } 1015c323cf04SArnaldo Carvalho de Melo 1016c323cf04SArnaldo Carvalho de Melo /* 1017c323cf04SArnaldo Carvalho de Melo * Keep the entries sorted, they are bsearch'ed 1018c323cf04SArnaldo Carvalho de Melo */ 10197c3102b8SArnaldo Carvalho de Melo static struct annotate_config { 1020c323cf04SArnaldo Carvalho de Melo const char *name; 1021c323cf04SArnaldo Carvalho de Melo bool *value; 1022c323cf04SArnaldo Carvalho de Melo } annotate__configs[] = { 1023c323cf04SArnaldo Carvalho de Melo ANNOTATE_CFG(hide_src_code), 1024c323cf04SArnaldo Carvalho de Melo ANNOTATE_CFG(jump_arrows), 1025e592488cSAndi Kleen ANNOTATE_CFG(show_linenr), 1026c323cf04SArnaldo Carvalho de Melo ANNOTATE_CFG(show_nr_jumps), 10279cef4b0bSTaeung Song ANNOTATE_CFG(show_nr_samples), 10280c4a5bceSMartin Liška ANNOTATE_CFG(show_total_period), 102939ff7cdbSNamhyung Kim ANNOTATE_CFG(use_offset), 1030c323cf04SArnaldo Carvalho de Melo }; 1031c323cf04SArnaldo Carvalho de Melo 1032c323cf04SArnaldo Carvalho de Melo #undef ANNOTATE_CFG 1033c323cf04SArnaldo Carvalho de Melo 1034c323cf04SArnaldo Carvalho de Melo static int annotate_config__cmp(const void *name, const void *cfgp) 1035c323cf04SArnaldo Carvalho de Melo { 10367c3102b8SArnaldo Carvalho de Melo const struct annotate_config *cfg = cfgp; 1037c323cf04SArnaldo Carvalho de Melo 1038c323cf04SArnaldo Carvalho de Melo return strcmp(name, cfg->name); 1039c323cf04SArnaldo Carvalho de Melo } 1040c323cf04SArnaldo Carvalho de Melo 10411d037ca1SIrina Tirdea static int annotate__config(const char *var, const char *value, 10421d037ca1SIrina Tirdea void *data __maybe_unused) 1043c323cf04SArnaldo Carvalho de Melo { 10447c3102b8SArnaldo Carvalho de Melo struct annotate_config *cfg; 1045c323cf04SArnaldo Carvalho de Melo const char *name; 1046c323cf04SArnaldo Carvalho de Melo 10478e99b6d4SArnaldo Carvalho de Melo if (!strstarts(var, "annotate.")) 1048c323cf04SArnaldo Carvalho de Melo return 0; 1049c323cf04SArnaldo Carvalho de Melo 1050c323cf04SArnaldo Carvalho de Melo name = var + 9; 1051c323cf04SArnaldo Carvalho de Melo cfg = bsearch(name, annotate__configs, ARRAY_SIZE(annotate__configs), 10527c3102b8SArnaldo Carvalho de Melo sizeof(struct annotate_config), annotate_config__cmp); 1053c323cf04SArnaldo Carvalho de Melo 1054c323cf04SArnaldo Carvalho de Melo if (cfg == NULL) 1055f06cff7cSArnaldo Carvalho de Melo ui__warning("%s variable unknown, ignoring...", var); 1056f06cff7cSArnaldo Carvalho de Melo else 1057c323cf04SArnaldo Carvalho de Melo *cfg->value = perf_config_bool(name, value); 1058c323cf04SArnaldo Carvalho de Melo return 0; 1059c323cf04SArnaldo Carvalho de Melo } 1060c323cf04SArnaldo Carvalho de Melo 1061c323cf04SArnaldo Carvalho de Melo void annotate_browser__init(void) 1062c323cf04SArnaldo Carvalho de Melo { 1063c323cf04SArnaldo Carvalho de Melo perf_config(annotate__config, NULL); 1064c323cf04SArnaldo Carvalho de Melo } 1065