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>
#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
#define FCN_DEPTH 512
@ -23,16 +23,16 @@
// 64KB max 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_JMP 10000
#define DB a->sdb_fcns
#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 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 VERBOSE_DELAY if(0)
#define VERBOSE_DELAY if (0)
#if USE_SDB_CACHE
static Sdb *HB = NULL;
@ -51,7 +51,7 @@ R_API const char *r_anal_fcn_type_tostring(int type) {
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;
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->xrefs);
#endif
//all functions are freed in anal->fcns
// all functions are freed in anal->fcns
fcn->fcn_locs = NULL;
if (fcn->bbs) {
fcn->bbs->free = (RListFree)r_anal_bb_free;
fcn->bbs->free = (RListFree) r_anal_bb_free;
r_list_free (fcn->bbs);
fcn->bbs = NULL;
}
@ -195,10 +195,10 @@ R_API int r_anal_fcn_xref_add(RAnal *a, RAnalFunction *fcn, ut64 at, ut64 addr,
}
#endif
#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 ?
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
return true;
}
@ -209,17 +209,17 @@ R_API int r_anal_fcn_xref_del(RAnal *a, RAnalFunction *fcn, ut64 at, ut64 addr,
RListIter *iter;
/* No need for _safe loop coz we return immediately after the delete. */
r_list_foreach (fcn->xrefs, iter, ref) {
if ((type != -1 || type == ref->type) &&
(at == 0LL || at == ref->at) &&
(addr == 0LL || addr == ref->addr)) {
r_list_delete (fcn->xrefs, iter);
return true;
if ((type != -1 || type == ref->type) &&
(at == 0LL || at == ref->at) &&
(addr == 0LL || addr == ref->addr)) {
r_list_delete (fcn->xrefs, iter);
return true;
}
}
#endif
#if FCN_SDB
// TODO
//sdb_array_delete_num (DB, key, at, 0);
// sdb_array_delete_num (DB, key, at, 0);
#endif
return false;
}
@ -239,7 +239,7 @@ static RAnalBlock *bbget(RAnalFunction *fcn, ut64 addr) {
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 ();
if (!bb) {
return NULL;
@ -257,11 +257,11 @@ static RAnalBlock* appendBasicBlock (RAnal *anal, RAnalFunction *fcn, ut64 addr)
}
#define FITFCNSZ() {\
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 (r_anal_fcn_size (fcn) > MAX_FCN_SIZE) { \
/* eprintf ("Function too big at 0x%"PFMT64x" + %d\n", bb->addr, fcn->size); */ \
r_anal_fcn_set_size (fcn, 0); \
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 (r_anal_fcn_size (fcn) > MAX_FCN_SIZE) {\
/* eprintf ("Function too big at 0x%"PFMT64x" + %d\n", bb->addr, fcn->size); */\
r_anal_fcn_set_size (fcn, 0);\
return R_ANAL_RET_ERROR; }
#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);
#define recurseAt(x) { \
ut8 *bbuf = malloc (MAXBBSIZE);\
anal->iob.read_at (anal->iob.io, x, bbuf, MAXBBSIZE); \
ret = fcn_recurse (anal, fcn, x, bbuf, MAXBBSIZE, depth - 1); \
update_tinyrange_bbs (fcn); \
free (bbuf); \
#define recurseAt(x) {\
ut8 *bbuf = malloc (MAXBBSIZE);\
anal->iob.read_at (anal->iob.io, x, bbuf, MAXBBSIZE);\
ret = fcn_recurse (anal, fcn, x, bbuf, MAXBBSIZE, depth - 1);\
update_tinyrange_bbs (fcn);\
free (bbuf);\
}
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;
}
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)) {
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) {
ut64 offs, oplen;
RAnalOp op = {0};
RAnalOp op = {
0
};
ut64 ret = UT64_MAX;
for (offs = 0; offs < len; offs += oplen) {
r_anal_op_fini (&op);
if ((oplen = r_anal_op (anal, &op, addr + offs, buf + offs, len - offs)) < 1) {
break;
}
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.dst && op.dst->reg && op.dst->reg->name && !strcmp (op.dst->reg->name, regsz)) {
if (op.src[0]) {
ret = op.src[0]->delta;
}
}
}
return ret;
}
#define gotoBeach(x) ret=x;goto beach;
#define gotoBeach(x) ret = x; goto beach;
#define gotoBeachRet() goto beach;
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;
addr = ptr_end;
while ((*addr != '0' || *(addr + 1) != 'x') &&
addr >= esil_buf + 1 && *addr != ',' ) {
addr >= esil_buf + 1 && *addr != ',') {
addr--;
}
if (strncmp (addr, "0x", 2)) {
@ -399,9 +403,9 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
free (esil_buf);
return;
}
ptr = (st64)r_num_get (NULL, addr);
if(*sign =='+') {
if (ptr < fcn->maxstack && type == 's') {
ptr = (st64) r_num_get (NULL, addr);
if (*sign == '+') {
if (ptr < fcn->maxstack && type == 's') {
varname = get_varname (anal, fcn, type, VARPREFIX, R_ABS (ptr));
} else {
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 {
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_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);
@ -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) {
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_SP], "+", 's');
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, "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) {
int i;
ut64 dst;
st32 jmptbl[32] = {0};
anal->iob.read_at (anal->iob.io, ptr, (ut8*)&jmptbl, 32);
st32 jmptbl[32] = {
0
};
anal->iob.read_at (anal->iob.io, ptr, (ut8 *) &jmptbl, 32);
// XXX this is not endian safe
for (i = 0; i < 4; i++) {
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;
}
//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,
char *tmp_buf, int oplen, int un_idx, int *idx) {
//this step is required in order to prevent infinite recursion in some cases
char *tmp_buf, int oplen, int un_idx, int *idx) {
// this step is required in order to prevent infinite recursion in some cases
if ((addr + un_idx - oplen) == fcn->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);
@ -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) {
RAnalOp op = {0};
RAnalOp op = {
0
};
int oplen, idx = 0;
while (idx < len) {
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_JMP:
// eprintf ("CASE AT 0x%llx size %d\n", addr, idx + oplen);
eprintf ("afb+ 0x%"PFMT64x" 0x%"PFMT64x" %d\n",
fcn->addr, addr, idx + oplen);
eprintf ("afbe 0x%"PFMT64x" 0x%"PFMT64x"\n",
addr_bbsw, addr);
eprintf ("afb+ 0x%"PFMT64x " 0x%"PFMT64x " %d\n",
fcn->addr, addr, idx + oplen);
eprintf ("afbe 0x%"PFMT64x " 0x%"PFMT64x "\n",
addr_bbsw, addr);
return 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) {
ut8 buf[1024];
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++) {
anal->iob.read_at (anal->iob.io, at, buf, sizeof (buf));
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 overlapped = 0;
char *varname;
RAnalOp op = {0};
RAnalOp op = {
0
};
int oplen, idx = 0;
struct {
int cnt;
@ -533,7 +543,9 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
int pending;
int adjust;
int un_idx; // delay.un_idx
} delay = {0};
} delay = {
0
};
char tmp_buf[MAX_FLG_NAME_SIZE + 5] = "skip";
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 //:
if (!anal->iob.is_valid_offset (anal->iob.io, addr, 0)) {
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
}
@ -570,14 +582,14 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
bb = appendBasicBlock (anal, fcn, addr);
VERBOSE_ANAL eprintf ("Append bb at 0x%08"PFMT64x
" (fcn 0x%08"PFMT64x")\n", addr, fcn->addr);
VERBOSE_ANAL eprintf("Append bb at 0x%08"PFMT64x
" (fcn 0x%08"PFMT64x ")\n", addr, fcn->addr);
bool last_is_push = false;
ut64 last_push_addr = UT64_MAX;
while (idx < len) {
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;
}
}
@ -587,14 +599,14 @@ repeat:
}
r_anal_op_fini (&op);
if (isInvalidMemory (buf + idx, len - idx)) {
FITFCNSZ();
VERBOSE_ANAL eprintf ("FFFF opcode at 0x%08"PFMT64x"\n", addr+idx);
FITFCNSZ ();
VERBOSE_ANAL eprintf("FFFF opcode at 0x%08"PFMT64x "\n", addr + idx);
return R_ANAL_RET_ERROR;
}
// check if opcode is in another basic block
// in that case we break
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) {
gotoBeach (R_ANAL_RET_END);
} else {
@ -606,16 +618,16 @@ repeat:
if (bbg && bbg != bb) {
bb->jump = addr + idx;
overlapped = 1;
VERBOSE_ANAL eprintf ("Overlapped at 0x%08"PFMT64x"\n", addr + idx);
//return R_ANAL_RET_END;
VERBOSE_ANAL eprintf("Overlapped at 0x%08"PFMT64x "\n", addr + idx);
// return R_ANAL_RET_END;
}
}
if (!overlapped) {
r_anal_bb_set_offset (bb, bb->ninstr++, addr + idx - bb->addr);
bb->size += oplen;
fcn->ninstr++;
// FITFCNSZ(); // defer this, in case this instruction is a branch delay entry
// fcn->size += oplen; /// XXX. must be the sum of all the bblocks
// FITFCNSZ(); // defer this, in case this instruction is a branch delay entry
// fcn->size += oplen; /// XXX. must be the sum of all the bblocks
}
idx += oplen;
delay.un_idx = idx;
@ -625,7 +637,7 @@ repeat:
// Save the location of it in `delay.idx`
// note, we have still increased size of basic block
// (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.cnt = op.delay;
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.
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;
idx = delay.idx;
// At this point, we are still looking at the
@ -648,16 +660,16 @@ repeat:
// the branch delay.
}
} 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
// But we also already counted this instruction in the
// size of the current basic block, so we need to fix that
if (delay.adjust) {
bb->size -= oplen;
fcn->ninstr--;
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));
FITFCNSZ();
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));
FITFCNSZ ();
}
// Next time, we go to the opcode after the delay count
// Take care not to use this below, use delay.un_idx instead ...
@ -682,10 +694,10 @@ repeat:
break;
// TODO: use fcn->maxstack to know our stackframe
case R_ANAL_STACK_SET:
if ((int)op.ptr > 0) {
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS(op.ptr));
if ((int) op.ptr > 0) {
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS (op.ptr));
} 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_access (anal, fcn->addr, 'b', 1, op.ptr, 1, op.addr);
@ -693,12 +705,12 @@ repeat:
break;
// TODO: use fcn->maxstack to know our stackframe
case R_ANAL_STACK_GET:
if (((int)op.ptr) > 0) {
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS(op.ptr));
if (((int) op.ptr) > 0) {
varname = get_varname (anal, fcn, 'b', ARGPREFIX, R_ABS (op.ptr));
} 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);
free (varname);
break;
@ -711,9 +723,9 @@ repeat:
switch (op.type & R_ANAL_OP_TYPE_MASK) {
case R_ANAL_OP_TYPE_MOV:
//skip mov reg,reg
if (anal->opt.hpskip && regs_exist(op.src[0], op.dst)
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
// skip mov reg,reg
if (anal->opt.hpskip && regs_exist (op.src[0], op.dst)
&& !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);
if (skip_ret == 1) {
goto repeat;
@ -724,9 +736,9 @@ repeat:
}
break;
case R_ANAL_OP_TYPE_LEA:
//skip lea reg,[reg]
if (anal->opt.hpskip && regs_exist(op.src[0], op.dst)
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
// skip lea reg,[reg]
if (anal->opt.hpskip && regs_exist (op.src[0], op.dst)
&& !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);
if (skip_ret == 1) {
goto repeat;
@ -737,10 +749,10 @@ repeat:
}
if (anal->opt.jmptbl) {
if (is_delta_pointer_table (anal, op.ptr)) {
anal->cb_printf ("pxt. 0x%08"PFMT64x" @ 0x%08"PFMT64x"\n", op.addr, op.ptr);
//jmptbl_addr = op.ptr;
//jmptbl_size = -1;
//ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, op.ptr, 4);
anal->cb_printf ("pxt. 0x%08"PFMT64x " @ 0x%08"PFMT64x "\n", op.addr, op.ptr);
// jmptbl_addr = op.ptr;
// jmptbl_size = -1;
// ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, op.ptr, 4);
}
}
break;
@ -778,7 +790,7 @@ repeat:
case R_ANAL_OP_TYPE_NOP:
if (anal->opt.nopskip) {
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
RFlagItem *fi = anal->flb.get_at (anal->flb.f, addr, false);
if (!fi || strncmp (fi->name, "sym.", 4)) {
@ -832,7 +844,7 @@ repeat:
must_eob = s != d;
}
if (must_eob) {
FITFCNSZ();
FITFCNSZ ();
op.jump = UT64_MAX;
recurseAt (op.jump);
recurseAt (op.fail);
@ -844,7 +856,7 @@ repeat:
#if FIX_JMP_FWD
bb->jump = op.jump;
bb->fail = UT64_MAX;
FITFCNSZ();
FITFCNSZ ();
return R_ANAL_RET_END;
#else
if (!overlapped) {
@ -852,7 +864,7 @@ repeat:
bb->fail = UT64_MAX;
}
recurseAt (op.jump);
FITFCNSZ();
FITFCNSZ ();
gotoBeachRet ();
#endif
} else {
@ -867,14 +879,14 @@ repeat:
bb->jump = op.jump;
bb->fail = UT64_MAX;
}
FITFCNSZ();
FITFCNSZ ();
return R_ANAL_RET_END;
#else
// hardcoded jmp size // must be checked at the end wtf?
// always fitfcnsz and retend
if (r_anal_fcn_is_in_offset (fcn, op.jump)) {
/* jump inside the same function */
FITFCNSZ();
FITFCNSZ ();
return R_ANAL_RET_END;
#if JMP_IS_EOB_RANGE > 0
} else {
@ -894,7 +906,7 @@ repeat:
bb->jump = op.jump;
bb->fail = UT64_MAX;
}
FITFCNSZ();
FITFCNSZ ();
return R_ANAL_RET_END;
}
}
@ -921,7 +933,7 @@ repeat:
bb->jump = op.jump;
bb->fail = UT64_MAX;
}
FITFCNSZ();
FITFCNSZ ();
recurseAt (op.jump);
recurseAt (op.fail);
return R_ANAL_RET_END;
@ -931,11 +943,11 @@ repeat:
if (op.jump > fcn->addr + JMP_IS_EOB_RANGE) {
recurseAt (op.fail);
/* jump inside the same function */
FITFCNSZ();
FITFCNSZ ();
return R_ANAL_RET_END;
#if JMP_IS_EOB_RANGE > 0
} 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);
}
if (op.jump > addr + JMP_IS_EOB_RANGE) {
@ -955,7 +967,7 @@ repeat:
bb->jump = op.jump;
bb->fail = UT64_MAX;
}
FITFCNSZ();
FITFCNSZ ();
return R_ANAL_RET_END;
}
}
@ -980,7 +992,7 @@ repeat:
return R_ANAL_RET_END;
}
// 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;
case R_ANAL_OP_TYPE_CCALL:
case R_ANAL_OP_TYPE_CALL:
@ -990,7 +1002,7 @@ repeat:
r_anal_op_fini (&op);
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
recurseAt (op.jump);
recurseAt (op.fail);
@ -1008,10 +1020,10 @@ repeat:
RAnalRef *last_ref = fcn->refs->tail->data;
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);
} else { // indirect jump: table pointer is unknown
} else { // indirect jump: table pointer is unknown
if (op.src[0] && op.src[0]->reg) {
ut64 ptr = search_reg_val (anal, buf, idx, addr, op.src[0]->reg->name);
if (ptr && ptr != UT64_MAX) {
@ -1032,7 +1044,9 @@ repeat:
}
if (anal->cur->arch && strstr (anal->cur->arch, "arm")) {
if (anal->bits == 64) {
if (!in_plt) goto river;
if (!in_plt) {
goto river;
}
}
} else {
if (in_plt) {
@ -1046,12 +1060,12 @@ repeat:
return R_ANAL_RET_END;
river:
break;
/* fallthru */
/* fallthru */
case R_ANAL_OP_TYPE_PUSH:
last_is_push = true;
last_push_addr = op.val;
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;
case R_ANAL_OP_TYPE_RET:
@ -1066,9 +1080,9 @@ river:
gotoBeachRet ();
} else {
if (!op.cond) {
VERBOSE_ANAL eprintf ("RET 0x%08"PFMT64x". %d %d %d\n",
addr + delay.un_idx-oplen, overlapped,
bb->size, r_anal_fcn_size (fcn));
VERBOSE_ANAL eprintf("RET 0x%08"PFMT64x ". %d %d %d\n",
addr + delay.un_idx - oplen, overlapped,
bb->size, r_anal_fcn_size (fcn));
FITFCNSZ ();
r_anal_op_fini (&op);
return R_ANAL_RET_END;
@ -1090,22 +1104,24 @@ static int check_preludes(ut8 *buf, ut16 bufsz) {
if (bufsz < 10) {
return false;
}
if (!memcmp (buf, (const ut8 *)"\x55\x89\xe5", 3)) {
if (!memcmp (buf, (const ut8 *) "\x55\x89\xe5", 3)) {
return true;
} else if (!memcmp (buf, (const ut8 *)"\x55\x8b\xec", 3)) {
} else if (!memcmp (buf, (const ut8 *) "\x55\x8b\xec", 3)) {
return true;
} else if (!memcmp (buf, (const ut8 *)"\x8b\xff", 2)) {
} else if (!memcmp (buf, (const ut8 *) "\x8b\xff", 2)) {
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;
} 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 false;
}
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;
if (check_preludes (buf, bufsz)) {
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);
}
static void fcnfit (RAnal *a, RAnalFunction *f) {
static void fcnfit(RAnal *a, RAnalFunction *f) {
// find next function
RAnalFunction *next = r_anal_fcn_next (a, f->addr);
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_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) {
fcnfit (anal, fcn);
} 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);
/* defines fcn. or loc. prefix */
fcn->type = (reftype == R_ANAL_REF_TYPE_CODE)
? R_ANAL_FCN_TYPE_LOC
? R_ANAL_FCN_TYPE_LOC
: R_ANAL_FCN_TYPE_FCN;
if (fcn->addr == UT64_MAX) {
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;
ret = fcn_recurse (anal, fcn, addr, buf, len, FCN_DEPTH);
//update tinyrange for the function
// update tinyrange for the function
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;
RAnalBlock *bb;
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) {
endaddr += bb->size;
} else if (endaddr < bb->addr &&
bb->addr - endaddr <
anal->opt.bbs_alignment &&
!(bb->addr &
(anal->opt.bbs_alignment - 1))) {
bb->addr - endaddr <
anal->opt.bbs_alignment &&
!(bb->addr &
(anal->opt.bbs_alignment - 1))) {
endaddr = bb->addr + bb->size;
} else {
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);
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);
if (f) {
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) {
#if USE_NEW_FCN_STORE
// 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);
#else
RAnalFunction *fcn, *ret = NULL;
RListIter *iter;
if (type == R_ANAL_FCN_TYPE_ROOT) {
r_list_foreach (anal->fcns, iter, fcn) {
if (addr == fcn->addr)
if (addr == fcn->addr) {
return fcn;
}
}
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
#warning TODO: r_anal_get_fcn_in_bounds
// 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);
#else
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) {
//eprintf ("Basic Block overlaps another one that should be shrinked\n");
// eprintf ("Basic Block overlaps another one that should be shrinked\n");
if (bbi) {
/* shrink overlapped basic block */
bbi->size = addr - (bbi->addr);
@ -1533,14 +1550,14 @@ R_API int r_anal_fcn_bb_overlaps(RAnalFunction *fcn, RAnalBlock *bb) {
RAnalBlock *bbi;
RListIter *iter;
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->jump = bbi->addr;
bb->fail = -1;
bb->conditional = false;
if (bbi->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 {
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) {
/*
CC = E - N + 2P
E = the number of edges of the graph.
N = the number of nodes of the graph.
P = the number of connected components (exit nodes).
*/
CC = E - N + 2P
E = the number of edges of the graph.
N = the number of nodes of the graph.
P = the number of connected components (exit nodes).
*/
int E = 0, N = 0, P = 0;
RListIter *iter;
RAnalBlock *bb;
@ -1576,7 +1593,7 @@ R_API int r_anal_fcn_cc(RAnalFunction *fcn) {
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;
}
@ -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) {
#if USE_NEW_FCN_STORE
// 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);
#else
RAnalFunction *fcn, *ret = NULL;
@ -1638,8 +1655,8 @@ R_API RAnalFunction *r_anal_fcn_next(RAnal *anal, ut64 addr) {
RListIter *iter;
RAnalFunction *closer = NULL;
r_list_foreach (anal->fcns, iter, fcni) {
//if (fcni->addr == addr)
if (fcni->addr > addr && (!closer || fcni->addr<closer->addr)) {
// if (fcni->addr == addr)
if (fcni->addr > addr && (!closer || fcni->addr < closer->addr)) {
closer = fcni;
}
}
@ -1648,14 +1665,17 @@ R_API RAnalFunction *r_anal_fcn_next(RAnal *anal, ut64 addr) {
/* getters */
#if FCN_OLD
R_API RList* r_anal_fcn_get_refs (RAnalFunction *anal) { return anal->refs; }
R_API RList* r_anal_fcn_get_xrefs (RAnalFunction *anal) { return anal->xrefs; }
R_API RList* r_anal_fcn_get_vars (RAnalFunction *anal) { return anal->vars; }
R_API RList *r_anal_fcn_get_refs(RAnalFunction *fcn) {
return fcn->refs;
}
R_API RList *r_anal_fcn_get_xrefs(RAnalFunction *fcn) {
return fcn->xrefs;
}
#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
//anal->bbs->rc++;
// anal->bbs->rc++;
anal->bbs->free = NULL;
return anal->bbs;
}
@ -1671,7 +1691,7 @@ R_API int r_anal_fcn_is_in_offset(RAnalFunction *fcn, ut64 addr) {
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;
RAnalFunction *fcni;
RListIter *iter;
@ -1718,7 +1738,7 @@ R_API void r_anal_fcn_set_size(RAnalFunction *fcn, ut32 size) {
/* returns the size of the function.
* IMPORTANT: this will change, one day, because it doesn't have much sense */
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
@ -1740,16 +1760,16 @@ R_API ut32 r_anal_fcn_realsize(const RAnalFunction *fcn) {
return sz;
}
//continious function size without loc.*
// continious function size without loc.*
R_API ut32 r_anal_fcn_contsize(const RAnalFunction *fcn) {
RListIter *iter;
RAnalBlock *bb;
ut32 sz = 0;
r_list_foreach (fcn->bbs, iter, bb) {
/* 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.
* Another way to remove this is to throw away BBs before the function
* entry point at the analysis time in the r_anal_fcn. */
* able to handle BBs that comes before the function emtry point.
* Another way to remove this is to throw away BBs before the function
* entry point at the analysis time in the r_anal_fcn. */
if (bb->addr >= fcn->addr) {
sz += bb->size;
}
@ -1769,11 +1789,11 @@ R_API ut32 r_anal_fcn_cost(RAnal *anal, RAnalFunction *fcn) {
RAnalOp op;
ut64 at, end = bb->addr + 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;
for (at = bb->addr; at < end; ) {
for (at = bb->addr; at < end;) {
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) {
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;
}
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) {
// convert to C text... maybe that should be in format string..
return NULL;

View File

@ -16,10 +16,10 @@ struct VarType {
#define SDB_VARTYPE_FMT "czdz"
#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 SETKEY2(x,y...) snprintf (key2, sizeof (key)-1, x, ##y);
#define SETVAL(x,y...) snprintf (val, sizeof (val)-1, x, ##y);
#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 SETKEY2(x, y ...) snprintf (key2, sizeof (key) - 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) {
char *fmt = r_anal_type_format (anal, type);
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);
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) {
char *sign = "";
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 = "_";
}
/* local variable */
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 *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", addr, scope, name);
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 *name_key = sdb_fmt (3, "var.0x%"PFMT64x ".%d.%s", addr, scope, name);
char *shortvar = sdb_fmt (4, "%d.%s%d", scope, sign, delta);
sdb_array_add (DB, fcn_key, shortvar, 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 {
/* global variable */
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);
}
// ls_sort (DB->ht->list, mystrcmp);
// ls_sort (DB->ht->list, mystrcmp);
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);
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) {
char *sign = "";
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 = "_";
}
/* local variable */
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 *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", fcn->addr, scope, name);
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 *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 *name_val = sdb_fmt (5, "%c,%d", kind, delta);
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 *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")) {
char *field, *field_key, *field_type;
int field_n, field_offset;
char *type_key = r_str_newf ("%s.%s", type_kind, type);
for (field_n = 0;
(field = sdb_array_get (TDB, type_key, field_n, NULL));
field_n++) {
(field = sdb_array_get (TDB, type_key, field_n, NULL));
field_n++) {
field_key = r_str_newf ("%s.%s", type_key, field);
field_type = sdb_array_get (TDB, field_key, 0, 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;
RList *list = r_anal_var_list (a, fcn, kind);
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_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) {
RAnalVar *av = r_anal_var_get (a, addr, kind, scope, delta);
if (!av) return false;
if (!av) {
return false;
}
if (scope > 0) {
char *sign = "";
if (delta < 0) {
delta = -delta;
sign = "_";
}
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 *name_key = sdb_fmt (3, "var.0x%"PFMT64x".%d.%s", addr, scope, av->name);
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 *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);
sdb_array_remove (DB, fcn_key, shortvar, 0);
sdb_unset (DB, var_key, 0);
sdb_unset (DB, name_key, 0);
if (*sign) delta = -delta;
if (*sign) {
delta = -delta;
}
} else {
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);
}
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) {
return false;
}
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) {
char *next, *ptr = 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 *sign = strstr (word, "_");
const char *vardef = sdb_const_get (DB, sdb_fmt (1,
"var.0x%"PFMT64x".%c.%s",
fcn->addr, kind, word), 0);
"var.0x%"PFMT64x ".%c.%s",
fcn->addr, kind, word), 0);
if (sign) {
*sign = '-';
}
int delta = strlen (word) < 3 ? -1 : atoi (word + 2);
int delta = strlen (word) < 3? -1: atoi (word + 2);
if (vardef) {
const char *p = strchr (vardef, ',');
if (p) {
@ -273,11 +277,11 @@ R_API bool r_anal_var_delete_byname(RAnal *a, RAnalFunction *fcn, int kind, cons
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) {
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);
if (!name_value) {
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) {
RAnalVar *av;
struct VarType vt = { 0 };
struct VarType vt = {
0
};
char *sign = "";
RAnalFunction *fcn = r_anal_get_fcn_in (a, addr, 0);
if (!fcn) {
@ -303,7 +309,7 @@ R_API RAnalVar *r_anal_var_get(RAnal *a, ut64 addr, char kind, int scope, int de
sign = "_";
}
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);
if (*sign) {
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->scope = scope;
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->type = vt.type? strdup (vt.type) : strdup ("unkown_type");
av->type = vt.type? strdup (vt.type): strdup ("unkown_type");
av->kind = kind;
sdb_fmt_free (&vt, SDB_VARTYPE_FMT);
// TODO:
@ -352,12 +358,24 @@ R_API int r_anal_var_check_name(const char *name) {
// restrict length
// name is not base64'd . because no specials can be contained
// TODO: check that new_name is valid. this is a hack
if (*name=='0' || atoi (name)>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;
if (*name == '0' || atoi (name) > 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;
}
@ -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);
RAnalVar *v1 = r_anal_var_get_byname (a, fcn, new_name);
if(v1) {
if (v1) {
r_anal_var_free (v1);
eprintf ("variable or arg with name `%s` already exist\n", new_name);
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.
if (scope > 0) { // local
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 *comma = strchr (name_val, ',');
if (comma) {
delta = r_num_math (NULL, comma + 1);
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);
free (name_val);
if (delta < 0) {
delta = -delta;
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);
}
} else { // global
@ -419,62 +437,64 @@ R_API int r_anal_var_rename(RAnal *a, ut64 var_addr, int scope, char kind, const
}
// 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 *xs_type_str = xs_type? "writes": "reads";
// TODO: kind is not used
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);
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 *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,
kind, scope, delta);
sdb_set (DB, inst_key, var_def, 0);
return sdb_array_add_num (DB, var_local, xs_addr, 0);
}
// global
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);
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);
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];
if (scope>0) { // local arg or var
SETKEY ("var.0x%"PFMT64x".%d.%d.%s", var_addr, scope, delta, "writes");
SETKEY2 ("var.0x%"PFMT64x".%d.%d.%s", var_addr, scope, delta, "reads");
if (scope > 0) { // local arg or var
SETKEY ("var.0x%"PFMT64x ".%d.%d.%s", var_addr, scope, delta, "writes");
SETKEY2 ("var.0x%"PFMT64x ".%d.%d.%s", var_addr, scope, delta, "reads");
} else { // global
SETKEY ("var.0x%"PFMT64x".%s", var_addr, "writes");
SETKEY2 ("var.0x%"PFMT64x".%s", var_addr, "reads");
SETKEY ("var.0x%"PFMT64x ".%s", var_addr, "writes");
SETKEY2 ("var.0x%"PFMT64x ".%s", var_addr, "reads");
}
sdb_unset (DB, key, 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;
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);
idx = sdb_array_indexof (DB, key, v, 0);
if (idx != -1) {
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);
}
return false;
}
R_API int r_anal_var_count(RAnal *a, RAnalFunction *fcn, int kind, int type) {
//local: type = 0
//arg: type = 1
// local: type = 0
// arg: type = 1
RList *list = r_anal_var_list (a, fcn, kind);
RAnalVar *var;
RListIter *iter;
int count[2] = {0};
int count[2] = {
0
};
r_list_foreach (list, iter, var) {
if (kind == R_ANAL_VAR_KIND_REG) {
count[1] ++;
count[1]++;
continue;
}
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];
}
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 */
Sdb *TDB = a->sdb_types;
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;
char *type_key = r_str_newf ("%s.%s", type_kind, av->type);
for (field_n = 0;
(field_name = sdb_array_get (TDB, type_key, field_n, NULL));
field_n++) {
(field_name = sdb_array_get (TDB, type_key, field_n, NULL));
field_n++) {
field_key = r_str_newf ("%s.%s", type_key, field_name);
field_type = sdb_array_get (TDB, field_key, 0, NULL);
field_offset = sdb_array_get_num (TDB, field_key, 1, 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);
if (field_offset == 0) {
free (av->name);
@ -531,20 +551,22 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
if (!a || !fcn) {
return NULL;
}
list = r_list_new ();
list = r_list_newf ((RListFree) r_anal_var_free);
if (kind < 1) {
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) {
char *next, *ptr = varlist;
if (varlist && *varlist) {
do {
struct VarType vt = {0};
struct VarType vt = {
0
};
char *word = sdb_anext (ptr, &next);
const char *vardef = sdb_const_get (DB, sdb_fmt (1,
"var.0x%"PFMT64x".%c.%s",
fcn->addr, kind, word), 0);
"var.0x%"PFMT64x ".%c.%s",
fcn->addr, kind, word), 0);
if (word[2] == '_') {
word[2] = '-';
}
@ -559,9 +581,9 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
return NULL;
}
if (!vt.name || !vt.type) {
//This should be properly fixed
eprintf ("Warning null var in fcn.0x%"PFMT64x".%c.%s\n",
fcn->addr, kind, word);
// This should be properly fixed
eprintf ("Warning null var in fcn.0x%"PFMT64x ".%c.%s\n",
fcn->addr, kind, word);
free (av);
continue;
}
@ -583,7 +605,19 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind, bool dyn
}
}
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;
}
@ -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);
}
static int var_comparator (const RAnalVar *a, const RAnalVar *b){
//avoid NULL dereference
return (a && b) ? a->delta > b->delta : false;
static int var_comparator(const RAnalVar *a, const RAnalVar *b){
// avoid NULL dereference
return (a && b)? a->delta > b->delta: false;
}
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);
r_list_sort (list, (RListComparator)var_comparator);
r_list_sort (list, (RListComparator) var_comparator);
RAnalVar *var;
RListIter *iter;
if (mode=='j') {
if (mode == 'j') {
anal->cb_printf ("[");
}
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) {
case '*':
// 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);
if (!i) {
eprintf ("Register not found");
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);
} 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,
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) {
anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"arg\",\"type\":\"%s\",\"ref\":"
"{\"base\":\"%s\", \"offset\":%"PFMT64d"}}",
var->name, var->type,anal->reg->name[R_REG_NAME_BP],
"{\"base\":\"%s\", \"offset\":%"PFMT64d "}}",
var->name, var->type, anal->reg->name[R_REG_NAME_BP],
var->delta);
} else {
anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"var\",\"type\":\"%s\",\"ref\":"
"{\"base\":\"%s\", \"offset\":-%"PFMT64d"}}",
var->name, var->type,anal->reg->name[R_REG_NAME_BP],
"{\"base\":\"%s\", \"offset\":-%"PFMT64d "}}",
var->name, var->type, anal->reg->name[R_REG_NAME_BP],
-var->delta);
}
break;
case R_ANAL_VAR_KIND_REG:{
case R_ANAL_VAR_KIND_REG: {
RRegItem *i = r_reg_index_get (anal->reg, var->delta);
if (!i) {
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\","
"\"kind\":\"reg\",\"type\":\"%s\",\"ref\":\"%s\"}",
var->name, var->type, i->name, anal->reg->name[var->delta]);
}
}
break;
case R_ANAL_VAR_KIND_SPV:
if (var->delta < fcn->maxstack) {
anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"arg\",\"type\":\"%s\",\"ref\":"
"{\"base\":\"%s\", \"offset\":%"PFMT64d"}}",
var->name, var->type,anal->reg->name[R_REG_NAME_SP],
"{\"base\":\"%s\", \"offset\":%"PFMT64d "}}",
var->name, var->type, anal->reg->name[R_REG_NAME_SP],
var->delta);
} else {
anal->cb_printf ("{\"name\":\"%s\","
"\"kind\":\"var\",\"type\":\"%s\",\"ref\":"
"{\"base\":\"%s\", \"offset\":-%"PFMT64d"}}",
var->name, var->type,anal->reg->name[R_REG_NAME_SP],
"{\"base\":\"%s\", \"offset\":-%"PFMT64d "}}",
var->name, var->type, anal->reg->name[R_REG_NAME_SP],
var->delta);
}
break;
}
if (iter->n) {
if (iter->n) {
anal->cb_printf (",");
}
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: {
RRegItem *i = r_reg_index_get (anal->reg, var->delta);
if (!i) {
eprintf("Register not found");
eprintf ("Register not found");
break;
}
anal->cb_printf ("reg %s %s @ %s\n",
var->type, var->name, i->name);
}
}
break;
case R_ANAL_VAR_KIND_SPV:
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 *locals; // list of local labels -> moved to anal->sdb_fcns
RList *bbs;
RList *vars;
#if FCN_OLD
RList *refs;
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 */
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_all_list(RAnal *anal, RAnalFunction *fcn);
R_API RList *r_anal_var_list_dynamic(RAnal *anal, RAnalFunction *fcn, int kind);
// calling conventions API