// - name should be allocated on the heap R_API char *r_bin_filter_name(RBinFile *bf, Sdb *db, ut64 vaddr, char *name) { r_return_val_if_fail (db && name, NULL); char *resname = name; const char *uname = sdb_fmt ("%" PFMT64x ".%s", vaddr, resname); ut32 vhash = sdb_hash (uname); // vaddr hash - unique ut32 hash = sdb_hash (resname); // name hash - if dupped and not in unique hash must insert int count = sdb_num_inc (db, sdb_fmt ("%x", hash), 1, 0); if (sdb_exists (db, sdb_fmt ("%x", vhash))) { // TODO: symbol is dupped, so symbol can be removed! return resname; } sdb_num_set (db, sdb_fmt ("%x", vhash), 1, 0); if (vaddr) { char *p = hashify (resname, vaddr); if (p) { resname = p; } } if (count > 1) { char *p = r_str_appendf (resname, "_%d", count - 1); if (p) { resname = p; } // two symbols at different addresses and same name wtf // eprintf ("Symbol '%s' dupped!\n", sym->name); } return resname; }
static void cmdhash(const char *s) { unsigned int i; char su[100]; for (i=0; s[i]; i++) su[i] = toupper ((unsigned char)s[i]); su[i] = 0; printf ("#define MCSDB_CMD_%s 0x%x\n", su, sdb_hash (s)); }
R_API void r_bin_filter_sym(RBinFile *bf, Sdb *db, ut64 vaddr, RBinSymbol *sym) { if (!db || !sym || !sym->name) { return; } char *name = sym->name; // if (!strncmp (sym->name, "imp.", 4)) { // demangle symbol name depending on the language specs if any if (bf && bf->o && bf->o->lang) { const char *lang = r_bin_lang_tostring (bf->o->lang); char *dn = r_bin_demangle (bf, lang, sym->name, sym->vaddr); if (dn && *dn) { sym->dname = dn; // XXX this is wrong but is required for this test to pass // pmb:new pancake$ bin/r2r.js db/formats/mangling/swift sym->name = dn; // extract class information from demangled symbol name char *p = strchr (dn, '.'); if (p) { if (IS_UPPER (*dn)) { sym->classname = strdup (dn); sym->classname[p - dn] = 0; } else if (IS_UPPER (p[1])) { sym->classname = strdup (p + 1); p = strchr (sym->classname, '.'); if (p) { *p = 0; } } } } } // XXX this is very slow, must be optimized const char *uname = sdb_fmt ("%" PFMT64x ".%s", vaddr, name); ut32 vhash = sdb_hash (uname); // vaddr hash - unique ut32 hash = sdb_hash (name); // name hash - if dupped and not in unique hash must insert int count = sdb_num_inc (db, sdb_fmt ("%x", hash), 1, 0); if (sdb_exists (db, sdb_fmt ("%x", vhash))) { // TODO: symbol is dupped, so symbol can be removed! return; } sdb_num_set (db, sdb_fmt ("%x", vhash), 1, 0); sym->dup_count = count - 1; }
SDB_VISIBLE int sdb_exists (Sdb* s, const char *key) { char ch; SdbKv *kv; int klen = strlen (key); ut32 pos, hash = sdb_hash (key, klen); kv = (SdbKv*)ht_lookup (s->ht, hash); if (kv) return (*kv->value)? 1: 0; if (s->fd == -1) return 0; cdb_findstart (&s->db); if (cdb_findnext (&s->db, hash, key, klen)) { pos = cdb_datapos (&s->db); cdb_read (&s->db, &ch, 1, pos); return ch != 0; } return 0; }
SDB_VISIBLE char *sdb_get (Sdb* s, const char *key, ut32 *cas) { char *buf; ut32 hash, pos, len, keylen; SdbKv *kv; ut64 now = 0LL; if (cas) *cas = 0; if (!s || !key) return NULL; keylen = strlen (key)+1; hash = sdb_hash (key, keylen); /* search in memory */ kv = (SdbKv*)ht_lookup (s->ht, hash); if (kv) { if (*kv->value) { if (kv->expire) { if (!now) now = sdb_now (); if (now > kv->expire) { sdb_remove (s, key, 0); return NULL; } } if (cas) *cas = kv->cas; return strdup (kv->value); // XXX too many mallocs } return NULL; } /* search in disk */ if (s->fd == -1) return NULL; cdb_findstart (&s->db); if (!cdb_findnext (&s->db, hash, key, keylen)) return NULL; len = cdb_datalen (&s->db); if (len == 0) return NULL; pos = cdb_datapos (&s->db); if (!(buf = malloc (len+1))) // XXX too many mallocs return NULL; cdb_read (&s->db, buf, len, pos); buf[len] = 0; return buf; }
static char *hashify(char *s, ut64 vaddr) { r_return_val_if_fail (s, NULL); char *os = s; while (*s) { if (!IS_PRINTABLE (*s)) { if (vaddr && vaddr != UT64_MAX) { free (os); return r_str_newf ("_%" PFMT64d, vaddr); } ut32 hash = sdb_hash (s); free (os); return r_str_newf ("%x", hash); } s++; } return os; }
SDB_VISIBLE const char *sdb_getc (Sdb* s, const char *key, ut32 *cas) { ut32 hash, pos, len, keylen; SdbKv *kv; ut64 now = 0LL; if (cas) *cas = 0; if (!s||!key) return NULL; keylen = strlen (key)+1; hash = sdb_hash (key, keylen); /* search in memory */ kv = (SdbKv*)ht_lookup (s->ht, hash); if (kv) { if (*kv->value) { if (kv->expire) { if (!now) now = sdb_now (); if (now > kv->expire) { sdb_remove (s, key, 0); return NULL; } } if (cas) *cas = kv->cas; return kv->value; } return NULL; } /* search in disk */ if (s->fd == -1) return NULL; cdb_findstart (&s->db); if (!cdb_findnext (&s->db, hash, key, keylen)) return NULL; len = cdb_datalen (&s->db); if (len == 0) return NULL; pos = cdb_datapos (&s->db); return s->db.map+pos; }