Use RSpaces in RFlag ##refactor

This commit is contained in:
Riccardo Schirone 2019-02-03 16:06:45 +01:00 committed by radare
parent 5daf89a4b0
commit e5b4d9294c
20 changed files with 338 additions and 524 deletions

View File

@ -1341,7 +1341,7 @@ int main(int argc, char **argv, char **envp) {
}
// no flagspace selected by default the beginning
r.flags->space_idx = -1;
r_flag_space_set (r.flags, NULL);
/* load <file>.r2 */
{
char f[128];
@ -1440,7 +1440,7 @@ int main(int argc, char **argv, char **envp) {
}
// no flagspace selected by default the beginning
r.flags->space_idx = -1;
r_flag_space_set (r.flags, NULL);
if (!debug && r.bin && r.bin->cur && r.bin->cur->o && r.bin->cur->o->info) {
if (r.bin->cur->o->info->arch) {
r_core_cmd0 (&r, "aeip");

View File

@ -2663,7 +2663,7 @@ escape_backtick:
bool is_arch_set = false;
char *tmpeval = NULL;
char *tmpasm = NULL;
int flgspc = -123;
bool flgspc_changed = false;
int tmpfd = -1;
int sz, len;
ut8 *buf;
@ -2718,8 +2718,7 @@ repeat_arroba:
} else if (ptr[0] && ptr[1] == ':' && ptr[2]) {
switch (ptr[0]) {
case 'F': // "@F:" // temporary flag space
flgspc = r_flag_space_get (core->flags, ptr + 2);
r_flag_space_set (core->flags, ptr + 2);
flgspc_changed = r_flag_space_push (core->flags, ptr + 2);
break;
case 'B': // "@B:#" // seek to the last instruction in current bb
{
@ -3002,8 +3001,8 @@ next_arroba:
r_core_cmd0 (core, tmpeval);
R_FREE (tmpeval);
}
if (flgspc != -123) {
r_flag_space_set_i (core->flags, flgspc);
if (flgspc_changed) {
r_flag_space_pop (core->flags);
}
*ptr = '@';
rc = ret;
@ -3607,7 +3606,7 @@ R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each) {
}
str[i] = ch;
{
int flagspace = core->flags->space_idx;
const RSpace *flagspace = r_flag_space_cur (core->flags);
RList *match_flag_items = r_list_newf ((RListFree)r_flag_item_free);
if (!match_flag_items) {
break;
@ -3642,7 +3641,6 @@ R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each) {
}
r_list_free (match_flag_items);
core->flags->space_idx = flagspace;
core->rcmd->macro.counter++ ;
R_FREE (word);
}

View File

@ -341,6 +341,56 @@ static bool adjust_offset(RFlagItem *flag, void *user) {
return true;
}
static void print_space_stack(RFlag *f, int ordinal, const char *name, bool selected, PJ *pj, int mode) {
bool first = ordinal == 0;
switch (mode) {
case 'j': {
char *ename = r_str_escape (name);
if (!ename) {
return;
}
pj_o (pj);
pj_ki (pj, "ordinal", ordinal);
pj_ks (pj, "name", ename);
pj_kb (pj, "selected", selected);
pj_end (pj);
free (ename);
break;
}
case '*': {
const char *fmt = first? "fs %s\n": "fs+%s\n";
r_cons_printf (fmt, name);
break;
}
default:
r_cons_printf ("%-2d %s%s\n", ordinal, name, selected? " (selected)": "");
break;
}
}
static int flag_space_stack_list(RFlag *f, int mode) {
RListIter *iter;
char *space;
int i = 0;
PJ *pj = NULL;
if (mode == 'j') {
pj = pj_new ();
pj_a (pj);
}
r_list_foreach (f->spaces.spacestack, iter, space) {
print_space_stack (f, i++, space, false, pj, mode);
}
const char *cur_name = r_flag_space_cur_name (f);
print_space_stack (f, i++, cur_name, true, pj, mode);
if (mode == 'j') {
pj_end (pj);
r_cons_printf ("%s\n", pj_string (pj));
pj_free (pj);
}
return i;
}
static int cmd_flag(void *data, const char *input) {
static int flagenum = 0;
RCore *core = (RCore *)data;
@ -709,19 +759,20 @@ rep:
}
break;
case 's':
r_flag_space_stack_list (core->flags, input[2]);
flag_space_stack_list (core->flags, input[2]);
break;
case '-':
switch (input[2]) {
case '*':
r_flag_space_unset (core->flags, NULL);
break;
case '.':
{
const char *curfs = r_flag_space_cur (core->flags);
r_flag_space_unset (core->flags, curfs);
case '.': {
const RSpace *sp = r_flag_space_cur (core->flags);
if (sp) {
r_flag_space_unset (core->flags, sp->name);
}
break;
}
case 0:
r_flag_space_pop (core->flags);
break;
@ -734,7 +785,7 @@ rep:
case '\0':
case '*':
case 'q':
r_flag_space_list (core->flags, input[1]);
spaces_list (&core->flags->spaces, input[1]);
break;
case ' ':
r_flag_space_set (core->flags, input+2);
@ -747,21 +798,15 @@ rep:
}
f = r_flag_get_i (core->flags, off);
if (f) {
f->space = core->flags->space_idx;
f->space = r_flag_space_cur (core->flags);
} else {
eprintf ("Cannot find any flag at 0x%"PFMT64x".\n", off);
}
}
break;
default: {
int i, j = 0;
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (core->flags->spaces[i])
r_cons_printf ("%02d %c %s\n", j++,
(i == core->flags->space_idx)?'*':' ',
core->flags->spaces[i]);
}
} break;
default:
spaces_list (&core->flags->spaces, 0);
break;
}
break;
case 'g':
@ -888,7 +933,6 @@ rep:
ut64 addr = core->offset;
char *arg = NULL;
RFlagItem *f = NULL;
bool space_strict = true;
bool strict_offset = false;
switch (input[1]) {
case '?':
@ -901,7 +945,6 @@ rep:
addr = core->offset;
break;
case 'd':
space_strict = false;
arg = strchr (input, ' ');
if (arg) {
addr = r_num_math (core->num, arg + 1);
@ -924,47 +967,46 @@ rep:
}
return 0;
}
case 'w':
{
case 'w': {
arg = strchr (input, ' ');
if (arg) {
arg++;
if (*arg) {
RFlag *f = core->flags;
RList *temp = r_flag_all_list (f);
ut64 loff = 0;
ut64 uoff = 0;
ut64 curseek = core->offset;
char *lmatch = NULL , *umatch = NULL;
RFlagItem *flag;
RListIter *iter;
r_list_sort (temp, &cmpflag);
r_list_foreach (temp, iter, flag) {
if ((f->space_idx != -1) && (flag->space != f->space_idx)) {
continue;
}
if (strstr (flag->name , arg) != NULL) {
if (flag->offset < core->offset) {
loff = flag->offset;
lmatch = flag->name;
continue;
}
uoff = flag->offset;
umatch = flag->name;
break;
}
}
char *match = (curseek - loff) < (uoff - curseek) ? lmatch : umatch ;
if (match) {
if (*match) {
r_cons_println (match);
}
}
r_list_free (temp);
}
if (!arg) {
return 0;
}
arg++;
if (!*arg) {
return 0;
}
RFlag *f = core->flags;
RList *temp = r_flag_all_list (f, true);
ut64 loff = 0;
ut64 uoff = 0;
ut64 curseek = core->offset;
char *lmatch = NULL , *umatch = NULL;
RFlagItem *flag;
RListIter *iter;
r_list_sort (temp, &cmpflag);
r_list_foreach (temp, iter, flag) {
if (strstr (flag->name , arg) != NULL) {
if (flag->offset < core->offset) {
loff = flag->offset;
lmatch = flag->name;
continue;
}
uoff = flag->offset;
umatch = flag->name;
break;
}
}
char *match = (curseek - loff) < (uoff - curseek) ? lmatch : umatch ;
if (match) {
if (*match) {
r_cons_println (match);
}
}
r_list_free (temp);
return 0;
}
}
default:
arg = strchr (input, ' ');
if (arg) {
@ -972,9 +1014,7 @@ rep:
}
break;
}
core->flags->space_strict = space_strict;
f = r_flag_get_at (core->flags, addr, !strict_offset);
core->flags->space_strict = false;
if (f) {
if (f->offset != addr) {
// if input contains 'j' print json

View File

@ -1098,17 +1098,10 @@ static int cmd_meta(void *data, const char *input) {
case ' ': // "CS "
r_spaces_set (ms, input + 2);
break;
default: {
RSpace *s;
RBIter it;
const RSpace *cur = r_spaces_current (ms);
r_rbtree_foreach (ms->spaces, it, s, RSpace, rb) {
r_cons_printf ("%c %s\n", (s == cur)? '*': ' ',
s->name);
}
default:
spaces_list (ms, 0);
break;
}
}
break;
}
return true;

View File

@ -1761,7 +1761,7 @@ R_API void r_core_print_examine(RCore *core, const char *str) {
}
struct count_pz_t {
int flagspace;
RSpace *flagspace;
ut64 addr;
ut64 size;
int *ret;
@ -1821,8 +1821,7 @@ static int printzoomcallback(void *user, int mode, ut64 addr, ut8 *bufz, ut64 si
}
break;
case 's': // "pzs"
j = r_flag_space_get (core->flags, "strings");
u.flagspace = j;
u.flagspace = r_flag_space_get (core->flags, "strings");
u.addr = addr;
u.size = size;
u.ret = &ret;

View File

@ -493,9 +493,7 @@ static int cmd_seek(void *data, const char *input) {
r_list_foreach (list, iter, undo) {
char *name = NULL;
core->flags->space_strict = true;
RFlagItem *f = r_flag_get_at (core->flags, undo->off, true);
core->flags->space_strict = false;
if (f) {
if (f->offset != undo->off) {
name = r_str_newf ("%s+%d", f->name,
@ -551,9 +549,7 @@ static int cmd_seek(void *data, const char *input) {
r_list_foreach (list, iter, undo) {
char *name = NULL;
core->flags->space_strict = true;
RFlagItem *f = r_flag_get_at (core->flags, undo->off, true);
core->flags->space_strict = false;
if (f) {
if (f->offset != undo->off) {
name = r_str_newf ("%s + %d\n", f->name,

View File

@ -1173,10 +1173,10 @@ static void autocomplete_zignatures(RLine* line, const char* msg) {
int length = strlen (msg);
RSpaces *zs = &core->anal->zign_spaces;
RSpace *s;
RBIter it;
RSpaceIter it;
int i = 0;
r_rbtree_foreach (zs->spaces, it, s, RSpace, rb) {
r_spaces_foreach (zs, it, s) {
if (i == TMP_ARGV_SZ - 1) {
break;
}
@ -1202,23 +1202,21 @@ static void autocomplete_flagspaces(RLine* line, const char* msg) {
}
int length = strlen (msg);
RFlag *flag = core->flags;
int j, i = 0;
for (j = 0; j < R_FLAG_SPACES_MAX - 1; j++) {
if (flag->spaces[j] && flag->spaces[j][0]) {
if (i == TMP_ARGV_SZ - 1) {
break;
}
if (!strncmp (msg, flag->spaces[j], length)) {
if (i + 1 < TMP_ARGV_SZ) {
tmp_argv[i++] = flag->spaces[j];
}
int i = 0;
RSpaceIter it;
RSpace *s;
r_flag_space_foreach (flag, it, s) {
if (i == TMP_ARGV_SZ - 1) {
break;
}
if (!strncmp (msg, s->name, length)) {
if (i + 1 < TMP_ARGV_SZ) {
tmp_argv[i++] = s->name;
}
}
}
if (flag->spaces[j] && !strncmp (msg, flag->spaces[j], strlen (msg))) {
if (i + 1 < TMP_ARGV_SZ) {
tmp_argv[i++] = "*";
}
if (i + 1 < TMP_ARGV_SZ) {
tmp_argv[i++] = "*";
}
tmp_argv[i] = NULL;
line->completion.argc = i;
@ -2209,25 +2207,28 @@ static char *get_comments_cb(void *user, ut64 addr) {
}
R_IPI void spaces_list(RSpaces *sp, int mode) {
RBIter it;
RSpaceIter it;
RSpace *s;
bool first = true;
const RSpace *cur = r_spaces_current (sp);
PJ *pj = NULL;
if (mode == 'j') {
r_cons_printf ("[");
pj = pj_new ();
pj_a (pj);
}
r_rbtree_foreach (sp->spaces, it, s, RSpace, rb) {
r_spaces_foreach (sp, it, s) {
int count = r_spaces_count (sp, s->name);
if (mode == 'j') {
r_cons_printf ("%s{\"name\":\"%s\"%s,\"count\":%d}",
!first? ",": "", s->name,
cur == s? ",\"selected\":true": "",
count);
pj_o (pj);
pj_ks (pj, "name", s->name);
pj_ki (pj, "count", count);
pj_kb (pj, "selected", cur == s);
pj_end (pj);
} else if (mode == '*') {
r_cons_printf ("%s %s\n", sp->name, s->name);
} else {
r_cons_printf ("%d %c %s\n", count, cur == s? '*': '.',
s->name);
r_cons_printf ("%5d %c %s\n", count, (!cur || cur == s)? '*': '.',
s->name);
}
first = false;
}
@ -2235,7 +2236,9 @@ R_IPI void spaces_list(RSpaces *sp, int mode) {
r_cons_printf ("%s %s # current\n", sp->name, r_spaces_current_name (sp));
}
if (mode == 'j') {
r_cons_printf ("]\n");
pj_end (pj);
r_cons_printf ("%s\n", pj_string (pj));
pj_free (pj);
}
}

View File

@ -160,7 +160,7 @@ typedef struct {
RStrEnc strenc;
int cursor;
int show_comment_right_default;
int flagspace_ports;
RSpace *flagspace_ports;
int show_flag_in_bytes;
int lbytes;
int show_comment_right;
@ -985,18 +985,18 @@ static void ds_build_op_str(RDisasmState *ds, bool print_color) {
ds->opstr = strdup (ds->hint->opcode);
}
if (ds->filter) {
int ofs = core->parser->flagspace;
int fs = ds->flagspace_ports;
RSpace *ofs = core->parser->flagspace;
RSpace *fs = ds->flagspace_ports;
if (ds->analop.type == R_ANAL_OP_TYPE_IO) {
core->parser->notin_flagspace = -1;
core->parser->notin_flagspace = NULL;
core->parser->flagspace = fs;
} else {
if (fs != -1) {
if (fs) {
core->parser->notin_flagspace = fs;
core->parser->flagspace = fs;
} else {
core->parser->notin_flagspace = -1;
core->parser->flagspace = -1;
core->parser->notin_flagspace = NULL;
core->parser->flagspace = NULL;
}
}
if (ds->analop.refptr) {
@ -5362,18 +5362,18 @@ R_API int r_core_print_disasm_instructions(RCore *core, int nb_bytes, int nb_opc
}
} else if (ds->filter) {
char *asm_str;
int ofs = core->parser->flagspace;
int fs = ds->flagspace_ports;
RSpace *ofs = core->parser->flagspace;
RSpace *fs = ds->flagspace_ports;
if (ds->analop.type == R_ANAL_OP_TYPE_IO) {
core->parser->notin_flagspace = -1;
core->parser->notin_flagspace = NULL;
core->parser->flagspace = fs;
} else {
if (fs != -1) {
if (fs) {
core->parser->notin_flagspace = fs;
core->parser->flagspace = fs;
} else {
core->parser->notin_flagspace = -1;
core->parser->flagspace = -1;
core->parser->notin_flagspace = NULL;
core->parser->flagspace = NULL;
}
}
core->parser->hint = ds->hint;

View File

@ -606,7 +606,7 @@ static bool simpleProjectSaveScript(RCore *core, const char *file, int opts) {
static bool projectSaveScript(RCore *core, const char *file, int opts) {
char *filename, *hl, *ohl = NULL;
int fd, fdold, tmp;
int fd, fdold;
if (!file || *file == '\0') {
return false;
@ -633,10 +633,9 @@ static bool projectSaveScript(RCore *core, const char *file, int opts) {
if (opts & R_CORE_PRJ_FLAGS) {
r_str_write (fd, "# flags\n");
tmp = core->flags->space_idx;
core->flags->space_idx = -1;
r_flag_space_push (core->flags, NULL);
r_flag_list (core->flags, true, NULL);
core->flags->space_idx = tmp;
r_flag_space_pop (core->flags);
r_cons_flush ();
}
// Set file.path and file.lastpath to empty string to signal

View File

@ -3512,24 +3512,15 @@ R_API void r_core_visual_title(RCore *core, int color) {
filename = desc? desc->name: "";
{ /* get flag with delta */
ut64 addr = core->offset + (core->print->cur_enabled? core->print->cur: 0);
#if 1
/* TODO: we need a helper into r_flags to do that */
bool oss = core->flags->space_strict;
int osi = core->flags->space_idx;
RFlagItem *f = NULL;
core->flags->space_strict = true;
core->anal->flb.set_fs (core->flags, "symbols");
if (core->flags->space_idx != -1) {
if (core->anal->flb.push_fs (core->flags, "symbols")) {
f = core->anal->flb.get_at (core->flags, addr, showDelta);
core->anal->flb.pop_fs (core->flags);
}
core->flags->space_strict = oss;
core->flags->space_idx = osi;
if (!f) {
f = r_flag_get_at (core->flags, addr, showDelta);
}
#else
RFlagItem *f = r_flag_get_at (core->flags, addr, false);
#endif
if (f) {
if (f->offset == addr || !f->offset) {
snprintf (pos, sizeof (pos), "@ %s", f->name);

View File

@ -595,7 +595,7 @@ static int sdbforcb (void *p, const char *k, const char *v) {
R_API int r_core_visual_types(RCore *core) {
RCoreVisualTypes vt = {core, 0, 0};
int i, j, ch;
int i, ch;
int _option = 0;
int option = 0;
char *txt;
@ -612,12 +612,7 @@ R_API int r_core_visual_types(RCore *core) {
NULL
};
bool use_color = core->print->flags & R_PRINT_FLAGS_COLOR;
for (j = i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (core->flags->spaces[i]) {
j = 1;
}
}
if (j == 0) {
if (r_flag_space_is_empty (core->flags)) {
menu = 1;
}
for (;;) {
@ -716,12 +711,7 @@ R_API int r_core_visual_types(RCore *core) {
option = _option;
if (menu==0) {
// if no flagspaces, just quit
for (j = i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (core->flags->spaces[i]) {
j = 1;
}
}
if (!j) {
if (r_flag_space_is_empty (core->flags)) {
return true;
}
}
@ -1518,12 +1508,7 @@ R_API int r_core_visual_trackflags(RCore *core) {
int menu = 0;
int sort = SORT_NONE;
for (j=i=0; i<R_FLAG_SPACES_MAX; i++) {
if (core->flags->spaces[i]) {
j = 1;
}
}
if (j == 0) {
if (r_flag_space_is_empty (core->flags)) {
menu = 1;
}
for (;;) {
@ -1532,19 +1517,14 @@ R_API int r_core_visual_trackflags(RCore *core) {
if (menu) {
r_cons_printf ("Flags in flagspace '%s'. Press '?' for help.\n\n",
(core->flags->space_idx==-1)?"*":core->flags->spaces[core->flags->space_idx]);
r_flag_space_cur_name (core->flags));
hit = 0;
i = j = 0;
RList *l = r_flag_all_list (core->flags);
RList *l = r_flag_all_list (core->flags, true);
RListIter *iter;
RFlagItem *fi;
sort_flags (l, sort);
r_list_foreach (l, iter, fi) {
/* filter per flag spaces */
if ((core->flags->space_idx != -1) &&
(fi->space != core->flags->space_idx)) {
continue;
}
if (option == i) {
fs2 = fi->name;
hit = 1;
@ -1591,34 +1571,32 @@ R_API int r_core_visual_trackflags(RCore *core) {
} else {
r_cons_printf ("Flag spaces:\n\n");
hit = 0;
for (j=i=0;i<R_FLAG_SPACES_MAX;i++) {
if (core->flags->spaces[i]) {
if (option == i) {
fs = core->flags->spaces[i];
hit = 1;
}
if ((i >= option - delta) && ((i < option + delta)|| \
((option < delta) && (i < (delta << 1))))) {
r_cons_printf (" %c %02d %c %s\n",
(option==i)?'>':' ', j,
(i==core->flags->space_idx)?'*':' ',
core->flags->spaces[i]);
j++;
}
}
}
if (core->flags->spaces[9]) {
if (option == j) {
fs = "*";
RSpaceIter it;
const RSpace *s, *cur = r_flag_space_cur (core->flags);
int i = 0;
r_flag_space_foreach (core->flags, it, s) {
if (option == i) {
fs = s->name;
hit = 1;
}
r_cons_printf (" %c %02d %c %s\n",
(option==j)?'>':' ', j,
(i==core->flags->space_idx)?'*':' ',
"*");
if ((i >= option - delta) && ((i < option + delta) ||
((option < delta) && (i < (delta << 1))))) {
r_cons_printf (" %c %c %s\n",
(option == i)? '>': ' ',
(s == cur)? '*': ' ',
s->name);
}
i++;
}
if (!hit && j > 0) {
option = j - 1;
if (option == i) {
fs = "*";
hit = 1;
}
r_cons_printf (" %c %c %s\n", (option == i)? '>': ' ',
!cur? '*': ' ', "*");
i++;
if (!hit && i > 0) {
option = i - 1;
continue;
}
}
@ -1663,12 +1641,7 @@ R_API int r_core_visual_trackflags(RCore *core) {
if (menu == 0) {
r_flag_space_set (core->flags, NULL);
// if no flagspaces, just quit
for (j=i=0;i<R_FLAG_SPACES_MAX;i++) {
if (core->flags->spaces[i]) {
j = 1;
}
}
if (!j) {
if (r_flag_space_is_empty (core->flags)) {
return true;
}
}

View File

@ -2,6 +2,6 @@ include ../config.mk
NAME=r_flag
DEPS=r_util
OBJS=flag.o spaces.o zones.o tags.o
OBJS=flag.o zones.o tags.o
include ../rules.mk

View File

@ -7,8 +7,8 @@
R_LIB_VERSION(r_flag);
#define IS_FI_NOTIN_SPACE(f, i) ((f)->space_idx != -1 && (i)->space != (f)->space_idx)
#define IS_FI_IN_SPACE(fi, spidx) ((spidx) == -1 || (fi)->space == (spidx))
#define IS_FI_NOTIN_SPACE(f, i) (r_flag_space_cur (f) && (i)->space != r_flag_space_cur (f))
#define IS_FI_IN_SPACE(fi, sp) (!(sp) || (fi)->space == (sp))
#define STRDUP_OR_NULL(s) (!R_STR_ISEMPTY (s)? strdup (s): NULL)
static const char *str_callback(RNum *user, ut64 off, int *ok) {
@ -190,8 +190,38 @@ static void ht_free_flag(HtPPKv *kv) {
r_flag_item_free (kv->value);
}
static bool count_flags(RFlagItem *fi, void *user) {
int *count = (int *)user;
(*count)++;
return true;
}
static bool unset_flags_space(RFlagItem *fi, void *user) {
fi->space = NULL;
return true;
}
static void count_flags_in_space(REvent *ev, int type, void *user, void *data) {
RSpaces *sp = (RSpaces *)user;
RFlag *f = container_of (sp, RFlag, spaces);
RSpaceEvent *spe = (RSpaceEvent *)data;
r_flag_foreach_space (f, spe->data.count.space, count_flags, &spe->res);
}
static void unset_flagspace(REvent *ev, int type, void *user, void *data) {
RSpaces *sp = (RSpaces *)user;
RFlag *f = container_of (sp, RFlag, spaces);
const RSpaceEvent *spe = (const RSpaceEvent *)data;
r_flag_foreach_space (f, spe->data.unset.space, unset_flags_space, NULL);
}
static void new_spaces(RFlag *f) {
r_spaces_init (&f->spaces, "fs");
r_event_hook (f->spaces.event, R_SPACE_EVENT_COUNT, count_flags_in_space);
r_event_hook (f->spaces.event, R_SPACE_EVENT_UNSET, unset_flagspace);
}
R_API RFlag *r_flag_new() {
int i;
RFlag *f = R_NEW0 (RFlag);
if (!f) {
return NULL;
@ -209,12 +239,6 @@ R_API RFlag *r_flag_new() {
f->zones = NULL;
#endif
f->tags = sdb_new0 ();
f->space_idx = -1;
f->spacestack = r_list_newf (NULL);
if (!f->spacestack) {
r_flag_free (f);
return NULL;
}
f->ht_name = ht_pp_new (NULL, ht_free_flag, NULL);
f->by_off = r_skiplist_new (flag_skiplist_free, flag_skiplist_cmp);
#if R_FLAG_ZONE_USE_SDB
@ -222,9 +246,7 @@ R_API RFlag *r_flag_new() {
#else
r_list_free (f->zones);
#endif
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
f->spaces[i] = NULL;
}
new_spaces(f);
return f;
}
@ -261,15 +283,10 @@ R_API void r_flag_item_free(RFlagItem *item) {
R_API RFlag *r_flag_free(RFlag *f) {
r_return_val_if_fail (f, NULL);
int i;
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
free (f->spaces[i]);
}
r_skiplist_free (f->by_off);
ht_pp_free (f->ht_name);
sdb_free (f->tags);
r_list_free (f->spacestack);
r_spaces_fini (&f->spaces);
r_num_free (f->num);
free (f);
return NULL;
@ -287,7 +304,7 @@ struct print_flag_t {
bool in_range;
ut64 range_from;
ut64 range_to;
int fs;
RSpace *fs;
bool real;
const char *pfx;
};
@ -317,13 +334,9 @@ static bool print_flag_rad(RFlagItem *flag, void *user) {
if (u->in_range && (flag->offset < u->range_from || flag->offset >= u->range_to)) {
return true;
}
if (u->fs == -1 || flag->space != u->fs) {
if (!u->fs || flag->space != u->fs) {
u->fs = flag->space;
const char *flagspace = r_flag_space_get_i (u->f, u->fs);
if (!flagspace || !*flagspace) {
flagspace = "*";
}
u->f->cb_printf ("fs %s\n", flagspace);
u->f->cb_printf ("fs %s\n", u->fs? u->fs->name: "*");
}
if (flag->alias) {
u->f->cb_printf ("fa %s %s\n", flag->name, flag->alias);
@ -360,7 +373,6 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
bool in_range = false;
ut64 range_from = UT64_MAX;
ut64 range_to = UT64_MAX;
int fs = -1;
if (rad == 'i') {
char *sp, *arg = strdup (pfx + 1);
sp = strchr (arg, ' ');
@ -385,7 +397,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
switch (rad) {
case 'q':
r_flag_foreach_space (f, f->space_idx, print_flag_name, f);
r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_name, f);
break;
case 'j': {
PJ *pj = pj_new ();
@ -398,7 +410,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
.real = false
};
pj_a (pj);
r_flag_foreach_space (f, f->space_idx, print_flag_json, &u);
r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_json, &u);
pj_end (pj);
f->cb_printf ("%s\n", pj_string (pj));
pj_free (pj);
@ -411,10 +423,10 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
.in_range = in_range,
.range_from = range_from,
.range_to = range_to,
.fs = fs,
.fs = NULL,
.pfx = pfx
};
r_flag_foreach_space (f, f->space_idx, print_flag_rad, &u);
r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_rad, &u);
break;
}
default:
@ -427,7 +439,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
.range_to = range_to,
.real = (rad == 'n')
};
r_flag_foreach_space (f, f->space_idx, print_flag_orig_name, &u);
r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_orig_name, &u);
} else {
PJ *pj = pj_new ();
struct print_flag_t u = {
@ -439,7 +451,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
.real = true
};
pj_a (pj);
r_flag_foreach_space (f, f->space_idx, print_flag_json, &u);
r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_json, &u);
pj_end (pj);
f->cb_printf ("%s\n", pj_string (pj));
pj_free (pj);
@ -554,7 +566,7 @@ R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off, bool closest) {
}
if (flags_at->off == off) {
r_list_foreach (flags_at->flags, iter, item) {
if (f->space_idx != -1 && item->space != f->space_idx) {
if (IS_FI_NOTIN_SPACE (f, item)) {
continue;
}
if (nice) {
@ -573,7 +585,7 @@ R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off, bool closest) {
}
while (!nice && flags_at) {
r_list_foreach (flags_at->flags, iter, item) {
if (f->space_strict && IS_FI_NOTIN_SPACE (f, item)) {
if (IS_FI_NOTIN_SPACE (f, item)) {
continue;
}
if (item->offset == off) {
@ -592,17 +604,20 @@ R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off, bool closest) {
return nice? evalFlag (f, nice): NULL;
}
static bool append_to_list(void *user, const void *k, const void *v) {
static bool append_to_list(RFlagItem *fi, void *user) {
RList *ret = (RList *)user;
r_list_append (ret, (RFlagItem *)v);
r_list_append (ret, fi);
return true;
}
R_API RList *r_flag_all_list(RFlag *f) {
R_API RList *r_flag_all_list(RFlag *f, bool by_space) {
RList *ret = r_list_new ();
if (ret) {
ht_pp_foreach (f->ht_name, append_to_list, ret);
if (!ret) {
return NULL;
}
RSpace *cur = by_space? r_flag_space_cur (f): NULL;
r_flag_foreach_space (f, cur, append_to_list, ret);
return ret;
}
@ -676,7 +691,7 @@ R_API RFlagItem *r_flag_set(RFlag *f, const char *name, ut64 off, ut32 size) {
}
}
item->space = f->space_idx;
item->space = r_flag_space_cur (f);
item->size = size;
update_flag_item_offset (f, item, off + f->base, true);
@ -774,11 +789,11 @@ R_API bool r_flag_unset_name(RFlag *f, const char *name) {
/* unset all flag items in the RFlag f */
R_API void r_flag_unset_all(RFlag *f) {
r_return_if_fail (f);
f->space_idx = -1;
ht_pp_free (f->ht_name);
f->ht_name = ht_pp_new (NULL, ht_free_flag, NULL);
r_skiplist_purge (f->by_off);
r_flag_space_unset (f, NULL);
r_spaces_fini (&f->spaces);
new_spaces (f);
}
struct flag_relocate_t {
@ -900,6 +915,6 @@ R_API void r_flag_foreach_glob(RFlag *f, const char *glob, RFlagItemCb cb, void
FOREACH_BODY (!glob || r_str_glob (fi->name, glob));
}
R_API void r_flag_foreach_space(RFlag *f, int space, RFlagItemCb cb, void *user) {
R_API void r_flag_foreach_space(RFlag *f, const RSpace *space, RFlagItemCb cb, void *user) {
FOREACH_BODY (IS_FI_IN_SPACE (fi, space));
}

View File

@ -1,7 +1,6 @@
r_flag_sources = [
'flag.c',
'tags.c',
'spaces.c',
'zones.c'
]

View File

@ -1,252 +0,0 @@
/* radare - LGPL - Copyright 2008-2016 - pancake */
#include <r_flag.h>
#include <r_cons.h>
R_API int r_flag_space_get(RFlag *f, const char *name) {
int i;
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (f->spaces[i] != NULL) {
if (!strcmp (name, f->spaces[i])) {
return i;
}
}
}
return -1;
}
R_API const char *r_flag_space_get_i(RFlag *f, int idx) {
if (idx == -1 || idx >= R_FLAG_SPACES_MAX || !f || !f->spaces[idx] || !*f->spaces[idx]) {
return "";
}
return f->spaces[idx];
}
R_API const char *r_flag_space_cur(RFlag *f) {
r_return_val_if_fail (f, NULL);
return r_flag_space_get_i (f, f->space_idx);
}
R_API bool r_flag_space_push(RFlag *f, const char *name) {
r_return_val_if_fail (f && name, false);
if (f->space_idx != -1 && f->spaces[f->space_idx]) {
r_list_push (f->spacestack, f->spaces[f->space_idx]);
} else {
r_list_push (f->spacestack, "*");
}
r_flag_space_set (f, name);
return true;
}
R_API bool r_flag_space_pop(RFlag *f) {
r_return_val_if_fail (f, false);
char *p = r_list_pop (f->spacestack);
if (p) {
if (*p) {
r_flag_space_set (f, p);
}
return true;
}
return false;
}
R_API bool r_flag_space_set_i(RFlag *f, int idx) {
int i;
r_return_val_if_fail (f, false);
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (f->spaces[i]) {
f->space_idx = idx;
return true;
}
}
return false;
}
R_API int r_flag_space_set(RFlag *f, const char *name) {
int i;
if (!name || !*name || *name == '*') {
f->space_idx = -1;
return f->space_idx;
}
if (f->space_idx != -1) {
if (!strcmp (name, f->spaces[f->space_idx])) {
return f->space_idx;
}
}
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (f->spaces[i] && !strcmp (name, f->spaces[i])) {
f->space_idx = i;
return f->space_idx;
}
}
/* not found */
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (!f->spaces[i]) {
f->spaces[i] = strdup (name);
f->space_idx = i;
break;
}
}
return f->space_idx;
}
static bool unset_space(RFlagItem *fi, void *user) {
fi->space = -1;
return true;
}
R_API int r_flag_space_unset(RFlag *f, const char *fs) {
r_return_val_if_fail (f, false);
int i, count = 0;
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (!f->spaces[i]) {
continue;
}
if (!fs || !strcmp (fs, f->spaces[i])) {
if (f->space_idx == i) {
f->space_idx = -1;
}
R_FREE (f->spaces[i]);
// remove all flags space references
r_flag_foreach_space (f, i, unset_space, NULL);
count++;
}
}
return count;
}
static bool space_count(RFlagItem *fi, void *user) {
int *count = (int *)user;
(*count)++;
return true;
}
static int r_flag_space_count(RFlag *f, int n) {
int count = 0;
if (n != -1) {
r_flag_foreach_space (f, n, space_count, &count);
}
return count;
}
R_API int r_flag_space_list(RFlag *f, int mode) {
r_return_val_if_fail (f, -1);
const char *defspace = NULL;
int count, len, i, j = 0;
bool allSelected = f->space_idx == -1;
if (mode == 'j') {
f->cb_printf ("[");
}
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (!f->spaces[i]) {
continue;
}
count = r_flag_space_count (f, i);
if (mode == 'q') {
f->cb_printf ("%s\n", f->spaces[i]);
} else if (mode == 'j') {
f->cb_printf ("%s{\"name\":\"%s\",\"count\":%d,\"selected\":%s}",
j? ",":"", f->spaces[i], count,
(allSelected || i == f->space_idx)? "true":"false");
} else if (mode=='*') {
f->cb_printf ("fs %s\n", f->spaces[i]);
if (i == f->space_idx) {
defspace = f->spaces[i];
}
} else {
#define INDENT 5
char num0[64], num1[64], spaces[32];
snprintf (num0, sizeof (num0), "%d", i);
snprintf (num1, sizeof (num1), "%d", count);
memset(spaces, ' ', sizeof (spaces));
len = strlen (num0) + strlen (num1);
if (len < INDENT) {
spaces[INDENT-len] = 0;
} else {
spaces[0] = 0;
}
f->cb_printf ("%s%s %s %c %s\n", num0, spaces, num1,
(allSelected || i==f->space_idx)?'*':'.',
f->spaces[i]);
}
j++;
}
if (defspace) {
f->cb_printf ("fs %s # current\n", defspace);
}
if (mode == 'j') {
f->cb_printf ("]\n");
}
return j;
}
R_API bool r_flag_space_rename (RFlag *f, const char *oname, const char *nname) {
int i;
r_return_val_if_fail (f && nname, false);
if (!oname) {
if (f->space_idx == -1) {
return false;
}
oname = f->spaces[f->space_idx];
}
oname = r_str_trim_ro (oname);
nname = r_str_trim_ro (nname);
for (i = 0; i < R_FLAG_SPACES_MAX; i++) {
if (f->spaces[i] && !strcmp (oname, f->spaces[i])) {
free (f->spaces[i]);
f->spaces[i] = strdup (nname);
return true;
}
}
return false;
}
static void print_space_stack(RFlag *f, int ordinal, char *name, bool selected, int mode) {
bool first = ordinal == 0;
switch (mode) {
case 'j':
if (!first) {
f->cb_printf (",");
}
{
char *ename = r_str_escape (name);
f->cb_printf ("{\"ordinal\":%d,\"name\":\"%s\",\"selected\":%s}",
ordinal, ename, selected? "true":"false");
free (ename);
}
break;
case '*':
if (first) {
f->cb_printf ("fs %s\n", name);
} else {
f->cb_printf ("fs+%s\n", name);
}
break;
default:
f->cb_printf ("%-2d %s%s\n", ordinal, name, selected? " (selected)":"");
break;
}
}
R_API int r_flag_space_stack_list(RFlag *f, int mode) {
RListIter *iter;
char *space;
int i = 0;
if (mode == 'j') {
f->cb_printf ("[");
}
r_list_foreach (f->spacestack, iter, space) {
print_space_stack (f, i++, space, false, mode);
}
if (f->space_idx == -1) {
print_space_stack (f, i++, "*", true, mode);
} else {
if (f->spaces[f->space_idx]) {
print_space_stack (f, i++, f->spaces[f->space_idx], true, mode);
}
}
if (mode == 'j') {
f->cb_printf ("]\n");
}
return i;
}

View File

@ -14,7 +14,6 @@ extern "C" {
R_LIB_VERSION_HEADER(r_flag);
#define R_FLAG_NAME_SIZE 512
#define R_FLAG_SPACES_MAX 128
/* zones.c */
@ -42,23 +41,20 @@ typedef struct r_flag_item_t {
char *realname; /* real name, without any escaping */
ut64 offset; /* offset flagged by this item */
ut64 size; /* size of the flag item */
int space; /* flag space this item belongs to */
RSpace *space; /* flag space this item belongs to */
char *color; /* item color */
char *comment; /* item comment */
char *alias; /* used to define a flag based on a math expression (e.g. foo + 3) */
} RFlagItem;
typedef struct r_flag_t {
RSpaces spaces; /* handle flag spaces */
st64 base; /* base address for all flag items */
int space_idx; /* index of the selected space in spaces array */
bool space_strict; /* when true returned flag items must belong to the selected space */
bool realnames;
char *spaces[R_FLAG_SPACES_MAX]; /* array of flag spaces */
Sdb *tags;
RNum *num;
RSkipList *by_off; /* flags sorted by offset, value=RFlagsAtOffset */
HtPP *ht_name; /* hashmap key=item name, value=RList of items */
RList *spacestack;
PrintfCallback cb_printf;
#if R_FLAG_ZONE_USE_SDB
Sdb *zones;
@ -76,7 +72,7 @@ typedef RFlagItem* (*RFlagSet)(RFlag *f, const char *name, ut64 addr, ut32 size)
typedef bool (*RFlagUnset)(RFlag *f, RFlagItem *item);
typedef bool (*RFlagUnsetName)(RFlag *f, const char *name);
typedef bool (*RFlagUnsetOff)(RFlag *f, ut64 addr);
typedef int (*RFlagSetSpace)(RFlag *f, const char *name);
typedef RSpace *(*RFlagSetSpace)(RFlag *f, const char *name);
typedef bool (*RFlagPopSpace)(RFlag *f);
typedef bool (*RFlagPushSpace)(RFlag *f, const char *name);
@ -109,7 +105,7 @@ R_API RFlagItem *r_flag_get(RFlag *f, const char *name);
R_API RFlagItem *r_flag_get_i(RFlag *f, ut64 off);
R_API RFlagItem *r_flag_get_i2(RFlag *f, ut64 off);
R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off, bool closest);
R_API RList *r_flag_all_list(RFlag *f);
R_API RList *r_flag_all_list(RFlag *f, bool by_space);
R_API const RList* /*<RFlagItem*>*/ r_flag_get_list(RFlag *f, ut64 off);
R_API char *r_flag_get_liststr(RFlag *f, ut64 off);
R_API bool r_flag_unset(RFlag *f, RFlagItem *item);
@ -128,25 +124,55 @@ R_API int r_flag_rename(RFlag *f, RFlagItem *item, const char *name);
R_API int r_flag_relocate(RFlag *f, ut64 off, ut64 off_mask, ut64 to);
R_API bool r_flag_move (RFlag *f, ut64 at, ut64 to);
R_API const char *r_flag_color(RFlag *f, RFlagItem *it, const char *color);
R_API int r_flag_count(RFlag *f, const char *glob);
R_API void r_flag_foreach(RFlag *f, RFlagItemCb cb, void *user);
R_API void r_flag_foreach_prefix(RFlag *f, const char *pfx, int pfx_len, RFlagItemCb cb, void *user);
R_API void r_flag_foreach_range(RFlag *f, ut64 from, ut64 to, RFlagItemCb cb, void *user);
R_API void r_flag_foreach_glob(RFlag *f, const char *glob, RFlagItemCb cb, void *user);
R_API void r_flag_foreach_space(RFlag *f, int space, RFlagItemCb cb, void *user);
R_API void r_flag_foreach_space(RFlag *f, const RSpace *space, RFlagItemCb cb, void *user);
/* spaces */
R_API int r_flag_space_get(RFlag *f, const char *name);
R_API const char *r_flag_space_get_i(RFlag *f, int idx);
R_API const char *r_flag_space_cur(RFlag *f);
R_API int r_flag_space_set(RFlag *f, const char *name);
R_API bool r_flag_space_set_i(RFlag *f, int idx);
R_API int r_flag_count(RFlag *f, const char *name);
R_API int r_flag_space_unset(RFlag *f, const char *fs);
R_API int r_flag_space_list(RFlag *f, int mode);
R_API bool r_flag_space_rename(RFlag *f, const char *oname, const char *nname);
R_API bool r_flag_space_pop(RFlag *f);
R_API bool r_flag_space_push(RFlag *f, const char *name);
R_API int r_flag_space_stack_list(RFlag *f, int mode);
static inline RSpace *r_flag_space_get(RFlag *f, const char *name) {
return r_spaces_get (&f->spaces, name);
}
static inline RSpace *r_flag_space_cur(RFlag *f) {
return r_spaces_current (&f->spaces);
}
static inline const char *r_flag_space_cur_name(RFlag *f) {
return r_spaces_current_name (&f->spaces);
}
static inline RSpace *r_flag_space_set(RFlag *f, const char *name) {
return r_spaces_set (&f->spaces, name);
}
static inline bool r_flag_space_unset(RFlag *f, const char *name) {
return r_spaces_unset (&f->spaces, name);
}
static inline bool r_flag_space_rename(RFlag *f, const char *oname, const char *nname) {
return r_spaces_rename (&f->spaces, oname, nname);
}
static inline bool r_flag_space_push(RFlag *f, const char *name) {
return r_spaces_push (&f->spaces, name);
}
static inline bool r_flag_space_pop(RFlag *f) {
return r_spaces_pop (&f->spaces);
}
static inline int r_flag_space_count(RFlag *f, const char *name) {
return r_spaces_count (&f->spaces, name);
}
static inline bool r_flag_space_is_empty(RFlag *f) {
return r_spaces_is_empty (&f->spaces);
}
#define r_flag_space_foreach(f, it, s) r_spaces_foreach (&(f)->spaces, (it), (s))
/* tags */
R_API RList *r_flag_tags_list(RFlag *f);

View File

@ -20,8 +20,8 @@ typedef RList* (*RAnalVarList)(RAnal *anal, RAnalFunction *fcn, int kind);
typedef struct r_parse_t {
void *user;
int flagspace;
int notin_flagspace;
RSpace *flagspace;
RSpace *notin_flagspace;
bool pseudo;
bool relsub; // replace rip relative expressions in instruction
bool tailsub; // replace any immediate relative to current address with .. prefix syntax

View File

@ -73,7 +73,7 @@ R_API RSpace *r_spaces_get(RSpaces *sp, const char *name);
R_API RSpace *r_spaces_add(RSpaces *sp, const char *name);
// Add and select a new RSpace if one does not already exist, otherwise return and select the existing one
R_API RSpace *r_spaces_set(RSpaces *sp, const char *name);
// Remove the RSpace with the given name
// Remove the RSpace with the given name or all of them if name is NULL
R_API bool r_spaces_unset(RSpaces *sp, const char *name);
// Change the name of RSpace with oname to nname
R_API bool r_spaces_rename(RSpaces *sp, const char *oname, const char *nname);
@ -92,6 +92,15 @@ static inline const char *r_spaces_current_name(RSpaces *sp) {
return sp->current? sp->current->name: "*";
}
static inline bool r_spaces_is_empty(RSpaces *sp) {
RBIter it = r_rbtree_first (sp->spaces);
return it.len == 0;
}
typedef RBIter RSpaceIter;
#define r_spaces_foreach(sp, it, s) \
r_rbtree_foreach ((sp)->spaces, (it), (s), RSpace, rb)
#ifdef __cplusplus
}
#endif

View File

@ -23,8 +23,8 @@ R_API RParse *r_parse_new() {
return NULL;
}
p->parsers->free = NULL; // memleak
p->notin_flagspace = -1;
p->flagspace = -1;
p->notin_flagspace = NULL;
p->flagspace = NULL;
p->pseudo = false;
p->relsub = false;
p->tailsub = false;
@ -275,11 +275,11 @@ static int filter(RParse *p, ut64 addr, RFlag *f, char *data, char *str, int len
}
}
if (isvalidflag (flag)) {
if (p->notin_flagspace != -1) {
if (p->notin_flagspace) {
if (p->flagspace == flag->space) {
continue;
}
} else if (p->flagspace != -1 && (p->flagspace != flag->space)) {
} else if (p->flagspace && (p->flagspace != flag->space)) {
ptr = ptr2;
continue;
}
@ -588,10 +588,6 @@ R_API void r_parse_set_user_ptr(RParse *p, void *user) {
p->user = user;
}
R_API void r_parse_set_flagspace(RParse *p, int fs) {
p->flagspace = fs;
}
/* TODO: DEPRECATE */
R_API int r_parse_list(RParse *p) {
RListIter *iter;

View File

@ -69,6 +69,9 @@ static int name_space_cmp(const void *incoming, const RBNode *rb) {
}
R_API RSpace *r_spaces_get(RSpaces *sp, const char *name) {
if (!name) {
return NULL;
}
RBNode *n = r_rbtree_find (sp->spaces, (void *)name, name_space_cmp);
return n? container_of (n, RSpace, rb): NULL;
}
@ -110,7 +113,7 @@ R_API RSpace *r_spaces_set(RSpaces *sp, const char *name) {
return sp->current;
}
R_API bool r_spaces_unset(RSpaces *sp, const char *name) {
static bool spaces_unset_single(RSpaces *sp, const char *name) {
RSpace *space = r_spaces_get (sp, name);
if (!space) {
return false;
@ -121,6 +124,32 @@ R_API bool r_spaces_unset(RSpaces *sp, const char *name) {
return r_rbtree_delete (&sp->spaces, (void *)name, name_space_cmp, space_node_free);
}
R_API bool r_spaces_unset(RSpaces *sp, const char *name) {
if (name) {
return spaces_unset_single (sp, name);
}
RList *names = r_list_newf ((RListFree)free);
if (!names) {
return false;
}
RBIter it;
RSpace *s;
r_spaces_foreach (sp, it, s) {
r_list_append (names, strdup (s->name));
}
RListIter *lit;
const char *n;
bool res = false;
r_list_foreach (names, lit, n) {
res |= spaces_unset_single (sp, n);
}
r_list_free (names);
return res;
}
R_API int r_spaces_count(RSpaces *sp, const char *name) {
RSpace *s = r_spaces_get (sp, name);
if (!s) {