1e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../browser.h" 2e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../helpline.h" 3e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../libslang.h" 4e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../../annotate.h" 5e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../../hist.h" 6e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../../sort.h" 7e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "../../symbol.h" 8e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <pthread.h> 9e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 10e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void ui__error_window(const char *fmt, ...) 11e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 12e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_list ap; 13e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 14e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_start(ap, fmt); 15e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap); 16e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng va_end(ap); 17e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 18e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 19e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct annotate_browser { 20e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct ui_browser b; 21e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_root entries; 22e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node *curr_hot; 23e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 24e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 25e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct objdump_line_rb_node { 26e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node rb_node; 27e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng double percent; 28e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u32 idx; 29e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng}; 30e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 31e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic inline 32e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct objdump_line_rb_node *objdump_line__rb(struct objdump_line *self) 33e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 34e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return (struct objdump_line_rb_node *)(self + 1); 35e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 36e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 37e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void annotate_browser__write(struct ui_browser *self, void *entry, int row) 38e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 39e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); 40e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng bool current_entry = ui_browser__is_current_entry(self, row); 41e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int width = self->width; 42e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 43e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (ol->offset != -1) { 44e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line_rb_node *olrb = objdump_line__rb(ol); 45e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ui_browser__set_percent_color(self, olrb->percent, current_entry); 46e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng slsmg_printf(" %7.2f ", olrb->percent); 47e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 48e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ui_browser__set_percent_color(self, 0, current_entry); 49e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng slsmg_write_nstring(" ", 9); 50e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 51e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 52e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng SLsmg_write_char(':'); 53e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng slsmg_write_nstring(" ", 8); 54e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!*ol->line) 55e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng slsmg_write_nstring(" ", width - 18); 56e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 57e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng slsmg_write_nstring(ol->line, width - 18); 58e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 59e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!current_entry) 60e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ui_browser__set_color(self, HE_COLORSET_CODE); 61e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 62e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 63e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic double objdump_line__calc_percent(struct objdump_line *self, 64e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct symbol *sym, int evidx) 65e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 66e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng double percent = 0.0; 67e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 68e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (self->offset != -1) { 69e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int len = sym->end - sym->start; 70e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int hits = 0; 71e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct annotation *notes = symbol__annotation(sym); 72e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct source_line *src_line = notes->src->lines; 73e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct sym_hist *h = annotation__histogram(notes, evidx); 74e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng s64 offset = self->offset; 75e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line *next; 76e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 77e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng next = objdump__get_next_ip_line(¬es->src->source, self); 78e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (offset < (s64)len && 79e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng (next == NULL || offset < next->offset)) { 80e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (src_line) { 81e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng percent += src_line[offset].percent; 82e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else 83e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng hits += h->addr[offset]; 84e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 85e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ++offset; 86e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 87e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 88e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * If the percentage wasn't already calculated in 89e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * symbol__get_source_line, do it now: 90e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 91e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (src_line == NULL && h->sum) 92e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng percent = 100.0 * hits / h->sum; 93e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 94e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 95e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return percent; 96e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 97e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 98e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void objdump__insert_line(struct rb_root *self, 99e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line_rb_node *line) 100e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 101e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node **p = &self->rb_node; 102e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node *parent = NULL; 103e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line_rb_node *l; 104e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 105e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (*p != NULL) { 106e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng parent = *p; 107e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng l = rb_entry(parent, struct objdump_line_rb_node, rb_node); 108e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (line->percent < l->percent) 109e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng p = &(*p)->rb_left; 110e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 111e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng p = &(*p)->rb_right; 112e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 113e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rb_link_node(&line->rb_node, parent, p); 114e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rb_insert_color(&line->rb_node, self); 115e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 116e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 117e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void annotate_browser__set_top(struct annotate_browser *self, 118e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node *nd) 119e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 120e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line_rb_node *rbpos; 121e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line *pos; 122e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned back; 123e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 124e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ui_browser__refresh_dimensions(&self->b); 125e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng back = self->b.height / 2; 126e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node); 127e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pos = ((struct objdump_line *)rbpos) - 1; 128e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng self->b.top_idx = self->b.index = rbpos->idx; 129e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 130e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (self->b.top_idx != 0 && back != 0) { 131e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pos = list_entry(pos->node.prev, struct objdump_line, node); 132e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 133e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng --self->b.top_idx; 134e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng --back; 135e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 136e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 137e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng self->b.top = pos; 138e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng self->curr_hot = nd; 139e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 140e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 141e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void annotate_browser__calc_percent(struct annotate_browser *browser, 142e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int evidx) 143e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 144e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct symbol *sym = browser->b.priv; 145e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct annotation *notes = symbol__annotation(sym); 146e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line *pos; 147e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 148e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng browser->entries = RB_ROOT; 149e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 150e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_mutex_lock(¬es->lock); 151e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 152e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry(pos, ¬es->src->source, node) { 153e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line_rb_node *rbpos = objdump_line__rb(pos); 154e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rbpos->percent = objdump_line__calc_percent(pos, sym, evidx); 155e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (rbpos->percent < 0.01) { 156e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng RB_CLEAR_NODE(&rbpos->rb_node); 157e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng continue; 158e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 159e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng objdump__insert_line(&browser->entries, rbpos); 160e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 161e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pthread_mutex_unlock(¬es->lock); 162e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 163e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng browser->curr_hot = rb_last(&browser->entries); 164e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 165e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 166e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int annotate_browser__run(struct annotate_browser *self, int evidx, 167e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int refresh) 168e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 169e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct rb_node *nd = NULL; 170e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct symbol *sym = self->b.priv; 171e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 172e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * RIGHT To allow builtin-annotate to cycle thru multiple symbols by 173e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * examining the exit key for this function. 174e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 175e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int exit_keys[] = { 'H', NEWT_KEY_TAB, NEWT_KEY_UNTAB, 176e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng NEWT_KEY_RIGHT, 0 }; 177e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int key; 178e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 179e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (ui_browser__show(&self->b, sym->name, 180e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "<-, -> or ESC: exit, TAB/shift+TAB: " 181e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng "cycle hottest lines, H: Hottest") < 0) 182e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 183e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 184e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ui_browser__add_exit_keys(&self->b, exit_keys); 185e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng annotate_browser__calc_percent(self, evidx); 186e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 187e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (self->curr_hot) 188e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng annotate_browser__set_top(self, self->curr_hot); 189e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 190e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = self->curr_hot; 191e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 192e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (refresh != 0) 193e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng newtFormSetTimer(self->b.form, refresh); 194e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 195e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng while (1) { 196e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng key = ui_browser__run(&self->b); 197e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 198e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (refresh != 0) { 199e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng annotate_browser__calc_percent(self, evidx); 200e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 201e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Current line focus got out of the list of most active 202e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * lines, NULL it so that if TAB|UNTAB is pressed, we 203e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * move to curr_hot (current hottest line). 204e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 205e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nd != NULL && RB_EMPTY_NODE(nd)) 206e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = NULL; 207e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 208e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 209e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng switch (key) { 210e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case -1: 211e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 212e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * FIXME we need to check if it was 213e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * es.reason == NEWT_EXIT_TIMER 214e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 215e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (refresh != 0) 216e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng symbol__annotate_decay_histogram(sym, evidx); 217e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng continue; 218e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case NEWT_KEY_TAB: 219e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nd != NULL) { 220e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = rb_prev(nd); 221e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nd == NULL) 222e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = rb_last(&self->entries); 223e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else 224e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = self->curr_hot; 225e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 226e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case NEWT_KEY_UNTAB: 227e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nd != NULL) 228e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = rb_next(nd); 229e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nd == NULL) 230e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = rb_first(&self->entries); 231e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 232e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = self->curr_hot; 233e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 234e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng case 'H': 235e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng nd = self->curr_hot; 236e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng break; 237e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng default: 238e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto out; 239e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 240e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 241e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (nd != NULL) 242e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng annotate_browser__set_top(self, nd); 243e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 244e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengout: 245e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ui_browser__hide(&self->b); 246e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return key; 247e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 248e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 249e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint hist_entry__tui_annotate(struct hist_entry *he, int evidx) 250e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 251e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, 0); 252e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 253e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 254e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, 255e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int refresh) 256e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 257e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line *pos, *n; 258e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct annotation *notes; 259e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct annotate_browser browser = { 260e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .b = { 261e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .refresh = ui_browser__list_head_refresh, 262e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .seek = ui_browser__list_head_seek, 263e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .write = annotate_browser__write, 264e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .priv = sym, 265e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng }, 266e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng }; 267e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int ret; 268e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 269e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (sym == NULL) 270e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 271e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 272e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (map->dso->annotate_warned) 273e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 274e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 275e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (symbol__annotate(sym, map, sizeof(struct objdump_line_rb_node)) < 0) { 276e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ui__error_window(ui_helpline__last_msg); 277e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 278e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 279e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 280e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ui_helpline__push("Press <- or ESC to exit"); 281e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 282e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng notes = symbol__annotation(sym); 283e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 284e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry(pos, ¬es->src->source, node) { 285e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct objdump_line_rb_node *rbpos; 286e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng size_t line_len = strlen(pos->line); 287e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 288e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (browser.b.width < line_len) 289e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng browser.b.width = line_len; 290e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rbpos = objdump_line__rb(pos); 291e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng rbpos->idx = browser.b.nr_entries++; 292e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 293e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 294e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng browser.b.entries = ¬es->src->source, 295e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng browser.b.width += 18; /* Percentage */ 296e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ret = annotate_browser__run(&browser, evidx, refresh); 297e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry_safe(pos, n, ¬es->src->source, node) { 298e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_del(&pos->node); 299e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng objdump_line__free(pos); 300e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 301e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return ret; 302e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 303