/* radare - LGPL - Copyright 2014 - pancake */ #include #define DB anal->sdb_fcns // list of all the labels for a specific function #define LABELS sdb_fmt (0, "fcn.%"PFMT64x".labels", fcn->addr) // value of each element in the labels list #define ADDRLABEL(x,y) sdb_fmt (1, "0x%"PFMT64x"/%s", x,y) // resolve by name #define LABEL(x) sdb_fmt (2, "fcn.%"PFMT64x".label.%s", fcn->addr, x) // resolve by addr #define ADDR(x) sdb_fmt (3, "fcn.%"PFMT64x".label.0x%"PFMT64x, fcn->addr,x) // SDB looks like fcn.0x80480408.labels=0x8048480/patata,0x0405850/potro R_API ut64 r_anal_fcn_label_get (RAnal *anal, RAnalFunction *fcn, const char *name) { if (!anal || !fcn) return UT64_MAX; return sdb_num_get (DB, LABEL(name), NULL); } R_API const char *r_anal_fcn_label_at (RAnal *anal, RAnalFunction *fcn, ut64 addr) { if (!anal || !fcn) return NULL; return sdb_const_get (DB, ADDR(addr), NULL); } R_API int r_anal_fcn_label_set (RAnal *anal, RAnalFunction *fcn, const char *name, ut64 addr) { if (!anal || !fcn) return false; if (sdb_add (DB, ADDR(addr), name, 0)) { if (sdb_num_add (DB, LABEL(name), addr, 0)) { sdb_array_add (DB, LABELS, ADDRLABEL (addr, name), 0); return true; } else { sdb_unset (DB, ADDR(addr), 0); } } else { eprintf ("Cannot add\n"); } return false; } R_API int r_anal_fcn_label_del (RAnal *anal, RAnalFunction *fcn, const char *name, ut64 addr) { if (!anal || !fcn || !name) return false; sdb_array_remove (DB, LABELS, ADDRLABEL (addr, name), 0); sdb_unset (DB, LABEL(name), 0); sdb_unset (DB, ADDR(addr), 0); return true; } R_API int r_anal_fcn_labels(RAnal *anal, RAnalFunction *fcn, int rad) { if (!anal) return 0; if (fcn) { char *cur, *token; char *str = sdb_get (DB, LABELS, 0); sdb_aforeach (cur, str) { struct { ut64 addr; char *name; } loc; token = strchr (cur, '/'); if (!token) break; *token = ','; sdb_fmt_tobin (cur, "qz", &loc); switch (rad) { case '*': case 1: anal->cb_printf ("f.%s@0x%08"PFMT64x"\n", loc.name, loc.addr); break; case 'j': eprintf ("TODO\n"); break; default: anal->cb_printf ("0x%08"PFMT64x" %s [%s + %"PFMT64d"]\n", loc.addr, loc.name, fcn->name, loc.addr - fcn->addr, loc.addr); } *token = '/'; sdb_fmt_free (&loc, "qz"); sdb_aforeach_next (cur); } free (str); } else { RAnalFunction *f; RListIter *iter; r_list_foreach (anal->fcns, iter, f) { r_anal_fcn_labels (anal, f, rad); } } return true; }