/* radare - LGPL - Copyright 2011 -- pancake */ /* this file contains a test implementation of the ~O(1) function search */ // TODO: REFACTOR: This must be a generic data structure named RListRange // TODO: We need a standard struct named Surface1D {.addr, .size}, so we can // simplify all this by just passing the offset of the field of the given ptr // TODO: RListComparator does not supports *user #define RANGEBITS 10 // 1024 #define RANGE (1< static int cmpfun(void *a, void *b) { RAnalFcn *fa = (RAnalFcn*)a; RAnalFcn *fb = (RAnalFcn*)b; // TODO: swap sort order here or wtf? return (fb->addr - fa->addr); } R_API RListRange* r_listrange_new () { RListRange *s = R_NEW (RListRange); s->h = r_hashtable64_new (); s->l = r_list_new (); return s; } static inline ut64 r_listrange_key(ut64 addr) { const ut64 KXOR = 0x18abc3e127d549ac; // XXX wrong for mingw32 ut64 key = addr & 0xfffffffffffff400; key ^= KXOR; //eprintf ("%llx = %llx\n", addr, key); return key; //return (addr >> RANGEBITS); } static inline ut64 r_listrange_next(ut64 addr) { return (addr + RANGE); } R_API void r_listrange_free(RListRange *s) { r_hashtable64_free (s->h); r_list_destroy (s->l); free (s); } R_API void r_listrange_add(RListRange *s, RAnalFcn *f) { ut64 addr; RList *list; ut64 from = f->addr; ut64 to = f->addr + f->size; for (addr = from; addrh, key); if (list) { if (!r_list_contains (list, f)) //r_list_add_sorted (list, f, cmpfun); r_list_append (list, f); } else { list = r_list_new (); //r_list_add_sorted (list, f, cmpfun); r_list_append (list, f); r_hashtable64_insert (s->h, key, list); } } r_list_add_sorted (s->l, f, cmpfun); } R_API void r_listrange_del(RListRange *s, RAnalFcn *f) { RList *list; ut64 addr, from, to; if (!f) return; from = f->addr; to = f->addr + f->size; for (addr = from; addrh, r_listrange_key (addr)); if (list) r_list_delete_data (list, f); } r_list_delete_data (s->l, f); } R_API void r_listrange_resize(RListRange *s, RAnalFcn *f, int newsize) { r_listrange_del (s, f); f->size = newsize; r_listrange_add (s, f); } R_API RAnalFcn *r_listrange_find_in_range(RListRange* s, ut64 addr) { RAnalFcn *f; RListIter *iter; RList *list = r_hashtable64_lookup (s->h, r_listrange_key (addr)); if (list) r_list_foreach (list, iter, f) { if (R_BETWEEN (f->addr, addr, f->addr+f->size)) return f; } return NULL; } R_API RAnalFcn *r_listrange_find_root(RListRange* s, ut64 addr) { RAnalFcn *f; RListIter *iter; RList *list = r_hashtable64_lookup (s->h, r_listrange_key (addr)); if (list) r_list_foreach (list, iter, f) { if (addr == f->addr) return f; } return NULL; } #if 0 main() { RHashTable64 *h = r_listrange_new(); r_listrange_add (h, f1); } #endif