Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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(&notes->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, &notes->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(&notes->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(&notes->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(&notes->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(&notes->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, &notes->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, &notes->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, &notes->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 = &notes->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(&notes->offsets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }