* 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
This commit is contained in:
pancake 2010-09-18 02:51:17 +02:00
parent 90a2b9f84a
commit 1356a9bdd1
14 changed files with 229 additions and 137 deletions

View File

@ -2,3 +2,11 @@ Main developers aka /dev/radare
- pancake <nopcode.org>
- nibble.ds <gmail.com>
Contributors
- earada
- esteve <estlack.org>
- elektranox
- neuroflip
- graz
- pof

19
TODO
View File

@ -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
======

View File

@ -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;i<nargs;i++) {

View File

@ -7,7 +7,7 @@
/* restore program counter after breakpoint hit */
static int r_debug_recoil(RDebug *dbg) {
int recoil, ret = R_FALSE;
RRegisterItem *ri;
RRegItem *ri;
r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
ri = r_reg_get (dbg->reg, 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);

View File

@ -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));

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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 {

View File

@ -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

View File

@ -1,11 +1,10 @@
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
#include <r_reg.h>
/* 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; i<R_REG_TYPE_LAST; i++) {
arena = reg->regset[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;i<R_REG_TYPE_LAST;i++) {
list_for_each(pos, &reg->regset[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;i<R_REG_TYPE_LAST;i++) {
for (i=0; i<R_REG_TYPE_LAST; i++) {
arena = reg->regset[i].arena;
arena->size = 0;
list_for_each(pos, &reg->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);
}

View File

@ -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

View File

@ -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; i<R_REG_TYPE_LAST; i++)
list_for_each_safe (pos, n, &reg->regset[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<R_REG_NAME_LAST)
if (role>=0 && role<R_REG_NAME_LAST) {
reg->name[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 && role<R_REG_NAME_LAST)
return reg->name[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; i<R_REG_TYPE_LAST; i++) {
r_list_destroy (reg->regset[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; i<R_REG_NAME_LAST; i++)
reg->name[i] = NULL;
for (i=0; i<R_REG_TYPE_LAST; i++) {
INIT_LIST_HEAD (&reg->regset[i].arenas);
INIT_LIST_HEAD (&reg->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 (&reg->regset[i].arena->list,
&reg->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; i<R_REG_TYPE_LAST; i++) {
if (!(reg->regset[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; i<R_REG_TYPE_LAST; i++) {
if (r_list_length(reg->regset[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, &reg->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 (; i<e; i++)
list_for_each (pos, &reg->regset[i].regs) {
r = list_entry (pos, RRegisterItem, list);
if (!strcmp (r->name, name))
return r;
for (; i<e; i++) {
r_list_foreach (reg->regset[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 &reg->regset[type].regs;
return reg->regset[type].regs;
}

View File

@ -1,12 +1,12 @@
#include <r_reg.h>
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;
}