Add file percentage in visual mode (V/Vv)
This commit is contained in:
parent
01203509ff
commit
48c2c5f287
4 changed files with 154 additions and 2 deletions
|
|
@ -363,6 +363,8 @@ typedef struct rz_core_visual_t {
|
|||
int current5format;
|
||||
/* Panels */
|
||||
RzPanelsRoot *panels_root;
|
||||
/* file percentage */
|
||||
float percentage;
|
||||
} RzCoreVisual;
|
||||
|
||||
RZ_IPI RZ_OWN RzCoreVisual *rz_core_visual_new();
|
||||
|
|
|
|||
|
|
@ -3503,6 +3503,113 @@ RZ_IPI void rz_core_visual_scrollbar_bottom(RzCore *core) {
|
|||
rz_cons_flush();
|
||||
}
|
||||
|
||||
static bool is_in_symbol_range(ut64 sym_addr, ut64 sym_size, ut64 addr) {
|
||||
if (addr == sym_addr && sym_size == 0) {
|
||||
return true;
|
||||
}
|
||||
if (sym_size == 0) {
|
||||
return false;
|
||||
}
|
||||
return RZ_BETWEEN(sym_addr, addr, sym_addr + sym_size - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief The percentage of the mapped memory region returned for the given address.
|
||||
*
|
||||
* \param core RzCore
|
||||
* \param addr The given address
|
||||
* \return percentage of mapped memory region, or -1 if not in mapped memory or error happens
|
||||
*/
|
||||
static float get_percentage_of_mapped_region(RzCore *core, ut64 addr) {
|
||||
rz_return_val_if_fail(core, -1);
|
||||
|
||||
float percentage = -1;
|
||||
RzBinObject *bin_obj = rz_bin_cur_object(core->bin);
|
||||
RzPVector *sections = rz_bin_object_get_sections(bin_obj);
|
||||
if (!sections) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
RzBinSection *section;
|
||||
void **iter;
|
||||
rz_pvector_foreach (sections, iter) {
|
||||
section = *iter;
|
||||
if (is_in_symbol_range(section->vaddr, section->vsize, addr)) {
|
||||
// calculate the percentage
|
||||
percentage = (addr - section->vaddr) / (float)section->vsize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rz_pvector_free(sections);
|
||||
return percentage;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the address of the data of the row at the bottom of the screen
|
||||
* for calculating file percentage
|
||||
*
|
||||
* \param core RzCore
|
||||
* \return captured address
|
||||
*/
|
||||
static RZ_OWN char *screen_bottom_address(RzCore *core) {
|
||||
rz_return_val_if_fail(core, NULL);
|
||||
|
||||
char *rtn = NULL;
|
||||
// get the line at the bottom of the screen
|
||||
if (!core->cons->lastline) {
|
||||
return NULL;
|
||||
}
|
||||
char *output = strdup(core->cons->lastline);
|
||||
size_t line_count = 0, *line_index = rz_str_split_lines(output, &line_count);
|
||||
int rows;
|
||||
rz_cons_get_size(&rows);
|
||||
if (!line_index || rows > line_count) {
|
||||
goto exit1;
|
||||
}
|
||||
char *lastline = output + line_index[rows - 1];
|
||||
|
||||
// capture the address from the line at the bottom
|
||||
char *regex_str = ((RzCoreVisual *)core->visual)->printidx == RZ_CORE_VISUAL_MODE_CD ? "[0-9abcdefABCDEF]+" : "0x[0-9ABCDEFabcdef]+";
|
||||
RzRegex *re = rz_regex_new(regex_str, RZ_REGEX_EXTENDED, 0);
|
||||
RzPVector *matches = rz_regex_match_all_not_grouped(re, lastline, RZ_REGEX_ZERO_TERMINATED, 0, RZ_REGEX_DEFAULT);
|
||||
if (!matches || rz_pvector_empty(matches)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
RzRegexMatch *match = rz_pvector_at(matches, 0);
|
||||
rtn = rz_str_ndup(lastline + match->start, match->len);
|
||||
|
||||
// filter address in command, xref like ; CALL XREF from entry.fini0 @ 0x6b67
|
||||
char *comment_signs[] = { "@", ";" };
|
||||
char *addr_pos = strstr(lastline, rtn);
|
||||
for (ut32 i = 0; i < sizeof(comment_signs) / sizeof(comment_signs[0]); i++) {
|
||||
const char *sign_pos = rz_str_strchr(lastline, comment_signs[i]);
|
||||
if (sign_pos) {
|
||||
if (addr_pos && addr_pos > sign_pos) {
|
||||
rtn = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// in case the address doesn't have 0x prefix (RZ_CORE_VISUAL_MODE_CD)
|
||||
if (rtn && !rz_str_startswith_icase(rtn, "0x")) {
|
||||
ut32 addr_len = strlen(rtn), prefix_len = strlen("0x");
|
||||
rtn = realloc(rtn, prefix_len + addr_len + 1);
|
||||
memmove(rtn + 2, rtn, addr_len);
|
||||
rtn[0] = '0';
|
||||
rtn[1] = 'x';
|
||||
}
|
||||
|
||||
exit:
|
||||
rz_pvector_free(matches);
|
||||
rz_regex_free(re);
|
||||
exit1:
|
||||
free(line_index);
|
||||
free(output);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static void visual_refresh(RzCore *core) {
|
||||
static ut64 oseek = UT64_MAX;
|
||||
const char *vi, *vcmd, *cmd_str;
|
||||
|
|
@ -3606,6 +3713,14 @@ static void visual_refresh(RzCore *core) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// get the address in the line at the bottom of the screen to calculate the percentage
|
||||
char *bottom_addr = screen_bottom_address(core);
|
||||
if (bottom_addr) {
|
||||
ut64 addr = rz_num_math(NULL, bottom_addr);
|
||||
visual->percentage = get_percentage_of_mapped_region(core, addr);
|
||||
free(bottom_addr);
|
||||
}
|
||||
|
||||
/* this is why there's flickering */
|
||||
if (core->print->vflush) {
|
||||
rz_cons_visual_flush();
|
||||
|
|
@ -3624,6 +3739,15 @@ static void visual_refresh(RzCore *core) {
|
|||
if (rz_config_get_i(core->config, "scr.scrollbar")) {
|
||||
rz_core_visual_scrollbar(core);
|
||||
}
|
||||
|
||||
int h, cols = rz_cons_get_size(&h);
|
||||
if (visual->percentage >= 0) {
|
||||
char *percentage_str = rz_str_newf("%.1f%%", visual->percentage * 100);
|
||||
rz_cons_gotoxy(cols - strlen(percentage_str) - 1, h);
|
||||
rz_cons_printf("%s", percentage_str);
|
||||
rz_cons_flush();
|
||||
free(percentage_str);
|
||||
}
|
||||
}
|
||||
|
||||
static void visual_refresh_oneshot(RzCore *core) {
|
||||
|
|
@ -3831,6 +3955,7 @@ RZ_IPI int rz_core_visual(RzCore *core, const char *input) {
|
|||
|
||||
rz_cons_enable_mouse(false);
|
||||
if (visual->color) {
|
||||
|
||||
rz_cons_strcat(Color_RESET);
|
||||
}
|
||||
rz_config_set_i(core->config, "scr.color", visual->color);
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ static ut64 var_variables_show(RzCore *core, int idx, int *vindex, int show, int
|
|||
|
||||
static int level = 0;
|
||||
static st64 delta = 0;
|
||||
static ut64 column_nlines = 0;
|
||||
// output is used to store the result of printCmds
|
||||
// and avoid duplicated analysis while j and k is pressed
|
||||
static char *output = NULL;
|
||||
|
|
@ -289,7 +290,16 @@ static void rz_core_visual_analysis_refresh_column(RzCore *core, int colpos) {
|
|||
free(cmdf);
|
||||
}
|
||||
if (output) {
|
||||
// 'h - 2' because we have two new lines in rz_cons_printf
|
||||
// count the lines of output for calculating percentage
|
||||
column_nlines = 0;
|
||||
char *s = output;
|
||||
while (*s) {
|
||||
if (*s == '\n') {
|
||||
column_nlines++;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
// crop and print output, 'h - 2' because we have two new lines in rz_cons_printf
|
||||
char *out;
|
||||
if (printMode == 1) {
|
||||
out = rz_str_ansi_crop(output, 0, 0, w - colpos, h - 2);
|
||||
|
|
@ -453,6 +463,19 @@ static ut64 rz_core_visual_analysis_refresh(RzCore *core) {
|
|||
rz_warn_if_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
// print percentage at right corner
|
||||
cols = rz_cons_get_size(&h);
|
||||
float p = (float)(delta + h - 2) / (float)column_nlines;
|
||||
if (p > 1) {
|
||||
p = 1;
|
||||
}
|
||||
char *percentage = rz_str_newf("%.1f%%", p * 100);
|
||||
// move to the right corner
|
||||
rz_cons_gotoxy(cols - strlen(percentage) - 1, h);
|
||||
rz_cons_printf("%s", percentage);
|
||||
free(percentage);
|
||||
rz_cons_show_cursor(false);
|
||||
rz_cons_flush();
|
||||
return addr;
|
||||
}
|
||||
|
|
@ -708,11 +731,13 @@ RZ_IPI void rz_core_visual_analysis(RzCore *core, const char *input) {
|
|||
}
|
||||
break;
|
||||
case ':': {
|
||||
rz_cons_show_cursor(true);
|
||||
ut64 orig = core->offset;
|
||||
rz_core_seek(core, addr, false);
|
||||
while (rz_core_visual_prompt(core))
|
||||
;
|
||||
rz_core_seek(core, orig, false);
|
||||
rz_cons_show_cursor(false);
|
||||
}
|
||||
continue;
|
||||
case '/':
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ EXPECT=<<EOF
|
|||
0x00005b40 488d 3d21 c701 0048 8d35 1ac7 0100 4829 H.=!...H.5....H)
|
||||
0x00005b50 fe48 c1fe 0348 89f0 48c1 e83f 4801 c648 .H...H..H..?H..H
|
||||
0x00005b60 d1fe 7414 488b 053d c401 0048 85c0 7408 ..t.H..=...H..t.
|
||||
0x00005b70 ffe0 660f 1f44 0000 c30f 1f80 0000 0000 ..f..D.......... [?25h[0m[2J
[0;0H
|
||||
0x00005b70 ffe0 660f 1f44 0000 c30f 1f80 0000 0000 ..f..D.......... [12;75H9.2%[?25h[0m[2J
[0;0H
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue