From 1356a9bdd1439e955c9a112f522777273d4d51d8 Mon Sep 17 00:00:00 2001 From: pancake Date: Sat, 18 Sep 2010 02:51:17 +0200 Subject: [PATCH] * Highlight destination offset when cursor on jmp/call in visual * Show call decompilations under the opcode as a comment * Rename RRegister as RReg - Deprecate r_reg_init and use r_reg_new - Rewrite the list.h dependency in r_reg in order to use r_list - Fix some memory leaks * Implement push/pop methods in RReg class - add test case using it - will be used for register diffing and tracing --- AUTHORS | 8 ++ TODO | 19 +++-- libr/core/cmd.c | 39 ++++++--- libr/debug/debug.c | 4 +- libr/debug/p/debug_native.c | 4 +- libr/debug/p/native/w32.c | 4 +- libr/debug/reg.c | 12 +-- libr/debug/trace.c | 2 +- libr/include/r_anal.h | 6 +- libr/include/r_reg.h | 29 ++++--- libr/reg/arena.c | 56 ++++++------- libr/reg/p/x86-linux.regs | 1 + libr/reg/reg.c | 153 +++++++++++++++++++++++------------- libr/reg/t/test.c | 29 +++++-- 14 files changed, 229 insertions(+), 137 deletions(-) diff --git a/AUTHORS b/AUTHORS index 9ac37bc79e..588a9995c0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,3 +2,11 @@ Main developers aka /dev/radare - pancake - nibble.ds + +Contributors + - earada + - esteve + - elektranox + - neuroflip + - graz + - pof diff --git a/TODO b/TODO index 7eeaeb4f65..fbf2c1b650 100644 --- a/TODO +++ b/TODO @@ -14,19 +14,12 @@ Questions 0.6 RELEASE =========== -* Add support for STATIC_PLUGINS in r_lang - - r_lang_define is implemented in lang.c, but requires the collaboration - of the plugins to properly setup the environment for the script execution. - - Add support for STATIC_PLUGINS in r_lang - - dlerror(/usr/lib/radare2/lang_perl.so): libperl.so: cannot open shared object file: No such file or directory - This issue is fixed by setting LD_LIBRARY_PATH...looks like dlopen ignores rpath * Colorize destination address when cursor in branch * Reimplement or fix the delta diffing in C - first we need to do it for ired.. * Add dex format support to rabin (android) * Trace contents of buffers: filter search results..? cc 8080 @@ hit* .. check for values that has changed. * Create radare2-testsuite project -* Colorize registers that has changed Build system: ------------- @@ -70,6 +63,7 @@ TODO pancake ------------ * Display eflags in ascii mode - use r_str_bits() + - r_reg must have a format string for flags, using r_str_bitz - r_reg_eflags(dbg->reg, "cpastidor", mode) // must be in r_util.. as a bit helper - static buffer in dbg->reg..fixed size (32) - printf("eflags: %s\n", r_reg_get_flags (dbg->reg, "cpastidor"); @@ -90,10 +84,8 @@ TODO pancake - function signature comparsion if they dont match r_anal_fcn_cmp (anal, f1, f2); } - - add support for sign/unsigned registers..or at least a way to cast them - add push/pop of register states (maybe we only need 2 levels of states) - - display regs in colors - - can be used for diffing registers + - display changed registers in colors - is also useful to store values before emulating code - we can probably implement this in a clone() method? (too heavy? more orgtogonal) @@ -143,7 +135,14 @@ Refactoring 0.7 === * Is RCore->block and blocksize a RBuf ? refactor!11 +* add support for sign/unsigned registers..or at least a way to cast them * Implement rap:// upload/download protocol commands (maybe just system() with rsc2+wget? +* Add support for STATIC_PLUGINS in r_lang + - r_lang_define is implemented in lang.c, but requires the collaboration + of the plugins to properly setup the environment for the script execution. + - Add support for STATIC_PLUGINS in r_lang + - dlerror(/usr/lib/radare2/lang_perl.so): libperl.so: cannot open shared object file: No such file or directory + This issue is fixed by setting LD_LIBRARY_PATH...looks like dlopen ignores rpath Future ====== diff --git a/libr/core/cmd.c b/libr/core/cmd.c index 1b8c53fe0a..8f2ba81357 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -25,6 +25,11 @@ static int checkbpcallback(RCore *core) { return R_FALSE; } +static void printoffset(ut64 off, int show_color) { + if (show_color) + r_cons_printf (Color_GREEN"0x%08"PFMT64x" "Color_RESET, off); + else r_cons_printf ("0x%08"PFMT64x" ", off); +} /* TODO: move to print/disasm.c */ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int l) { RAnalFcn *fcn, *fcni = NULL; @@ -39,8 +44,8 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, RAnalOp analop; RFlagItem *flag; RMetaItem *mi; + ut64 dest = UT64_MAX; - r_vm_reset (core->vm); // TODO: import values from debugger is possible // TODO: allow to get those register snapshots from traces // TODO: per-function register state trace @@ -64,6 +69,7 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int linesopts = 0; nb = nbytes*2; + r_vm_reset (core->vm); if (core->print->cur_enabled) { if (core->print->cur<0) core->print->cur = 0; @@ -92,6 +98,22 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, } } #endif + if (core->print->cur_enabled) { + // TODO: support in-the-middle-of-instruction too + int ret = r_anal_aop (core->anal, &analop, core->offset+core->print->cur, + buf+core->print->cur, (int)(len-core->print->cur)); + // TODO: check for analop.type and ret + dest = analop.jump; +#if 0 + if (ret) + switch (analop.type) { + case R_ANAL_OP_TYPE_JMP: + case R_ANAL_OP_TYPE_CALL: + dest = analop.jump; + break; + } +#endif + } // TODO: make anal->reflines implicit free (core->reflines); // TODO: leak free (core->reflines2); // TODO: leak @@ -187,19 +209,16 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, if (flag && !show_bytes) { if (show_lines && line) r_cons_strcat (line); - if (show_offset) { - if (show_color) - r_cons_printf (Color_GREEN"0x%08"PFMT64x" "Color_RESET, at); - else r_cons_printf ("0x%08"PFMT64x" ", at); - } + if (show_offset) + printoffset(at, show_color); r_cons_printf ("%s:\n", flag->name); } if (show_lines && line) r_cons_strcat (line); if (show_offset) { - if (show_color) - r_cons_printf (Color_GREEN"0x%08"PFMT64x" "Color_RESET, at); - else r_cons_printf ("0x%08"PFMT64x" ", at); + if (at == dest) + r_cons_invert (R_TRUE, R_TRUE); + printoffset (at, show_color); } if (show_trace) { RDebugTracepoint *tp = r_debug_trace_get (core->dbg, at); @@ -375,8 +394,8 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, if((st64)esp<0) esp=-esp; nargs = (esp)/4; #endif - fcn = r_anal_fcn_find (core->anal, analop.jump); + r_cons_printf("\n "); if(fcn&&fcn->name) r_cons_printf ("; %s(", fcn->name); else r_cons_printf ("; 0x%08"PFMT64x"(", analop.jump); for(i=0;ireg, dbg->reg->name[R_REG_NAME_PC], -1); if (ri) { @@ -83,7 +83,7 @@ R_API ut64 r_debug_execute(struct r_debug_t *dbg, ut8 *buf, int len) { int orig_sz; ut8 stackbackup[4096]; ut8 *backup, *orig = NULL; - RRegisterItem *ri, *risp, *ripc; + RRegItem *ri, *risp, *ripc; ut64 rsp, rpc, ra0 = 0LL; ripc = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_PC], R_REG_TYPE_GPR); risp = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_PC], R_REG_TYPE_GPR); diff --git a/libr/debug/p/debug_native.c b/libr/debug/p/debug_native.c index 89def2e147..b181e0591c 100644 --- a/libr/debug/p/debug_native.c +++ b/libr/debug/p/debug_native.c @@ -839,7 +839,7 @@ static int r_debug_native_bp_read(int pid, ut64 addr, int hw, int rwx) { #if __i386__ /* TODO: Can I use this as in a coroutine? */ static RList *r_debug_native_frames(RDebug *dbg) { - RRegister *reg = dbg->reg; + RReg *reg = dbg->reg; ut32 i, _esp, esp, ebp2; RList *list = r_list_new (); RIOBind *bio = &dbg->iob; @@ -873,7 +873,7 @@ static RList *r_debug_native_frames(RDebug *dbg) { ut64 ptr, ebp2; ut64 _rip, _rsp, _rbp; RList *list; - RRegister *reg = dbg->reg; + RReg *reg = dbg->reg; RIOBind *bio = &dbg->iob; _rip = r_reg_get_value (reg, r_reg_get (reg, "rip", R_REG_TYPE_GPR)); diff --git a/libr/debug/p/native/w32.c b/libr/debug/p/native/w32.c index 366a0eae61..1a81bb51f9 100644 --- a/libr/debug/p/native/w32.c +++ b/libr/debug/p/native/w32.c @@ -18,7 +18,7 @@ 1865 DWORD ErrorSelector; 1866 DWORD DataOffset; 1867 DWORD DataSelector; -1868 BYTE RegisterArea[80]; +1868 BYTE RegArea[80]; 1869 DWORD Cr0NpxState; 1870 } FLOATING_SAVE_AREA; @@ -47,7 +47,7 @@ 1893 DWORD EFlags; 1894 DWORD Esp; 1895 DWORD SegSs; -1896 BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; +1896 BYTE ExtendedRegs[MAXIMUM_SUPPORTED_EXTENSION]; 1897 } CONTEXT; #endif diff --git a/libr/debug/reg.c b/libr/debug/reg.c index bebf09c967..4b19835f58 100644 --- a/libr/debug/reg.c +++ b/libr/debug/reg.c @@ -28,8 +28,11 @@ R_API int r_debug_reg_sync(struct r_debug_t *dbg, int type, int write) { R_API int r_debug_reg_list(struct r_debug_t *dbg, int type, int size, int rad) { int cols, n = 0; - struct list_head *pos, *head; + RList *head; //struct list_head *pos, *head; + RListIter *iter; + RRegItem *item; const char *fmt, *fmt2; + if (!dbg || !dbg->reg) return R_FALSE; head = r_reg_get_list(dbg->reg, type); @@ -42,9 +45,8 @@ R_API int r_debug_reg_list(struct r_debug_t *dbg, int type, int size, int rad) { fmt2 = "%4s 0x%08"PFMT64x"%s"; cols = 4; } - list_for_each (pos, head) { + r_list_foreach (head, iter, item) { ut64 value; - struct r_reg_item_t *item = list_entry (pos, struct r_reg_item_t, list); if (type != -1 && type != item->type) continue; if (size != 0 && size != item->size) @@ -63,7 +65,7 @@ R_API int r_debug_reg_list(struct r_debug_t *dbg, int type, int size, int rad) { } R_API int r_debug_reg_set(struct r_debug_t *dbg, const char *name, ut64 num) { - RRegisterItem *ri; + RRegItem *ri; int role = r_reg_get_name_idx (name); if (!dbg || !dbg->reg) return R_FALSE; @@ -78,7 +80,7 @@ R_API int r_debug_reg_set(struct r_debug_t *dbg, const char *name, ut64 num) { } R_API ut64 r_debug_reg_get(struct r_debug_t *dbg, const char *name) { - RRegisterItem *ri = NULL; + RRegItem *ri = NULL; ut64 ret = 0LL; int role = r_reg_get_name_idx (name); if (!dbg || !dbg->reg) diff --git a/libr/debug/trace.c b/libr/debug/trace.c index 3d3a0855c8..5a8d2a39af 100644 --- a/libr/debug/trace.c +++ b/libr/debug/trace.c @@ -29,7 +29,7 @@ R_API int r_debug_trace_tag (RDebug *dbg, int tag) { R_API int r_debug_trace_pc (RDebug *dbg) { ut8 buf[32]; - RRegisterItem *ri; + RRegItem *ri; RAnalOp aop; static ut64 oldpc = 0LL; // Must trace the previously traced instruction r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE); diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index 7a5501155c..02f30813be 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -127,7 +127,7 @@ typedef struct r_anal_t { RList *bbs; RList *fcns; RList *vartypes; - RRegister *reg; + RReg *reg; struct r_anal_ctx_t *ctx; struct r_anal_plugin_t *cur; struct list_head anals; @@ -140,8 +140,8 @@ typedef struct r_anal_value_t { ut64 base ; // numeric address int delta; // numeric delta int mul; // multiplier (reg*4+base) - RRegisterItem *reg; // register index used (-1 if no reg) - RRegisterItem *regdelta; // register index used (-1 if no reg) + RRegItem *reg; // register index used (-1 if no reg) + RRegItem *regdelta; // register index used (-1 if no reg) } RAnalValue; typedef struct r_anal_aop_t { diff --git a/libr/include/r_reg.h b/libr/include/r_reg.h index 3c6aa58027..33a8649ead 100644 --- a/libr/include/r_reg.h +++ b/libr/include/r_reg.h @@ -36,32 +36,31 @@ typedef struct r_reg_item_t { int offset; // offset in data structure int packed_size; /* 0 means no packed register, 1byte pack, 2b pack... */ struct list_head list; -} RRegisterItem; +} RRegItem; typedef struct r_reg_arena_t { ut8 *bytes; int size; struct list_head list; -} RRegisterArena; +} RRegArena; typedef struct r_reg_set_t { - struct r_reg_arena_t *arena; - struct list_head arenas; /* r_reg_arena_t */ - struct list_head regs; /* r_reg_item_t */ -} RRegisterSet; + RRegArena *arena; + RList *pool; /* RRegArena */ + RList *regs; /* RRegItem */ +} RRegSet; typedef struct r_reg_t { char *profile; char *name[R_REG_NAME_LAST]; - RRegisterSet regset[R_REG_TYPE_LAST]; -} RRegister; + RRegSet regset[R_REG_TYPE_LAST]; +} RReg; -#define r_reg_new() r_reg_init (R_NEW (RRegister)) #ifdef R_API R_API const char *r_reg_get_type(int idx); R_API struct r_reg_t *r_reg_free(struct r_reg_t *reg); -R_API struct r_reg_t *r_reg_init(struct r_reg_t *reg); +R_API struct r_reg_t *r_reg_new(); //R_API struct r_reg_t *r_reg_new(); R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *profile); R_API int r_reg_set_profile(struct r_reg_t *reg, const char *profile); @@ -71,7 +70,7 @@ R_API const char *r_reg_get_name(struct r_reg_t *reg, int kind); R_API int r_reg_set_name(struct r_reg_t *reg, int role, const char *name); R_API struct r_reg_item_t *r_reg_get(struct r_reg_t *reg, const char *name, int type); -R_API struct list_head *r_reg_get_list(struct r_reg_t *reg, int type); +R_API RList *r_reg_get_list(struct r_reg_t *reg, int type); R_API int r_reg_type_by_name(const char *str); /* value */ @@ -85,11 +84,11 @@ R_API int r_reg_set_pvalue(struct r_reg_t *reg, struct r_reg_item_t *item, ut64 /* byte arena */ R_API ut8* r_reg_get_bytes(struct r_reg_t *reg, int type, int *size); R_API int r_reg_set_bytes(struct r_reg_t *reg, int type, const ut8* buf, int len); -R_API RRegisterArena *r_reg_arena_new (int size); +R_API RRegArena *r_reg_arena_new (int size); +R_API void r_reg_arena_free(RRegArena* ra); R_API int r_reg_fit_arena(struct r_reg_t *reg); - -// TODO: r_reg typedef must be renamed to this shorter version -#define RReg RRegister +R_API int r_reg_push(RReg *reg); +R_API void r_reg_pop(RReg *reg); #endif #endif diff --git a/libr/reg/arena.c b/libr/reg/arena.c index 89eeb3c39e..9466503f65 100644 --- a/libr/reg/arena.c +++ b/libr/reg/arena.c @@ -1,11 +1,10 @@ /* radare - LGPL - Copyright 2009-2010 pancake */ #include -/* TODO: add push/pop.. */ /* non-endian safe - used for raw mapping with system registers */ -R_API ut8* r_reg_get_bytes(struct r_reg_t *reg, int type, int *size) { - RRegisterArena *arena; +R_API ut8* r_reg_get_bytes(RReg *reg, int type, int *size) { + RRegArena *arena; int i, sz, osize; ut8 *buf; if (type == -1) { @@ -38,22 +37,21 @@ R_API ut8* r_reg_get_bytes(struct r_reg_t *reg, int type, int *size) { } /* reduce number of return statements */ -R_API int r_reg_set_bytes(struct r_reg_t *reg, int type, const ut8* buf, int len) { +R_API int r_reg_set_bytes(RReg *reg, int type, const ut8* buf, int len) { int i, ret = R_FALSE; struct r_reg_set_t *regset; - struct r_reg_arena_t *arena; + RRegArena *arena; int off = 0; if (type == -1) { ret = R_TRUE; /* deserialize ALL register types in a single buffer */ for(i=0; iregset[i].arena; - if (arena == NULL) { - arena = reg->regset[i].arena = R_NEW (RRegisterArena); + if (!reg->regset[i].arena) { + arena = reg->regset[i].arena = R_NEW (RRegArena); arena->size = len; arena->bytes = malloc(len); - } + } else arena = reg->regset[i].arena; if (arena->bytes == NULL) return R_FALSE; memcpy (arena->bytes, buf+off, arena->size); @@ -75,16 +73,14 @@ R_API int r_reg_set_bytes(struct r_reg_t *reg, int type, const ut8* buf, int len return ret; } -R_API int r_reg_export_to(struct r_reg_t *reg, struct r_reg_t *dst) { - //struct r_reg_arena_t *arena; - struct r_reg_item_t *r; - struct list_head *pos; +R_API int r_reg_export_to(RReg *reg, RReg *dst) { + RRegItem *r; + RListIter *iter; int i, ret = R_FALSE; if (dst) { // foreach reg of every time in reg, define it in dst for(i=0;iregset[i].regs) { - r = list_entry(pos, struct r_reg_item_t, list); + r_list_foreach (reg->regset[i].regs, iter, r) { // TODO: export to not implemented //r_reg_set(dst, r_reg_get(dst, r->name), ); //r_mem_copybits_delta( @@ -94,19 +90,18 @@ R_API int r_reg_export_to(struct r_reg_t *reg, struct r_reg_t *dst) { return ret; } -R_API int r_reg_fit_arena(struct r_reg_t *reg) { - struct list_head *pos; - struct r_reg_item_t *r; - struct r_reg_arena_t *arena; +R_API int r_reg_fit_arena(RReg *reg) { + RRegArena *arena; + RListIter *iter; + RRegItem *r; int size, i; /* propagate arenas */ - for(i=0;iregset[i].arena; arena->size = 0; - list_for_each(pos, ®->regset[i].regs) { - r = list_entry(pos, struct r_reg_item_t, list); - size = BITS2BYTES(r->offset+r->size); + r_list_foreach (reg->regset[i].regs, iter, r) { + size = BITS2BYTES (r->offset+r->size); if (size>arena->size) { arena->size = size; arena->bytes = realloc (arena->bytes, size); @@ -114,18 +109,25 @@ R_API int r_reg_fit_arena(struct r_reg_t *reg) { return R_FALSE; } } - memset(arena->bytes, 0, arena->size); + memset (arena->bytes, 0, arena->size); } return R_TRUE; } -R_API RRegisterArena *r_reg_arena_new (int size) { - RRegisterArena *arena = R_NEW (RRegisterArena); +R_API RRegArena *r_reg_arena_new (int size) { + RRegArena *arena = R_NEW (RRegArena); if (arena) { - if ((arena->bytes = malloc (size+8)) == NULL) { + if (size<1) + size = 1; + if (!(arena->bytes = malloc (size+8))) { free (arena); arena = NULL; } else arena->size = size; } return arena; } + +R_API void r_reg_arena_free(RRegArena* ra) { + free (ra->bytes); + free (ra); +} diff --git a/libr/reg/p/x86-linux.regs b/libr/reg/p/x86-linux.regs index 8edb97192c..33cb8937a2 100644 --- a/libr/reg/p/x86-linux.regs +++ b/libr/reg/p/x86-linux.regs @@ -25,6 +25,7 @@ seg xgs .32 40 0 seg xcs .32 52 0 seg xss .32 52 0 gpr eflags .32 56 0 +#>cpazstidor0 carry parity above zero XX trap XX direction XX XX XX # base address is 448bit flg carry .1 .448 0 diff --git a/libr/reg/reg.c b/libr/reg/reg.c index f843c904eb..c312f259d4 100644 --- a/libr/reg/reg.c +++ b/libr/reg/reg.c @@ -14,17 +14,9 @@ R_API const char *r_reg_get_type(int idx) { return NULL; } -static void r_reg_free_internal(struct r_reg_t *reg) { - struct list_head *pos, *n; - RRegisterItem *r; - int i; - - for (i=0; iregset[i].regs) { - r = list_entry (pos, RRegisterItem, list); - list_del (&r->list); - free (r); - } +static void r_reg_item_free(RRegItem *item) { + free (item->name); + free (item); } R_API int r_reg_get_name_idx(const char *type) { @@ -42,51 +34,107 @@ R_API int r_reg_get_name_idx(const char *type) { return -1; } -R_API int r_reg_set_name(struct r_reg_t *reg, int role, const char *name) { - int ret = R_TRUE; + +R_API int r_reg_set_name(RReg *reg, int role, const char *name) { // TODO: ensure this range check in a define.. somewhere - if (role>=0 && role=0 && rolename[role] = r_str_dup (reg->name[role], name); - else ret = R_FALSE; - return ret; + return R_TRUE; + } + return R_FALSE; } -R_API const char *r_reg_get_name(struct r_reg_t *reg, int role) { +R_API const char *r_reg_get_name(RReg *reg, int role) { if (reg && role>=0 && rolename[role]; return NULL; } -R_API struct r_reg_t *r_reg_free(struct r_reg_t *reg) { +R_API void r_reg_free_internal(RReg *reg) { + int i; + for (i=0; iregset[i].regs); + r_list_destroy (reg->regset[i].pool); + reg->regset[i].arena = r_reg_arena_new (0); + } +} + +R_API RReg *r_reg_free(RReg *reg) { if (reg) { - // TODO: free more things here + r_reg_free_internal (reg); free (reg); } return NULL; } -// TODO: must be deprecated.. use from _new() -R_API struct r_reg_t *r_reg_init(struct r_reg_t *reg) { +R_API RReg *r_reg_new() { + RReg *reg = R_NEW (RReg); int i; - if (!reg) - return NULL; reg->profile = NULL; for (i=0; iname[i] = NULL; for (i=0; iregset[i].arenas); - INIT_LIST_HEAD (®->regset[i].regs); - if ((reg->regset[i].arena = r_reg_arena_new (0)) == NULL) + reg->regset[i].pool = r_list_new (); + reg->regset[i].pool->free = (RListFree)r_reg_arena_free; + reg->regset[i].regs = r_list_new (); + reg->regset[i].regs->free = (RListFree)r_reg_item_free; + if (!(reg->regset[i].arena = r_reg_arena_new (0))) return NULL; - list_add_tail (®->regset[i].arena->list, - ®->regset[i].arenas); + r_list_append (reg->regset[i].pool, reg->regset[i].arena); } return reg; } -static RRegisterItem *r_reg_item_new() { - RRegisterItem *item = R_NEW (RRegisterItem); - memset (item, 0, sizeof (RRegisterItem)); +R_API int r_reg_push(RReg *reg) { + int i; + for (i=0; iregset[i].arena = r_reg_arena_new (0))) + return 0; + r_list_prepend (reg->regset[i].pool, reg->regset[i].arena); + } + return r_list_length (reg->regset[0].pool); +} + +/* + +arena2 + +// notify the debugger that something has changed, and registers needs to be pushed +r_debug_reg_change() + +for(;;) { + read_regs \___ reg_pre() + r_reg_push / + + step + + read_regs \_. + r_reg_cmp(); / '- reg_post() + + r_reg_pop() >-- reg_fini() +} +*/ + + +R_API void r_reg_pop(RReg *reg) { + int i; + for (i=0; iregset[i].pool)>0) { + r_list_delete (reg->regset[i].pool, + r_list_head (reg->regset[i].pool)); + // SEGFAULT: r_reg_arena_free (reg->regset[i].arena); + reg->regset[i].arena = (RRegArena*)r_list_head ( + reg->regset[i].pool); + } else { + eprintf ("Cannot pop more\n"); + break; + } + } +} + +static RRegItem *r_reg_item_new() { + RRegItem *item = R_NEW (RRegItem); + memset (item, 0, sizeof (RRegItem)); return item; } @@ -102,7 +150,7 @@ R_API int r_reg_type_by_name(const char *str) { } /* TODO: make this parser better and cleaner */ -static int r_reg_set_word(RRegisterItem *item, int idx, char *word) { +static int r_reg_set_word(RRegItem *item, int idx, char *word) { int ret = R_TRUE; switch(idx) { case 0: @@ -135,8 +183,8 @@ static int r_reg_set_word(RRegisterItem *item, int idx, char *word) { } /* TODO: make this parser better and cleaner */ -R_API int r_reg_set_profile_string(RRegister *reg, const char *str) { - RRegisterItem *item; +R_API int r_reg_set_profile_string(RReg *reg, const char *str) { + RRegItem *item; int setname = -1; int ret = R_FALSE; int lastchar = 0; @@ -160,7 +208,7 @@ R_API int r_reg_set_profile_string(RRegister *reg, const char *str) { switch (*str) { case ' ': case '\t': - // UGLY PASTAFARIAN TO PARSE + /* UGLY PASTAFARIAN PARSING */ if (word==0 && *buf=='=') { setname = r_reg_get_name_idx (buf+1); if (setname == -1) @@ -177,7 +225,7 @@ R_API int r_reg_set_profile_string(RRegister *reg, const char *str) { else if (word>3) { r_reg_set_word (item, word, buf); if (item->name != NULL) { - list_add_tail(&item->list, ®->regset[item->type].regs); + r_list_append (reg->regset[item->type].regs, item); item = r_reg_item_new(); } } @@ -194,16 +242,13 @@ R_API int r_reg_set_profile_string(RRegister *reg, const char *str) { lastchar = *str; str++; } - free (item->name); - free (item); + r_reg_item_free (item); r_reg_fit_arena (reg); - - /* do we reach the end ? */ - if (!*str) ret = R_TRUE; - return ret; + + return *str?ret:R_TRUE; } -R_API int r_reg_set_profile(struct r_reg_t *reg, const char *profile) { +R_API int r_reg_set_profile(RReg *reg, const char *profile) { int ret = R_FALSE; const char *base; char *str, *file; @@ -222,9 +267,9 @@ R_API int r_reg_set_profile(struct r_reg_t *reg, const char *profile) { return ret; } -R_API RRegisterItem *r_reg_get(struct r_reg_t *reg, const char *name, int type) { - struct list_head *pos; - RRegisterItem *r; +R_API RRegItem *r_reg_get(RReg *reg, const char *name, int type) { + RListIter *iter; + RRegItem *r; int i, e; if (!reg) return NULL; @@ -236,19 +281,17 @@ R_API RRegisterItem *r_reg_get(struct r_reg_t *reg, const char *name, int type) e = type+1; } - // TODO: use RList here - for (; iregset[i].regs) { - r = list_entry (pos, RRegisterItem, list); - if (!strcmp (r->name, name)) - return r; + for (; iregset[i].regs, iter, r) { + if (!strcmp (r->name, name)) + return r; + } } return NULL; } -// TODO: deprecate.. must use RList here -R_API struct list_head *r_reg_get_list(struct r_reg_t *reg, int type) { +R_API RList *r_reg_get_list(RReg *reg, int type) { if (type<0 || type>R_REG_TYPE_LAST) return NULL; - return ®->regset[type].regs; + return reg->regset[type].regs; } diff --git a/libr/reg/t/test.c b/libr/reg/t/test.c index dfa86f3c73..570cb21a36 100644 --- a/libr/reg/t/test.c +++ b/libr/reg/t/test.c @@ -1,12 +1,12 @@ #include -void show_regs(struct r_reg_t *reg, int bitsize) -{ - struct list_head *pos, *reglist; +void show_regs(struct r_reg_t *reg, int bitsize) { + RList *reglist; + RListIter *iter; + RRegItem *ri; printf("%d bit registers:\n", bitsize); reglist = r_reg_get_list(reg, R_REG_TYPE_GPR); - list_for_each(pos, reglist) { - struct r_reg_item_t *ri = list_entry(pos, struct r_reg_item_t, list); + r_list_foreach (reglist, iter, ri) { if (ri->size == bitsize) printf(" - %s : 0x%08"PFMT64x"\n", ri->name, r_reg_get_value(reg, ri)); } @@ -37,5 +37,24 @@ int main() { for (i=0;(type=r_reg_get_type(i));i++) printf (" - %s\n", type); + r_reg_push(reg); + r_reg_pop(reg); + + r_reg_push(reg); + r_reg_push(reg); + r_reg_push(reg); + r_reg_pop(reg); + r_reg_pop(reg); + r_reg_push(reg); + r_reg_pop(reg); + r_reg_pop(reg); + +/* + r_reg_pop(reg); + r_reg_pop(reg); + r_reg_pop(reg); + r_reg_pop(reg); +*/ + return 0; }