mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-03 19:01:31 +00:00
Better vars naming, Add e cmd.fcn.{new|rename|delete}
- Bump sdb from git
This commit is contained in:
parent
813d13d589
commit
d991769935
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2009-2014 - pancake, nibble */
|
||||
/* radare - LGPL - Copyright 2009-2015 - pancake, nibble */
|
||||
|
||||
#include <r_anal.h>
|
||||
#include <r_util.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2010-2014 - nibble, pancake */
|
||||
/* radare - LGPL - Copyright 2010-2015 - nibble, pancake */
|
||||
|
||||
#include <r_anal.h>
|
||||
#include <r_util.h>
|
||||
@ -175,17 +175,17 @@ static int bbsum(RAnalFunction *fcn) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static RAnalBlock* appendBasicBlock (RAnalFunction *fcn, ut64 addr) {
|
||||
static RAnalBlock* appendBasicBlock (RAnal *anal, RAnalFunction *fcn, ut64 addr) {
|
||||
RAnalBlock *bb;
|
||||
#if 0
|
||||
RListIter *iter;
|
||||
// TODO: check if its already there
|
||||
r_list_foreach (fcn->bbs, iter, bb) {
|
||||
if (bb->addr == addr)
|
||||
return bb;
|
||||
}
|
||||
#endif
|
||||
// TODO: echeck if its already there
|
||||
bb = r_anal_bb_new();
|
||||
bb = r_anal_bb_new ();
|
||||
if (!bb) return NULL;
|
||||
bb->addr = addr;
|
||||
bb->size = 0;
|
||||
@ -193,6 +193,9 @@ static RAnalBlock* appendBasicBlock (RAnalFunction *fcn, ut64 addr) {
|
||||
bb->fail = UT64_MAX;
|
||||
bb->type = 0; // TODO
|
||||
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;
|
||||
}
|
||||
//fcn->addr += n; fcn->size -= n; } else
|
||||
@ -206,6 +209,20 @@ static RAnalBlock* appendBasicBlock (RAnalFunction *fcn, ut64 addr) {
|
||||
|
||||
#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;
|
||||
static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64 len, int depth) {
|
||||
int continue_after_jump = anal->afterjmp;
|
||||
@ -239,13 +256,13 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
|
||||
#endif
|
||||
bb = bbget (fcn, addr);
|
||||
if (bb) {
|
||||
r_anal_fcn_split_bb (fcn, bb, addr);
|
||||
r_anal_fcn_split_bb (anal, fcn, bb, addr);
|
||||
if (anal->recont)
|
||||
return R_ANAL_RET_END;
|
||||
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
|
||||
" (fcn 0x%08llx)\n", addr, fcn->addr);
|
||||
@ -345,27 +362,26 @@ repeat:
|
||||
// TODO: use fcn->stack to know our stackframe
|
||||
case R_ANAL_STACK_SET:
|
||||
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);
|
||||
// TODO: DIR_IN?
|
||||
} 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);
|
||||
'v', NULL, anal->bits/8, varname);
|
||||
}
|
||||
free (varname);
|
||||
break;
|
||||
// TODO: use fcn->stack to know our stackframe
|
||||
case R_ANAL_STACK_GET:
|
||||
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_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);
|
||||
} 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_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);
|
||||
@ -585,6 +601,9 @@ fcn.<offset>.bbs
|
||||
sdb_set (DB, sdb_fmt (0, "fcn.0x%"PFMT64x"", "", 0));
|
||||
#endif
|
||||
r_list_append (anal->fcns, fcn);
|
||||
if (anal->cb.on_fcn_new) {
|
||||
anal->cb.on_fcn_new (anal, anal->user, fcn);
|
||||
}
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
@ -660,6 +679,9 @@ R_API int r_anal_fcn_del(RAnal *a, ut64 addr) {
|
||||
RListIter *iter, *iter_tmp;
|
||||
r_list_foreach_safe (a->fcns, iter, iter_tmp, fcni) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -705,7 +727,7 @@ R_API RAnalFunction *r_anal_fcn_find_name(RAnal *anal, const char *name) {
|
||||
}
|
||||
|
||||
/* 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;
|
||||
RListIter *iter;
|
||||
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;
|
||||
}
|
||||
if (bb == NULL) {
|
||||
bb = appendBasicBlock (fcn, addr);
|
||||
bb = appendBasicBlock (anal, fcn, addr);
|
||||
if (!bb) {
|
||||
eprintf ("appendBasicBlock failed\n");
|
||||
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()
|
||||
// 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;
|
||||
#if R_ANAL_BB_HAS_OPS
|
||||
RAnalOp *opi;
|
||||
@ -764,7 +786,7 @@ R_API int r_anal_fcn_split_bb(RAnalFunction *fcn, RAnalBlock *bb, ut64 addr) {
|
||||
if (addr == bbi->addr)
|
||||
return R_ANAL_RET_DUP;
|
||||
if (addr > bbi->addr && addr < bbi->addr + bbi->size) {
|
||||
bb = appendBasicBlock (fcn, addr);
|
||||
bb = appendBasicBlock (anal, fcn, addr);
|
||||
//r_list_append (fcn->bbs, bb);
|
||||
//bb->addr = addr+bbi->size;
|
||||
bb->size = bbi->addr + bbi->size - addr;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2010-2014 - pancake */
|
||||
/* radare - LGPL - Copyright 2010-2015 - pancake */
|
||||
|
||||
#include <r_anal.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);
|
||||
sdb_array_add (DB, var_global, var_def, 0);
|
||||
}
|
||||
// ls_sort (DB->ht->list, mystrcmp);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
@ -540,10 +540,13 @@ R_API int r_core_anal_bb(RCore *core, RAnalFunction *fcn, ut64 at, int head) {
|
||||
return R_FALSE;
|
||||
if (!(bb = r_anal_bb_new ()))
|
||||
return R_FALSE;
|
||||
if (split) ret = r_anal_fcn_split_bb (fcn, bb, at);
|
||||
else r_list_foreach (fcn->bbs, iter, bbi) {
|
||||
if (split) {
|
||||
ret = r_anal_fcn_split_bb (core->anal, fcn, bb, at);
|
||||
} else {
|
||||
r_list_foreach (fcn->bbs, iter, bbi) {
|
||||
if (at == bbi->addr)
|
||||
ret = R_ANAL_RET_DUP;
|
||||
}
|
||||
}
|
||||
if (ret == R_ANAL_RET_DUP) { /* Dupped bb */
|
||||
goto error;
|
||||
|
@ -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);
|
||||
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) {
|
||||
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) {
|
||||
char *oname;
|
||||
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)
|
||||
return 0;
|
||||
//r_cons_printf ("fr %s %s@ 0x%"PFMT64x"\n",
|
||||
// fcn->name, name, off);
|
||||
r_core_cmdf (core, "fr %s %s@ 0x%"PFMT64x,
|
||||
fcn->name, name, off);
|
||||
free (fcn->name);
|
||||
fcn->name, name, off);
|
||||
oname = fcn->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;
|
||||
}
|
||||
|
||||
@ -538,7 +544,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
|
||||
{
|
||||
ut64 addr = core->offset;
|
||||
ut64 addr_end = r_num_math (core->num, input+2);
|
||||
if (addr_end< addr) {
|
||||
if (addr_end < addr) {
|
||||
eprintf ("Invalid address ranges\n");
|
||||
} else {
|
||||
int depth = 1;
|
||||
@ -1690,7 +1696,7 @@ static void cmd_anal_calls(RCore *core, const char *input) {
|
||||
if (op.size<1)
|
||||
op.size = minop; // XXX must be +4 on arm/mips/.. like we do in disasm.c
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
@ -2399,7 +2405,7 @@ static int cmd_anal(void *data, const char *input) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
case 'c': // "ac"
|
||||
cmd_anal_calls (core, input + 1);
|
||||
break;
|
||||
case 'C':
|
||||
|
@ -1135,6 +1135,9 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETPREF("cmd.open", "", "Command executed when file its opened");
|
||||
SETPREF("cmd.prompt", "", "Prompt commands");
|
||||
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.vprompt", "", "Visual prompt commands");
|
||||
|
||||
|
@ -11,6 +11,46 @@
|
||||
|
||||
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) {
|
||||
const char *cmdbp;
|
||||
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;
|
||||
default:
|
||||
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
|
||||
ut64 addr = r_anal_fcn_label_get (core->anal, core->offset, str);
|
||||
if (addr != 0) {
|
||||
@ -812,6 +858,9 @@ R_API int r_core_init(RCore *core) {
|
||||
core->assembler->num = core->num;
|
||||
r_asm_set_user_ptr (core->assembler, core);
|
||||
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->anal->syscall; // BIND syscall anal/asm
|
||||
r_anal_set_user_ptr (core->anal, core);
|
||||
|
@ -690,32 +690,35 @@ static void handle_show_xrefs (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 brackets = 0;
|
||||
char *t, *b;
|
||||
free (ds->opstr);
|
||||
ds->opstr = b = malloc (strlen (ds->asmop.buf_asm)* (ds->atabs+1)*4);
|
||||
strcpy (b, ds->asmop.buf_asm);
|
||||
for (; *b; b++, i++) {
|
||||
if (*b=='(' || *b=='[') brackets++;
|
||||
if (*b==')' || *b==']') brackets--;
|
||||
if (*b==',') comma = 1;
|
||||
if (*b!=' ') continue;
|
||||
if (word>0 && !comma) continue; //&& b[1]=='[') continue;
|
||||
if (brackets>0) continue;
|
||||
comma = 0;
|
||||
brackets = 0;
|
||||
n = (ds->atabs-i);
|
||||
t = strdup (b+1); //XXX slow!
|
||||
if (n<1) n = 1;
|
||||
memset (b, ' ', n);
|
||||
b += n;
|
||||
strcpy (b, t);
|
||||
free (t);
|
||||
i = 0;
|
||||
word++;
|
||||
}
|
||||
int n, i = 0, comma = 0, word = 0;
|
||||
int size, brackets = 0;
|
||||
char *t, *b;
|
||||
if (!ds || !ds->atabs)
|
||||
return;
|
||||
size = strlen (ds->asmop.buf_asm)* (ds->atabs+1)*4;
|
||||
if (size<1)
|
||||
return;
|
||||
free (ds->opstr);
|
||||
ds->opstr = b = malloc (size);
|
||||
strcpy (b, ds->asmop.buf_asm);
|
||||
for (; *b; b++, i++) {
|
||||
if (*b=='(' || *b=='[') brackets++;
|
||||
if (*b==')' || *b==']') brackets--;
|
||||
if (*b==',') comma = 1;
|
||||
if (*b!=' ') continue;
|
||||
if (word>0 && !comma) continue; //&& b[1]=='[') continue;
|
||||
if (brackets>0) continue;
|
||||
comma = 0;
|
||||
brackets = 0;
|
||||
n = (ds->atabs-i);
|
||||
t = strdup (b+1); //XXX slow!
|
||||
if (n<1) n = 1;
|
||||
memset (b, ' ', n);
|
||||
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) {
|
||||
if (ds->show_functions) {
|
||||
RAnalFunction *f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
||||
if (f) {
|
||||
if (f->addr == ds->at) {
|
||||
char *sign = r_anal_fcn_to_string (core->anal, f);
|
||||
if (f->type == R_ANAL_FCN_TYPE_LOC) {
|
||||
if (ds->show_color) {
|
||||
r_cons_printf ("%s%s ", ds->color_fline,
|
||||
core->cons->vline[LINE_CROSS]); // |-
|
||||
r_cons_printf ("%s%s"Color_RESET" %d\n",
|
||||
ds->color_floc, f->name, f->size);
|
||||
r_cons_printf ("%s%s "Color_RESET,
|
||||
ds->color_fline, core->cons->vline[LINE_VERT]); // |
|
||||
} else {
|
||||
r_cons_printf ("%s %s %d\n%s ", core->cons->vline[LINE_CROSS],
|
||||
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";
|
||||
RAnalFunction *f;
|
||||
char *sign;
|
||||
if (!core || !ds || !ds->show_functions)
|
||||
return;
|
||||
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
||||
if (!f) return;
|
||||
if (f->addr != ds->at) {
|
||||
return;
|
||||
}
|
||||
sign = r_anal_fcn_to_string (core->anal, f);
|
||||
if (f->type == R_ANAL_FCN_TYPE_LOC) {
|
||||
if (ds->show_color) {
|
||||
r_cons_printf ("%s%s ", ds->color_fline,
|
||||
core->cons->vline[LINE_CROSS]); // |-
|
||||
r_cons_printf ("%s%s"Color_RESET" %d\n",
|
||||
ds->color_floc, f->name, f->size);
|
||||
r_cons_printf ("%s%s "Color_RESET,
|
||||
ds->color_fline, core->cons->vline[LINE_VERT]); // |
|
||||
} else {
|
||||
r_cons_printf ("%s %s %d\n%s ", core->cons->vline[LINE_CROSS],
|
||||
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
|
||||
int corner = (f->size <= ds->analop.size)? RDWN_CORNER: LINE_VERT;
|
||||
corner = LINE_VERT; // 99% of cases
|
||||
RFlagItem *item = r_flag_get_i (core->flags, f->addr);
|
||||
corner = item? LINE_VERT: RDWN_CORNER;
|
||||
if (item)
|
||||
corner = 0;
|
||||
int corner = (f->size <= ds->analop.size)? RDWN_CORNER: LINE_VERT;
|
||||
corner = LINE_VERT; // 99% of cases
|
||||
RFlagItem *item = r_flag_get_i (core->flags, f->addr);
|
||||
corner = item? LINE_VERT: RDWN_CORNER;
|
||||
if (item)
|
||||
corner = 0;
|
||||
#endif
|
||||
handle_set_pre (ds, core->cons->vline[RUP_CORNER]);
|
||||
if (ds->show_color) {
|
||||
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_IMP)?"imp":"loc",
|
||||
f->name, f->size);
|
||||
} else {
|
||||
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_IMP)?"imp":"loc",
|
||||
f->name, f->size);
|
||||
}
|
||||
}
|
||||
if (sign) r_cons_printf ("// %s\n", sign);
|
||||
free (sign);
|
||||
sign = NULL;
|
||||
handle_set_pre (ds, core->cons->vline[LINE_VERT]);
|
||||
ds->pre = r_str_concat (ds->pre, " ");
|
||||
ds->stackptr = 0;
|
||||
if (ds->vars) {
|
||||
RList *args = r_anal_var_list (core->anal, f, 'a');
|
||||
RList *vars = r_anal_var_list (core->anal, f, 'v');
|
||||
r_list_join (vars, args);
|
||||
RAnalVar *var;
|
||||
RListIter *iter;
|
||||
r_list_foreach (vars, iter, var) {
|
||||
if (ds->show_color) {
|
||||
r_cons_printf ("%s%s %s"Color_RESET,
|
||||
ds->color_fline, core->cons->vline[LINE_VERT], ds->refline2);
|
||||
r_cons_printf ("%s; %s %s %s @ %s%s0x%x"Color_RESET"\n",
|
||||
ds->color_other,
|
||||
var->kind=='v'?"var":"arg",
|
||||
var->type,
|
||||
var->name,
|
||||
core->anal->reg->name[R_REG_NAME_BP],
|
||||
(var->kind=='v')?"-":"+",
|
||||
var->delta);
|
||||
} else {
|
||||
r_cons_printf ("%s %s",
|
||||
core->cons->vline[LINE_VERT], ds->refline2);
|
||||
r_cons_printf ("; %s %s %s @ %s%s0x%x\n",
|
||||
var->kind=='v'?"var":"arg",
|
||||
var->type,
|
||||
var->name,
|
||||
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);
|
||||
}
|
||||
handle_set_pre (ds, core->cons->vline[RUP_CORNER]);
|
||||
if (ds->show_color) {
|
||||
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_IMP)?"imp":"loc",
|
||||
f->name, f->size);
|
||||
} else {
|
||||
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_IMP)?"imp":"loc",
|
||||
f->name, f->size);
|
||||
}
|
||||
}
|
||||
if (sign) r_cons_printf ("// %s\n", sign);
|
||||
free (sign);
|
||||
sign = NULL;
|
||||
handle_set_pre (ds, core->cons->vline[LINE_VERT]);
|
||||
ds->pre = r_str_concat (ds->pre, " ");
|
||||
ds->stackptr = 0;
|
||||
if (ds->vars) {
|
||||
char spaces[32];
|
||||
RList *args = r_anal_var_list (core->anal, f, 'a');
|
||||
RList *vars = r_anal_var_list (core->anal, f, 'v');
|
||||
r_list_join (vars, args);
|
||||
RAnalVar *var;
|
||||
RListIter *iter;
|
||||
// TODO: show first args, and then vars
|
||||
r_list_foreach (vars, iter, var) {
|
||||
int idx;
|
||||
memset (spaces, ' ', sizeof(spaces));
|
||||
idx = 12-strlen (var->name);
|
||||
if (idx<0)idx = 0;
|
||||
spaces[idx] = 0;
|
||||
if (ds->show_color) {
|
||||
r_cons_printf ("%s%s %s"Color_RESET,
|
||||
ds->color_fline, core->cons->vline[LINE_VERT], ds->refline2);
|
||||
r_cons_printf ("%s; %s %s %s %s@ %s%s0x%x"Color_RESET"\n",
|
||||
ds->color_other,
|
||||
var->kind=='v'?"var":"arg",
|
||||
var->type,
|
||||
var->name,
|
||||
spaces,
|
||||
core->anal->reg->name[R_REG_NAME_BP],
|
||||
(var->kind=='v')?"-":"+",
|
||||
var->delta);
|
||||
} else {
|
||||
r_cons_printf ("%s %s",
|
||||
core->cons->vline[LINE_VERT], ds->refline2);
|
||||
r_cons_printf ("; %s %s %s %s@ %s%s0x%x\n",
|
||||
var->kind=='v'?"var":"arg",
|
||||
var->type,
|
||||
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) {
|
||||
int linelen, maxclen ;
|
||||
RAnalFunction *f;
|
||||
RFlagItem *item;
|
||||
/* show comment at right? */
|
||||
ds->show_comment_right = 0;
|
||||
if (ds->show_comments) {
|
||||
RAnalFunction *f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
||||
RFlagItem *item = r_flag_get_i (core->flags, ds->at);
|
||||
ds->comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at);
|
||||
if (!ds->comment && item && item->comment) {
|
||||
ds->ocomment = item->comment;
|
||||
ds->comment = strdup (item->comment);
|
||||
if (!ds->show_comments)
|
||||
return;
|
||||
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
|
||||
item = r_flag_get_i (core->flags, ds->at);
|
||||
ds->comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, ds->at);
|
||||
if (!ds->comment && item && 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;
|
||||
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->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 (!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
|
||||
r_cons_strcat ("; ");
|
||||
// XXX: always prefix with ; the comments
|
||||
if (*ds->comment != ';') r_cons_strcat (" ; ");
|
||||
r_cons_strcat_justify (ds->comment, mycols, ';');
|
||||
r_cons_strcat ("; ");
|
||||
// XXX: always prefix with ; the comments
|
||||
if (*ds->comment != ';') r_cons_strcat (" ; ");
|
||||
r_cons_strcat_justify (ds->comment, mycols, ';');
|
||||
#else
|
||||
infun = f && (f->addr != ds->at);
|
||||
if (infun) {
|
||||
char *str = strdup (ds->show_color?ds->color_fline: "");
|
||||
str = r_str_concat (str, core->cons->vline[LINE_VERT]);
|
||||
if (ds->show_color)
|
||||
str = r_str_concat (str, ds->color_flow);
|
||||
// color refline
|
||||
str = r_str_concat (str, " ");
|
||||
str = r_str_concat (str, ds->refline2);
|
||||
// color comment
|
||||
if (ds->show_color)
|
||||
str = r_str_concat (str, ds->color_comment);
|
||||
str = r_str_concat (str, "; ");
|
||||
ds->comment = r_str_prefix_all (ds->comment, str);
|
||||
free (str);
|
||||
} else {
|
||||
ds->comment = r_str_prefix_all (ds->comment, " ; ");
|
||||
}
|
||||
r_cons_strcat (ds->comment);
|
||||
infun = f && (f->addr != ds->at);
|
||||
if (infun) {
|
||||
char *str = strdup (ds->show_color?ds->color_fline: "");
|
||||
str = r_str_concat (str, core->cons->vline[LINE_VERT]);
|
||||
if (ds->show_color)
|
||||
str = r_str_concat (str, ds->color_flow);
|
||||
// color refline
|
||||
str = r_str_concat (str, " ");
|
||||
str = r_str_concat (str, ds->refline2);
|
||||
// color comment
|
||||
if (ds->show_color)
|
||||
str = r_str_concat (str, ds->color_comment);
|
||||
str = r_str_concat (str, "; ");
|
||||
ds->comment = r_str_prefix_all (ds->comment, str);
|
||||
free (str);
|
||||
} else {
|
||||
ds->comment = r_str_prefix_all (ds->comment, " ; ");
|
||||
}
|
||||
r_cons_strcat (ds->comment);
|
||||
#endif
|
||||
if (ds->show_color) handle_print_color_reset (core, ds);
|
||||
r_cons_newline ();
|
||||
free (ds->comment);
|
||||
ds->comment = NULL;
|
||||
if (ds->show_color) handle_print_color_reset (core, ds);
|
||||
r_cons_newline ();
|
||||
free (ds->comment);
|
||||
ds->comment = NULL;
|
||||
|
||||
/* flag one */
|
||||
if (item && item->comment && ds->ocomment != item->comment) {
|
||||
if (ds->show_color) r_cons_strcat (ds->pal_comment);
|
||||
r_cons_newline ();
|
||||
r_cons_strcat (" ; ");
|
||||
r_cons_strcat_justify (item->comment, mycols, ';');
|
||||
r_cons_newline ();
|
||||
if (ds->show_color) handle_print_color_reset (core, ds);
|
||||
}
|
||||
}
|
||||
/* flag one */
|
||||
if (item && item->comment && ds->ocomment != item->comment) {
|
||||
if (ds->show_color) r_cons_strcat (ds->pal_comment);
|
||||
r_cons_newline ();
|
||||
r_cons_strcat (" ; ");
|
||||
r_cons_strcat_justify (item->comment, mycols, ';');
|
||||
r_cons_newline ();
|
||||
if (ds->show_color) handle_print_color_reset (core, ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -531,6 +531,17 @@ typedef struct r_anal_switch_obj_t {
|
||||
RList *cases;
|
||||
} 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 {
|
||||
char *cpu;
|
||||
int bits;
|
||||
@ -585,6 +596,7 @@ typedef struct r_anal_t {
|
||||
#endif
|
||||
Sdb *sdb_hints; // OK
|
||||
//RList *hints; // XXX use better data structure here (slist?)
|
||||
RAnalCallbacks cb;
|
||||
} RAnal;
|
||||
|
||||
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);
|
||||
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_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);
|
||||
|
||||
/* 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_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 RAnalVar *r_anal_fcn_get_var(RAnalFunction *fs, int num, int dir);
|
||||
R_API void r_anal_fcn_fit_overlaps (RAnal *anal, RAnalFunction *fcn);
|
||||
|
@ -37,7 +37,7 @@ SDB_API SdbList *ls_new(void);
|
||||
SDB_API SdbListIter *ls_append(SdbList *list, void *data);
|
||||
SDB_API SdbListIter *ls_prepend(SdbList *list, void *data);
|
||||
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_delete (SdbList *list, SdbListIter *iter);
|
||||
|
@ -14,6 +14,19 @@ SDB_API SdbList *ls_new() {
|
||||
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) {
|
||||
if (!list || !iter) return;
|
||||
ls_split_iter (list, iter);
|
||||
|
@ -37,7 +37,7 @@ SDB_API SdbList *ls_new(void);
|
||||
SDB_API SdbListIter *ls_append(SdbList *list, void *data);
|
||||
SDB_API SdbListIter *ls_prepend(SdbList *list, void *data);
|
||||
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_delete (SdbList *list, SdbListIter *iter);
|
||||
|
@ -343,7 +343,7 @@ next_quote:
|
||||
} else {
|
||||
/* +[idx]key --> key[idx] + 1 */
|
||||
/* -[idx]key --> key[idx] - 1 */
|
||||
char *nstr, numstr[32];
|
||||
char *nstr, numstr[128];
|
||||
if (*cmd=='+') {
|
||||
curnum ++;
|
||||
} else if (*cmd=='-') {
|
||||
|
Loading…
Reference in New Issue
Block a user