Remove fcn->vars and reindent anal/fcn.c var.c and flirt.c

This commit is contained in:
Álvaro Felipe Melchor 2017-03-09 23:46:02 +01:00 committed by radare
parent 526699a4d3
commit e8f80a165c
5 changed files with 746 additions and 674 deletions

View File

@ -5,7 +5,7 @@
#include <r_list.h> #include <r_list.h>
#define USE_SDB_CACHE 0 #define USE_SDB_CACHE 0
#define SDB_KEY_BB "bb.0x%"PFMT64x".0x%"PFMT64x #define SDB_KEY_BB "bb.0x%"PFMT64x ".0x%"PFMT64x
// XXX must be configurable by the user // XXX must be configurable by the user
#define FCN_DEPTH 512 #define FCN_DEPTH 512
@ -23,16 +23,16 @@
// 64KB max size // 64KB max size
// 256KB max function size // 256KB max function size
#define MAX_FCN_SIZE (1024*256) #define MAX_FCN_SIZE (1024 * 256)
#define MAX_JMPTBL_SIZE 1000 #define MAX_JMPTBL_SIZE 1000
#define MAX_JMPTBL_JMP 10000 #define MAX_JMPTBL_JMP 10000
#define DB a->sdb_fcns #define DB a->sdb_fcns
#define EXISTS(x,y...) snprintf (key, sizeof(key)-1,x,##y),sdb_exists(DB,key) #define EXISTS(x, y ...) snprintf (key, sizeof(key) - 1, x, ## y), sdb_exists (DB, key)
#define SETKEY(x,y...) snprintf (key, sizeof (key)-1, x,##y); #define SETKEY(x, y ...) snprintf (key, sizeof (key) - 1, x, ## y);
#define VERBOSE_DELAY if(0) #define VERBOSE_DELAY if (0)
#if USE_SDB_CACHE #if USE_SDB_CACHE
static Sdb *HB = NULL; static Sdb *HB = NULL;
@ -51,7 +51,7 @@ R_API const char *r_anal_fcn_type_tostring(int type) {
return "unk"; return "unk";
} }
static int cmpaddr (const void *_a, const void *_b) { static int cmpaddr(const void *_a, const void *_b) {
const RAnalBlock *a = _a, *b = _b; const RAnalBlock *a = _a, *b = _b;
return (a->addr > b->addr); return (a->addr > b->addr);
} }
@ -143,10 +143,10 @@ R_API void r_anal_fcn_free(void *_fcn) {
r_list_free (fcn->refs); r_list_free (fcn->refs);
r_list_free (fcn->xrefs); r_list_free (fcn->xrefs);
#endif #endif
//all functions are freed in anal->fcns // all functions are freed in anal->fcns
fcn->fcn_locs = NULL; fcn->fcn_locs = NULL;
if (fcn->bbs) { if (fcn->bbs) {
fcn->bbs->free = (RListFree)r_anal_bb_free; fcn->bbs->free = (RListFree) r_anal_bb_free;
r_list_free (fcn->bbs); r_list_free (fcn->bbs);
fcn->bbs = NULL; fcn->bbs = NULL;
} }
@ -195,10 +195,10 @@ R_API int r_anal_fcn_xref_add(RAnal *a, RAnalFunction *fcn, ut64 at, ut64 addr,
} }
#endif #endif
#if FCN_SDB #if FCN_SDB
sdb_add (DB, sdb_fmt (0, "fcn.0x%08"PFMT64x".name", fcn->addr), fcn->name, 0); sdb_add (DB, sdb_fmt (0, "fcn.0x%08"PFMT64x ".name", fcn->addr), fcn->name, 0);
// encode the name in base64 ? // encode the name in base64 ?
sdb_num_add (DB, sdb_fmt (0, "fcn.name.%s", fcn->name), fcn->addr, 0); sdb_num_add (DB, sdb_fmt (0, "fcn.name.%s", fcn->name), fcn->addr, 0);
sdb_array_add_num (DB, sdb_fmt (0, "fcn.0x%08"PFMT64x".xrefs", fcn->addr), at, 0); sdb_array_add_num (DB, sdb_fmt (0, "fcn.0x%08"PFMT64x ".xrefs", fcn->addr), at, 0);
#endif #endif
return true; return true;
} }
@ -209,17 +209,17 @@ R_API int r_anal_fcn_xref_del(RAnal *a, RAnalFunction *fcn, ut64 at, ut64 addr,
RListIter *iter; RListIter *iter;
/* No need for _safe loop coz we return immediately after the delete. */ /* No need for _safe loop coz we return immediately after the delete. */
r_list_foreach (fcn->xrefs, iter, ref) { r_list_foreach (fcn->xrefs, iter, ref) {
if ((type != -1 || type == ref->type) && if ((type != -1 || type == ref->type) &&
(at == 0LL || at == ref->at) && (at == 0LL || at == ref->at) &&
(addr == 0LL || addr == ref->addr)) { (addr == 0LL || addr == ref->addr)) {
r_list_delete (fcn->xrefs, iter); r_list_delete (fcn->xrefs, iter);
return true; return true;
} }
} }
#endif #endif
#if FCN_SDB #if FCN_SDB
// TODO // TODO
//sdb_array_delete_num (DB, key, at, 0); // sdb_array_delete_num (DB, key, at, 0);
#endif #endif
return false; return false;
} }
@ -239,7 +239,7 @@ static RAnalBlock *bbget(RAnalFunction *fcn, ut64 addr) {
return NULL; return NULL;
} }
static RAnalBlock* appendBasicBlock (RAnal *anal, RAnalFunction *fcn, ut64 addr) { static RAnalBlock *appendBasicBlock(RAnal *anal, RAnalFunction *fcn, ut64 addr) {
RAnalBlock *bb = r_anal_bb_new (); RAnalBlock *bb = r_anal_bb_new ();
if (!bb) { if (!bb) {
return NULL; return NULL;
@ -257,11 +257,11 @@ static RAnalBlock* appendBasicBlock (RAnal *anal, RAnalFunction *fcn, ut64 addr)
} }
#define FITFCNSZ() {\ #define FITFCNSZ() {\
st64 n = bb->addr + bb->size-fcn->addr; \ st64 n = bb->addr + bb->size - fcn->addr;\
if (n >= 0 && r_anal_fcn_size (fcn) <n) {r_anal_fcn_set_size (fcn, n); } } \ if (n >= 0 && r_anal_fcn_size (fcn) < n) { r_anal_fcn_set_size (fcn, n); } }\
if (r_anal_fcn_size (fcn) > MAX_FCN_SIZE) { \ if (r_anal_fcn_size (fcn) > MAX_FCN_SIZE) {\
/* eprintf ("Function too big at 0x%"PFMT64x" + %d\n", bb->addr, fcn->size); */ \ /* eprintf ("Function too big at 0x%"PFMT64x" + %d\n", bb->addr, fcn->size); */\
r_anal_fcn_set_size (fcn, 0); \ r_anal_fcn_set_size (fcn, 0);\
return R_ANAL_RET_ERROR; } return R_ANAL_RET_ERROR; }
#define VARPREFIX "local" #define VARPREFIX "local"
@ -293,12 +293,12 @@ static char *get_varname(RAnal *a, RAnalFunction *fcn, char type, const char *pf
} }
static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64 len, int depth); static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64 len, int depth);
#define recurseAt(x) { \ #define recurseAt(x) {\
ut8 *bbuf = malloc (MAXBBSIZE);\ ut8 *bbuf = malloc (MAXBBSIZE);\
anal->iob.read_at (anal->iob.io, x, bbuf, MAXBBSIZE); \ anal->iob.read_at (anal->iob.io, x, bbuf, MAXBBSIZE);\
ret = fcn_recurse (anal, fcn, x, bbuf, MAXBBSIZE, depth - 1); \ ret = fcn_recurse (anal, fcn, x, bbuf, MAXBBSIZE, depth - 1);\
update_tinyrange_bbs (fcn); \ update_tinyrange_bbs (fcn);\
free (bbuf); \ free (bbuf);\
} }
static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut64 ip, ut64 ptr, int ret0) { static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut64 ip, ut64 ptr, int ret0) {
@ -328,7 +328,7 @@ static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut
break; break;
} }
if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) { if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) {
jmpptr = ptr + (st32)jmpptr; jmpptr = ptr + (st32) jmpptr;
if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) { if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) {
break; break;
} }
@ -347,21 +347,25 @@ static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut
static ut64 search_reg_val(RAnal *anal, ut8 *buf, ut64 len, ut64 addr, char *regsz) { static ut64 search_reg_val(RAnal *anal, ut8 *buf, ut64 len, ut64 addr, char *regsz) {
ut64 offs, oplen; ut64 offs, oplen;
RAnalOp op = {0}; RAnalOp op = {
0
};
ut64 ret = UT64_MAX; ut64 ret = UT64_MAX;
for (offs = 0; offs < len; offs += oplen) { for (offs = 0; offs < len; offs += oplen) {
r_anal_op_fini (&op); r_anal_op_fini (&op);
if ((oplen = r_anal_op (anal, &op, addr + offs, buf + offs, len - offs)) < 1) { if ((oplen = r_anal_op (anal, &op, addr + offs, buf + offs, len - offs)) < 1) {
break; break;
} }
if (op.dst && op.dst->reg && op.dst->reg->name && !strcmp(op.dst->reg->name, regsz)) { if (op.dst && op.dst->reg && op.dst->reg->name && !strcmp (op.dst->reg->name, regsz)) {
if (op.src[0]) ret = op.src[0]->delta; if (op.src[0]) {
ret = op.src[0]->delta;
}
} }
} }
return ret; return ret;
} }
#define gotoBeach(x) ret=x;goto beach; #define gotoBeach(x) ret = x; goto beach;
#define gotoBeachRet() goto beach; #define gotoBeachRet() goto beach;
static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char *reg, const char *sign, char type) { static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char *reg, const char *sign, char type) {
@ -391,7 +395,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
*ptr_end = 0; *ptr_end = 0;
addr = ptr_end; addr = ptr_end;
while ((*addr != '0' || *(addr + 1) != 'x') && while ((*addr != '0' || *(addr + 1) != 'x') &&
addr >= esil_buf + 1 && *addr != ',' ) { addr >= esil_buf + 1 && *addr != ',') {
addr--; addr--;
} }
if (strncmp (addr, "0x", 2)) { if (strncmp (addr, "0x", 2)) {
@ -399,9 +403,9 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
free (esil_buf); free (esil_buf);
return; return;
} }
ptr = (st64)r_num_get (NULL, addr); ptr = (st64) r_num_get (NULL, addr);
if(*sign =='+') { if (*sign == '+') {
if (ptr < fcn->maxstack && type == 's') { if (ptr < fcn->maxstack && type == 's') {
varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr)); varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr));
} else { } else {
varname = get_varname (anal, fcn, type, ARGPREFIX, R_ABS (ptr)); varname = get_varname (anal, fcn, type, ARGPREFIX, R_ABS (ptr));
@ -411,7 +415,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
} else { } else {
varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr)); varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr));
r_anal_var_add (anal, fcn->addr, 1, -ptr, type, NULL, anal->bits / 8, varname); r_anal_var_add (anal, fcn->addr, 1, -ptr, type, NULL, anal->bits / 8, varname);
r_anal_var_access (anal, fcn->addr, type, 1,-ptr, 1, op->addr); r_anal_var_access (anal, fcn->addr, type, 1, -ptr, 1, op->addr);
} }
free (varname); free (varname);
@ -421,9 +425,9 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
R_API void fill_args(RAnal *anal, RAnalFunction *fcn, RAnalOp *op) { R_API void fill_args(RAnal *anal, RAnalFunction *fcn, RAnalOp *op) {
if (anal && anal->reg) { if (anal && anal->reg) {
extract_arg (anal, fcn, op, anal->reg->name [R_REG_NAME_BP], "+", 'b'); extract_arg (anal, fcn, op, anal->reg->name[R_REG_NAME_BP], "+", 'b');
extract_arg (anal, fcn, op, anal->reg->name [R_REG_NAME_BP], "-", 'b'); extract_arg (anal, fcn, op, anal->reg->name[R_REG_NAME_BP], "-", 'b');
extract_arg (anal, fcn, op, anal->reg->name [R_REG_NAME_SP], "+", 's'); extract_arg (anal, fcn, op, anal->reg->name[R_REG_NAME_SP], "+", 's');
} }
extract_arg (anal, fcn, op, "bp", "+", 'b'); extract_arg (anal, fcn, op, "bp", "+", 'b');
extract_arg (anal, fcn, op, "bp", "-", 'b'); extract_arg (anal, fcn, op, "bp", "-", 'b');
@ -439,8 +443,10 @@ static bool isInvalidMemory(const ut8 *buf, int len) {
static bool is_delta_pointer_table(RAnal *anal, ut64 ptr) { static bool is_delta_pointer_table(RAnal *anal, ut64 ptr) {
int i; int i;
ut64 dst; ut64 dst;
st32 jmptbl[32] = {0}; st32 jmptbl[32] = {
anal->iob.read_at (anal->iob.io, ptr, (ut8*)&jmptbl, 32); 0
};
anal->iob.read_at (anal->iob.io, ptr, (ut8 *) &jmptbl, 32);
// XXX this is not endian safe // XXX this is not endian safe
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
dst = ptr + jmptbl[0]; dst = ptr + jmptbl[0];
@ -455,10 +461,10 @@ static bool regs_exist(RAnalValue *src, RAnalValue *dst) {
return src && dst && src->reg && dst->reg && src->reg->name && dst->reg->name; return src && dst && src->reg && dst->reg && src->reg->name && dst->reg->name;
} }
//0 if not skipped; 1 if skipped; 2 if skipped before // 0 if not skipped; 1 if skipped; 2 if skipped before
static int skip_hp(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, RAnalBlock *bb, ut64 addr, static int skip_hp(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, RAnalBlock *bb, ut64 addr,
char *tmp_buf, int oplen, int un_idx, int *idx) { char *tmp_buf, int oplen, int un_idx, int *idx) {
//this step is required in order to prevent infinite recursion in some cases // this step is required in order to prevent infinite recursion in some cases
if ((addr + un_idx - oplen) == fcn->addr) { if ((addr + un_idx - oplen) == fcn->addr) {
if (!anal->flb.exist_at (anal->flb.f, "skip", 4, op->addr)) { if (!anal->flb.exist_at (anal->flb.f, "skip", 4, op->addr)) {
snprintf (tmp_buf + 5, MAX_FLG_NAME_SIZE - 6, "%"PFMT64u, op->addr); snprintf (tmp_buf + 5, MAX_FLG_NAME_SIZE - 6, "%"PFMT64u, op->addr);
@ -475,7 +481,9 @@ static int skip_hp(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, RAnalBlock *bb,
} }
R_API int r_anal_case(RAnal *anal, RAnalFunction *fcn, ut64 addr_bbsw, ut64 addr, ut8 *buf, ut64 len, int reftype) { R_API int r_anal_case(RAnal *anal, RAnalFunction *fcn, ut64 addr_bbsw, ut64 addr, ut8 *buf, ut64 len, int reftype) {
RAnalOp op = {0}; RAnalOp op = {
0
};
int oplen, idx = 0; int oplen, idx = 0;
while (idx < len) { while (idx < len) {
if ((len - idx) < 5) { if ((len - idx) < 5) {
@ -490,10 +498,10 @@ R_API int r_anal_case(RAnal *anal, RAnalFunction *fcn, ut64 addr_bbsw, ut64 addr
case R_ANAL_OP_TYPE_RET: case R_ANAL_OP_TYPE_RET:
case R_ANAL_OP_TYPE_JMP: case R_ANAL_OP_TYPE_JMP:
// eprintf ("CASE AT 0x%llx size %d\n", addr, idx + oplen); // eprintf ("CASE AT 0x%llx size %d\n", addr, idx + oplen);
eprintf ("afb+ 0x%"PFMT64x" 0x%"PFMT64x" %d\n", eprintf ("afb+ 0x%"PFMT64x " 0x%"PFMT64x " %d\n",
fcn->addr, addr, idx + oplen); fcn->addr, addr, idx + oplen);
eprintf ("afbe 0x%"PFMT64x" 0x%"PFMT64x"\n", eprintf ("afbe 0x%"PFMT64x " 0x%"PFMT64x "\n",
addr_bbsw, addr); addr_bbsw, addr);
return idx + oplen; return idx + oplen;
} }
idx += oplen; idx += oplen;
@ -504,7 +512,7 @@ R_API int r_anal_case(RAnal *anal, RAnalFunction *fcn, ut64 addr_bbsw, ut64 addr
static int walk_switch(RAnal *anal, RAnalFunction *fcn, ut64 from, ut64 at) { static int walk_switch(RAnal *anal, RAnalFunction *fcn, ut64 from, ut64 at) {
ut8 buf[1024]; ut8 buf[1024];
int i; int i;
eprintf ("WALK SWITCH TABLE INTO (0x%"PFMT64x") %"PFMT64x"\n", from, at); eprintf ("WALK SWITCH TABLE INTO (0x%"PFMT64x ") %"PFMT64x "\n", from, at);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
anal->iob.read_at (anal->iob.io, at, buf, sizeof (buf)); anal->iob.read_at (anal->iob.io, at, buf, sizeof (buf));
int sz = r_anal_case (anal, fcn, from, at, buf, sizeof (buf), 0); int sz = r_anal_case (anal, fcn, from, at, buf, sizeof (buf), 0);
@ -524,7 +532,9 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
int ret = R_ANAL_RET_END, skip_ret = 0; int ret = R_ANAL_RET_END, skip_ret = 0;
int overlapped = 0; int overlapped = 0;
char *varname; char *varname;
RAnalOp op = {0}; RAnalOp op = {
0
};
int oplen, idx = 0; int oplen, idx = 0;
struct { struct {
int cnt; int cnt;
@ -533,7 +543,9 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
int pending; int pending;
int adjust; int adjust;
int un_idx; // delay.un_idx int un_idx; // delay.un_idx
} delay = {0}; } delay = {
0
};
char tmp_buf[MAX_FLG_NAME_SIZE + 5] = "skip"; char tmp_buf[MAX_FLG_NAME_SIZE + 5] = "skip";
if (anal->sleep) { if (anal->sleep) {
@ -551,7 +563,7 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
// check if address is readable //: // check if address is readable //:
if (!anal->iob.is_valid_offset (anal->iob.io, addr, 0)) { if (!anal->iob.is_valid_offset (anal->iob.io, addr, 0)) {
if (addr != UT64_MAX && !anal->iob.io->va) { if (addr != UT64_MAX && !anal->iob.io->va) {
eprintf ("Invalid address 0x%"PFMT64x". Try with io.va=true\n", addr); eprintf ("Invalid address 0x%"PFMT64x ". Try with io.va=true\n", addr);
} }
return R_ANAL_RET_ERROR; // MUST BE TOO DEEP return R_ANAL_RET_ERROR; // MUST BE TOO DEEP
} }
@ -570,14 +582,14 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
bb = appendBasicBlock (anal, fcn, addr); bb = appendBasicBlock (anal, fcn, addr);
VERBOSE_ANAL eprintf ("Append bb at 0x%08"PFMT64x VERBOSE_ANAL eprintf("Append bb at 0x%08"PFMT64x
" (fcn 0x%08"PFMT64x")\n", addr, fcn->addr); " (fcn 0x%08"PFMT64x ")\n", addr, fcn->addr);
bool last_is_push = false; bool last_is_push = false;
ut64 last_push_addr = UT64_MAX; ut64 last_push_addr = UT64_MAX;
while (idx < len) { while (idx < len) {
if (anal->limit) { if (anal->limit) {
if ((addr + idx) < anal->limit->from || (addr + idx + 1) >anal->limit->to) { if ((addr + idx) < anal->limit->from || (addr + idx + 1) > anal->limit->to) {
break; break;
} }
} }
@ -587,14 +599,14 @@ repeat:
} }
r_anal_op_fini (&op); r_anal_op_fini (&op);
if (isInvalidMemory (buf + idx, len - idx)) { if (isInvalidMemory (buf + idx, len - idx)) {
FITFCNSZ(); FITFCNSZ ();
VERBOSE_ANAL eprintf ("FFFF opcode at 0x%08"PFMT64x"\n", addr+idx); VERBOSE_ANAL eprintf("FFFF opcode at 0x%08"PFMT64x "\n", addr + idx);
return R_ANAL_RET_ERROR; return R_ANAL_RET_ERROR;
} }
// check if opcode is in another basic block // check if opcode is in another basic block
// in that case we break // in that case we break
if ((oplen = r_anal_op (anal, &op, addr + idx, buf + idx, len - idx)) < 1) { if ((oplen = r_anal_op (anal, &op, addr + idx, buf + idx, len - idx)) < 1) {
VERBOSE_ANAL eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr + idx); VERBOSE_ANAL eprintf("Unknown opcode at 0x%08"PFMT64x "\n", addr + idx);
if (!idx) { if (!idx) {
gotoBeach (R_ANAL_RET_END); gotoBeach (R_ANAL_RET_END);
} else { } else {
@ -606,16 +618,16 @@ repeat:
if (bbg && bbg != bb) { if (bbg && bbg != bb) {
bb->jump = addr + idx; bb->jump = addr + idx;
overlapped = 1; overlapped = 1;
VERBOSE_ANAL eprintf ("Overlapped at 0x%08"PFMT64x"\n", addr + idx); VERBOSE_ANAL eprintf("Overlapped at 0x%08"PFMT64x "\n", addr + idx);
//return R_ANAL_RET_END; // return R_ANAL_RET_END;
} }
} }
if (!overlapped) { if (!overlapped) {
r_anal_bb_set_offset (bb, bb->ninstr++, addr + idx - bb->addr); r_anal_bb_set_offset (bb, bb->ninstr++, addr + idx - bb->addr);
bb->size += oplen; bb->size += oplen;
fcn->ninstr++; fcn->ninstr++;
// FITFCNSZ(); // defer this, in case this instruction is a branch delay entry // FITFCNSZ(); // defer this, in case this instruction is a branch delay entry
// fcn->size += oplen; /// XXX. must be the sum of all the bblocks // fcn->size += oplen; /// XXX. must be the sum of all the bblocks
} }
idx += oplen; idx += oplen;
delay.un_idx = idx; delay.un_idx = idx;
@ -625,7 +637,7 @@ repeat:
// Save the location of it in `delay.idx` // Save the location of it in `delay.idx`
// note, we have still increased size of basic block // note, we have still increased size of basic block
// (and function) // (and function)
VERBOSE_DELAY eprintf ("Enter branch delay at 0x%08"PFMT64x ". bb->sz=%d\n", addr+idx-oplen, bb->size); VERBOSE_DELAY eprintf("Enter branch delay at 0x%08"PFMT64x ". bb->sz=%d\n", addr + idx - oplen, bb->size);
delay.idx = idx - oplen; delay.idx = idx - oplen;
delay.cnt = op.delay; delay.cnt = op.delay;
delay.pending = 1; // we need this in case the actual idx is zero... delay.pending = 1; // we need this in case the actual idx is zero...
@ -638,7 +650,7 @@ repeat:
// track of how many still to process. // track of how many still to process.
delay.cnt--; delay.cnt--;
if (!delay.cnt) { if (!delay.cnt) {
VERBOSE_DELAY eprintf ("Last branch delayed opcode at 0x%08"PFMT64x ". bb->sz=%d\n", addr+idx-oplen, bb->size); VERBOSE_DELAY eprintf("Last branch delayed opcode at 0x%08"PFMT64x ". bb->sz=%d\n", addr + idx - oplen, bb->size);
delay.after = idx; delay.after = idx;
idx = delay.idx; idx = delay.idx;
// At this point, we are still looking at the // At this point, we are still looking at the
@ -648,16 +660,16 @@ repeat:
// the branch delay. // the branch delay.
} }
} else if (op.delay > 0 && delay.pending) { } else if (op.delay > 0 && delay.pending) {
VERBOSE_DELAY eprintf ("Revisit branch delay jump at 0x%08"PFMT64x ". bb->sz=%d\n", addr+idx-oplen, bb->size); VERBOSE_DELAY eprintf("Revisit branch delay jump at 0x%08"PFMT64x ". bb->sz=%d\n", addr + idx - oplen, bb->size);
// This is the second pass of the branch delaying opcode // This is the second pass of the branch delaying opcode
// But we also already counted this instruction in the // But we also already counted this instruction in the
// size of the current basic block, so we need to fix that // size of the current basic block, so we need to fix that
if (delay.adjust) { if (delay.adjust) {
bb->size -= oplen; bb->size -= oplen;
fcn->ninstr--; fcn->ninstr--;
VERBOSE_DELAY eprintf ("Correct for branch delay @ %08"PFMT64x " bb.addr=%08"PFMT64x " corrected.bb=%d f.uncorr=%d\n", VERBOSE_DELAY eprintf("Correct for branch delay @ %08"PFMT64x " bb.addr=%08"PFMT64x " corrected.bb=%d f.uncorr=%d\n",
addr + idx - oplen, bb->addr, bb->size, r_anal_fcn_size (fcn)); addr + idx - oplen, bb->addr, bb->size, r_anal_fcn_size (fcn));
FITFCNSZ(); FITFCNSZ ();
} }
// Next time, we go to the opcode after the delay count // Next time, we go to the opcode after the delay count
// Take care not to use this below, use delay.un_idx instead ... // Take care not to use this below, use delay.un_idx instead ...
@ -682,10 +694,10 @@ repeat:
break; break;
// TODO: use fcn->maxstack to know our stackframe // TODO: use fcn->maxstack to know our stackframe
case R_ANAL_STACK_SET: case R_ANAL_STACK_SET:
if ((int)op.ptr > 0) { if ((int) op.ptr > 0) {
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS(op.ptr)); varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS (op.ptr));
} else { } else {
varname = get_varname (anal, fcn, 'b', VARPREFIX, R_ABS(op.ptr)); varname = get_varname (anal, fcn, 'b', VARPREFIX, R_ABS (op.ptr));
} }
r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'b', NULL, anal->bits / 8, varname); r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'b', NULL, anal->bits / 8, varname);
r_anal_var_access (anal, fcn->addr, 'b', 1, op.ptr, 1, op.addr); r_anal_var_access (anal, fcn->addr, 'b', 1, op.ptr, 1, op.addr);
@ -693,12 +705,12 @@ repeat:
break; break;
// TODO: use fcn->maxstack to know our stackframe // TODO: use fcn->maxstack to know our stackframe
case R_ANAL_STACK_GET: case R_ANAL_STACK_GET:
if (((int)op.ptr) > 0) { if (((int) op.ptr) > 0) {
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS(op.ptr)); varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS (op.ptr));
} else { } else {
varname = get_varname (anal, fcn, 'b', VARPREFIX, R_ABS(op.ptr)); varname = get_varname (anal, fcn, 'b', VARPREFIX, R_ABS (op.ptr));
} }
r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'b', NULL, anal->bits/8, varname); r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'b', NULL, anal->bits / 8, varname);
r_anal_var_access (anal, fcn->addr, 'b', 1, op.ptr, 0, op.addr); r_anal_var_access (anal, fcn->addr, 'b', 1, op.ptr, 0, op.addr);
free (varname); free (varname);
break; break;
@ -711,9 +723,9 @@ repeat:
switch (op.type & R_ANAL_OP_TYPE_MASK) { switch (op.type & R_ANAL_OP_TYPE_MASK) {
case R_ANAL_OP_TYPE_MOV: case R_ANAL_OP_TYPE_MOV:
//skip mov reg,reg // skip mov reg,reg
if (anal->opt.hpskip && regs_exist(op.src[0], op.dst) if (anal->opt.hpskip && regs_exist (op.src[0], op.dst)
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) { && !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
skip_ret = skip_hp (anal, fcn, &op, bb, addr, tmp_buf, oplen, delay.un_idx, &idx); skip_ret = skip_hp (anal, fcn, &op, bb, addr, tmp_buf, oplen, delay.un_idx, &idx);
if (skip_ret == 1) { if (skip_ret == 1) {
goto repeat; goto repeat;
@ -724,9 +736,9 @@ repeat:
} }
break; break;
case R_ANAL_OP_TYPE_LEA: case R_ANAL_OP_TYPE_LEA:
//skip lea reg,[reg] // skip lea reg,[reg]
if (anal->opt.hpskip && regs_exist(op.src[0], op.dst) if (anal->opt.hpskip && regs_exist (op.src[0], op.dst)
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) { && !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
skip_ret = skip_hp (anal, fcn, &op, bb, addr, tmp_buf, oplen, delay.un_idx, &idx); skip_ret = skip_hp (anal, fcn, &op, bb, addr, tmp_buf, oplen, delay.un_idx, &idx);
if (skip_ret == 1) { if (skip_ret == 1) {
goto repeat; goto repeat;
@ -737,10 +749,10 @@ repeat:
} }
if (anal->opt.jmptbl) { if (anal->opt.jmptbl) {
if (is_delta_pointer_table (anal, op.ptr)) { if (is_delta_pointer_table (anal, op.ptr)) {
anal->cb_printf ("pxt. 0x%08"PFMT64x" @ 0x%08"PFMT64x"\n", op.addr, op.ptr); anal->cb_printf ("pxt. 0x%08"PFMT64x " @ 0x%08"PFMT64x "\n", op.addr, op.ptr);
//jmptbl_addr = op.ptr; // jmptbl_addr = op.ptr;
//jmptbl_size = -1; // jmptbl_size = -1;
//ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, op.ptr, 4); // ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, op.ptr, 4);
} }
} }
break; break;
@ -778,7 +790,7 @@ repeat:
case R_ANAL_OP_TYPE_NOP: case R_ANAL_OP_TYPE_NOP:
if (anal->opt.nopskip) { if (anal->opt.nopskip) {
if (!strcmp (anal->cur->arch, "mips")) { if (!strcmp (anal->cur->arch, "mips")) {
//Looks like this flags check is useful only for mips // Looks like this flags check is useful only for mips
// do not skip nops if there's a flag at starting address // do not skip nops if there's a flag at starting address
RFlagItem *fi = anal->flb.get_at (anal->flb.f, addr, false); RFlagItem *fi = anal->flb.get_at (anal->flb.f, addr, false);
if (!fi || strncmp (fi->name, "sym.", 4)) { if (!fi || strncmp (fi->name, "sym.", 4)) {
@ -832,7 +844,7 @@ repeat:
must_eob = s != d; must_eob = s != d;
} }
if (must_eob) { if (must_eob) {
FITFCNSZ(); FITFCNSZ ();
op.jump = UT64_MAX; op.jump = UT64_MAX;
recurseAt (op.jump); recurseAt (op.jump);
recurseAt (op.fail); recurseAt (op.fail);
@ -844,7 +856,7 @@ repeat:
#if FIX_JMP_FWD #if FIX_JMP_FWD
bb->jump = op.jump; bb->jump = op.jump;
bb->fail = UT64_MAX; bb->fail = UT64_MAX;
FITFCNSZ(); FITFCNSZ ();
return R_ANAL_RET_END; return R_ANAL_RET_END;
#else #else
if (!overlapped) { if (!overlapped) {
@ -852,7 +864,7 @@ repeat:
bb->fail = UT64_MAX; bb->fail = UT64_MAX;
} }
recurseAt (op.jump); recurseAt (op.jump);
FITFCNSZ(); FITFCNSZ ();
gotoBeachRet (); gotoBeachRet ();
#endif #endif
} else { } else {
@ -867,14 +879,14 @@ repeat:
bb->jump = op.jump; bb->jump = op.jump;
bb->fail = UT64_MAX; bb->fail = UT64_MAX;
} }
FITFCNSZ(); FITFCNSZ ();
return R_ANAL_RET_END; return R_ANAL_RET_END;
#else #else
// hardcoded jmp size // must be checked at the end wtf? // hardcoded jmp size // must be checked at the end wtf?
// always fitfcnsz and retend // always fitfcnsz and retend
if (r_anal_fcn_is_in_offset (fcn, op.jump)) { if (r_anal_fcn_is_in_offset (fcn, op.jump)) {
/* jump inside the same function */ /* jump inside the same function */
FITFCNSZ(); FITFCNSZ ();
return R_ANAL_RET_END; return R_ANAL_RET_END;
#if JMP_IS_EOB_RANGE > 0 #if JMP_IS_EOB_RANGE > 0
} else { } else {
@ -894,7 +906,7 @@ repeat:
bb->jump = op.jump; bb->jump = op.jump;
bb->fail = UT64_MAX; bb->fail = UT64_MAX;
} }
FITFCNSZ(); FITFCNSZ ();
return R_ANAL_RET_END; return R_ANAL_RET_END;
} }
} }
@ -921,7 +933,7 @@ repeat:
bb->jump = op.jump; bb->jump = op.jump;
bb->fail = UT64_MAX; bb->fail = UT64_MAX;
} }
FITFCNSZ(); FITFCNSZ ();
recurseAt (op.jump); recurseAt (op.jump);
recurseAt (op.fail); recurseAt (op.fail);
return R_ANAL_RET_END; return R_ANAL_RET_END;
@ -931,11 +943,11 @@ repeat:
if (op.jump > fcn->addr + JMP_IS_EOB_RANGE) { if (op.jump > fcn->addr + JMP_IS_EOB_RANGE) {
recurseAt (op.fail); recurseAt (op.fail);
/* jump inside the same function */ /* jump inside the same function */
FITFCNSZ(); FITFCNSZ ();
return R_ANAL_RET_END; return R_ANAL_RET_END;
#if JMP_IS_EOB_RANGE > 0 #if JMP_IS_EOB_RANGE > 0
} else { } else {
if (op.jump < addr - JMP_IS_EOB_RANGE && op.jump<addr) { if (op.jump < addr - JMP_IS_EOB_RANGE && op.jump < addr) {
gotoBeach (R_ANAL_RET_END); gotoBeach (R_ANAL_RET_END);
} }
if (op.jump > addr + JMP_IS_EOB_RANGE) { if (op.jump > addr + JMP_IS_EOB_RANGE) {
@ -955,7 +967,7 @@ repeat:
bb->jump = op.jump; bb->jump = op.jump;
bb->fail = UT64_MAX; bb->fail = UT64_MAX;
} }
FITFCNSZ(); FITFCNSZ ();
return R_ANAL_RET_END; return R_ANAL_RET_END;
} }
} }
@ -980,7 +992,7 @@ repeat:
return R_ANAL_RET_END; return R_ANAL_RET_END;
} }
// XXX: this is TYPE_MCALL or indirect-call // XXX: this is TYPE_MCALL or indirect-call
(void)r_anal_fcn_xref_add (anal, fcn, op.addr, op.ptr, R_ANAL_REF_TYPE_CALL); (void) r_anal_fcn_xref_add (anal, fcn, op.addr, op.ptr, R_ANAL_REF_TYPE_CALL);
break; break;
case R_ANAL_OP_TYPE_CCALL: case R_ANAL_OP_TYPE_CCALL:
case R_ANAL_OP_TYPE_CALL: case R_ANAL_OP_TYPE_CALL:
@ -990,7 +1002,7 @@ repeat:
r_anal_op_fini (&op); r_anal_op_fini (&op);
return R_ANAL_RET_END; return R_ANAL_RET_END;
} }
(void)r_anal_fcn_xref_add (anal, fcn, op.addr, op.jump, R_ANAL_REF_TYPE_CALL); (void) r_anal_fcn_xref_add (anal, fcn, op.addr, op.jump, R_ANAL_REF_TYPE_CALL);
#if CALL_IS_EOB #if CALL_IS_EOB
recurseAt (op.jump); recurseAt (op.jump);
recurseAt (op.fail); recurseAt (op.fail);
@ -1008,10 +1020,10 @@ repeat:
RAnalRef *last_ref = fcn->refs->tail->data; RAnalRef *last_ref = fcn->refs->tail->data;
last_ref->type = R_ANAL_REF_TYPE_NULL; last_ref->type = R_ANAL_REF_TYPE_NULL;
} }
if (op.ptr != UT64_MAX) { // direct jump if (op.ptr != UT64_MAX) { // direct jump
ret = try_walkthrough_jmptbl (anal, fcn, depth, addr + idx, op.ptr, ret); ret = try_walkthrough_jmptbl (anal, fcn, depth, addr + idx, op.ptr, ret);
} else { // indirect jump: table pointer is unknown } else { // indirect jump: table pointer is unknown
if (op.src[0] && op.src[0]->reg) { if (op.src[0] && op.src[0]->reg) {
ut64 ptr = search_reg_val (anal, buf, idx, addr, op.src[0]->reg->name); ut64 ptr = search_reg_val (anal, buf, idx, addr, op.src[0]->reg->name);
if (ptr && ptr != UT64_MAX) { if (ptr && ptr != UT64_MAX) {
@ -1032,7 +1044,9 @@ repeat:
} }
if (anal->cur->arch && strstr (anal->cur->arch, "arm")) { if (anal->cur->arch && strstr (anal->cur->arch, "arm")) {
if (anal->bits == 64) { if (anal->bits == 64) {
if (!in_plt) goto river; if (!in_plt) {
goto river;
}
} }
} else { } else {
if (in_plt) { if (in_plt) {
@ -1046,12 +1060,12 @@ repeat:
return R_ANAL_RET_END; return R_ANAL_RET_END;
river: river:
break; break;
/* fallthru */ /* fallthru */
case R_ANAL_OP_TYPE_PUSH: case R_ANAL_OP_TYPE_PUSH:
last_is_push = true; last_is_push = true;
last_push_addr = op.val; last_push_addr = op.val;
if (anal->iob.is_valid_offset (anal->iob.io, op.val, 1)) { if (anal->iob.is_valid_offset (anal->iob.io, op.val, 1)) {
(void)r_anal_fcn_xref_add (anal, fcn, op.addr, op.val, R_ANAL_REF_TYPE_DATA); (void) r_anal_fcn_xref_add (anal, fcn, op.addr, op.val, R_ANAL_REF_TYPE_DATA);
} }
break; break;
case R_ANAL_OP_TYPE_RET: case R_ANAL_OP_TYPE_RET:
@ -1066,9 +1080,9 @@ river:
gotoBeachRet (); gotoBeachRet ();
} else { } else {
if (!op.cond) { if (!op.cond) {
VERBOSE_ANAL eprintf ("RET 0x%08"PFMT64x". %d %d %d\n", VERBOSE_ANAL eprintf("RET 0x%08"PFMT64x ". %d %d %d\n",
addr + delay.un_idx-oplen, overlapped, addr + delay.un_idx - oplen, overlapped,
bb->size, r_anal_fcn_size (fcn)); bb->size, r_anal_fcn_size (fcn));
FITFCNSZ (); FITFCNSZ ();
r_anal_op_fini (&op); r_anal_op_fini (&op);
return R_ANAL_RET_END; return R_ANAL_RET_END;
@ -1090,22 +1104,24 @@ static int check_preludes(ut8 *buf, ut16 bufsz) {
if (bufsz < 10) { if (bufsz < 10) {
return false; return false;
} }
if (!memcmp (buf, (const ut8 *)"\x55\x89\xe5", 3)) { if (!memcmp (buf, (const ut8 *) "\x55\x89\xe5", 3)) {
return true; return true;
} else if (!memcmp (buf, (const ut8 *)"\x55\x8b\xec", 3)) { } else if (!memcmp (buf, (const ut8 *) "\x55\x8b\xec", 3)) {
return true; return true;
} else if (!memcmp (buf, (const ut8 *)"\x8b\xff", 2)) { } else if (!memcmp (buf, (const ut8 *) "\x8b\xff", 2)) {
return true; return true;
} else if (!memcmp (buf, (const ut8 *)"\x55\x48\x89\xe5", 4)) { } else if (!memcmp (buf, (const ut8 *) "\x55\x48\x89\xe5", 4)) {
return true; return true;
} else if (!memcmp (buf, (const ut8 *)"\x55\x48\x8b\xec", 4)) { } else if (!memcmp (buf, (const ut8 *) "\x55\x48\x8b\xec", 4)) {
return true; return true;
} }
return false; return false;
} }
R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high) { R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high) {
RAnalOp op = {0}; RAnalOp op = {
0
};
int i, oplen, opcnt = 0, pushcnt = 0, movcnt = 0, brcnt = 0; int i, oplen, opcnt = 0, pushcnt = 0, movcnt = 0, brcnt = 0;
if (check_preludes (buf, bufsz)) { if (check_preludes (buf, bufsz)) {
return true; return true;
@ -1139,17 +1155,17 @@ R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 l
return (pushcnt + movcnt + brcnt > 5); return (pushcnt + movcnt + brcnt > 5);
} }
static void fcnfit (RAnal *a, RAnalFunction *f) { static void fcnfit(RAnal *a, RAnalFunction *f) {
// find next function // find next function
RAnalFunction *next = r_anal_fcn_next (a, f->addr); RAnalFunction *next = r_anal_fcn_next (a, f->addr);
if (next) { if (next) {
if ((f->addr + r_anal_fcn_size (f))> next->addr) { if ((f->addr + r_anal_fcn_size (f)) > next->addr) {
r_anal_fcn_resize (f, (next->addr - f->addr)); r_anal_fcn_resize (f, (next->addr - f->addr));
} }
} }
} }
R_API void r_anal_fcn_fit_overlaps (RAnal *anal, RAnalFunction *fcn) { R_API void r_anal_fcn_fit_overlaps(RAnal *anal, RAnalFunction *fcn) {
if (fcn) { if (fcn) {
fcnfit (anal, fcn); fcnfit (anal, fcn);
} else { } else {
@ -1177,7 +1193,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
r_anal_fcn_set_size (fcn, 0); r_anal_fcn_set_size (fcn, 0);
/* defines fcn. or loc. prefix */ /* defines fcn. or loc. prefix */
fcn->type = (reftype == R_ANAL_REF_TYPE_CODE) fcn->type = (reftype == R_ANAL_REF_TYPE_CODE)
? R_ANAL_FCN_TYPE_LOC ? R_ANAL_FCN_TYPE_LOC
: R_ANAL_FCN_TYPE_FCN; : R_ANAL_FCN_TYPE_FCN;
if (fcn->addr == UT64_MAX) { if (fcn->addr == UT64_MAX) {
fcn->addr = addr; fcn->addr = addr;
@ -1190,10 +1206,10 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
} }
fcn->maxstack = 0; fcn->maxstack = 0;
ret = fcn_recurse (anal, fcn, addr, buf, len, FCN_DEPTH); ret = fcn_recurse (anal, fcn, addr, buf, len, FCN_DEPTH);
//update tinyrange for the function // update tinyrange for the function
update_tinyrange_bbs (fcn); update_tinyrange_bbs (fcn);
if (ret == R_ANAL_RET_END && r_anal_fcn_size (fcn)) { // cfg analysis completed if (ret == R_ANAL_RET_END && r_anal_fcn_size (fcn)) { // cfg analysis completed
RListIter *iter; RListIter *iter;
RAnalBlock *bb; RAnalBlock *bb;
ut64 endaddr = fcn->addr; ut64 endaddr = fcn->addr;
@ -1206,10 +1222,10 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
if (endaddr == bb->addr) { if (endaddr == bb->addr) {
endaddr += bb->size; endaddr += bb->size;
} else if (endaddr < bb->addr && } else if (endaddr < bb->addr &&
bb->addr - endaddr < bb->addr - endaddr <
anal->opt.bbs_alignment && anal->opt.bbs_alignment &&
!(bb->addr & !(bb->addr &
(anal->opt.bbs_alignment - 1))) { (anal->opt.bbs_alignment - 1))) {
endaddr = bb->addr + bb->size; endaddr = bb->addr + bb->size;
} else { } else {
break; break;
@ -1237,7 +1253,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
// TODO: need to implement r_anal_fcn_remove(RAnal *anal, RAnalFunction *fcn); // TODO: need to implement r_anal_fcn_remove(RAnal *anal, RAnalFunction *fcn);
R_API int r_anal_fcn_insert(RAnal *anal, RAnalFunction *fcn) { R_API int r_anal_fcn_insert(RAnal *anal, RAnalFunction *fcn) {
//RAnalFunction *f = r_anal_get_fcn_in (anal, fcn->addr, R_ANAL_FCN_TYPE_ROOT); // RAnalFunction *f = r_anal_get_fcn_in (anal, fcn->addr, R_ANAL_FCN_TYPE_ROOT);
RAnalFunction *f = r_anal_get_fcn_at (anal, fcn->addr, R_ANAL_FCN_TYPE_ROOT); RAnalFunction *f = r_anal_get_fcn_at (anal, fcn->addr, R_ANAL_FCN_TYPE_ROOT);
if (f) { if (f) {
return false; return false;
@ -1354,15 +1370,16 @@ R_API int r_anal_fcn_del(RAnal *a, ut64 addr) {
R_API RAnalFunction *r_anal_get_fcn_in(RAnal *anal, ut64 addr, int type) { R_API RAnalFunction *r_anal_get_fcn_in(RAnal *anal, ut64 addr, int type) {
#if USE_NEW_FCN_STORE #if USE_NEW_FCN_STORE
// TODO: type is ignored here? wtf.. we need more work on fcnstore // TODO: type is ignored here? wtf.. we need more work on fcnstore
//if (root) return r_listrange_find_root (anal->fcnstore, addr); // if (root) return r_listrange_find_root (anal->fcnstore, addr);
return r_listrange_find_in_range (anal->fcnstore, addr); return r_listrange_find_in_range (anal->fcnstore, addr);
#else #else
RAnalFunction *fcn, *ret = NULL; RAnalFunction *fcn, *ret = NULL;
RListIter *iter; RListIter *iter;
if (type == R_ANAL_FCN_TYPE_ROOT) { if (type == R_ANAL_FCN_TYPE_ROOT) {
r_list_foreach (anal->fcns, iter, fcn) { r_list_foreach (anal->fcns, iter, fcn) {
if (addr == fcn->addr) if (addr == fcn->addr) {
return fcn; return fcn;
}
} }
return NULL; return NULL;
} }
@ -1386,7 +1403,7 @@ R_API RAnalFunction *r_anal_get_fcn_in_bounds(RAnal *anal, ut64 addr, int type)
#if USE_NEW_FCN_STORE #if USE_NEW_FCN_STORE
#warning TODO: r_anal_get_fcn_in_bounds #warning TODO: r_anal_get_fcn_in_bounds
// TODO: type is ignored here? wtf.. we need more work on fcnstore // TODO: type is ignored here? wtf.. we need more work on fcnstore
//if (root) return r_listrange_find_root (anal->fcnstore, addr); // if (root) return r_listrange_find_root (anal->fcnstore, addr);
return r_listrange_find_in_range (anal->fcnstore, addr); return r_listrange_find_in_range (anal->fcnstore, addr);
#else #else
RAnalFunction *fcn, *ret = NULL; RAnalFunction *fcn, *ret = NULL;
@ -1437,7 +1454,7 @@ R_API int r_anal_fcn_add_bb(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 siz
} }
} }
if (mid) { if (mid) {
//eprintf ("Basic Block overlaps another one that should be shrinked\n"); // eprintf ("Basic Block overlaps another one that should be shrinked\n");
if (bbi) { if (bbi) {
/* shrink overlapped basic block */ /* shrink overlapped basic block */
bbi->size = addr - (bbi->addr); bbi->size = addr - (bbi->addr);
@ -1533,14 +1550,14 @@ R_API int r_anal_fcn_bb_overlaps(RAnalFunction *fcn, RAnalBlock *bb) {
RAnalBlock *bbi; RAnalBlock *bbi;
RListIter *iter; RListIter *iter;
r_list_foreach (fcn->bbs, iter, bbi) { r_list_foreach (fcn->bbs, iter, bbi) {
if (bb->addr + bb->size > bbi->addr && bb->addr + bb->size <= bbi->addr+bbi->size) { if (bb->addr + bb->size > bbi->addr && bb->addr + bb->size <= bbi->addr + bbi->size) {
bb->size = bbi->addr - bb->addr; bb->size = bbi->addr - bb->addr;
bb->jump = bbi->addr; bb->jump = bbi->addr;
bb->fail = -1; bb->fail = -1;
bb->conditional = false; bb->conditional = false;
if (bbi->type & R_ANAL_BB_TYPE_HEAD) { if (bbi->type & R_ANAL_BB_TYPE_HEAD) {
bb->type = R_ANAL_BB_TYPE_HEAD; bb->type = R_ANAL_BB_TYPE_HEAD;
bbi->type = bbi->type^R_ANAL_BB_TYPE_HEAD; bbi->type = bbi->type ^ R_ANAL_BB_TYPE_HEAD;
} else { } else {
bb->type = R_ANAL_BB_TYPE_BODY; bb->type = R_ANAL_BB_TYPE_BODY;
} }
@ -1553,11 +1570,11 @@ R_API int r_anal_fcn_bb_overlaps(RAnalFunction *fcn, RAnalBlock *bb) {
R_API int r_anal_fcn_cc(RAnalFunction *fcn) { R_API int r_anal_fcn_cc(RAnalFunction *fcn) {
/* /*
CC = E - N + 2P CC = E - N + 2P
E = the number of edges of the graph. E = the number of edges of the graph.
N = the number of nodes of the graph. N = the number of nodes of the graph.
P = the number of connected components (exit nodes). P = the number of connected components (exit nodes).
*/ */
int E = 0, N = 0, P = 0; int E = 0, N = 0, P = 0;
RListIter *iter; RListIter *iter;
RAnalBlock *bb; RAnalBlock *bb;
@ -1576,7 +1593,7 @@ R_API int r_anal_fcn_cc(RAnalFunction *fcn) {
return E - N + 2; // (2 * P); return E - N + 2; // (2 * P);
} }
R_API char *r_anal_fcn_to_string(RAnal *a, RAnalFunction* fs) { R_API char *r_anal_fcn_to_string(RAnal *a, RAnalFunction *fs) {
return NULL; return NULL;
} }
@ -1609,7 +1626,7 @@ R_API int r_anal_str_to_fcn(RAnal *a, RAnalFunction *f, const char *sig) {
R_API RAnalFunction *r_anal_get_fcn_at(RAnal *anal, ut64 addr, int type) { R_API RAnalFunction *r_anal_get_fcn_at(RAnal *anal, ut64 addr, int type) {
#if USE_NEW_FCN_STORE #if USE_NEW_FCN_STORE
// TODO: type is ignored here? wtf.. we need more work on fcnstore // TODO: type is ignored here? wtf.. we need more work on fcnstore
//if (root) return r_listrange_find_root (anal->fcnstore, addr); // if (root) return r_listrange_find_root (anal->fcnstore, addr);
return r_listrange_find_root (anal->fcnstore, addr); return r_listrange_find_root (anal->fcnstore, addr);
#else #else
RAnalFunction *fcn, *ret = NULL; RAnalFunction *fcn, *ret = NULL;
@ -1638,8 +1655,8 @@ R_API RAnalFunction *r_anal_fcn_next(RAnal *anal, ut64 addr) {
RListIter *iter; RListIter *iter;
RAnalFunction *closer = NULL; RAnalFunction *closer = NULL;
r_list_foreach (anal->fcns, iter, fcni) { r_list_foreach (anal->fcns, iter, fcni) {
//if (fcni->addr == addr) // if (fcni->addr == addr)
if (fcni->addr > addr && (!closer || fcni->addr<closer->addr)) { if (fcni->addr > addr && (!closer || fcni->addr < closer->addr)) {
closer = fcni; closer = fcni;
} }
} }
@ -1648,14 +1665,17 @@ R_API RAnalFunction *r_anal_fcn_next(RAnal *anal, ut64 addr) {
/* getters */ /* getters */
#if FCN_OLD #if FCN_OLD
R_API RList* r_anal_fcn_get_refs (RAnalFunction *anal) { return anal->refs; } R_API RList *r_anal_fcn_get_refs(RAnalFunction *fcn) {
R_API RList* r_anal_fcn_get_xrefs (RAnalFunction *anal) { return anal->xrefs; } return fcn->refs;
R_API RList* r_anal_fcn_get_vars (RAnalFunction *anal) { return anal->vars; } }
R_API RList *r_anal_fcn_get_xrefs(RAnalFunction *fcn) {
return fcn->xrefs;
}
#endif #endif
R_API RList* r_anal_fcn_get_bbs (RAnalFunction *anal) { R_API RList *r_anal_fcn_get_bbs(RAnalFunction *anal) {
// avoid received to free this thing // avoid received to free this thing
//anal->bbs->rc++; // anal->bbs->rc++;
anal->bbs->free = NULL; anal->bbs->free = NULL;
return anal->bbs; return anal->bbs;
} }
@ -1671,7 +1691,7 @@ R_API int r_anal_fcn_is_in_offset(RAnalFunction *fcn, ut64 addr) {
return false; return false;
} }
R_API int r_anal_fcn_count (RAnal *anal, ut64 from, ut64 to) { R_API int r_anal_fcn_count(RAnal *anal, ut64 from, ut64 to) {
int n = 0; int n = 0;
RAnalFunction *fcni; RAnalFunction *fcni;
RListIter *iter; RListIter *iter;
@ -1718,7 +1738,7 @@ R_API void r_anal_fcn_set_size(RAnalFunction *fcn, ut32 size) {
/* returns the size of the function. /* returns the size of the function.
* IMPORTANT: this will change, one day, because it doesn't have much sense */ * IMPORTANT: this will change, one day, because it doesn't have much sense */
R_API ut32 r_anal_fcn_size(const RAnalFunction *fcn) { R_API ut32 r_anal_fcn_size(const RAnalFunction *fcn) {
return fcn ? fcn->_size : 0; return fcn? fcn->_size: 0;
} }
/* return the "real" size of the function, that is the sum of the size of the /* return the "real" size of the function, that is the sum of the size of the
@ -1740,16 +1760,16 @@ R_API ut32 r_anal_fcn_realsize(const RAnalFunction *fcn) {
return sz; return sz;
} }
//continious function size without loc.* // continious function size without loc.*
R_API ut32 r_anal_fcn_contsize(const RAnalFunction *fcn) { R_API ut32 r_anal_fcn_contsize(const RAnalFunction *fcn) {
RListIter *iter; RListIter *iter;
RAnalBlock *bb; RAnalBlock *bb;
ut32 sz = 0; ut32 sz = 0;
r_list_foreach (fcn->bbs, iter, bb) { r_list_foreach (fcn->bbs, iter, bb) {
/* TODO: this if is an ugly hack and should be removed when r2 will be /* TODO: this if is an ugly hack and should be removed when r2 will be
* able to handle BBs that comes before the function emtry point. * able to handle BBs that comes before the function emtry point.
* Another way to remove this is to throw away BBs before the function * Another way to remove this is to throw away BBs before the function
* entry point at the analysis time in the r_anal_fcn. */ * entry point at the analysis time in the r_anal_fcn. */
if (bb->addr >= fcn->addr) { if (bb->addr >= fcn->addr) {
sz += bb->size; sz += bb->size;
} }
@ -1769,11 +1789,11 @@ R_API ut32 r_anal_fcn_cost(RAnal *anal, RAnalFunction *fcn) {
RAnalOp op; RAnalOp op;
ut64 at, end = bb->addr + bb->size; ut64 at, end = bb->addr + bb->size;
ut8 *buf = malloc (bb->size); ut8 *buf = malloc (bb->size);
anal->iob.read_at (anal->iob.io, bb->addr, (ut8 *)buf, bb->size); anal->iob.read_at (anal->iob.io, bb->addr, (ut8 *) buf, bb->size);
int idx = 0; int idx = 0;
for (at = bb->addr; at < end; ) { for (at = bb->addr; at < end;) {
memset (&op, 0, sizeof (op)); memset (&op, 0, sizeof (op));
(void)r_anal_op (anal, &op, at, buf + idx, bb->size - idx); (void) r_anal_op (anal, &op, at, buf + idx, bb->size - idx);
if (op.size < 1) { if (op.size < 1) {
op.size = 1; op.size = 1;
} }

File diff suppressed because it is too large Load Diff

View File

@ -118,69 +118,6 @@ R_API int r_anal_type_get_size(RAnal *anal, const char *type) {
return 0; return 0;
} }
R_API RList *r_anal_type_fcn_list(RAnal *anal) {
SdbList *sdb_list = sdb_foreach_match (anal->sdb_types, "=^func$", false);
RList *list = r_list_newf ((RListFree)r_anal_fcn_free);
char *name, *value;
const char *key;
SdbListIter *sdb_iter;
int args_n, i;
SdbKv *kv;
if (!list || !sdb_list) {
r_list_free (list);
ls_free (sdb_list);
return 0;
}
ls_foreach (sdb_list, sdb_iter, kv) {
RAnalFunction *fcn = r_anal_fcn_new ();
r_list_append (list, fcn);
//setting function name and return type
fcn->name = strdup (kv->key);
//setting function return type
key = sdb_fmt (-1, "func.%s.ret", kv->key);
fcn->rets = sdb_get (anal->sdb_types, key, 0);
//setting calling conventions
key = sdb_fmt (-1, "func.%s.cc", kv->key);
fcn->cc = sdb_get (anal->sdb_types, key, 0);
//Filling function args
key = sdb_fmt (-1, "func.%s.args", kv->key);
value = sdb_get (anal->sdb_types, key, 0);
args_n = r_num_math (NULL, value);
free (value);
if (!args_n) {
continue;
}
//XXX we should handle as much calling conventions
//for as much architectures as we want here
fcn->vars = r_list_newf ((RListFree)r_anal_var_free);
if (!fcn->vars) {
continue;
}
for (i = 0; i < args_n; i++) {
key = r_str_newf ("func.%s.arg.%d", kv->key, i);
value = sdb_get (anal->sdb_types, key, 0);
if (value) {
name = strstr (value, ",");
*name++ = 0;
RAnalVar *arg = R_NEW0 (RAnalVar);
arg->name = strdup (name);
arg->type = value;
arg->kind = 'a';
//TODO Calculate the size and the delta
arg->delta = i;
r_list_append (fcn->vars, arg);
}
}
}
ls_free (sdb_list);
if (r_list_empty (list)) {
r_list_free (list);
return NULL;
}
return list;
}
R_API char* r_anal_type_to_str (RAnal *a, const char *type) { R_API char* r_anal_type_to_str (RAnal *a, const char *type) {
// convert to C text... maybe that should be in format string.. // convert to C text... maybe that should be in format string..
return NULL; return NULL;

View File

@ -16,10 +16,10 @@ struct VarType {
#define SDB_VARTYPE_FMT "czdz" #define SDB_VARTYPE_FMT "czdz"
#define EXISTS(x,y...) snprintf (key, sizeof (key)-1, x, ##y), sdb_exists(DB,key) #define EXISTS(x, y ...) snprintf (key, sizeof (key) - 1, x, ## y), sdb_exists (DB, key)
#define SETKEY(x,y...) snprintf (key, sizeof (key)-1, x, ##y); #define SETKEY(x, y ...) snprintf (key, sizeof (key) - 1, x, ## y);
#define SETKEY2(x,y...) snprintf (key2, sizeof (key)-1, x, ##y); #define SETKEY2(x, y ...) snprintf (key2, sizeof (key) - 1, x, ## y);
#define SETVAL(x,y...) snprintf (val, sizeof (val)-1, x, ##y); #define SETVAL(x, y ...) snprintf (val, sizeof (val) - 1, x, ## y);
R_API bool r_anal_var_display(RAnal *anal, int delta, char kind, const char *type) { R_API bool r_anal_var_display(RAnal *anal, int delta, char kind, const char *type) {
char *fmt = r_anal_type_format (anal, type); char *fmt = r_anal_type_format (anal, type);
RRegItem *i; RRegItem *i;
@ -68,7 +68,7 @@ R_API int r_anal_var_add(RAnal *a, ut64 addr, int scope, int delta, char kind, c
eprintf ("Invalid var kind '%c'\n", kind); eprintf ("Invalid var kind '%c'\n", kind);
return false; return false;
} }
var_def = sdb_fmt (0,"%c,%s,%d,%s", kind, type, size, name); var_def = sdb_fmt (0, "%c,%s,%d,%s", kind, type, size, name);
if (scope > 0) { if (scope > 0) {
char *sign = ""; char *sign = "";
if (delta < 0) { if (delta < 0) {
@ -76,9 +76,9 @@ R_API int r_anal_var_add(RAnal *a, ut64 addr, int scope, int delta, char kind, c
sign = "_"; sign = "_";
} }
/* local variable */ /* local variable */
char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x".%c", addr, kind); char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x ".%c", addr, kind);
char *var_key = sdb_fmt (2, "var.0x%"PFMT64x".%c.%d.%s%d", addr, kind, scope, sign, delta); char *var_key = sdb_fmt (2, "var.0x%"PFMT64x ".%c.%d.%s%d", addr, kind, scope, sign, delta);
char *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", addr, scope, name); char *name_key = sdb_fmt (3, "var.0x%"PFMT64x ".%d.%s", addr, scope, name);
char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta); char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
sdb_array_add (DB, fcn_key, shortvar, 0); sdb_array_add (DB, fcn_key, shortvar, 0);
sdb_set (DB, var_key, var_def, 0); sdb_set (DB, var_key, var_def, 0);
@ -90,10 +90,10 @@ R_API int r_anal_var_add(RAnal *a, ut64 addr, int scope, int delta, char kind, c
} else { } else {
/* global variable */ /* global variable */
char *var_global = sdb_fmt (1, "var.0x%"PFMT64x, addr); char *var_global = sdb_fmt (1, "var.0x%"PFMT64x, addr);
char *var_def = sdb_fmt (2,"%c.%s,%d,%s", kind, type, size, name); char *var_def = sdb_fmt (2, "%c.%s,%d,%s", kind, type, size, name);
sdb_array_add (DB, var_global, var_def, 0); sdb_array_add (DB, var_global, var_def, 0);
} }
// ls_sort (DB->ht->list, mystrcmp); // ls_sort (DB->ht->list, mystrcmp);
return true; return true;
} }
@ -136,7 +136,7 @@ R_API int r_anal_var_retype(RAnal *a, ut64 addr, int scope, int delta, char kind
eprintf ("Invalid var kind '%c'\n", kind); eprintf ("Invalid var kind '%c'\n", kind);
return false; return false;
} }
var_def = sdb_fmt (0,"%c,%s,%d,%s", kind, type, size, name); var_def = sdb_fmt (0, "%c,%s,%d,%s", kind, type, size, name);
if (scope > 0) { if (scope > 0) {
char *sign = ""; char *sign = "";
if (delta < 0) { if (delta < 0) {
@ -144,9 +144,9 @@ R_API int r_anal_var_retype(RAnal *a, ut64 addr, int scope, int delta, char kind
sign = "_"; sign = "_";
} }
/* local variable */ /* local variable */
const char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x".%c", fcn->addr, kind); const char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x ".%c", fcn->addr, kind);
const char *var_key = sdb_fmt (2, "var.0x%"PFMT64x".%c.%d.%s%d", fcn->addr, kind, scope, sign, delta); const char *var_key = sdb_fmt (2, "var.0x%"PFMT64x ".%c.%d.%s%d", fcn->addr, kind, scope, sign, delta);
const char *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", fcn->addr, scope, name); const char *name_key = sdb_fmt (3, "var.0x%"PFMT64x ".%d.%s", fcn->addr, scope, name);
const char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta); const char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
const char *name_val = sdb_fmt (5, "%c,%d", kind, delta); const char *name_val = sdb_fmt (5, "%c,%d", kind, delta);
sdb_array_add (DB, fcn_key, shortvar, 0); sdb_array_add (DB, fcn_key, shortvar, 0);
@ -156,14 +156,14 @@ R_API int r_anal_var_retype(RAnal *a, ut64 addr, int scope, int delta, char kind
} }
sdb_set (DB, name_key, name_val, 0); sdb_set (DB, name_key, name_val, 0);
Sdb *TDB = a->sdb_types; Sdb *TDB = a->sdb_types;
const char* type_kind = sdb_const_get (TDB, type, 0); const char *type_kind = sdb_const_get (TDB, type, 0);
if (type_kind && r_str_startswith (type_kind, "struct")) { if (type_kind && r_str_startswith (type_kind, "struct")) {
char *field, *field_key, *field_type; char *field, *field_key, *field_type;
int field_n, field_offset; int field_n, field_offset;
char *type_key = r_str_newf ("%s.%s", type_kind, type); char *type_key = r_str_newf ("%s.%s", type_kind, type);
for (field_n = 0; for (field_n = 0;
(field = sdb_array_get (TDB, type_key, field_n, NULL)); (field = sdb_array_get (TDB, type_key, field_n, NULL));
field_n++) { field_n++) {
field_key = r_str_newf ("%s.%s", type_key, field); field_key = r_str_newf ("%s.%s", type_key, field);
field_type = sdb_array_get (TDB, field_key, 0, NULL); field_type = sdb_array_get (TDB, field_key, 0, NULL);
field_offset = sdb_array_get_num (TDB, field_key, 1, NULL); field_offset = sdb_array_get_num (TDB, field_key, 1, NULL);
@ -192,7 +192,7 @@ R_API int r_anal_var_delete_all(RAnal *a, ut64 addr, const char kind) {
RListIter *iter; RListIter *iter;
RList *list = r_anal_var_list (a, fcn, kind); RList *list = r_anal_var_list (a, fcn, kind);
r_list_foreach (list, iter, v) { r_list_foreach (list, iter, v) {
//r_anal_var_delete (a, addr, kind, v->scope, v->delta); // r_anal_var_delete (a, addr, kind, v->scope, v->delta);
r_anal_var_delete (a, addr, kind, 1, v->delta); r_anal_var_delete (a, addr, kind, 1, v->delta);
} }
r_list_free (list); r_list_free (list);
@ -202,24 +202,28 @@ R_API int r_anal_var_delete_all(RAnal *a, ut64 addr, const char kind) {
R_API int r_anal_var_delete(RAnal *a, ut64 addr, const char kind, int scope, int delta) { R_API int r_anal_var_delete(RAnal *a, ut64 addr, const char kind, int scope, int delta) {
RAnalVar *av = r_anal_var_get (a, addr, kind, scope, delta); RAnalVar *av = r_anal_var_get (a, addr, kind, scope, delta);
if (!av) return false; if (!av) {
return false;
}
if (scope > 0) { if (scope > 0) {
char *sign = ""; char *sign = "";
if (delta < 0) { if (delta < 0) {
delta = -delta; delta = -delta;
sign = "_"; sign = "_";
} }
char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x".%c", addr, kind); char *fcn_key = sdb_fmt (1, "fcn.0x%"PFMT64x ".%c", addr, kind);
char *var_key = sdb_fmt (2, "var.0x%"PFMT64x".%c.%d.%s%d", addr, kind, scope, sign, delta); char *var_key = sdb_fmt (2, "var.0x%"PFMT64x ".%c.%d.%s%d", addr, kind, scope, sign, delta);
char *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", addr, scope, av->name); char *name_key = sdb_fmt (3, "var.0x%"PFMT64x ".%d.%s", addr, scope, av->name);
char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta); char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
sdb_array_remove (DB, fcn_key, shortvar, 0); sdb_array_remove (DB, fcn_key, shortvar, 0);
sdb_unset (DB, var_key, 0); sdb_unset (DB, var_key, 0);
sdb_unset (DB, name_key, 0); sdb_unset (DB, name_key, 0);
if (*sign) delta = -delta; if (*sign) {
delta = -delta;
}
} else { } else {
char *var_global = sdb_fmt (1, "var.0x%"PFMT64x, addr); char *var_global = sdb_fmt (1, "var.0x%"PFMT64x, addr);
char *var_def = sdb_fmt (2,"%c.%s,%d,%s", kind, av->type, av->size, av->name); char *var_def = sdb_fmt (2, "%c.%s,%d,%s", kind, av->type, av->size, av->name);
sdb_array_remove (DB, var_global, var_def, 0); sdb_array_remove (DB, var_global, var_def, 0);
} }
r_anal_var_free (av); r_anal_var_free (av);
@ -232,8 +236,8 @@ R_API bool r_anal_var_delete_byname(RAnal *a, RAnalFunction *fcn, int kind, cons
if (!a || !fcn) { if (!a || !fcn) {
return false; return false;
} }
varlist = sdb_get (DB, sdb_fmt (0, "fcn.0x%"PFMT64x".%c", varlist = sdb_get (DB, sdb_fmt (0, "fcn.0x%"PFMT64x ".%c",
fcn->addr, kind), 0); fcn->addr, kind), 0);
if (varlist) { if (varlist) {
char *next, *ptr = varlist; char *next, *ptr = varlist;
if (varlist && *varlist) { if (varlist && *varlist) {
@ -241,12 +245,12 @@ R_API bool r_anal_var_delete_byname(RAnal *a, RAnalFunction *fcn, int kind, cons
char *word = sdb_anext (ptr, &next); char *word = sdb_anext (ptr, &next);
char *sign = strstr (word, "_"); char *sign = strstr (word, "_");
const char *vardef = sdb_const_get (DB, sdb_fmt (1, const char *vardef = sdb_const_get (DB, sdb_fmt (1,
"var.0x%"PFMT64x".%c.%s", "var.0x%"PFMT64x ".%c.%s",
fcn->addr, kind, word), 0); fcn->addr, kind, word), 0);
if (sign) { if (sign) {
*sign = '-'; *sign = '-';
} }
int delta = strlen (word) < 3 ? -1 : atoi (word + 2); int delta = strlen (word) < 3? -1: atoi (word + 2);
if (vardef) { if (vardef) {
const char *p = strchr (vardef, ','); const char *p = strchr (vardef, ',');
if (p) { if (p) {
@ -273,11 +277,11 @@ R_API bool r_anal_var_delete_byname(RAnal *a, RAnalFunction *fcn, int kind, cons
return false; return false;
} }
R_API RAnalVar *r_anal_var_get_byname(RAnal *a, RAnalFunction *fcn, const char* name) { R_API RAnalVar *r_anal_var_get_byname(RAnal *a, RAnalFunction *fcn, const char *name) {
if (!fcn || !a || !name) { if (!fcn || !a || !name) {
return NULL; return NULL;
} }
char *name_key = sdb_fmt (-1, "var.0x%"PFMT64x".%d.%s", fcn->addr, 1, name); char *name_key = sdb_fmt (-1, "var.0x%"PFMT64x ".%d.%s", fcn->addr, 1, name);
const char *name_value = sdb_const_get (DB, name_key, 0); const char *name_value = sdb_const_get (DB, name_key, 0);
if (!name_value) { if (!name_value) {
return NULL; return NULL;
@ -292,7 +296,9 @@ R_API RAnalVar *r_anal_var_get_byname(RAnal *a, RAnalFunction *fcn, const char*
R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int delta) { R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int delta) {
RAnalVar *av; RAnalVar *av;
struct VarType vt = { 0 }; struct VarType vt = {
0
};
char *sign = ""; char *sign = "";
RAnalFunction *fcn = r_anal_get_fcn_in (a, addr, 0); RAnalFunction *fcn = r_anal_get_fcn_in (a, addr, 0);
if (!fcn) { if (!fcn) {
@ -303,7 +309,7 @@ R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int de
sign = "_"; sign = "_";
} }
const char *vardef = sdb_const_get (DB, const char *vardef = sdb_const_get (DB,
sdb_fmt (-1, "var.0x%"PFMT64x".%c.%d.%s%d", sdb_fmt (-1, "var.0x%"PFMT64x ".%c.%d.%s%d",
fcn->addr, kind, scope, sign, delta), 0); fcn->addr, kind, scope, sign, delta), 0);
if (*sign) { if (*sign) {
delta = -delta; delta = -delta;
@ -322,9 +328,9 @@ R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int de
av->addr = fcn->addr; av->addr = fcn->addr;
av->scope = scope; av->scope = scope;
av->delta = delta; av->delta = delta;
av->name = vt.name? strdup (vt.name) : strdup ("unkown_var"); av->name = vt.name? strdup (vt.name): strdup ("unkown_var");
av->size = vt.size; av->size = vt.size;
av->type = vt.type? strdup (vt.type) : strdup ("unkown_type"); av->type = vt.type? strdup (vt.type): strdup ("unkown_type");
av->kind = kind; av->kind = kind;
sdb_fmt_free (&vt, SDB_VARTYPE_FMT); sdb_fmt_free (&vt, SDB_VARTYPE_FMT);
// TODO: // TODO:
@ -352,12 +358,24 @@ R_API int r_anal_var_check_name(const char *name) {
// restrict length // restrict length
// name is not base64'd . because no specials can be contained // name is not base64'd . because no specials can be contained
// TODO: check that new_name is valid. this is a hack // TODO: check that new_name is valid. this is a hack
if (*name=='0' || atoi (name)>0) return 0; if (*name == '0' || atoi (name) > 0) {
if (strchr (name, '.')) return 0; return 0;
if (strchr (name, ',')) return 0; }
if (strchr (name, ' ')) return 0; if (strchr (name, '.')) {
if (strchr (name, '=')) return 0; return 0;
if (strchr (name, '/')) return 0; }
if (strchr (name, ',')) {
return 0;
}
if (strchr (name, ' ')) {
return 0;
}
if (strchr (name, '=')) {
return 0;
}
if (strchr (name, '/')) {
return 0;
}
return 1; return 1;
} }
@ -371,7 +389,7 @@ R_API int r_anal_var_rename(RAnal *a, ut64 var_addr, int scope, char kind, const
} }
RAnalFunction *fcn = r_anal_get_fcn_in (a, var_addr, 0); RAnalFunction *fcn = r_anal_get_fcn_in (a, var_addr, 0);
RAnalVar *v1 = r_anal_var_get_byname (a, fcn, new_name); RAnalVar *v1 = r_anal_var_get_byname (a, fcn, new_name);
if(v1) { if (v1) {
r_anal_var_free (v1); r_anal_var_free (v1);
eprintf ("variable or arg with name `%s` already exist\n", new_name); eprintf ("variable or arg with name `%s` already exist\n", new_name);
return false; return false;
@ -381,20 +399,20 @@ R_API int r_anal_var_rename(RAnal *a, ut64 var_addr, int scope, char kind, const
// XXX. this is pretty weak, because oldname may not exist too and error returned. // XXX. this is pretty weak, because oldname may not exist too and error returned.
if (scope > 0) { // local if (scope > 0) { // local
const char *sign = ""; const char *sign = "";
SETKEY ("var.0x%"PFMT64x".%d.%s", var_addr, scope, old_name); SETKEY ("var.0x%"PFMT64x ".%d.%s", var_addr, scope, old_name);
char *name_val = sdb_get (DB, key, 0); char *name_val = sdb_get (DB, key, 0);
char *comma = strchr (name_val, ','); char *comma = strchr (name_val, ',');
if (comma) { if (comma) {
delta = r_num_math (NULL, comma + 1); delta = r_num_math (NULL, comma + 1);
sdb_unset (DB, key, 0); sdb_unset (DB, key, 0);
SETKEY ("var.0x%"PFMT64x".%d.%s", var_addr, scope, new_name); SETKEY ("var.0x%"PFMT64x ".%d.%s", var_addr, scope, new_name);
sdb_set (DB, key, name_val, 0); sdb_set (DB, key, name_val, 0);
free (name_val); free (name_val);
if (delta < 0) { if (delta < 0) {
delta = -delta; delta = -delta;
sign = "_"; sign = "_";
} }
SETKEY ("var.0x%"PFMT64x".%c.%d.%s%d", var_addr, kind, scope, sign, delta); SETKEY ("var.0x%"PFMT64x ".%c.%d.%s%d", var_addr, kind, scope, sign, delta);
sdb_array_set (DB, key, R_ANAL_VAR_SDB_NAME, new_name, 0); sdb_array_set (DB, key, R_ANAL_VAR_SDB_NAME, new_name, 0);
} }
} else { // global } else { // global
@ -419,62 +437,64 @@ R_API int r_anal_var_rename(RAnal *a, ut64 var_addr, int scope, char kind, const
} }
// avr // avr
R_API int r_anal_var_access (RAnal *a, ut64 var_addr, char kind, int scope, int delta, int xs_type, ut64 xs_addr) { R_API int r_anal_var_access(RAnal *a, ut64 var_addr, char kind, int scope, int delta, int xs_type, ut64 xs_addr) {
const char *var_global; const char *var_global;
const char *xs_type_str = xs_type? "writes": "reads"; const char *xs_type_str = xs_type? "writes": "reads";
// TODO: kind is not used // TODO: kind is not used
if (scope > 0) { // local if (scope > 0) { // local
const char *var_local = sdb_fmt (0, "var.0x%"PFMT64x".%d.%d.%s", const char *var_local = sdb_fmt (0, "var.0x%"PFMT64x ".%d.%d.%s",
var_addr, scope, delta, xs_type_str); var_addr, scope, delta, xs_type_str);
const char *inst_key = sdb_fmt (1, "inst.0x%"PFMT64x".vars", xs_addr); const char *inst_key = sdb_fmt (1, "inst.0x%"PFMT64x ".vars", xs_addr);
const char *var_def = sdb_fmt (2, "0x%"PFMT64x",%c,0x%x,0x%x", var_addr, const char *var_def = sdb_fmt (2, "0x%"PFMT64x ",%c,0x%x,0x%x", var_addr,
kind, scope, delta); kind, scope, delta);
sdb_set (DB, inst_key, var_def, 0); sdb_set (DB, inst_key, var_def, 0);
return sdb_array_add_num (DB, var_local, xs_addr, 0); return sdb_array_add_num (DB, var_local, xs_addr, 0);
} }
// global // global
sdb_add (DB, sdb_fmt (0,"var.0x%"PFMT64x, var_addr), "a,", 0); sdb_add (DB, sdb_fmt (0, "var.0x%"PFMT64x, var_addr), "a,", 0);
var_global = sdb_fmt (0, "var.0x%"PFMT64x".%s", var_addr, xs_type_str); var_global = sdb_fmt (0, "var.0x%"PFMT64x ".%s", var_addr, xs_type_str);
return sdb_array_add_num (DB, var_global, xs_addr, 0); return sdb_array_add_num (DB, var_global, xs_addr, 0);
} }
R_API void r_anal_var_access_clear (RAnal *a, ut64 var_addr, int scope, int delta) { R_API void r_anal_var_access_clear(RAnal *a, ut64 var_addr, int scope, int delta) {
char key[128], key2[128]; char key[128], key2[128];
if (scope>0) { // local arg or var if (scope > 0) { // local arg or var
SETKEY ("var.0x%"PFMT64x".%d.%d.%s", var_addr, scope, delta, "writes"); SETKEY ("var.0x%"PFMT64x ".%d.%d.%s", var_addr, scope, delta, "writes");
SETKEY2 ("var.0x%"PFMT64x".%d.%d.%s", var_addr, scope, delta, "reads"); SETKEY2 ("var.0x%"PFMT64x ".%d.%d.%s", var_addr, scope, delta, "reads");
} else { // global } else { // global
SETKEY ("var.0x%"PFMT64x".%s", var_addr, "writes"); SETKEY ("var.0x%"PFMT64x ".%s", var_addr, "writes");
SETKEY2 ("var.0x%"PFMT64x".%s", var_addr, "reads"); SETKEY2 ("var.0x%"PFMT64x ".%s", var_addr, "reads");
} }
sdb_unset (DB, key, 0); sdb_unset (DB, key, 0);
sdb_unset (DB, key2, 0); sdb_unset (DB, key2, 0);
} }
R_API int r_anal_fcn_var_del_bydelta (RAnal *a, ut64 fna, const char kind, int scope, ut32 delta) { R_API int r_anal_fcn_var_del_bydelta(RAnal *a, ut64 fna, const char kind, int scope, ut32 delta) {
int idx; int idx;
char key[128], val[128], *v; char key[128], val[128], *v;
SETKEY("fcn.0x%08"PFMT64x".%c", fna, kind); SETKEY ("fcn.0x%08"PFMT64x ".%c", fna, kind);
v = sdb_itoa (delta, val, 10); v = sdb_itoa (delta, val, 10);
idx = sdb_array_indexof (DB, key, v, 0); idx = sdb_array_indexof (DB, key, v, 0);
if (idx != -1) { if (idx != -1) {
sdb_array_delete (DB, key, idx, 0); sdb_array_delete (DB, key, idx, 0);
SETKEY ("fcn.0x%08"PFMT64x".%c.%d", fna, kind, delta); SETKEY ("fcn.0x%08"PFMT64x ".%c.%d", fna, kind, delta);
sdb_unset (DB, key, 0); sdb_unset (DB, key, 0);
} }
return false; return false;
} }
R_API int r_anal_var_count(RAnal *a, RAnalFunction *fcn, int kind, int type) { R_API int r_anal_var_count(RAnal *a, RAnalFunction *fcn, int kind, int type) {
//local: type = 0 // local: type = 0
//arg: type = 1 // arg: type = 1
RList *list = r_anal_var_list (a, fcn, kind); RList *list = r_anal_var_list (a, fcn, kind);
RAnalVar *var; RAnalVar *var;
RListIter *iter; RListIter *iter;
int count[2] = {0}; int count[2] = {
0
};
r_list_foreach (list, iter, var) { r_list_foreach (list, iter, var) {
if (kind == R_ANAL_VAR_KIND_REG) { if (kind == R_ANAL_VAR_KIND_REG) {
count[1] ++; count[1]++;
continue; continue;
} }
count[(kind == R_ANAL_VAR_KIND_BPV && var->delta > 0) || (kind == R_ANAL_VAR_KIND_SPV && var->delta > fcn->maxstack)]++; count[(kind == R_ANAL_VAR_KIND_BPV && var->delta > 0) || (kind == R_ANAL_VAR_KIND_SPV && var->delta > fcn->maxstack)]++;
@ -483,7 +503,7 @@ R_API int r_anal_var_count(RAnal *a, RAnalFunction *fcn, int kind, int type) {
return count[type]; return count[type];
} }
static void var_add_structure_fields_to_list(RAnal *a, RAnalVar *av, const char* base_name, int delta, RList *list) { static void var_add_structure_fields_to_list(RAnal *a, RAnalVar *av, const char *base_name, int delta, RList *list) {
/* ATTENTION: av->name might be freed and reassigned */ /* ATTENTION: av->name might be freed and reassigned */
Sdb *TDB = a->sdb_types; Sdb *TDB = a->sdb_types;
const char *type_kind = sdb_const_get (TDB, av->type, 0); const char *type_kind = sdb_const_get (TDB, av->type, 0);
@ -492,13 +512,13 @@ static void var_add_structure_fields_to_list(RAnal *a, RAnalVar *av, const char*
int field_n, field_offset, field_count, field_size; int field_n, field_offset, field_count, field_size;
char *type_key = r_str_newf ("%s.%s", type_kind, av->type); char *type_key = r_str_newf ("%s.%s", type_kind, av->type);
for (field_n = 0; for (field_n = 0;
(field_name = sdb_array_get (TDB, type_key, field_n, NULL)); (field_name = sdb_array_get (TDB, type_key, field_n, NULL));
field_n++) { field_n++) {
field_key = r_str_newf ("%s.%s", type_key, field_name); field_key = r_str_newf ("%s.%s", type_key, field_name);
field_type = sdb_array_get (TDB, field_key, 0, NULL); field_type = sdb_array_get (TDB, field_key, 0, NULL);
field_offset = sdb_array_get_num (TDB, field_key, 1, NULL); field_offset = sdb_array_get_num (TDB, field_key, 1, NULL);
field_count = sdb_array_get_num (TDB, field_key, 2, NULL); field_count = sdb_array_get_num (TDB, field_key, 2, NULL);
field_size = r_anal_type_get_size (a, field_type) * (field_count ? field_count : 1); field_size = r_anal_type_get_size (a, field_type) * (field_count? field_count: 1);
new_name = r_str_newf ( "%s.%s", base_name, field_name); new_name = r_str_newf ( "%s.%s", base_name, field_name);
if (field_offset == 0) { if (field_offset == 0) {
free (av->name); free (av->name);
@ -531,20 +551,22 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
if (!a || !fcn) { if (!a || !fcn) {
return NULL; return NULL;
} }
list = r_list_new (); list = r_list_newf ((RListFree) r_anal_var_free);
if (kind < 1) { if (kind < 1) {
kind = R_ANAL_VAR_KIND_BPV; // by default show vars kind = R_ANAL_VAR_KIND_BPV; // by default show vars
} }
varlist = sdb_get (DB, sdb_fmt (0, "fcn.0x%"PFMT64x".%c", fcn->addr, kind), 0); varlist = sdb_get (DB, sdb_fmt (0, "fcn.0x%"PFMT64x ".%c", fcn->addr, kind), 0);
if (varlist) { if (varlist) {
char *next, *ptr = varlist; char *next, *ptr = varlist;
if (varlist && *varlist) { if (varlist && *varlist) {
do { do {
struct VarType vt = {0}; struct VarType vt = {
0
};
char *word = sdb_anext (ptr, &next); char *word = sdb_anext (ptr, &next);
const char *vardef = sdb_const_get (DB, sdb_fmt (1, const char *vardef = sdb_const_get (DB, sdb_fmt (1,
"var.0x%"PFMT64x".%c.%s", "var.0x%"PFMT64x ".%c.%s",
fcn->addr, kind, word), 0); fcn->addr, kind, word), 0);
if (word[2] == '_') { if (word[2] == '_') {
word[2] = '-'; word[2] = '-';
} }
@ -559,9 +581,9 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
return NULL; return NULL;
} }
if (!vt.name || !vt.type) { if (!vt.name || !vt.type) {
//This should be properly fixed // This should be properly fixed
eprintf ("Warning null var in fcn.0x%"PFMT64x".%c.%s\n", eprintf ("Warning null var in fcn.0x%"PFMT64x ".%c.%s\n",
fcn->addr, kind, word); fcn->addr, kind, word);
free (av); free (av);
continue; continue;
} }
@ -583,7 +605,19 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
} }
} }
free (varlist); free (varlist);
list->free = (RListFree)r_anal_var_free; return list;
}
R_API RList *r_anal_var_all_list(RAnal *anal, RAnalFunction *fcn) {
// r_anal_var_list if there are not vars with that kind returns a list with
// zero element
RList *list = r_anal_var_list (anal, fcn, R_ANAL_VAR_KIND_ARG);
if (!list) {
return NULL;
}
r_list_join (list, r_anal_var_list (anal, fcn, R_ANAL_VAR_KIND_REG));
r_list_join (list, r_anal_var_list (anal, fcn, R_ANAL_VAR_KIND_BPV));
r_list_join (list, r_anal_var_list (anal, fcn, R_ANAL_VAR_KIND_SPV));
return list; return list;
} }
@ -595,17 +629,17 @@ R_API RList *r_anal_var_list_dynamic(RAnal *a, RAnalFunction *fcn, int kind) {
return var_generate_list (a, fcn, kind, true); return var_generate_list (a, fcn, kind, true);
} }
static int var_comparator (const RAnalVar *a, const RAnalVar *b){ static int var_comparator(const RAnalVar *a, const RAnalVar *b){
//avoid NULL dereference // avoid NULL dereference
return (a && b) ? a->delta > b->delta : false; return (a && b)? a->delta > b->delta: false;
} }
R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int mode) { R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int mode) {
RList *list = r_anal_var_list (anal, fcn, kind); RList *list = r_anal_var_list (anal, fcn, kind);
r_list_sort (list, (RListComparator)var_comparator); r_list_sort (list, (RListComparator) var_comparator);
RAnalVar *var; RAnalVar *var;
RListIter *iter; RListIter *iter;
if (mode=='j') { if (mode == 'j') {
anal->cb_printf ("["); anal->cb_printf ("[");
} }
r_list_foreach (list, iter, var) { r_list_foreach (list, iter, var) {
@ -615,17 +649,17 @@ R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int m
switch (mode) { switch (mode) {
case '*': case '*':
// we cant express all type info here :( // we cant express all type info here :(
if (kind == R_ANAL_VAR_KIND_REG) { //registers if (kind == R_ANAL_VAR_KIND_REG) { // registers
RRegItem *i = r_reg_index_get (anal->reg, var->delta); RRegItem *i = r_reg_index_get (anal->reg, var->delta);
if (!i) { if (!i) {
eprintf ("Register not found"); eprintf ("Register not found");
break; break;
} }
anal->cb_printf ("afv%c %s %s %s @ 0x%"PFMT64x"\n", anal->cb_printf ("afv%c %s %s %s @ 0x%"PFMT64x "\n",
kind, i->name, var->name, var->type, fcn->addr); kind, i->name, var->name, var->type, fcn->addr);
} else { } else {
anal->cb_printf ("afv%c %d %s %s @ 0x%"PFMT64x"\n", anal->cb_printf ("afv%c %d %s %s @ 0x%"PFMT64x "\n",
kind, var->delta, var->name, var->type, kind, var->delta, var->name, var->type,
fcn->addr); fcn->addr);
} }
@ -636,18 +670,18 @@ R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int m
if (var->delta > 0) { if (var->delta > 0) {
anal->cb_printf ("{\"name\":\"%s\"," anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"arg\",\"type\":\"%s\",\"ref\":" "\"kind\":\"arg\",\"type\":\"%s\",\"ref\":"
"{\"base\":\"%s\", \"offset\":%"PFMT64d"}}", "{\"base\":\"%s\", \"offset\":%"PFMT64d "}}",
var->name, var->type,anal->reg->name[R_REG_NAME_BP], var->name, var->type, anal->reg->name[R_REG_NAME_BP],
var->delta); var->delta);
} else { } else {
anal->cb_printf ("{\"name\":\"%s\"," anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"var\",\"type\":\"%s\",\"ref\":" "\"kind\":\"var\",\"type\":\"%s\",\"ref\":"
"{\"base\":\"%s\", \"offset\":-%"PFMT64d"}}", "{\"base\":\"%s\", \"offset\":-%"PFMT64d "}}",
var->name, var->type,anal->reg->name[R_REG_NAME_BP], var->name, var->type, anal->reg->name[R_REG_NAME_BP],
-var->delta); -var->delta);
} }
break; break;
case R_ANAL_VAR_KIND_REG:{ case R_ANAL_VAR_KIND_REG: {
RRegItem *i = r_reg_index_get (anal->reg, var->delta); RRegItem *i = r_reg_index_get (anal->reg, var->delta);
if (!i) { if (!i) {
eprintf ("Register not found"); eprintf ("Register not found");
@ -656,25 +690,25 @@ R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int m
anal->cb_printf ("{\"name\":\"%s\"," anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"reg\",\"type\":\"%s\",\"ref\":\"%s\"}", "\"kind\":\"reg\",\"type\":\"%s\",\"ref\":\"%s\"}",
var->name, var->type, i->name, anal->reg->name[var->delta]); var->name, var->type, i->name, anal->reg->name[var->delta]);
} }
break; break;
case R_ANAL_VAR_KIND_SPV: case R_ANAL_VAR_KIND_SPV:
if (var->delta < fcn->maxstack) { if (var->delta < fcn->maxstack) {
anal->cb_printf ("{\"name\":\"%s\"," anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"arg\",\"type\":\"%s\",\"ref\":" "\"kind\":\"arg\",\"type\":\"%s\",\"ref\":"
"{\"base\":\"%s\", \"offset\":%"PFMT64d"}}", "{\"base\":\"%s\", \"offset\":%"PFMT64d "}}",
var->name, var->type,anal->reg->name[R_REG_NAME_SP], var->name, var->type, anal->reg->name[R_REG_NAME_SP],
var->delta); var->delta);
} else { } else {
anal->cb_printf ("{\"name\":\"%s\"," anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"var\",\"type\":\"%s\",\"ref\":" "\"kind\":\"var\",\"type\":\"%s\",\"ref\":"
"{\"base\":\"%s\", \"offset\":-%"PFMT64d"}}", "{\"base\":\"%s\", \"offset\":-%"PFMT64d "}}",
var->name, var->type,anal->reg->name[R_REG_NAME_SP], var->name, var->type, anal->reg->name[R_REG_NAME_SP],
var->delta); var->delta);
} }
break; break;
} }
if (iter->n) { if (iter->n) {
anal->cb_printf (","); anal->cb_printf (",");
} }
break; break;
@ -696,13 +730,13 @@ R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int m
case R_ANAL_VAR_KIND_REG: { case R_ANAL_VAR_KIND_REG: {
RRegItem *i = r_reg_index_get (anal->reg, var->delta); RRegItem *i = r_reg_index_get (anal->reg, var->delta);
if (!i) { if (!i) {
eprintf("Register not found"); eprintf ("Register not found");
break; break;
} }
anal->cb_printf ("reg %s %s @ %s\n", anal->cb_printf ("reg %s %s @ %s\n",
var->type, var->name, i->name); var->type, var->name, i->name);
} }
break; break;
case R_ANAL_VAR_KIND_SPV: case R_ANAL_VAR_KIND_SPV:
if (var->delta < fcn->maxstack) { if (var->delta < fcn->maxstack) {

View File

@ -291,7 +291,6 @@ typedef struct r_anal_type_function_t {
RList *fcn_locs; //sorted list of a function *.loc refs RList *fcn_locs; //sorted list of a function *.loc refs
//RList *locals; // list of local labels -> moved to anal->sdb_fcns //RList *locals; // list of local labels -> moved to anal->sdb_fcns
RList *bbs; RList *bbs;
RList *vars;
#if FCN_OLD #if FCN_OLD
RList *refs; RList *refs;
RList *xrefs; RList *xrefs;
@ -1433,6 +1432,7 @@ R_API RList *r_anal_reflines_fcn_get(struct r_anal_t *anal, RAnalFunction *fcn,
/* TODO move to r_core */ /* TODO move to r_core */
R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int mode); R_API void r_anal_var_list_show(RAnal *anal, RAnalFunction *fcn, int kind, int mode);
R_API RList *r_anal_var_list(RAnal *anal, RAnalFunction *fcn, int kind); R_API RList *r_anal_var_list(RAnal *anal, RAnalFunction *fcn, int kind);
R_API RList *r_anal_var_all_list(RAnal *anal, RAnalFunction *fcn);
R_API RList *r_anal_var_list_dynamic(RAnal *anal, RAnalFunction *fcn, int kind); R_API RList *r_anal_var_list_dynamic(RAnal *anal, RAnalFunction *fcn, int kind);
// calling conventions API // calling conventions API