Better vars naming, Add e cmd.fcn.{new|rename|delete}

- Bump sdb from git
This commit is contained in:
pancake 2015-03-16 02:52:26 +01:00
parent 813d13d589
commit d991769935
13 changed files with 326 additions and 199 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2014 - pancake, nibble */ /* radare - LGPL - Copyright 2009-2015 - pancake, nibble */
#include <r_anal.h> #include <r_anal.h>
#include <r_util.h> #include <r_util.h>

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2014 - nibble, pancake */ /* radare - LGPL - Copyright 2010-2015 - nibble, pancake */
#include <r_anal.h> #include <r_anal.h>
#include <r_util.h> #include <r_util.h>
@ -175,17 +175,17 @@ static int bbsum(RAnalFunction *fcn) {
} }
#endif #endif
static RAnalBlock* appendBasicBlock (RAnalFunction *fcn, ut64 addr) { static RAnalBlock* appendBasicBlock (RAnal *anal, RAnalFunction *fcn, ut64 addr) {
RAnalBlock *bb; RAnalBlock *bb;
#if 0 #if 0
RListIter *iter; RListIter *iter;
// TODO: check if its already there
r_list_foreach (fcn->bbs, iter, bb) { r_list_foreach (fcn->bbs, iter, bb) {
if (bb->addr == addr) if (bb->addr == addr)
return bb; return bb;
} }
#endif #endif
// TODO: echeck if its already there bb = r_anal_bb_new ();
bb = r_anal_bb_new();
if (!bb) return NULL; if (!bb) return NULL;
bb->addr = addr; bb->addr = addr;
bb->size = 0; bb->size = 0;
@ -193,6 +193,9 @@ static RAnalBlock* appendBasicBlock (RAnalFunction *fcn, ut64 addr) {
bb->fail = UT64_MAX; bb->fail = UT64_MAX;
bb->type = 0; // TODO bb->type = 0; // TODO
r_list_append (fcn->bbs, bb); r_list_append (fcn->bbs, bb);
if (anal->cb.on_fcn_bb_new) {
anal->cb.on_fcn_bb_new (anal, anal->user, fcn, bb);
}
return bb; return bb;
} }
//fcn->addr += n; fcn->size -= n; } else //fcn->addr += n; fcn->size -= n; } else
@ -206,6 +209,20 @@ static RAnalBlock* appendBasicBlock (RAnalFunction *fcn, ut64 addr) {
#define MAXBBSIZE 8096 #define MAXBBSIZE 8096
#define VARPREFIX "local"
//#define VARPREFIX "var"
#define ARGPREFIX "arg"
static char *get_varname (RAnal *a, const char *pfx, int idx) {
char *s;
int word = a->bits / 8;
if (idx%word) {
s = r_str_newf ("%s_%d_%d", pfx, idx/word, R_ABS(idx%word));
} else {
s = r_str_newf ("%s_%d", pfx, idx/word);
}
return s;
}
#define gotoBeach(x) ret=x;goto beach; #define gotoBeach(x) ret=x;goto beach;
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) {
int continue_after_jump = anal->afterjmp; int continue_after_jump = anal->afterjmp;
@ -239,13 +256,13 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
#endif #endif
bb = bbget (fcn, addr); bb = bbget (fcn, addr);
if (bb) { if (bb) {
r_anal_fcn_split_bb (fcn, bb, addr); r_anal_fcn_split_bb (anal, fcn, bb, addr);
if (anal->recont) if (anal->recont)
return R_ANAL_RET_END; return R_ANAL_RET_END;
return R_ANAL_RET_ERROR; // MUST BE NOT DUP return R_ANAL_RET_ERROR; // MUST BE NOT DUP
} }
bb = appendBasicBlock (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%08llx)\n", addr, fcn->addr); " (fcn 0x%08llx)\n", addr, fcn->addr);
@ -345,27 +362,26 @@ repeat:
// TODO: use fcn->stack to know our stackframe // TODO: use fcn->stack 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 = r_str_newf ("arg_%x", op.ptr); varname = get_varname (anal, ARGPREFIX, R_ABS(op.ptr));
r_anal_var_add (anal, fcn->addr, 1, op.ptr, r_anal_var_add (anal, fcn->addr, 1, op.ptr,
'a', NULL, anal->bits/8, varname); 'a', NULL, anal->bits/8, varname);
// TODO: DIR_IN? // TODO: DIR_IN?
} else { } else {
varname = r_str_newf ("local_%x", -op.ptr); varname = get_varname (anal, VARPREFIX, R_ABS(op.ptr));
r_anal_var_add (anal, fcn->addr, 1, -op.ptr, r_anal_var_add (anal, fcn->addr, 1, -op.ptr,
'v', NULL, 'v', NULL, anal->bits/8, varname);
anal->bits/8, varname);
} }
free (varname); free (varname);
break; break;
// TODO: use fcn->stack to know our stackframe // TODO: use fcn->stack 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 = r_str_newf ("arg_%x", op.ptr); varname = get_varname (anal, ARGPREFIX, R_ABS(op.ptr));
r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'a', NULL, anal->bits/8, varname); r_anal_var_add (anal, fcn->addr, 1, op.ptr, 'a', NULL, anal->bits/8, varname);
r_anal_var_access (anal, fcn->addr, 'a', 0, op.ptr, 0, op.addr); //, NULL, varname, 0); r_anal_var_access (anal, fcn->addr, 'a', 0, op.ptr, 0, op.addr); //, NULL, varname, 0);
//R_ANAL_VAR_SCOPE_ARG|R_ANAL_VAR_DIR_IN, NULL, varname, 0); //R_ANAL_VAR_SCOPE_ARG|R_ANAL_VAR_DIR_IN, NULL, varname, 0);
} else { } else {
varname = r_str_newf ("local_%x", -op.ptr); varname = get_varname (anal, VARPREFIX, R_ABS(op.ptr));
r_anal_var_add (anal, fcn->addr, 1, -op.ptr, 'v', NULL, anal->bits/8, varname); r_anal_var_add (anal, fcn->addr, 1, -op.ptr, 'v', NULL, anal->bits/8, varname);
r_anal_var_access (anal, fcn->addr, 'v', 0, -op.ptr, 0, -op.addr); //, 'v', NULL, varname, 0); r_anal_var_access (anal, fcn->addr, 'v', 0, -op.ptr, 0, -op.addr); //, 'v', NULL, varname, 0);
//R_ANAL_VAR_SCOPE_LOCAL|R_ANAL_VAR_DIR_NONE, NULL, varname, 0); //R_ANAL_VAR_SCOPE_LOCAL|R_ANAL_VAR_DIR_NONE, NULL, varname, 0);
@ -585,6 +601,9 @@ fcn.<offset>.bbs
sdb_set (DB, sdb_fmt (0, "fcn.0x%"PFMT64x"", "", 0)); sdb_set (DB, sdb_fmt (0, "fcn.0x%"PFMT64x"", "", 0));
#endif #endif
r_list_append (anal->fcns, fcn); r_list_append (anal->fcns, fcn);
if (anal->cb.on_fcn_new) {
anal->cb.on_fcn_new (anal, anal->user, fcn);
}
return R_TRUE; return R_TRUE;
} }
@ -660,6 +679,9 @@ R_API int r_anal_fcn_del(RAnal *a, ut64 addr) {
RListIter *iter, *iter_tmp; RListIter *iter, *iter_tmp;
r_list_foreach_safe (a->fcns, iter, iter_tmp, fcni) { r_list_foreach_safe (a->fcns, iter, iter_tmp, fcni) {
if (addr >= fcni->addr && addr < fcni->addr+fcni->size) { if (addr >= fcni->addr && addr < fcni->addr+fcni->size) {
if (a->cb.on_fcn_delete) {
a->cb.on_fcn_delete (a, a->user, fcni);
}
r_list_delete (a->fcns, iter); r_list_delete (a->fcns, iter);
} }
} }
@ -705,7 +727,7 @@ R_API RAnalFunction *r_anal_fcn_find_name(RAnal *anal, const char *name) {
} }
/* rename RAnalFunctionBB.add() */ /* rename RAnalFunctionBB.add() */
R_API int r_anal_fcn_add_bb(RAnalFunction *fcn, ut64 addr, ut64 size, ut64 jump, ut64 fail, int type, RAnalDiff *diff) { R_API int r_anal_fcn_add_bb(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 size, ut64 jump, ut64 fail, int type, RAnalDiff *diff) {
RAnalBlock *bb = NULL, *bbi; RAnalBlock *bb = NULL, *bbi;
RListIter *iter; RListIter *iter;
int mid = 0; int mid = 0;
@ -728,7 +750,7 @@ R_API int r_anal_fcn_add_bb(RAnalFunction *fcn, ut64 addr, ut64 size, ut64 jump,
//return R_FALSE; //return R_FALSE;
} }
if (bb == NULL) { if (bb == NULL) {
bb = appendBasicBlock (fcn, addr); bb = appendBasicBlock (anal, fcn, addr);
if (!bb) { if (!bb) {
eprintf ("appendBasicBlock failed\n"); eprintf ("appendBasicBlock failed\n");
return R_FALSE; return R_FALSE;
@ -751,7 +773,7 @@ R_API int r_anal_fcn_add_bb(RAnalFunction *fcn, ut64 addr, ut64 size, ut64 jump,
// TODO: rename fcn_bb_split() // TODO: rename fcn_bb_split()
// bb seems to be ignored // bb seems to be ignored
R_API int r_anal_fcn_split_bb(RAnalFunction *fcn, RAnalBlock *bb, ut64 addr) { R_API int r_anal_fcn_split_bb(RAnal *anal, RAnalFunction *fcn, RAnalBlock *bb, ut64 addr) {
RAnalBlock *bbi; RAnalBlock *bbi;
#if R_ANAL_BB_HAS_OPS #if R_ANAL_BB_HAS_OPS
RAnalOp *opi; RAnalOp *opi;
@ -764,7 +786,7 @@ R_API int r_anal_fcn_split_bb(RAnalFunction *fcn, RAnalBlock *bb, ut64 addr) {
if (addr == bbi->addr) if (addr == bbi->addr)
return R_ANAL_RET_DUP; return R_ANAL_RET_DUP;
if (addr > bbi->addr && addr < bbi->addr + bbi->size) { if (addr > bbi->addr && addr < bbi->addr + bbi->size) {
bb = appendBasicBlock (fcn, addr); bb = appendBasicBlock (anal, fcn, addr);
//r_list_append (fcn->bbs, bb); //r_list_append (fcn->bbs, bb);
//bb->addr = addr+bbi->size; //bb->addr = addr+bbi->size;
bb->size = bbi->addr + bbi->size - addr; bb->size = bbi->addr + bbi->size - addr;

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2014 - pancake */ /* radare - LGPL - Copyright 2010-2015 - pancake */
#include <r_anal.h> #include <r_anal.h>
#include <r_util.h> #include <r_util.h>
@ -66,6 +66,7 @@ R_API int r_anal_var_add (RAnal *a, ut64 addr, int scope, int delta, char kind,
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);
return R_TRUE; return R_TRUE;
} }

View File

@ -540,10 +540,13 @@ R_API int r_core_anal_bb(RCore *core, RAnalFunction *fcn, ut64 at, int head) {
return R_FALSE; return R_FALSE;
if (!(bb = r_anal_bb_new ())) if (!(bb = r_anal_bb_new ()))
return R_FALSE; return R_FALSE;
if (split) ret = r_anal_fcn_split_bb (fcn, bb, at); if (split) {
else r_list_foreach (fcn->bbs, iter, bbi) { ret = r_anal_fcn_split_bb (core->anal, fcn, bb, at);
} else {
r_list_foreach (fcn->bbs, iter, bbi) {
if (at == bbi->addr) if (at == bbi->addr)
ret = R_ANAL_RET_DUP; ret = R_ANAL_RET_DUP;
}
} }
if (ret == R_ANAL_RET_DUP) { /* Dupped bb */ if (ret == R_ANAL_RET_DUP) { /* Dupped bb */
goto error; goto error;

View File

@ -495,7 +495,8 @@ static int anal_fcn_add_bb (RCore *core, const char *input) {
} }
fcn = r_anal_get_fcn_in (core->anal, fcnaddr, 0); fcn = r_anal_get_fcn_in (core->anal, fcnaddr, 0);
if (fcn) { if (fcn) {
int ret = r_anal_fcn_add_bb (fcn, addr, size, jump, fail, type, diff); int ret = r_anal_fcn_add_bb (core->anal, fcn, addr,
size, jump, fail, type, diff);
if (!ret) { if (!ret) {
eprintf ("Cannot add basic block\n"); eprintf ("Cannot add basic block\n");
} }
@ -508,16 +509,21 @@ static int anal_fcn_add_bb (RCore *core, const char *input) {
} }
static int setFunctionName(RCore *core, ut64 off, const char *name) { static int setFunctionName(RCore *core, ut64 off, const char *name) {
char *oname;
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, off, RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, off,
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM|R_ANAL_FCN_TYPE_LOC); R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM|R_ANAL_FCN_TYPE_LOC);
if (!fcn) if (!fcn)
return 0; return 0;
//r_cons_printf ("fr %s %s@ 0x%"PFMT64x"\n", //r_cons_printf ("fr %s %s@ 0x%"PFMT64x"\n",
// fcn->name, name, off); // fcn->name, name, off);
r_core_cmdf (core, "fr %s %s@ 0x%"PFMT64x, r_core_cmdf (core, "fr %s %s@ 0x%"PFMT64x,
fcn->name, name, off); fcn->name, name, off);
free (fcn->name); oname = fcn->name;
fcn->name = strdup (name); fcn->name = strdup (name);
if (core->anal->cb.on_fcn_rename) {
core->anal->cb.on_fcn_rename (core->anal, core->anal->user, fcn, oname);
}
free (oname);
return 1; return 1;
} }
@ -538,7 +544,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
{ {
ut64 addr = core->offset; ut64 addr = core->offset;
ut64 addr_end = r_num_math (core->num, input+2); ut64 addr_end = r_num_math (core->num, input+2);
if (addr_end< addr) { if (addr_end < addr) {
eprintf ("Invalid address ranges\n"); eprintf ("Invalid address ranges\n");
} else { } else {
int depth = 1; int depth = 1;
@ -1690,7 +1696,7 @@ static void cmd_anal_calls(RCore *core, const char *input) {
if (op.size<1) if (op.size<1)
op.size = minop; // XXX must be +4 on arm/mips/.. like we do in disasm.c op.size = minop; // XXX must be +4 on arm/mips/.. like we do in disasm.c
if (op.type == R_ANAL_OP_TYPE_CALL) { if (op.type == R_ANAL_OP_TYPE_CALL) {
eprintf ("af @ 0x%08"PFMT64x"\n", op.jump); // eprintf ("af @ 0x%08"PFMT64x"\n", op.jump);
r_core_cmdf (core, "af@0x%08"PFMT64x, op.jump); r_core_cmdf (core, "af@0x%08"PFMT64x, op.jump);
} }
} else { } else {
@ -2399,7 +2405,7 @@ static int cmd_anal(void *data, const char *input) {
break; break;
} }
break; break;
case 'c': case 'c': // "ac"
cmd_anal_calls (core, input + 1); cmd_anal_calls (core, input + 1);
break; break;
case 'C': case 'C':

View File

@ -1135,6 +1135,9 @@ R_API int r_core_config_init(RCore *core) {
SETPREF("cmd.open", "", "Command executed when file its opened"); SETPREF("cmd.open", "", "Command executed when file its opened");
SETPREF("cmd.prompt", "", "Prompt commands"); SETPREF("cmd.prompt", "", "Prompt commands");
SETCB("cmd.repeat", "true", &cb_cmdrepeat, "Alias newline (empty command) as '..'"); SETCB("cmd.repeat", "true", &cb_cmdrepeat, "Alias newline (empty command) as '..'");
SETPREF("cmd.fcn.new", "", "Run command when new function is analyzed");
SETPREF("cmd.fcn.delete", "", "Run command when a function is deleted");
SETPREF("cmd.fcn.rename", "", "Run command when a function is renamed");
SETPREF("cmd.visual", "", "Replace current print mode"); SETPREF("cmd.visual", "", "Replace current print mode");
SETPREF("cmd.vprompt", "", "Visual prompt commands"); SETPREF("cmd.vprompt", "", "Visual prompt commands");

View File

@ -11,6 +11,46 @@
R_LIB_VERSION(r_core); R_LIB_VERSION(r_core);
static int on_fcn_new(void *_anal, void* _user, RAnalFunction *fcn) {
RCore *core = (RCore*)_user;
const char *cmd = r_config_get (core->config, "cmd.fcn.new");
if (cmd && *cmd) {
ut64 oaddr = core->offset;
ut64 addr = fcn->addr;
r_core_seek (core, addr, 1);
r_core_cmd0 (core, cmd);
r_core_seek (core, oaddr, 1);
}
return 0;
}
static int on_fcn_delete (void *_anal, void* _user, RAnalFunction *fcn) {
RCore *core = (RCore*)_user;
const char *cmd = r_config_get (core->config, "cmd.fcn.delete");
if (cmd && *cmd) {
ut64 oaddr = core->offset;
ut64 addr = fcn->addr;
r_core_seek (core, addr, 1);
r_core_cmd0 (core, cmd);
r_core_seek (core, oaddr, 1);
}
return 0;
}
static int on_fcn_rename(void *_anal, void* _user, RAnalFunction *fcn, const char *oname) {
RCore *core = (RCore*)_user;
const char *cmd = r_config_get (core->config, "cmd.fcn.rename");
if (cmd && *cmd) {
// XXX: wat do with old name here?
ut64 oaddr = core->offset;
ut64 addr = fcn->addr;
r_core_seek (core, addr, 1);
r_core_cmd0 (core, cmd);
r_core_seek (core, oaddr, 1);
}
return 0;
}
static void r_core_debug_breakpoint_hit(RCore *core, RBreakpointItem *bpi) { static void r_core_debug_breakpoint_hit(RCore *core, RBreakpointItem *bpi) {
const char *cmdbp; const char *cmdbp;
int oecho = core->cons->echo; // should be configurable by user? int oecho = core->cons->echo; // should be configurable by user?
@ -204,6 +244,12 @@ static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
break; break;
default: default:
if (*str>'A') { if (*str>'A') {
// NOTE: functions override flags
RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, str);
if (fcn) {
if (ok) *ok = R_TRUE;
return fcn->addr;
}
#if 0 #if 0
ut64 addr = r_anal_fcn_label_get (core->anal, core->offset, str); ut64 addr = r_anal_fcn_label_get (core->anal, core->offset, str);
if (addr != 0) { if (addr != 0) {
@ -812,6 +858,9 @@ R_API int r_core_init(RCore *core) {
core->assembler->num = core->num; core->assembler->num = core->num;
r_asm_set_user_ptr (core->assembler, core); r_asm_set_user_ptr (core->assembler, core);
core->anal = r_anal_new (); core->anal = r_anal_new ();
core->anal->cb.on_fcn_new = on_fcn_new;
core->anal->cb.on_fcn_delete = on_fcn_delete;
core->anal->cb.on_fcn_rename = on_fcn_rename;
core->assembler->syscall = \ core->assembler->syscall = \
core->anal->syscall; // BIND syscall anal/asm core->anal->syscall; // BIND syscall anal/asm
r_anal_set_user_ptr (core->anal, core); r_anal_set_user_ptr (core->anal, core);

View File

@ -690,32 +690,35 @@ static void handle_show_xrefs (RCore *core, RDisasmState *ds) {
} }
static void handle_atabs_option(RCore *core, RDisasmState *ds) { static void handle_atabs_option(RCore *core, RDisasmState *ds) {
if (ds->atabs) { int n, i = 0, comma = 0, word = 0;
int n, i = 0, comma = 0, word = 0; int size, brackets = 0;
int brackets = 0; char *t, *b;
char *t, *b; if (!ds || !ds->atabs)
free (ds->opstr); return;
ds->opstr = b = malloc (strlen (ds->asmop.buf_asm)* (ds->atabs+1)*4); size = strlen (ds->asmop.buf_asm)* (ds->atabs+1)*4;
strcpy (b, ds->asmop.buf_asm); if (size<1)
for (; *b; b++, i++) { return;
if (*b=='(' || *b=='[') brackets++; free (ds->opstr);
if (*b==')' || *b==']') brackets--; ds->opstr = b = malloc (size);
if (*b==',') comma = 1; strcpy (b, ds->asmop.buf_asm);
if (*b!=' ') continue; for (; *b; b++, i++) {
if (word>0 && !comma) continue; //&& b[1]=='[') continue; if (*b=='(' || *b=='[') brackets++;
if (brackets>0) continue; if (*b==')' || *b==']') brackets--;
comma = 0; if (*b==',') comma = 1;
brackets = 0; if (*b!=' ') continue;
n = (ds->atabs-i); if (word>0 && !comma) continue; //&& b[1]=='[') continue;
t = strdup (b+1); //XXX slow! if (brackets>0) continue;
if (n<1) n = 1; comma = 0;
memset (b, ' ', n); brackets = 0;
b += n; n = (ds->atabs-i);
strcpy (b, t); t = strdup (b+1); //XXX slow!
free (t); if (n<1) n = 1;
i = 0; memset (b, ' ', n);
word++; b += n;
} strcpy (b, t);
free (t);
i = 0;
word++;
} }
} }
@ -728,90 +731,101 @@ static void handle_print_show_cursor (RCore *core, RDisasmState *ds) {
} }
static void handle_show_functions (RCore *core, RDisasmState *ds) { static void handle_show_functions (RCore *core, RDisasmState *ds) {
if (ds->show_functions) { RAnalFunction *f;
RAnalFunction *f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL); char *sign;
if (f) { if (!core || !ds || !ds->show_functions)
if (f->addr == ds->at) { return;
char *sign = r_anal_fcn_to_string (core->anal, f); f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
if (f->type == R_ANAL_FCN_TYPE_LOC) { if (!f) return;
if (ds->show_color) { if (f->addr != ds->at) {
r_cons_printf ("%s%s ", ds->color_fline, return;
core->cons->vline[LINE_CROSS]); // |- }
r_cons_printf ("%s%s"Color_RESET" %d\n", sign = r_anal_fcn_to_string (core->anal, f);
ds->color_floc, f->name, f->size); if (f->type == R_ANAL_FCN_TYPE_LOC) {
r_cons_printf ("%s%s "Color_RESET, if (ds->show_color) {
ds->color_fline, core->cons->vline[LINE_VERT]); // | r_cons_printf ("%s%s ", ds->color_fline,
} else { core->cons->vline[LINE_CROSS]); // |-
r_cons_printf ("%s %s %d\n%s ", core->cons->vline[LINE_CROSS], r_cons_printf ("%s%s"Color_RESET" %d\n",
f->name, f->size, core->cons->vline[LINE_VERT]); // |- ds->color_floc, f->name, f->size);
} r_cons_printf ("%s%s "Color_RESET,
} else { ds->color_fline, core->cons->vline[LINE_VERT]); // |
const char *fmt = ds->show_color? } else {
"%s%s "Color_RESET"%s(%s) %s"Color_RESET" %d\n": r_cons_printf ("%s %s %d\n%s ", core->cons->vline[LINE_CROSS],
"%s (%s) %s %d\n"; f->name, f->size, core->cons->vline[LINE_VERT]); // |-
}
} else {
const char *fmt = ds->show_color?
"%s%s "Color_RESET"%s(%s) %s"Color_RESET" %d\n":
"%s (%s) %s %d\n";
#if SLOW_BUT_OK #if SLOW_BUT_OK
int corner = (f->size <= ds->analop.size)? RDWN_CORNER: LINE_VERT; int corner = (f->size <= ds->analop.size)? RDWN_CORNER: LINE_VERT;
corner = LINE_VERT; // 99% of cases corner = LINE_VERT; // 99% of cases
RFlagItem *item = r_flag_get_i (core->flags, f->addr); RFlagItem *item = r_flag_get_i (core->flags, f->addr);
corner = item? LINE_VERT: RDWN_CORNER; corner = item? LINE_VERT: RDWN_CORNER;
if (item) if (item)
corner = 0; corner = 0;
#endif #endif
handle_set_pre (ds, core->cons->vline[RUP_CORNER]); handle_set_pre (ds, core->cons->vline[RUP_CORNER]);
if (ds->show_color) { if (ds->show_color) {
r_cons_printf (fmt, ds->color_fline, ds->pre, ds->color_fname, r_cons_printf (fmt, ds->color_fline, ds->pre, ds->color_fname,
(f->type==R_ANAL_FCN_TYPE_FCN || f->type==R_ANAL_FCN_TYPE_SYM)?"fcn": (f->type==R_ANAL_FCN_TYPE_FCN || f->type==R_ANAL_FCN_TYPE_SYM)?"fcn":
(f->type==R_ANAL_FCN_TYPE_IMP)?"imp":"loc", (f->type==R_ANAL_FCN_TYPE_IMP)?"imp":"loc",
f->name, f->size); f->name, f->size);
} else { } else {
r_cons_printf (fmt, ds->pre, r_cons_printf (fmt, ds->pre,
(f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"fcn": (f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"fcn":
(f->type==R_ANAL_FCN_TYPE_IMP)?"imp":"loc", (f->type==R_ANAL_FCN_TYPE_IMP)?"imp":"loc",
f->name, f->size); f->name, f->size);
} }
} }
if (sign) r_cons_printf ("// %s\n", sign); if (sign) r_cons_printf ("// %s\n", sign);
free (sign); free (sign);
sign = NULL; sign = NULL;
handle_set_pre (ds, core->cons->vline[LINE_VERT]); handle_set_pre (ds, core->cons->vline[LINE_VERT]);
ds->pre = r_str_concat (ds->pre, " "); ds->pre = r_str_concat (ds->pre, " ");
ds->stackptr = 0; ds->stackptr = 0;
if (ds->vars) { if (ds->vars) {
RList *args = r_anal_var_list (core->anal, f, 'a'); char spaces[32];
RList *vars = r_anal_var_list (core->anal, f, 'v'); RList *args = r_anal_var_list (core->anal, f, 'a');
r_list_join (vars, args); RList *vars = r_anal_var_list (core->anal, f, 'v');
RAnalVar *var; r_list_join (vars, args);
RListIter *iter; RAnalVar *var;
r_list_foreach (vars, iter, var) { RListIter *iter;
if (ds->show_color) { // TODO: show first args, and then vars
r_cons_printf ("%s%s %s"Color_RESET, r_list_foreach (vars, iter, var) {
ds->color_fline, core->cons->vline[LINE_VERT], ds->refline2); int idx;
r_cons_printf ("%s; %s %s %s @ %s%s0x%x"Color_RESET"\n", memset (spaces, ' ', sizeof(spaces));
ds->color_other, idx = 12-strlen (var->name);
var->kind=='v'?"var":"arg", if (idx<0)idx = 0;
var->type, spaces[idx] = 0;
var->name, if (ds->show_color) {
core->anal->reg->name[R_REG_NAME_BP], r_cons_printf ("%s%s %s"Color_RESET,
(var->kind=='v')?"-":"+", ds->color_fline, core->cons->vline[LINE_VERT], ds->refline2);
var->delta); r_cons_printf ("%s; %s %s %s %s@ %s%s0x%x"Color_RESET"\n",
} else { ds->color_other,
r_cons_printf ("%s %s", var->kind=='v'?"var":"arg",
core->cons->vline[LINE_VERT], ds->refline2); var->type,
r_cons_printf ("; %s %s %s @ %s%s0x%x\n", var->name,
var->kind=='v'?"var":"arg", spaces,
var->type, core->anal->reg->name[R_REG_NAME_BP],
var->name, (var->kind=='v')?"-":"+",
core->anal->reg->name[R_REG_NAME_BP], var->delta);
(var->kind=='v')?"-":"+", } else {
var->delta); r_cons_printf ("%s %s",
} core->cons->vline[LINE_VERT], ds->refline2);
} r_cons_printf ("; %s %s %s %s@ %s%s0x%x\n",
r_list_free (vars); var->kind=='v'?"var":"arg",
// it's already empty, but rlist instance is still there var->type,
r_list_free (args); var->name,
} spaces,
core->anal->reg->name[R_REG_NAME_BP],
(var->kind=='v')?"-":"+",
var->delta);
} }
} }
r_list_free (vars);
// it's already empty, but rlist instance is still there
r_list_free (args);
} }
} }
@ -854,74 +868,77 @@ static void handle_print_pre (RCore *core, RDisasmState *ds) {
} }
static void handle_show_comments_right (RCore *core, RDisasmState *ds) { static void handle_show_comments_right (RCore *core, RDisasmState *ds) {
int linelen, maxclen ;
RAnalFunction *f;
RFlagItem *item;
/* show comment at right? */ /* show comment at right? */
ds->show_comment_right = 0; ds->show_comment_right = 0;
if (ds->show_comments) { if (!ds->show_comments)
RAnalFunction *f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL); return;
RFlagItem *item = r_flag_get_i (core->flags, ds->at); f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
ds->comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at); item = r_flag_get_i (core->flags, ds->at);
if (!ds->comment && item && item->comment) { ds->comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at);
ds->ocomment = item->comment; if (!ds->comment && item && item->comment) {
ds->comment = strdup (item->comment); ds->ocomment = item->comment;
ds->comment = strdup (item->comment);
}
if (!ds->comment)
return;
maxclen = strlen (ds->comment)+5;
linelen = maxclen;
if (ds->show_comment_right_default) {
if (ds->ocols+maxclen < core->cons->columns) {
if (ds->comment && *ds->comment && strlen (ds->comment)<maxclen) {
if (!strchr (ds->comment, '\n')) // more than one line?
ds->show_comment_right = 1;
}
} }
if (ds->comment) { }
int linelen, maxclen = strlen (ds->comment)+5; if (!ds->show_comment_right) {
linelen = maxclen; int infun, mycols = ds->lcols;
if (ds->show_comment_right_default) { if (mycols + linelen + 10 > core->cons->columns)
if (ds->ocols+maxclen < core->cons->columns) { mycols = 0;
if (ds->comment && *ds->comment && strlen (ds->comment)<maxclen) { mycols /= 2;
if (!strchr (ds->comment, '\n')) // more than one line? if (ds->show_color) r_cons_strcat (ds->pal_comment);
ds->show_comment_right = 1;
}
}
}
if (!ds->show_comment_right) {
int infun, mycols = ds->lcols;
if (mycols + linelen + 10 > core->cons->columns)
mycols = 0;
mycols /= 2;
if (ds->show_color) r_cons_strcat (ds->pal_comment);
#if OLD_COMMENTS #if OLD_COMMENTS
r_cons_strcat ("; "); r_cons_strcat ("; ");
// XXX: always prefix with ; the comments // XXX: always prefix with ; the comments
if (*ds->comment != ';') r_cons_strcat (" ; "); if (*ds->comment != ';') r_cons_strcat (" ; ");
r_cons_strcat_justify (ds->comment, mycols, ';'); r_cons_strcat_justify (ds->comment, mycols, ';');
#else #else
infun = f && (f->addr != ds->at); infun = f && (f->addr != ds->at);
if (infun) { if (infun) {
char *str = strdup (ds->show_color?ds->color_fline: ""); char *str = strdup (ds->show_color?ds->color_fline: "");
str = r_str_concat (str, core->cons->vline[LINE_VERT]); str = r_str_concat (str, core->cons->vline[LINE_VERT]);
if (ds->show_color) if (ds->show_color)
str = r_str_concat (str, ds->color_flow); str = r_str_concat (str, ds->color_flow);
// color refline // color refline
str = r_str_concat (str, " "); str = r_str_concat (str, " ");
str = r_str_concat (str, ds->refline2); str = r_str_concat (str, ds->refline2);
// color comment // color comment
if (ds->show_color) if (ds->show_color)
str = r_str_concat (str, ds->color_comment); str = r_str_concat (str, ds->color_comment);
str = r_str_concat (str, "; "); str = r_str_concat (str, "; ");
ds->comment = r_str_prefix_all (ds->comment, str); ds->comment = r_str_prefix_all (ds->comment, str);
free (str); free (str);
} else { } else {
ds->comment = r_str_prefix_all (ds->comment, " ; "); ds->comment = r_str_prefix_all (ds->comment, " ; ");
} }
r_cons_strcat (ds->comment); r_cons_strcat (ds->comment);
#endif #endif
if (ds->show_color) handle_print_color_reset (core, ds); if (ds->show_color) handle_print_color_reset (core, ds);
r_cons_newline (); r_cons_newline ();
free (ds->comment); free (ds->comment);
ds->comment = NULL; ds->comment = NULL;
/* flag one */ /* flag one */
if (item && item->comment && ds->ocomment != item->comment) { if (item && item->comment && ds->ocomment != item->comment) {
if (ds->show_color) r_cons_strcat (ds->pal_comment); if (ds->show_color) r_cons_strcat (ds->pal_comment);
r_cons_newline (); r_cons_newline ();
r_cons_strcat (" ; "); r_cons_strcat (" ; ");
r_cons_strcat_justify (item->comment, mycols, ';'); r_cons_strcat_justify (item->comment, mycols, ';');
r_cons_newline (); r_cons_newline ();
if (ds->show_color) handle_print_color_reset (core, ds); if (ds->show_color) handle_print_color_reset (core, ds);
}
}
} }
} }
} }

View File

@ -531,6 +531,17 @@ typedef struct r_anal_switch_obj_t {
RList *cases; RList *cases;
} RAnalSwitchOp; } RAnalSwitchOp;
#define RANAL void*
//struct r_anal_t*
#define RANAL_BLOCK void*
//struct r_anal_bb_t*
typedef struct r_anal_callbacks_t {
int (*on_fcn_new) (RANAL, void *user, RAnalFunction *fcn);
int (*on_fcn_delete) (RANAL , void *user, RAnalFunction *fcn);
int (*on_fcn_rename) (RANAL, void *user, RAnalFunction *fcn, const char *oldname);
int (*on_fcn_bb_new) (RANAL, void *user, RAnalFunction *fcn, RANAL_BLOCK bb);
} RAnalCallbacks;
typedef struct r_anal_t { typedef struct r_anal_t {
char *cpu; char *cpu;
int bits; int bits;
@ -585,6 +596,7 @@ typedef struct r_anal_t {
#endif #endif
Sdb *sdb_hints; // OK Sdb *sdb_hints; // OK
//RList *hints; // XXX use better data structure here (slist?) //RList *hints; // XXX use better data structure here (slist?)
RAnalCallbacks cb;
} RAnal; } RAnal;
typedef struct r_anal_hint_t { typedef struct r_anal_hint_t {
@ -1063,7 +1075,8 @@ R_API int r_anal_fcn_add(RAnal *anal, ut64 addr, ut64 size,
const char *name, int type, RAnalDiff *diff); const char *name, int type, RAnalDiff *diff);
R_API int r_anal_fcn_del(RAnal *anal, ut64 addr); R_API int r_anal_fcn_del(RAnal *anal, ut64 addr);
R_API int r_anal_fcn_del_locs(RAnal *anal, ut64 addr); R_API int r_anal_fcn_del_locs(RAnal *anal, ut64 addr);
R_API int r_anal_fcn_add_bb(RAnalFunction *fcn, ut64 addr, ut64 size, R_API int r_anal_fcn_add_bb(RAnal *anal, RAnalFunction *fcn,
ut64 addr, ut64 size,
ut64 jump, ut64 fail, int type, RAnalDiff *diff); ut64 jump, ut64 fail, int type, RAnalDiff *diff);
/* locals */ /* locals */
@ -1095,7 +1108,7 @@ R_API int r_anal_fcn_var_del_byindex (RAnal *a, ut64 fna, const char kind,
R_API int r_anal_fcn_cc(RAnalFunction *fcn); R_API int r_anal_fcn_cc(RAnalFunction *fcn);
R_API int r_anal_fcn_split_bb(RAnalFunction *fcn, RAnalBlock *bb, ut64 addr); R_API int r_anal_fcn_split_bb(RAnal *anal, RAnalFunction *fcn, RAnalBlock *bb, ut64 addr);
R_API int r_anal_fcn_bb_overlaps(RAnalFunction *fcn, RAnalBlock *bb); R_API int r_anal_fcn_bb_overlaps(RAnalFunction *fcn, RAnalBlock *bb);
R_API RAnalVar *r_anal_fcn_get_var(RAnalFunction *fs, int num, int dir); R_API RAnalVar *r_anal_fcn_get_var(RAnalFunction *fs, int num, int dir);
R_API void r_anal_fcn_fit_overlaps (RAnal *anal, RAnalFunction *fcn); R_API void r_anal_fcn_fit_overlaps (RAnal *anal, RAnalFunction *fcn);

View File

@ -37,7 +37,7 @@ SDB_API SdbList *ls_new(void);
SDB_API SdbListIter *ls_append(SdbList *list, void *data); SDB_API SdbListIter *ls_append(SdbList *list, void *data);
SDB_API SdbListIter *ls_prepend(SdbList *list, void *data); SDB_API SdbListIter *ls_prepend(SdbList *list, void *data);
SDB_API int ls_length(SdbList *list); SDB_API int ls_length(SdbList *list);
SDB_API void ls_add_sorted(SdbList *list, void *data, SdbListComparator cmp); //SDB_API void ls_add_sorted(SdbList *list, void *data, SdbListComparator cmp);
SDB_API void ls_sort(SdbList *list, SdbListComparator cmp); SDB_API void ls_sort(SdbList *list, SdbListComparator cmp);
SDB_API void ls_delete (SdbList *list, SdbListIter *iter); SDB_API void ls_delete (SdbList *list, SdbListIter *iter);

View File

@ -14,6 +14,19 @@ SDB_API SdbList *ls_new() {
return list; return list;
} }
SDB_API void ls_sort(SdbList *list, SdbListComparator cmp) {
SdbListIter *it, *it2;
for (it = list->head; it && it->data; it = it->n) {
for (it2 = it->n; it2 && it2->data; it2 = it2->n) {
if (cmp (it->data, it2->data)>0) {
void *t = it->data;
it->data = it2->data;
it2->data = t;
}
}
}
}
SDB_API void ls_delete (SdbList *list, SdbListIter *iter) { SDB_API void ls_delete (SdbList *list, SdbListIter *iter) {
if (!list || !iter) return; if (!list || !iter) return;
ls_split_iter (list, iter); ls_split_iter (list, iter);

View File

@ -37,7 +37,7 @@ SDB_API SdbList *ls_new(void);
SDB_API SdbListIter *ls_append(SdbList *list, void *data); SDB_API SdbListIter *ls_append(SdbList *list, void *data);
SDB_API SdbListIter *ls_prepend(SdbList *list, void *data); SDB_API SdbListIter *ls_prepend(SdbList *list, void *data);
SDB_API int ls_length(SdbList *list); SDB_API int ls_length(SdbList *list);
SDB_API void ls_add_sorted(SdbList *list, void *data, SdbListComparator cmp); //SDB_API void ls_add_sorted(SdbList *list, void *data, SdbListComparator cmp);
SDB_API void ls_sort(SdbList *list, SdbListComparator cmp); SDB_API void ls_sort(SdbList *list, SdbListComparator cmp);
SDB_API void ls_delete (SdbList *list, SdbListIter *iter); SDB_API void ls_delete (SdbList *list, SdbListIter *iter);

View File

@ -343,7 +343,7 @@ next_quote:
} else { } else {
/* +[idx]key --> key[idx] + 1 */ /* +[idx]key --> key[idx] + 1 */
/* -[idx]key --> key[idx] - 1 */ /* -[idx]key --> key[idx] - 1 */
char *nstr, numstr[32]; char *nstr, numstr[128];
if (*cmd=='+') { if (*cmd=='+') {
curnum ++; curnum ++;
} else if (*cmd=='-') { } else if (*cmd=='-') {