^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include "../browser.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include "../helpline.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include "../ui.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "../../util/annotate.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "../../util/debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "../../util/dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "../../util/hist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "../../util/sort.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "../../util/map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "../../util/symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "../../util/evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "../../util/evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <pthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sys/ttydefaults.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct disasm_line_samples {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) double percent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct sym_hist_entry he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct arch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct annotate_browser {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct ui_browser b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct rb_root entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct rb_node *curr_hot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct annotation_line *selection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct arch *arch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct annotation_options *opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) bool searching_backwards;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) char search_bf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static inline struct annotation *browser__annotation(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct map_symbol *ms = browser->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return symbol__annotation(ms->sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static bool disasm_line__filter(struct ui_browser *browser, void *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct annotation *notes = browser__annotation(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct annotation_line *al = list_entry(entry, struct annotation_line, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return annotation_line__filter(al, notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int ui_browser__jumps_percent_color(struct ui_browser *browser, int nr, bool current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct annotation *notes = browser__annotation(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (current && (!browser->use_navkeypressed || browser->navkeypressed))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return HE_COLORSET_SELECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (nr == notes->max_jump_sources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return HE_COLORSET_TOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (nr > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return HE_COLORSET_MEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return HE_COLORSET_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int ui_browser__set_jumps_percent_color(void *browser, int nr, bool current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int color = ui_browser__jumps_percent_color(browser, nr, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return ui_browser__set_color(browser, color);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int annotate_browser__set_color(void *browser, int color)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return ui_browser__set_color(browser, color);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static void annotate_browser__write_graph(void *browser, int graph)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ui_browser__write_graph(browser, graph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static void annotate_browser__set_percent_color(void *browser, double percent, bool current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ui_browser__set_percent_color(browser, percent, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static void annotate_browser__printf(void *browser, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ui_browser__vprintf(browser, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void annotate_browser__write(struct ui_browser *browser, void *entry, int row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct annotation *notes = browser__annotation(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct annotation_line *al = list_entry(entry, struct annotation_line, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) const bool is_current_entry = ui_browser__is_current_entry(browser, row);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct annotation_write_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .first_line = row == 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .current_entry = is_current_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .change_color = (!notes->options->hide_src_code &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) (!is_current_entry ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) (browser->use_navkeypressed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) !browser->navkeypressed))),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .width = browser->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .obj = browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .set_color = annotate_browser__set_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .set_percent_color = annotate_browser__set_percent_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .set_jumps_percent_color = ui_browser__set_jumps_percent_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .printf = annotate_browser__printf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .write_graph = annotate_browser__write_graph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* The scroll bar isn't being used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (!browser->navkeypressed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ops.width += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) annotation_line__write(al, notes, &ops, ab->opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (ops.current_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ab->selection = al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct disasm_line *pos = list_prev_entry(cursor, al.node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (ins__is_lock(&pos->ins))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) name = pos->ops.locked.ins.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) name = pos->ins.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!name || !cursor->ins.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return ins__is_fused(ab->arch, name, cursor->ins.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static void annotate_browser__draw_current_jump(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct disasm_line *cursor = disasm_line(ab->selection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct annotation_line *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned int from, to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct map_symbol *ms = ab->b.priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct symbol *sym = ms->sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct annotation *notes = symbol__annotation(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u8 pcnt_width = annotation__pcnt_width(notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* PLT symbols contain external offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (strstr(sym->name, "@plt"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!disasm_line__is_valid_local_jump(cursor, sym))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * This first was seen with a gcc function, _cpp_lex_token, that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * has the usual jumps:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * │1159e6c: ↓ jne 115aa32 <_cpp_lex_token@@Base+0xf92>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * I.e. jumps to a label inside that function (_cpp_lex_token), and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * those works, but also this kind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * │1159e8b: ↓ jne c469be <cpp_named_operator2name@@Base+0xa72>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * I.e. jumps to another function, outside _cpp_lex_token, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * are not being correctly handled generating as a side effect references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * to ab->offset[] entries that are set to NULL, so to make this code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * more robust, check that here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * A proper fix for will be put in place, looking at the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * name right after the '<' token and probably treating this like a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * 'call' instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) target = notes->offsets[cursor->ops.target.offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (target == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ui_helpline__printf("WARN: jump target inconsistency, press 'o', notes->offsets[%#x] = NULL\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) cursor->ops.target.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (notes->options->hide_src_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) from = cursor->al.idx_asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) to = target->idx_asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) from = (u64)cursor->al.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) to = (u64)target->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) width = annotation__cycles_width(notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) __ui_browser__line_arrow(browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) pcnt_width + 2 + notes->widths.addr + width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) from, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (is_fused(ab, cursor)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ui_browser__mark_fused(browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) pcnt_width + 3 + notes->widths.addr + width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) from - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) to > from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static unsigned int annotate_browser__refresh(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct annotation *notes = browser__annotation(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int ret = ui_browser__list_head_refresh(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int pcnt_width = annotation__pcnt_width(notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (notes->options->jump_arrows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) annotate_browser__draw_current_jump(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ui_browser__set_color(browser, HE_COLORSET_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) __ui_browser__vline(browser, pcnt_width, 0, browser->rows - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static double disasm__cmp(struct annotation_line *a, struct annotation_line *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int percent_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) for (i = 0; i < a->data_nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (a->data[i].percent[percent_type] == b->data[i].percent[percent_type])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return a->data[i].percent[percent_type] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) b->data[i].percent[percent_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void disasm_rb_tree__insert(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct annotation_line *al)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct rb_root *root = &browser->entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct rb_node **p = &root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct annotation_line *l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) l = rb_entry(parent, struct annotation_line, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (disasm__cmp(al, l, browser->opts->percent_type) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) rb_link_node(&al->rb_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) rb_insert_color(&al->rb_node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void annotate_browser__set_top(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct annotation_line *pos, u32 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct annotation *notes = browser__annotation(&browser->b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) unsigned back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ui_browser__refresh_dimensions(&browser->b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) back = browser->b.height / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) browser->b.top_idx = browser->b.index = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) while (browser->b.top_idx != 0 && back != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) pos = list_entry(pos->node.prev, struct annotation_line, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (annotation_line__filter(pos, notes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) --browser->b.top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) --back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) browser->b.top = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) browser->b.navkeypressed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static void annotate_browser__set_rb_top(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct rb_node *nd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct annotation *notes = browser__annotation(&browser->b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct annotation_line * pos = rb_entry(nd, struct annotation_line, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u32 idx = pos->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (notes->options->hide_src_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) idx = pos->idx_asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) annotate_browser__set_top(browser, pos, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) browser->curr_hot = nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static void annotate_browser__calc_percent(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct map_symbol *ms = browser->b.priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct symbol *sym = ms->sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct annotation *notes = symbol__annotation(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct disasm_line *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) browser->entries = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) pthread_mutex_lock(¬es->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) symbol__calc_percent(sym, evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) list_for_each_entry(pos, ¬es->src->source, al.node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) double max_percent = 0.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (pos->al.offset == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) RB_CLEAR_NODE(&pos->al.rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) for (i = 0; i < pos->al.data_nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) double percent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) percent = annotation_data__percent(&pos->al.data[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) browser->opts->percent_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (max_percent < percent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) max_percent = percent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (max_percent < 0.01 && pos->al.ipc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) RB_CLEAR_NODE(&pos->al.rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) disasm_rb_tree__insert(browser, &pos->al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) pthread_mutex_unlock(¬es->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) browser->curr_hot = rb_last(&browser->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static bool annotate_browser__toggle_source(struct annotate_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct annotation *notes = browser__annotation(&browser->b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct annotation_line *al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) off_t offset = browser->b.index - browser->b.top_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) browser->b.seek(&browser->b, offset, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) al = list_entry(browser->b.top, struct annotation_line, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (notes->options->hide_src_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (al->idx_asm < offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) offset = al->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) browser->b.nr_entries = notes->nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) notes->options->hide_src_code = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) browser->b.seek(&browser->b, -offset, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) browser->b.top_idx = al->idx - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) browser->b.index = al->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (al->idx_asm < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ui_helpline__puts("Only available for assembly lines.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) browser->b.seek(&browser->b, -offset, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (al->idx_asm < offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) offset = al->idx_asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) browser->b.nr_entries = notes->nr_asm_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) notes->options->hide_src_code = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) browser->b.seek(&browser->b, -offset, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) browser->b.top_idx = al->idx_asm - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) browser->b.index = al->idx_asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static void ui_browser__init_asm_mode(struct ui_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct annotation *notes = browser__annotation(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ui_browser__reset_index(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) browser->nr_entries = notes->nr_asm_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #define SYM_TITLE_MAX_SIZE (PATH_MAX + 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int sym_title(struct symbol *sym, struct map *map, char *title,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) size_t sz, int percent_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, map->dso->long_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) percent_type_str(percent_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * This can be called from external jumps, i.e. jumps from one functon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * to another, like from the kernel's entry_SYSCALL_64 function to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * swapgs_restore_regs_and_return_to_usermode() function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * So all we check here is that dl->ops.target.sym is set, if it is, just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * go to that function and when exiting from its disassembly, come back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * to the calling function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static bool annotate_browser__callq(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct hist_browser_timer *hbt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct map_symbol *ms = browser->b.priv, target_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct disasm_line *dl = disasm_line(browser->selection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct annotation *notes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) char title[SYM_TITLE_MAX_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (!dl->ops.target.sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ui_helpline__puts("The called function was not found.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) notes = symbol__annotation(dl->ops.target.sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) pthread_mutex_lock(¬es->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (!symbol__hists(dl->ops.target.sym, evsel->evlist->core.nr_entries)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pthread_mutex_unlock(¬es->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ui__warning("Not enough memory for annotating '%s' symbol!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dl->ops.target.sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) target_ms.maps = ms->maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) target_ms.map = ms->map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) target_ms.sym = dl->ops.target.sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) pthread_mutex_unlock(¬es->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) symbol__tui_annotate(&target_ms, evsel, hbt, browser->opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) sym_title(ms->sym, ms->map, title, sizeof(title), browser->opts->percent_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ui_browser__show_title(&browser->b, title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct disasm_line *annotate_browser__find_offset(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) s64 offset, s64 *idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct annotation *notes = browser__annotation(&browser->b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct disasm_line *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) *idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) list_for_each_entry(pos, ¬es->src->source, al.node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (pos->al.offset == offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!annotation_line__filter(&pos->al, notes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ++*idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static bool annotate_browser__jump(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct hist_browser_timer *hbt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct disasm_line *dl = disasm_line(browser->selection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) u64 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) s64 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!ins__is_jump(&dl->ins))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (dl->ops.target.outside) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) annotate_browser__callq(browser, evsel, hbt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) offset = dl->ops.target.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) dl = annotate_browser__find_offset(browser, offset, &idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (dl == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ui_helpline__printf("Invalid jump offset: %" PRIx64, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) annotate_browser__set_top(browser, &dl->al, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct annotation_line *annotate_browser__find_string(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) char *s, s64 *idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct annotation *notes = browser__annotation(&browser->b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct annotation_line *al = browser->selection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) *idx = browser->b.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) list_for_each_entry_continue(al, ¬es->src->source, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (annotation_line__filter(al, notes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ++*idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (al->line && strstr(al->line, s) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static bool __annotate_browser__search(struct annotate_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct annotation_line *al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) s64 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) al = annotate_browser__find_string(browser, browser->search_bf, &idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (al == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ui_helpline__puts("String not found!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) annotate_browser__set_top(browser, al, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) browser->searching_backwards = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct annotation_line *annotate_browser__find_string_reverse(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) char *s, s64 *idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct annotation *notes = browser__annotation(&browser->b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct annotation_line *al = browser->selection;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *idx = browser->b.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) list_for_each_entry_continue_reverse(al, ¬es->src->source, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (annotation_line__filter(al, notes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) --*idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (al->line && strstr(al->line, s) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static bool __annotate_browser__search_reverse(struct annotate_browser *browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct annotation_line *al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) s64 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) al = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (al == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ui_helpline__puts("String not found!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) annotate_browser__set_top(browser, al, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) browser->searching_backwards = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static bool annotate_browser__search_window(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int delay_secs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (ui_browser__input_window("Search", "String: ", browser->search_bf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) "ENTER: OK, ESC: Cancel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) delay_secs * 2) != K_ENTER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) !*browser->search_bf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static bool annotate_browser__search(struct annotate_browser *browser, int delay_secs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (annotate_browser__search_window(browser, delay_secs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return __annotate_browser__search(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static bool annotate_browser__continue_search(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int delay_secs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!*browser->search_bf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return annotate_browser__search(browser, delay_secs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return __annotate_browser__search(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static bool annotate_browser__search_reverse(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int delay_secs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (annotate_browser__search_window(browser, delay_secs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return __annotate_browser__search_reverse(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) bool annotate_browser__continue_search_reverse(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int delay_secs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!*browser->search_bf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return annotate_browser__search_reverse(browser, delay_secs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return __annotate_browser__search_reverse(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static int annotate_browser__show(struct ui_browser *browser, char *title, const char *help)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct map_symbol *ms = browser->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct symbol *sym = ms->sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) char symbol_dso[SYM_TITLE_MAX_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (ui_browser__show(browser, title, help) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) sym_title(sym, ms->map, symbol_dso, sizeof(symbol_dso), ab->opts->percent_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ui_browser__gotorc_title(browser, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) ui_browser__set_color(browser, HE_COLORSET_ROOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ui_browser__write_nstring(browser, symbol_dso, browser->width + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) switch_percent_type(struct annotation_options *opts, bool base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) switch (opts->percent_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) case PERCENT_HITS_LOCAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) opts->percent_type = PERCENT_PERIOD_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) opts->percent_type = PERCENT_HITS_GLOBAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case PERCENT_HITS_GLOBAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) opts->percent_type = PERCENT_PERIOD_GLOBAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) opts->percent_type = PERCENT_HITS_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) case PERCENT_PERIOD_LOCAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) opts->percent_type = PERCENT_HITS_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) opts->percent_type = PERCENT_PERIOD_GLOBAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case PERCENT_PERIOD_GLOBAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) opts->percent_type = PERCENT_HITS_GLOBAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) opts->percent_type = PERCENT_PERIOD_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static int annotate_browser__run(struct annotate_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct hist_browser_timer *hbt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct rb_node *nd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct hists *hists = evsel__hists(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct map_symbol *ms = browser->b.priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct symbol *sym = ms->sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct annotation *notes = symbol__annotation(ms->sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) const char *help = "Press 'h' for help on key bindings";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int delay_secs = hbt ? hbt->refresh : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) char title[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) hists__scnprintf_title(hists, title, sizeof(title));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (annotate_browser__show(&browser->b, title, help) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) annotate_browser__calc_percent(browser, evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (browser->curr_hot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) annotate_browser__set_rb_top(browser, browser->curr_hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) browser->b.navkeypressed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) nd = browser->curr_hot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) key = ui_browser__run(&browser->b, delay_secs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (delay_secs != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) annotate_browser__calc_percent(browser, evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Current line focus got out of the list of most active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * lines, NULL it so that if TAB|UNTAB is pressed, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * move to curr_hot (current hottest line).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (nd != NULL && RB_EMPTY_NODE(nd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) nd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) switch (key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) case K_TIMER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (hbt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) hbt->timer(hbt->arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (delay_secs != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) symbol__annotate_decay_histogram(sym, evsel->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) hists__scnprintf_title(hists, title, sizeof(title));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) annotate_browser__show(&browser->b, title, help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) case K_TAB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (nd != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) nd = rb_prev(nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (nd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) nd = rb_last(&browser->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) nd = browser->curr_hot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case K_UNTAB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (nd != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) nd = rb_next(nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (nd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) nd = rb_first(&browser->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) nd = browser->curr_hot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) case K_F1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ui_browser__help_window(&browser->b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) "UP/DOWN/PGUP\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) "PGDN/SPACE Navigate\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) "q/ESC/CTRL+C Exit\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) "ENTER Go to target\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) "ESC Exit\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) "H Go to hottest instruction\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) "TAB/shift+TAB Cycle thru hottest instructions\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) "j Toggle showing jump to target arrows\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) "J Toggle showing number of jump sources on targets\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) "n Search next string\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) "o Toggle disassembler output/simplified view\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) "O Bump offset level (jump targets -> +call -> all -> cycle thru)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) "s Toggle source code view\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) "t Circulate percent, total period, samples view\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) "c Show min/max cycle\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) "/ Search string\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) "k Toggle line numbers\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) "P Print to [symbol_name].annotation file.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) "r Run available scripts\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) "p Toggle percent type [local/global]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) "b Toggle percent base [period/hits]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) "? Search string backwards\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case 'r':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) script_browse(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) annotate_browser__show(&browser->b, title, help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) case 'k':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) notes->options->show_linenr = !notes->options->show_linenr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) case 'H':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) nd = browser->curr_hot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (annotate_browser__toggle_source(browser))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ui_helpline__puts(help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) notes->options->use_offset = !notes->options->use_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) annotation__update_column_widths(notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) case 'O':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (++notes->options->offset_level > ANNOTATION__MAX_OFFSET_LEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) notes->options->offset_level = ANNOTATION__MIN_OFFSET_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case 'j':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) notes->options->jump_arrows = !notes->options->jump_arrows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) case 'J':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) notes->options->show_nr_jumps = !notes->options->show_nr_jumps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) annotation__update_column_widths(notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) case '/':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (annotate_browser__search(browser, delay_secs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) show_help:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ui_helpline__puts(help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (browser->searching_backwards ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) annotate_browser__continue_search_reverse(browser, delay_secs) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) annotate_browser__continue_search(browser, delay_secs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) goto show_help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (annotate_browser__search_reverse(browser, delay_secs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) goto show_help;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) case 'D': {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static int seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ui_helpline__pop();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ui_helpline__fpush("%d: nr_ent=%d, height=%d, idx=%d, top_idx=%d, nr_asm_entries=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) seq++, browser->b.nr_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) browser->b.height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) browser->b.index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) browser->b.top_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) notes->nr_asm_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) case K_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) case K_RIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct disasm_line *dl = disasm_line(browser->selection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (browser->selection == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) else if (browser->selection->offset == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ui_helpline__puts("Actions are only available for assembly lines.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) else if (!dl->ins.ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) goto show_sup_ins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) else if (ins__is_ret(&dl->ins))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) else if (!(annotate_browser__jump(browser, evsel, hbt) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) annotate_browser__callq(browser, evsel, hbt))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) show_sup_ins:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) ui_helpline__puts("Actions are only available for function call/return & jump/branch instructions.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) case 'P':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) map_symbol__annotation_dump(ms, evsel, browser->opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case 't':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (symbol_conf.show_total_period) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) symbol_conf.show_total_period = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) symbol_conf.show_nr_samples = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) } else if (symbol_conf.show_nr_samples)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) symbol_conf.show_nr_samples = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) symbol_conf.show_total_period = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) annotation__update_column_widths(notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (notes->options->show_minmax_cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) notes->options->show_minmax_cycle = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) notes->options->show_minmax_cycle = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) annotation__update_column_widths(notes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) switch_percent_type(browser->opts, key == 'b');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) hists__scnprintf_title(hists, title, sizeof(title));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) annotate_browser__show(&browser->b, title, help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) case K_LEFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) case K_ESC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case 'q':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) case CTRL('c'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (nd != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) annotate_browser__set_rb_top(browser, nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ui_browser__hide(&browser->b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int map_symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct hist_browser_timer *hbt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct annotation_options *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return symbol__tui_annotate(ms, evsel, hbt, opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) int hist_entry__tui_annotate(struct hist_entry *he, struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct hist_browser_timer *hbt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct annotation_options *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* reset abort key so that it can get Ctrl-C as a key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) SLang_reset_tty();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) SLang_init_tty(0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return map_symbol__tui_annotate(&he->ms, evsel, hbt, opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct hist_browser_timer *hbt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct annotation_options *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct symbol *sym = ms->sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct annotation *notes = symbol__annotation(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct annotate_browser browser = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .b = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .refresh = annotate_browser__refresh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .seek = ui_browser__list_head_seek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .write = annotate_browser__write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .filter = disasm_line__filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .extra_title_lines = 1, /* for hists__scnprintf_title() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .priv = ms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .use_navkeypressed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .opts = opts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int ret = -1, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (sym == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (ms->map->dso->annotate_warned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) err = symbol__annotate2(ms, evsel, opts, &browser.arch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) char msg[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ui__error("Couldn't annotate %s:\n%s", sym->name, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) goto out_free_offsets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) ui_helpline__push("Press ESC to exit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) browser.b.width = notes->max_line_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) browser.b.nr_entries = notes->nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) browser.b.entries = ¬es->src->source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) browser.b.width += 18; /* Percentage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (notes->options->hide_src_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ui_browser__init_asm_mode(&browser.b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ret = annotate_browser__run(&browser, evsel, hbt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) annotated_source__purge(notes->src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) out_free_offsets:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) zfree(¬es->offsets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }