1 // SPDX-License-Identifier: GPL-2.0
4 #include <sys/ttydefaults.h>
7 #include <linux/bitops.h>
8 #include "../../util/debug.h"
9 #include "../../util/map.h"
10 #include "../../util/dso.h"
11 #include "../../util/symbol.h"
12 #include "../browser.h"
13 #include "../helpline.h"
14 #include "../keysyms.h"
17 #include <linux/ctype.h>
25 static void map_browser__write(struct ui_browser
*browser
, void *nd
, int row
)
27 struct symbol
*sym
= rb_entry(nd
, struct symbol
, rb_node
);
28 struct map_browser
*mb
= container_of(browser
, struct map_browser
, b
);
29 bool current_entry
= ui_browser__is_current_entry(browser
, row
);
32 ui_browser__set_percent_color(browser
, 0, current_entry
);
33 ui_browser__printf(browser
, "%*" PRIx64
" %*" PRIx64
" %c ",
34 mb
->addrlen
, sym
->start
, mb
->addrlen
, sym
->end
,
35 sym
->binding
== STB_GLOBAL
? 'g' :
36 sym
->binding
== STB_LOCAL
? 'l' : 'w');
37 width
= browser
->width
- ((mb
->addrlen
* 2) + 4);
39 ui_browser__write_nstring(browser
, sym
->name
, width
);
42 /* FIXME uber-kludgy, see comment on cmd_report... */
43 static u32
*symbol__browser_index(struct symbol
*browser
)
45 return ((void *)browser
) - sizeof(struct rb_node
) - sizeof(u32
);
48 static int map_browser__search(struct map_browser
*browser
)
52 int err
= ui_browser__input_window("Search by name/addr",
53 "Prefix with 0x to search by address",
54 target
, "ENTER: OK, ESC: Cancel", 0);
58 if (target
[0] == '0' && tolower(target
[1]) == 'x') {
59 u64 addr
= strtoull(target
, NULL
, 16);
60 sym
= map__find_symbol(browser
->map
, addr
);
62 sym
= map__find_symbol_by_name(browser
->map
, target
);
65 u32
*idx
= symbol__browser_index(sym
);
67 browser
->b
.top
= &sym
->rb_node
;
68 browser
->b
.index
= browser
->b
.top_idx
= *idx
;
70 ui_helpline__fpush("%s not found!", target
);
75 static int map_browser__run(struct map_browser
*browser
)
79 if (ui_browser__show(&browser
->b
, browser
->map
->dso
->long_name
,
80 "Press ESC to exit, %s / to search",
81 verbose
> 0 ? "" : "restart with -v to use") < 0)
85 key
= ui_browser__run(&browser
->b
, 0);
90 map_browser__search(browser
);
101 ui_browser__hide(&browser
->b
);
105 int map__browse(struct map
*map
)
107 struct map_browser mb
= {
109 .entries
= &map
->dso
->symbols
,
110 .refresh
= ui_browser__rb_tree_refresh
,
111 .seek
= ui_browser__rb_tree_seek
,
112 .write
= map_browser__write
,
117 char tmp
[BITS_PER_LONG
/ 4];
120 for (nd
= rb_first(mb
.b
.entries
); nd
; nd
= rb_next(nd
)) {
121 struct symbol
*pos
= rb_entry(nd
, struct symbol
, rb_node
);
123 if (maxaddr
< pos
->end
)
126 u32
*idx
= symbol__browser_index(pos
);
127 *idx
= mb
.b
.nr_entries
;
132 mb
.addrlen
= snprintf(tmp
, sizeof(tmp
), "%" PRIx64
, maxaddr
);
133 return map_browser__run(&mb
);