1 #include "../libslang.h"
4 #include <sys/ttydefaults.h>
7 #include <linux/bitops.h>
8 #include "../../debug.h"
9 #include "../../symbol.h"
10 #include "../browser.h"
11 #include "../helpline.h"
14 static int ui_entry__read(const char *title
, char *bf
, size_t size
, int width
)
16 struct newtExitStruct es
;
17 newtComponent form
, entry
;
21 newtCenteredWindow(width
, 1, title
);
22 form
= newtForm(NULL
, NULL
, 0);
26 entry
= newtEntry(0, 0, "0x", width
, &result
, NEWT_FLAG_SCROLL
);
30 newtFormAddComponent(form
, entry
);
31 newtFormAddHotKey(form
, NEWT_KEY_ENTER
);
32 newtFormAddHotKey(form
, NEWT_KEY_ESCAPE
);
33 newtFormAddHotKey(form
, NEWT_KEY_LEFT
);
34 newtFormAddHotKey(form
, CTRL('c'));
35 newtFormRun(form
, &es
);
38 strncpy(bf
, result
, size
);
43 newtFormDestroy(form
);
54 static void map_browser__write(struct ui_browser
*self
, void *nd
, int row
)
56 struct symbol
*sym
= rb_entry(nd
, struct symbol
, rb_node
);
57 struct map_browser
*mb
= container_of(self
, struct map_browser
, b
);
58 bool current_entry
= ui_browser__is_current_entry(self
, row
);
59 int color
= ui_browser__percent_color(0, current_entry
);
61 SLsmg_set_color(color
);
62 slsmg_printf("%*llx %*llx %c ",
63 mb
->addrlen
, sym
->start
, mb
->addrlen
, sym
->end
,
64 sym
->binding
== STB_GLOBAL
? 'g' :
65 sym
->binding
== STB_LOCAL
? 'l' : 'w');
66 slsmg_write_nstring(sym
->name
, mb
->namelen
);
69 /* FIXME uber-kludgy, see comment on cmd_report... */
70 static u32
*symbol__browser_index(struct symbol
*self
)
72 return ((void *)self
) - sizeof(struct rb_node
) - sizeof(u32
);
75 static int map_browser__search(struct map_browser
*self
)
79 int err
= ui_entry__read("Search by name/addr", target
, sizeof(target
), 40);
84 if (target
[0] == '0' && tolower(target
[1]) == 'x') {
85 u64 addr
= strtoull(target
, NULL
, 16);
86 sym
= map__find_symbol(self
->map
, addr
, NULL
);
88 sym
= map__find_symbol_by_name(self
->map
, target
, NULL
);
91 u32
*idx
= symbol__browser_index(sym
);
93 self
->b
.top
= &sym
->rb_node
;
94 self
->b
.index
= self
->b
.top_idx
= *idx
;
96 ui_helpline__fpush("%s not found!", target
);
101 static int map_browser__run(struct map_browser
*self
, struct newtExitStruct
*es
)
103 if (ui_browser__show(&self
->b
, self
->map
->dso
->long_name
) < 0)
106 ui_helpline__fpush("Press <- or ESC to exit, %s / to search",
107 verbose
? "" : "restart with -v to use");
108 newtFormAddHotKey(self
->b
.form
, NEWT_KEY_LEFT
);
109 newtFormAddHotKey(self
->b
.form
, NEWT_KEY_ENTER
);
111 newtFormAddHotKey(self
->b
.form
, '/');
114 ui_browser__run(&self
->b
, es
);
116 if (es
->reason
!= NEWT_EXIT_HOTKEY
)
118 if (verbose
&& es
->u
.key
== '/')
119 map_browser__search(self
);
124 newtFormDestroy(self
->b
.form
);
130 int map__browse(struct map
*self
)
132 struct map_browser mb
= {
134 .entries
= &self
->dso
->symbols
[self
->type
],
135 .refresh
= ui_browser__rb_tree_refresh
,
136 .seek
= ui_browser__rb_tree_seek
,
137 .write
= map_browser__write
,
141 struct newtExitStruct es
;
143 char tmp
[BITS_PER_LONG
/ 4];
146 for (nd
= rb_first(mb
.b
.entries
); nd
; nd
= rb_next(nd
)) {
147 struct symbol
*pos
= rb_entry(nd
, struct symbol
, rb_node
);
149 if (mb
.namelen
< pos
->namelen
)
150 mb
.namelen
= pos
->namelen
;
151 if (maxaddr
< pos
->end
)
154 u32
*idx
= symbol__browser_index(pos
);
155 *idx
= mb
.b
.nr_entries
;
160 mb
.addrlen
= snprintf(tmp
, sizeof(tmp
), "%llx", maxaddr
);
161 mb
.b
.width
+= mb
.addrlen
* 2 + 4 + mb
.namelen
;
162 return map_browser__run(&mb
, &es
);