rizin/librz/core/tui/flags.c
Dean 59b38e6efa
Add /*<type>*/ comments everywhere (#2986)
Adds /*<type>*/ comments and a linter check from rz-bindgen to enforce
their existence and consistency

Also includes the following fixes made when adding the annotations:
* removed unused intern_table arguments in pyc_dis.c, pyc_dis.h, asm_pyc.c
* removed unused classes argument from place_nodes in agraph.c
* removed unused recurse and recurse_bb functions in canalysis.c
* removed unused vars field from RzPrint struct
* removed unused RzAnalysisType* structs from rz_analysis.h
* removed unused list field from RzEgg struct
* fixed bug in bp_plugin.c where duplication-checking logic iterates over the wrong list
* removed unused q_regs field from RzDebug struct
* removed unused backtrace field from RzDebugPlugin struct
* removed unused classes_list field from RzBinNXOObj struct
* removed unused methods_list and classes_list fields from RzBinZimgObj struct
2022-09-11 13:04:53 +08:00

361 lines
8.3 KiB
C

// SPDX-FileCopyrightText: 2009-2020 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include <string.h>
#include <rz_core.h>
#include <rz_util.h>
#include "../core_private.h"
#include <rz_asm.h>
#include <rz_util/rz_print.h>
#include <rz_util/rz_strbuf.h>
#define MAX_FORMAT 3
enum {
SORT_NONE,
SORT_NAME,
SORT_OFFSET
};
static int flag_name_sort(const void *a, const void *b) {
const RzFlagItem *fa = (const RzFlagItem *)a;
const RzFlagItem *fb = (const RzFlagItem *)b;
return strcmp(fa->name, fb->name);
}
static int flag_offset_sort(const void *a, const void *b) {
const RzFlagItem *fa = (const RzFlagItem *)a;
const RzFlagItem *fb = (const RzFlagItem *)b;
if (fa->offset < fb->offset) {
return -1;
}
if (fa->offset > fb->offset) {
return 1;
}
return 0;
}
static void sort_flags(RzList /*<RzFlagItem *>*/ *l, int sort) {
switch (sort) {
case SORT_NAME:
rz_list_sort(l, flag_name_sort);
break;
case SORT_OFFSET:
rz_list_sort(l, flag_offset_sort);
break;
case SORT_NONE:
default:
break;
}
}
RZ_IPI int rz_core_visual_trackflags(RzCore *core) {
const char *fs = NULL, *fs2 = NULL;
int hit, i, j, ch;
int _option = 0;
int option = 0;
char cmd[1024];
int format = 0;
int delta = 7;
int menu = 0;
int sort = SORT_NONE;
RzCoreVisual *visual = core->visual;
if (rz_flag_space_is_empty(core->flags)) {
menu = 1;
}
for (;;) {
bool hasColor = rz_config_get_i(core->config, "scr.color");
rz_cons_clear00();
if (menu) {
rz_cons_printf("Flags in flagspace '%s'. Press '?' for help.\n\n",
rz_flag_space_cur_name(core->flags));
hit = 0;
i = j = 0;
RzList *l = rz_flag_all_list(core->flags, true);
RzListIter *iter;
RzFlagItem *fi;
sort_flags(l, sort);
rz_list_foreach (l, iter, fi) {
if (option == i) {
fs2 = fi->name;
hit = 1;
}
if ((i >= option - delta) && ((i < option + delta) || ((option < delta) && (i < (delta << 1))))) {
bool cur = option == i;
if (cur && hasColor) {
rz_cons_printf(Color_INVERT);
}
rz_cons_printf(" %c %03d 0x%08" PFMT64x " %4" PFMT64d " %s\n",
cur ? '>' : ' ', i, fi->offset, fi->size, fi->name);
if (cur && hasColor) {
rz_cons_printf(Color_RESET);
}
j++;
}
i++;
}
rz_list_free(l);
if (!hit && i > 0) {
option = i - 1;
continue;
}
if (fs2) {
int cols, rows = rz_cons_get_size(&cols);
// int rows = 20;
rows -= 12;
rz_cons_printf("\n Selected: %s\n\n", fs2);
// Honor MAX_FORMATS here
switch (format) {
case 0:
snprintf(cmd, sizeof(cmd), "px %d @ %s!64", rows * 16, fs2);
visual->printidx = 0;
break;
case 1:
snprintf(cmd, sizeof(cmd), "pd %d @ %s!64", rows, fs2);
visual->printidx = 1;
break;
case 2:
snprintf(cmd, sizeof(cmd), "ps @ %s!64", fs2);
visual->printidx = 5;
break;
case 3: strcpy(cmd, "f="); break;
default: format = 0; continue;
}
if (*cmd) {
rz_core_cmd(core, cmd, 0);
}
} else {
rz_cons_printf("(no flags)\n");
}
} else {
rz_cons_printf("Flag spaces:\n\n");
hit = 0;
RzSpaceIter it;
const RzSpace *s, *cur = rz_flag_space_cur(core->flags);
int i = 0;
rz_flag_space_foreach(core->flags, it, s) {
if (option == i) {
fs = s->name;
hit = 1;
}
if ((i >= option - delta) && ((i < option + delta) || ((option < delta) && (i < (delta << 1))))) {
rz_cons_printf(" %c %c %s\n",
(option == i) ? '>' : ' ',
(s == cur) ? '*' : ' ',
s->name);
}
i++;
}
if (option == i) {
fs = "*";
hit = 1;
}
rz_cons_printf(" %c %c %s\n", (option == i) ? '>' : ' ',
!cur ? '*' : ' ', "*");
i++;
if (!hit && i > 0) {
option = i - 1;
continue;
}
}
rz_cons_visual_flush();
ch = rz_cons_readchar();
if (ch == -1 || ch == 4) {
return false;
}
ch = rz_cons_arrow_to_hjkl(ch); // get ESC+char, return 'hjkl' char
switch (ch) {
case 'C':
rz_config_toggle(core->config, "scr.color");
break;
case '_':
if (rz_core_visual_hudstuff(core)) {
return true;
}
break;
case 'J': option += 10; break;
case 'o': sort = SORT_OFFSET; break;
case 'n': sort = SORT_NAME; break;
case 'j': option++; break;
case 'k':
if (--option < 0) {
option = 0;
}
break;
case 'K':
option -= 10;
if (option < 0) {
option = 0;
}
break;
case 'h':
case 'b': // back
case 'Q':
case 'q':
if (menu <= 0) {
return true;
}
menu--;
option = _option;
if (menu == 0) {
rz_flag_space_set(core->flags, NULL);
// if no flagspaces, just quit
if (rz_flag_space_is_empty(core->flags)) {
return true;
}
}
break;
case 'a':
switch (menu) {
case 0: // new flag space
rz_cons_show_cursor(true);
rz_line_set_prompt("add flagspace: ");
if (rz_cons_fgets(cmd, sizeof(cmd), 0, NULL) > 0) {
rz_flag_space_set(core->flags, cmd);
rz_cons_set_raw(1);
rz_cons_show_cursor(false);
}
break;
case 1: // new flag
rz_cons_show_cursor(true);
rz_line_set_prompt("add flag: ");
strcpy(cmd, "f ");
if (rz_cons_fgets(cmd + 2, sizeof(cmd) - 2, 0, NULL) > 0) {
rz_core_cmd(core, cmd, 0);
rz_cons_set_raw(1);
rz_cons_show_cursor(false);
}
break;
}
break;
case 'd':
rz_flag_unset_name(core->flags, fs2);
break;
case 'e':
/* TODO: prompt for addr, size, name */
eprintf("TODO\n");
rz_sys_sleep(1);
break;
case '*':
rz_core_block_size(core, core->blocksize + 16);
break;
case '/':
rz_core_block_size(core, core->blocksize - 16);
break;
case '+':
if (menu == 1) {
rz_core_cmdf(core, "f %s @ %s+1", fs2, fs2);
} else {
rz_core_block_size(core, core->blocksize + 1);
}
break;
case '-':
if (menu == 1) {
rz_core_cmdf(core, "f %s @ %s-1", fs2, fs2);
} else {
rz_core_block_size(core, core->blocksize - 1);
}
break;
case 'r': // "Vtr"
if (menu == 1) {
int len;
rz_cons_show_cursor(true);
rz_cons_set_raw(0);
// TODO: use rz_flag_rename or fail?..`fr` doesn't uses this..
snprintf(cmd, sizeof(cmd), "fr %s ", fs2);
len = strlen(cmd);
eprintf("Rename flag '%s' as:\n", fs2);
rz_line_set_prompt(":> ");
if (rz_cons_fgets(cmd + len, sizeof(cmd) - len, 0, NULL) < 0) {
cmd[0] = '\0';
}
rz_core_cmd(core, cmd, 0);
rz_cons_set_raw(1);
rz_cons_show_cursor(false);
}
break;
case 'R':
if (menu == 1) {
char line[1024];
rz_cons_show_cursor(true);
rz_cons_set_raw(0);
eprintf("Rename function '%s' as:\n", fs2);
rz_line_set_prompt(":> ");
if (rz_cons_fgets(line, sizeof(line), 0, NULL) < 0) {
cmd[0] = '\0';
}
ut64 addr = rz_num_math(core->num, line);
rz_core_analysis_function_add(core, fs2, addr, true);
rz_cons_set_raw(1);
rz_cons_show_cursor(false);
}
break;
case 'P':
if (--format < 0) {
format = MAX_FORMAT;
}
break;
// = (format<=0)? MAX_FORMAT: format-1; break;
case 'p': format++; break;
case 'l':
case ' ':
case '\r':
case '\n':
if (menu == 1) {
ut64 addr = rz_num_math(core->num, fs2);
rz_core_seek_and_save(core, addr, true);
return true;
}
rz_flag_space_set(core->flags, fs);
menu = 1;
_option = option;
option = 0;
break;
case '?':
rz_cons_clear00();
rz_cons_printf(
"\nVF: Visual Flags help:\n\n"
" q - quit menu\n"
" j/k - line down/up keys\n"
" J/K - page down/up keys\n"
" h/b - go back\n"
" C - toggle colors\n"
" l/' ' - accept current selection\n"
" a/d/e - add/delete/edit flag\n"
" +/- - increase/decrease block size\n"
" o - sort flags by offset\n"
" r/R - rename flag / Rename function\n"
" n - sort flags by name\n"
" p/P - rotate print format\n"
" _ - hud for flags and comments\n"
" : - enter command\n");
rz_cons_flush();
rz_cons_any_key(NULL);
break;
case ':':
rz_cons_show_cursor(true);
rz_cons_set_raw(0);
*cmd = 0;
rz_line_set_prompt(":> ");
if (rz_cons_fgets(cmd, sizeof(cmd), 0, NULL) < 0) {
*cmd = 0;
}
cmd[sizeof(cmd) - 1] = 0;
rz_core_cmd0(core, cmd);
rz_cons_set_raw(1);
rz_cons_show_cursor(false);
if (*cmd) {
rz_cons_any_key(NULL);
}
// cons_gotoxy(0,0);
rz_cons_clear();
continue;
}
}
return true;
}