flags: refactoring of the APIs to unset a flag item

flags: free items when using unset_name, unset_off or unset_glob
This commit is contained in:
Riccardo Schirone 2016-02-20 15:25:27 +01:00 committed by pancake
parent 33afcbdb2f
commit b80c635aba
8 changed files with 83 additions and 100 deletions

View File

@ -2146,7 +2146,7 @@ R_API void r_core_anal_undefine (RCore *core, ut64 off) {
f = r_anal_get_fcn_in (core->anal, off, 0);
if (f) {
if (!strncmp (f->name, "fcn.", 4)) {
r_flag_unset (core->flags, f->name, NULL);
r_flag_unset_name (core->flags, f->name);
}
r_meta_del (core->anal, R_META_TYPE_ANY, off, f->size, "");
}

View File

@ -1198,7 +1198,7 @@ static int bin_symbols_internal(RCore *r, int mode, ut64 laddr, int va, ut64 at,
r_flag_item_set_name (fi, sn.methflag, sn.methname);
if ((fi->offset - r->flags->base) == addr) {
comment = fi->comment ? strdup (fi->comment) : NULL;
r_flag_unset (r->flags, sn.methflag, fi);
r_flag_unset (r->flags, fi);
fi = NULL;
}
} else {

View File

@ -1684,7 +1684,7 @@ static void cmd_esil_mem(RCore *core, const char *input) {
if (*input == '-') {
cf = r_core_file_get_by_fd (core, fi->offset);
r_core_file_close (core, cf);
r_flag_unset (core->flags, name, NULL);
r_flag_unset_name (core->flags, name);
eprintf ("Deinitialized %s\n", name);
return;
}

View File

@ -244,9 +244,9 @@ eprintf ("WTF 'f .xxx' adds a variable to the function? ?!!?(%s)\n");
} else {
if (strchr (flagname, '*'))
r_flag_unset_glob (core->flags, flagname);
else r_flag_unset (core->flags, flagname, NULL);
else r_flag_unset_name (core->flags, flagname);
}
} else r_flag_unset_i (core->flags, off, NULL);
} else r_flag_unset_off (core->flags, off);
break;
case '.':
if (input[1]==' ') input++;

View File

@ -1118,7 +1118,7 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
}
range = max-min+1;
if (!strcmp (n, "-")) {
r_flag_unset_i (core->flags, core->offset + core->print->cur, NULL);
r_flag_unset_off (core->flags, core->offset + core->print->cur);
} else if (*n=='.') {
if (n[1]=='-') {
//unset
@ -1127,7 +1127,7 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
r_core_cmdf (core, "f.%s@0x%"PFMT64x, n+1, core->offset+min);
}
} else if (*n=='-') {
if (*n) r_flag_unset (core->flags, n+1, NULL);
if (*n) r_flag_unset_name (core->flags, n+1);
} else {
if (range<1) range = 1;
if (*n) r_flag_set (core->flags, n,

View File

@ -658,7 +658,7 @@ R_API int r_core_visual_trackflags(RCore *core) {
}
break;
case 'd':
r_flag_unset (core->flags, fs2, NULL);
r_flag_unset_name (core->flags, fs2);
break;
case 'e':
/* TODO: prompt for addr, size, name */
@ -1454,7 +1454,7 @@ static void function_rename(RCore *core, ut64 addr, const char *name) {
r_list_foreach (core->anal->fcns, iter, fcn) {
if (fcn->addr == addr) {
r_flag_unset (core->flags, fcn->name, NULL);
r_flag_unset_name (core->flags, fcn->name);
free (fcn->name);
fcn->name = strdup (name);
r_flag_set (core->flags, name, addr, fcn->size, 0);

View File

@ -8,11 +8,12 @@
R_LIB_VERSION(r_flag);
/* aim to fix a bug in hashtable64 , collisions happen */
#define XORKEY 0x12345678
/* offset needs to be xored to avoid some collisions !!! must switch to sdb */
#define XORKEY 0x12345678
#define XOROFF(x) (x^XORKEY)
#define ISNULLSTR(x) (!x||!*x)
#define ISNULLSTR(x) (!(x) || !*(x))
#define IS_IN_SPACE(f, i) ((f)->space_idx != -1 && (i)->space != (f)->space_idx)
static ut64 num_callback(RNum *user, const char *name, int *ok) {
RFlag *f = (RFlag*)user;
@ -88,8 +89,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
int first = 1;
r_cons_printf ("[");
r_list_foreach (f->flags, iter, flag) {
if ((f->space_idx != -1) && (flag->space != f->space_idx))
continue;
if (IS_IN_SPACE (f, flag)) continue;
r_cons_printf ("%s{\"name\":\"%s\",\"size\":\"%"PFMT64d"\",",
first?"":",", flag->name, flag->size);
if (flag->alias) {
@ -108,8 +108,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
case 1:
case '*':
r_list_foreach (f->flags, iter, flag) {
if ((f->space_idx != -1) && (flag->space != f->space_idx))
continue;
if (IS_IN_SPACE (f, flag)) continue;
if (fs == -1 || flag->space != fs) {
const char *flagspace;
fs = flag->space;
@ -133,8 +132,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
break;
case 'n': // show original name
r_list_foreach (f->flags, iter, flag) {
if ((f->space_idx != -1) && (flag->space != f->space_idx))
continue;
if (IS_IN_SPACE (f, flag)) continue;
if (flag->alias) {
r_cons_printf ("%s %"PFMT64d" %s\n",
flag->alias, flag->size, flag->realname);
@ -146,8 +144,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) {
break;
default:
r_list_foreach (f->flags, iter, flag) {
if ((f->space_idx != -1) && (flag->space != f->space_idx))
continue;
if (IS_IN_SPACE (f, flag)) continue;
if (flag->alias) {
r_cons_printf ("%s %"PFMT64d" %s\n",
flag->alias, flag->size, flag->name);
@ -170,7 +167,9 @@ static RFlagItem *evalFlag(RFlag *f, RFlagItem *item) {
/* return the flag item with name "name" in the RFlag "f", if it exists.
* Otherwise, NULL is returned. */
R_API RFlagItem *r_flag_get(RFlag *f, const char *name) {
RFlagItem *r = r_hashtable64_lookup (f->ht_name, r_str_hash64 (name));
RFlagItem *r;
if (!f) return NULL;
r = r_hashtable64_lookup (f->ht_name, r_str_hash64 (name));
return evalFlag (f, r);
}
@ -179,13 +178,7 @@ R_API RFlagItem *r_flag_get_i(RFlag *f, ut64 off) {
RList *list;
if (!f) return NULL;
list = r_hashtable64_lookup (f->ht_off, XOROFF(off));
if (list) {
RFlagItem *item = r_list_get_top (list);
// XXX: hack, because some times the hashtable is poluted by ghost values
if (item && item->offset == off)
return item;
}
return NULL;
return list ? evalFlag (f, r_list_get_top (list)) : NULL;
}
/* return the first flag item at offset "off" that doesn't start with "loc.",
@ -201,39 +194,36 @@ R_API RFlagItem *r_flag_get_i2(RFlag *f, ut64 off) {
r_list_foreach (list, iter, item) {
// XXX: hack, because some times the hashtable is poluted by ghost values
if (item->offset != off)
continue;
if (!item->name)
continue;
if (item->offset != off) continue;
if (!item->name) continue;
/* catch sym. first */
if (!strncmp (item->name, "loc.", 4))
continue;
if (!strncmp (item->name, "fcn.", 4))
continue;
if (!strncmp (item->name, "section.", 4))
continue;
if (!strncmp (item->name, "loc.", 4)) continue;
if (!strncmp (item->name, "fcn.", 4)) continue;
if (!strncmp (item->name, "section.", 4)) continue;
if (r_str_nlen(item->name, 5) > 4 &&
item->name[3] == '.') {
oitem = item;
break;
}
oitem = item;
if (strlen (item->name) < 5 || item->name[3]!='.')
continue;
if (strlen (item->name) < 5 || item->name[3]!='.') continue;
oitem = item;
}
return oitem;
return evalFlag (f, oitem);
}
/* returns the last flag item defined before or at the given offset.
* NULL is returned if such a item is not found. */
R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off) {
RFlagItem *item, *nice = NULL;
RListIter *iter;
r_list_foreach (f->flags, iter, item) {
if (f->space_strict && (f->space_idx != -1) && (item->space != f->space_idx))
if (f->space_strict && IS_IN_SPACE (f, item))
continue;
if (item->offset == off) {
return item;
return evalFlag (f, item);
}
if (off > item->offset) {
if (!nice || nice->offset < item->offset) {
@ -241,7 +231,7 @@ R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off) {
}
}
}
return nice;
return evalFlag (f, nice);
}
/* return the list of flag items that are associated with a given offset */
@ -256,7 +246,7 @@ R_API char *r_flag_get_liststr(RFlag *f, ut64 off) {
char *p = NULL;
r_list_foreach (list, iter, fi) {
p = r_str_concatf (p, "%s%s",
fi->realname, iter->n?",":":");
fi->realname, iter->n ? "," : ":");
}
return p;
}
@ -269,7 +259,7 @@ R_API RFlagItem *r_flag_set(RFlag *f, const char *name, ut64 off, ut32 size, int
RListIter *iter2 = NULL;
RListIter *iter22 = NULL;
RFlagItem *item2 = NULL;
RList *list2, *list;
RList *list2;
/* contract fail */
if (!name || !*name) return NULL;
@ -352,7 +342,7 @@ R_API void r_flag_item_set_alias(RFlagItem *item, const char *alias) {
R_API void r_flag_item_set_comment(RFlagItem *item, const char *comment) {
if (item) {
free (item->comment);
item->comment = ISNULLSTR (comment)? NULL: strdup (comment);
item->comment = ISNULLSTR (comment) ? NULL : strdup (comment);
}
}
@ -389,7 +379,6 @@ R_API int r_flag_item_set_name(RFlagItem *item, const char *name, const char *re
* true is returned if everything works well, false otherwise */
R_API int r_flag_rename(RFlag *f, RFlagItem *item, const char *name) {
ut64 hash;
RList *list;
RFlagItem *p;
if (!f || !item || !name || !*name) return false;
@ -407,12 +396,33 @@ R_API int r_flag_rename(RFlag *f, RFlagItem *item, const char *name) {
return true;
}
/* unset the given flag item.
* returns true if the item is successfully unset, false otherwise.
*
* NOTE: the item is not freed. */
R_API int r_flag_unset(RFlag *f, RFlagItem *item) {
RList *fs_off = r_hashtable64_lookup (f->ht_off, XOROFF (item->offset));
RListFree orig = f->flags->free;
if (fs_off) {
r_list_delete_data (fs_off, item);
if (r_list_empty (fs_off)) {
r_hashtable64_remove (f->ht_off, XOROFF (item->offset));
}
}
r_hashtable64_remove (f->ht_name, item->namehash);
f->flags->free = NULL;
r_list_delete_data (f->flags, item);
f->flags->free = orig;
return true;
}
/* unset the first flag item found at offset off.
* return true if such a flag is found and unset, false otherwise */
R_API int r_flag_unset_i(RFlag *f, ut64 off, RFlagItem *p) {
RFlagItem *flag = r_flag_get_i (f, off);
if (flag) {
r_flag_unset (f, flag->name, NULL);
* return true if such a flag is found and unset, false otherwise. */
R_API int r_flag_unset_off(RFlag *f, ut64 off) {
RFlagItem *item = r_flag_get_i (f, off);
if (item && r_flag_unset (f, item)) {
free (item);
return true;
}
return false;
@ -421,15 +431,16 @@ R_API int r_flag_unset_i(RFlag *f, ut64 off, RFlagItem *p) {
/* unset all the flag items that satisfy the given glob.
* return the number of unset items. */
R_API int r_flag_unset_glob(RFlag *f, const char *glob) {
int n = 0;
RListIter it, *iter;
RFlagItem *flag;
int n = 0;
r_list_foreach (f->flags, iter, flag) {
if ((f->space_idx != -1) && (flag->space != f->space_idx))
continue;
if (IS_IN_SPACE (f, flag)) continue;
if (!glob || r_str_glob (flag->name, glob)) {
it.n = iter->n;
r_flag_unset (f, flag->name, flag);
r_flag_unset (f, flag);
free (flag);
iter = &it;
n++;
}
@ -437,8 +448,20 @@ R_API int r_flag_unset_glob(RFlag *f, const char *glob) {
return n;
}
/* unset the flag item with the given name.
* returns true if the item is found and unset, false otherwise. */
R_API int r_flag_unset_name(RFlag *f, const char *name) {
ut64 hash = r_str_hash64 (name);
RFlagItem *item = r_hashtable64_lookup (f->ht_name, hash);
if (item && r_flag_unset (f, item)) {
free (item);
return true;
}
return false;
}
/* unset all flag items in the RFlag f */
R_API void r_flag_unset_all (RFlag *f) {
R_API void r_flag_unset_all(RFlag *f) {
f->space_idx = -1;
r_list_free (f->flags);
@ -453,47 +476,6 @@ R_API void r_flag_unset_all (RFlag *f) {
r_flag_space_unset (f, NULL);
}
static void unflag(RFlag *f, RFlagItem *me) {
RListFree lf = f->flags->free;
f->flags->free = NULL;
memset (me, 0, sizeof (RFlagItem));
r_list_delete_data (f->flags, me);
f->flags->free = lf;
}
/* unset the given flag item.
* returns true if the item is successfully unset, false otherwise.
*
* NOTE: the item is not freed. */
R_API int r_flag_unset(RFlag *f, const char *name, RFlagItem *p) {
ut64 off;
RFlagItem *item = p;
ut64 hash = r_str_hash64 (name);
RList *list2, *list;
RFlagItem *tmp = r_hashtable64_lookup (f->ht_name, hash);
// list2 = off hash
if (tmp) {
if (!item) item = tmp;
if (!item) return false;
off = item->offset;
list2 = r_hashtable64_lookup (f->ht_off, XOROFF (off));
if (list2) {
/* delete flag by name */
r_list_delete_data (list2, item);
if (list2 && r_list_empty (list2)) {
r_list_free (list2);
r_hashtable64_remove (f->ht_off, XOROFF(off));
}
r_hashtable64_remove (f->ht_name, hash);
}
/* delete from f->flags list */
unflag (f, item);
return true;
}
return false;
}
R_API int r_flag_relocate(RFlag *f, ut64 off, ut64 off_mask, ut64 to) {
ut64 neg_mask = ~(off_mask);
RFlagItem *item;

View File

@ -69,8 +69,9 @@ R_API RFlagItem *r_flag_get_i2(RFlag *f, ut64 off);
R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off);
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 int r_flag_unset(RFlag *f, const char *name, RFlagItem *p);
R_API int r_flag_unset_i(RFlag *f, ut64 addr, RFlagItem *p);
R_API int r_flag_unset(RFlag *f, RFlagItem *item);
R_API int r_flag_unset_name(RFlag *f, const char *name);
R_API int r_flag_unset_off(RFlag *f, ut64 addr);
R_API void r_flag_unset_all (RFlag *f);
R_API RFlagItem *r_flag_set(RFlag *fo, const char *name, ut64 addr, ut32 size, int dup);
R_API int r_flag_sort(RFlag *f, int namesort);