radare2/libr/anal/labels.c
2017-04-18 14:03:42 +02:00

100 lines
2.5 KiB
C

/* radare - LGPL - Copyright 2014 - pancake */
#include <r_anal.h>
#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;
}