diff --git a/libr/core/anal.c b/libr/core/anal.c index 73f592b5f0..82c9ba6e34 100644 --- a/libr/core/anal.c +++ b/libr/core/anal.c @@ -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, ""); } diff --git a/libr/core/bin.c b/libr/core/bin.c index baecabe750..d4df485b37 100644 --- a/libr/core/bin.c +++ b/libr/core/bin.c @@ -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 { diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index 72b8d4e4a1..57b586285e 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -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; } diff --git a/libr/core/cmd_flag.c b/libr/core/cmd_flag.c index 5ff09ecf92..62fd583ea5 100644 --- a/libr/core/cmd_flag.c +++ b/libr/core/cmd_flag.c @@ -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++; diff --git a/libr/core/visual.c b/libr/core/visual.c index 82ffda3b40..10a9710c07 100644 --- a/libr/core/visual.c +++ b/libr/core/visual.c @@ -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, diff --git a/libr/core/vmenus.c b/libr/core/vmenus.c index c306bc2fad..48a5907886 100644 --- a/libr/core/vmenus.c +++ b/libr/core/vmenus.c @@ -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); diff --git a/libr/flags/flags.c b/libr/flags/flags.c index 10e7513447..392f14a38c 100644 --- a/libr/flags/flags.c +++ b/libr/flags/flags.c @@ -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 = ⁢ 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; diff --git a/libr/include/r_flags.h b/libr/include/r_flags.h index 8b41eae843..df819ff830 100644 --- a/libr/include/r_flags.h +++ b/libr/include/r_flags.h @@ -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* /**/ 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);