// afvn local_48 counter R_API int r_anal_var_rename (RAnal *a, ut64 var_addr, int scope, char kind, const char *old_name, const char *new_name) { char key[128]; char *stored_name; int delta; if (!r_anal_var_check_name (new_name)) return 0; if (scope>0) { // local SETKEY ("var.0x%"PFMT64x".%c.%d.%s", var_addr, kind, scope, old_name); delta = sdb_num_get (DB, key, 0); if (!delta) return 0; sdb_unset (DB, key, 0); SETKEY ("var.0x%"PFMT64x".%c.%d.%s", var_addr, kind, scope, new_name); sdb_num_set (DB, key, delta, 0); SETKEY ("var.0x%"PFMT64x".%c.%d.%d", var_addr, kind, scope, delta); sdb_array_set (DB, key, R_ANAL_VAR_SDB_NAME, new_name, 0); } else { // global SETKEY ("var.0x%"PFMT64x, var_addr); stored_name = sdb_array_get (DB, key, R_ANAL_VAR_SDB_NAME, 0); if (!stored_name) return 0; if (stored_name != old_name) return 0; sdb_unset (DB, key, 0); SETKEY ("var.0x%"PFMT64x, var_addr); sdb_array_set (DB, key, R_ANAL_VAR_SDB_NAME, new_name, 0); } // var.sdb_hash(old_name)=var_addr.scope.delta return 1; }
// avr 1,4 counter @ var_addr R_API int r_anal_var_rename (RAnal *a, ut64 var_addr, int scope, int delta, const char *new_name) { ut32 hash; char key[128], *old_name; if (!r_anal_var_check_name (new_name)) return 0; if (scope>0) { // local SETKEY ("var.0x%"PFMT64x".%d.%d", var_addr, scope, delta); old_name = sdb_array_get (DB, key, R_ANAL_VAR_SDB_NAME, 0); if (!old_name) return 0; SETKEY ("var.%s.%d", old_name, scope); sdb_unset (DB, key, 0); free (old_name); SETKEY ("var.%s.%d", new_name, scope); sdb_num_set (DB, key, var_addr, 0); SETKEY ("var.0x%x.%d.%d", hash, scope, delta); sdb_array_set (DB, key, R_ANAL_VAR_SDB_NAME, new_name, 0); } else { // global SETKEY ("var.0x%"PFMT64x, var_addr); old_name = sdb_array_get (DB, key, R_ANAL_VAR_SDB_NAME, 0); if (!old_name) return 0; SETKEY ("var.%s", old_name); sdb_unset (DB, key, 0); free (old_name); SETKEY ("var.%s.%d", new_name, scope); sdb_num_set (DB, key, var_addr, 0); SETKEY ("var.0x%x.%d.%d", hash, scope, delta); sdb_array_set (DB, key, R_ANAL_VAR_SDB_NAME, new_name, 0); } // var.sdb_hash(old_name)=var_addr.scope.delta return 1; }
SDB_API bool sdb_array_append(Sdb *s, const char *key, const char *val, ut32 cas) { #if SLOW return sdb_array_set (s, key, -1, val, cas); #else int str_len = 0; ut32 kas = cas; const char *str = sdb_const_get_len (s, key, &str_len, &kas); if (!val || (cas && cas != kas)) { return false; } cas = kas; if (str && *str && str_len > 0) { int val_len = strlen (val); char *newval = malloc (str_len + val_len + 2); if (!newval) { return false; } memcpy (newval, str, str_len); newval[str_len] = SDB_RS; memcpy (newval+str_len+1, val, val_len); newval[str_len+val_len+1] = 0; sdb_set_owned (s, key, newval, cas); } else { sdb_set (s, key, val, cas); } return true; #endif }
R_API bool r_anal_xrefs_init(RAnal *anal) { sdb_reset (DB); if (DB) { sdb_array_set (DB, "types", -1, "code.jmp,code.call,data.mem,data.string", 0); return true; } return false; }
R_API void r_anal_xrefs_init (RAnal *anal) { DB = NULL; DB = sdb_new (NULL, "xrefs", 0); // TODO sdb_array_set (DB, "types", -1, "code,data", 0); #if 0 //... r_anal_xrefs_get (anal, "code", 0); #endif }
R_API void r_anal_xrefs_load(RAnal *anal, const char *prjfile) { char *path, *db = r_str_newf (R2_HOMEDIR"/projects/%s.d/xrefs", prjfile); path = r_str_home (db); //eprintf ("Open (%s)\n", path); sdb_free (DB); DB = sdb_new (path, "xrefs", 0); sdb_array_set (DB, "types", -1, "code,data", 0); free (db); }
// TODO: done, but there's room for improvement SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val, ut32 cas) { int lnstr, lstr, lval; char *x, *ptr; const char *str = sdb_const_get_len (s, key, &lstr, 0); if (!str || !*str) { return sdb_set (s, key, val, cas); } lval = strlen (val); lstr--; //lstr = strlen (str); // we can optimize this by caching value len in memory . add sdb_const_get_size() x = malloc (lval + lstr + 2); if (idx == -1) { memcpy (x, str, lstr); x[lstr] = SDB_RS; memcpy (x+lstr+1, val, lval + 1); } else if (idx == 0) { memcpy (x, val, lval); x[lval] = SDB_RS; memcpy (x + lval + 1, str, lstr + 1); } else { char *nstr = malloc (lstr + 1); if (!nstr) { free (x); return false; } memcpy (nstr, str, lstr + 1); ptr = (char *)Aindexof (nstr, idx); if (ptr) { int lptr = (nstr+lstr+1)-ptr; *(ptr-1) = 0; lnstr = ptr-nstr-1; memcpy (x, nstr, lnstr); x[lnstr] = SDB_RS; memcpy (x + lnstr + 1, val, lval); x[lnstr + lval + 1] = SDB_RS; // TODO: this strlen hurts performance memcpy (x + lval + 2 + lnstr, ptr, lptr); //strlen (ptr)+1); free (nstr); } else { // this is not efficient free (nstr); free (x); // fallback for empty buckets return sdb_array_set (s, key, idx, val, cas); } } return sdb_set_owned (s, key, x, cas); }
static void setHint (RAnal *a, const char *type, ut64 addr, const char *s, ut64 ptr) { int idx; char key[128], val[128], *nval = NULL; setf (key, "hint.0x%"PFMT64x, addr); idx = sdb_array_indexof (DB, key, type, 0); if (s) nval = sdb_encode ((const ut8*)s, -1); else nval = sdb_itoa (ptr, val, 16); if (idx != -1) { if (!s) nval = sdb_itoa (ptr, val, 16); sdb_array_set (DB, key, idx+1, nval, 0); } else { sdb_array_push (DB, key, nval, 0); sdb_array_push (DB, key, type, 0); } if (s) free (nval); }
SDB_API int sdb_array_unset(Sdb *s, const char *key, int idx, ut32 cas) { return sdb_array_set (s, key, idx, "", cas); }
// XXX: index should be supressed here? if its a set we shouldnt change the index SDB_API int sdb_array_add(Sdb *s, const char *key, const char *val, ut32 cas) { if (sdb_array_contains (s, key, val, NULL)) { return 0; } return sdb_array_set (s, key, -1, val, cas); }
SDB_API int sdb_array_set_num(Sdb *s, const char *key, int idx, ut64 val, ut32 cas) { char valstr[SDB_NUM_BUFSZ]; return sdb_array_set (s, key, idx, sdb_itoa (val, valstr, SDB_NUM_BASE), cas); }
// TODO: done, but there's room for improvement SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val, ut32 cas) { int lnstr, lstr; size_t lval; char *x, *ptr; const char *str = sdb_const_get_len (s, key, &lstr, 0); if (!str || !*str) { return sdb_set (s, key, val, cas); } lval = strlen (val); lstr--; // XXX: lstr is wrongly computed in sdb_const_get_with an off-by-one // we can optimize this by caching value len in memory . add // sdb_const_get_size() lstr = strlen (str); // When removing strlen this conversion should be checked size_t lstr_tmp = lstr; if (SZT_ADD_OVFCHK (lval, lstr_tmp) || SZT_ADD_OVFCHK (lval + lstr_tmp, 2)) { return false; } x = malloc (lval + lstr_tmp + 2); if (!x) { return false; } if (idx == -1) { memcpy (x, str, lstr); x[lstr] = SDB_RS; memcpy (x + lstr + 1, val, lval + 1); } else if (!idx) { memcpy (x, val, lval); x[lval] = SDB_RS; memcpy (x + lval + 1, str, lstr + 1); } else { char *nstr = malloc (lstr + 1); if (!nstr) { free (x); return false; } memcpy (nstr, str, lstr + 1); ptr = (char *)Aindexof (nstr, idx); if (ptr) { int lptr = (nstr + lstr + 1) - ptr; char *p_1 = ptr > nstr? ptr - 1: ptr; *p_1 = 0; lnstr = ptr - nstr - 1; memcpy (x, nstr, lnstr); x[lnstr] = SDB_RS; memcpy (x + lnstr + 1, val, lval); x[lnstr + lval + 1] = SDB_RS; // TODO: this strlen hurts performance memcpy (x + lval + 2 + lnstr, ptr, lptr); //strlen (ptr)+1); free (nstr); } else { // this is not efficient free (nstr); free (x); // fallback for empty buckets return sdb_array_set (s, key, idx, val, cas); } } return sdb_set_owned (s, key, x, cas); }