diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index b531108643..fdfbaed897 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -1124,6 +1124,17 @@ static void ar_show_help(RCore *core) { r_core_cmd_help (core, help_message); } +static void cmd_ara_help(RCore *core) { + const char* help_msg[] = { + "Usage:", "ara[+-s]", "Register Arena Push/Pop/Swap", + "ara", "", "show all register arenas allocated", + "ara", "+", "push a new register arena for each type", + "ara", "-", "pop last register arena", + "aras", "", "swap last two register arenas", + NULL }; + r_core_cmd_help (core, help_msg); +} + // XXX dup from drp :OOO void cmd_anal_reg(RCore *core, const char *str) { int size = 0, i, type = R_REG_TYPE_GPR; @@ -1158,6 +1169,12 @@ void cmd_anal_reg(RCore *core, const char *str) { break; case 'a': // "ara" switch (str[1]) { + case '?': + cmd_ara_help (core); + break; + case 's': + r_reg_arena_swap (core->anal->reg, false); + break; case '+': r_reg_arena_push (core->anal->reg); break; diff --git a/libr/include/r_reg.h b/libr/include/r_reg.h index 34543e0224..88cc769ada 100644 --- a/libr/include/r_reg.h +++ b/libr/include/r_reg.h @@ -170,7 +170,7 @@ R_API ut64 r_reg_get_pack(RReg *reg, RRegItem *item, int packidx, int packbits); /* byte arena */ R_API ut8* r_reg_get_bytes(RReg *reg, int type, int *size); -R_API int r_reg_set_bytes(RReg *reg, int type, const ut8* buf, const int len); +R_API bool r_reg_set_bytes(RReg *reg, int type, const ut8* buf, const int len); 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(RReg *reg); diff --git a/libr/reg/arena.c b/libr/reg/arena.c index 71625d578f..b7a6d8a0a9 100644 --- a/libr/reg/arena.c +++ b/libr/reg/arena.c @@ -30,7 +30,6 @@ R_API ut8* r_reg_get_bytes(RReg *reg, int type, int *size) { if (size) *size = sz; return buf; } - if (type < 0 || type > (R_REG_TYPE_LAST-1)) return NULL; sz = reg->regset[type].arena->size; @@ -44,16 +43,16 @@ R_API ut8* r_reg_get_bytes(RReg *reg, int type, int *size) { } /* reduce number of return statements */ -R_API int r_reg_set_bytes(RReg *reg, int type, const ut8* buf, const int len) { - int i, ret = R_FALSE; +R_API bool r_reg_set_bytes(RReg *reg, int type, const ut8* buf, const int len) { + int i, ret = false; struct r_reg_set_t *regset; RRegArena *arena; int off = 0; if (len<0 || !buf) - return R_FALSE; + return false; if (type == -1) { - ret = R_TRUE; + ret = true; /* deserialize ALL register types in a single buffer */ for (i=0; iregset[i].arena) { @@ -72,7 +71,7 @@ R_API int r_reg_set_bytes(RReg *reg, int type, const ut8* buf, const int len) { R_MIN (len-off, arena->size)); off += arena->size; if (off>len) { - ret = R_FALSE; + ret = false; break; } } @@ -85,7 +84,7 @@ R_API int r_reg_set_bytes(RReg *reg, int type, const ut8* buf, const int len) { arena->bytes = malloc (len); if (!arena->bytes) { arena->size = 0; - return R_FALSE; + return false; } arena->size = len; } @@ -96,7 +95,7 @@ R_API int r_reg_set_bytes(RReg *reg, int type, const ut8* buf, const int len) { arena->bytes = buf; } else { eprintf ("Error resizing arena to %d\n", len); - return R_FALSE; + return false; } } if (arena->bytes) { @@ -104,8 +103,8 @@ R_API int r_reg_set_bytes(RReg *reg, int type, const ut8* buf, const int len) { //len = R_MIN (len, arena->size); memset (arena->bytes, 0, arena->size); memcpy (arena->bytes, buf, len); - ret = R_TRUE; - } else ret = R_FALSE; + ret = true; + } else ret = false; } } return ret; @@ -191,6 +190,7 @@ R_API void r_reg_arena_swap(RReg *reg, int copy) { void *tmp = ia->data; ia->data = ib->data; ib->data = tmp; + reg->regset[i].arena = ia->data; } else { //eprintf ("Cannot pop more\n"); break; @@ -203,8 +203,8 @@ R_API void r_reg_arena_swap(RReg *reg, int copy) { } R_API int r_reg_arena_set(RReg *reg, int n, int copy) { -// XXX this api should be deprecated -return false; + // XXX this api should be deprecated + return false; #if 0 int i; // XXX this shuoldnt be used at all @@ -238,19 +238,15 @@ return false; } R_API void r_reg_arena_pop(RReg *reg) { + RRegArena *a; int i; for (i=0; iregset[i].pool) > 1) { - RRegArena *a = r_list_pop (reg->regset[i].pool); - a = reg->regset[i].pool->tail->data; - if (a) { - reg->regset[i].arena = a; - //if (!i) { r_print_hexdump (NULL, 0, a->bytes, a->size, 16, 16); } - } - } else { - eprintf ("Cannot pop more\n"); - break; - } + if (r_list_length (reg->regset[i].pool) < 2) + continue; + a = r_list_pop (reg->regset[i].pool); + r_reg_arena_free (a); + a = reg->regset[i].pool->tail->data; + if (a) reg->regset[i].arena = a; } } diff --git a/libr/reg/profile.c b/libr/reg/profile.c index 1da6e28a8e..05c8e38448 100644 --- a/libr/reg/profile.c +++ b/libr/reg/profile.c @@ -87,6 +87,8 @@ R_API int r_reg_set_profile_string(RReg *reg, const char *str) { if (reg->reg_profile_str && !strcmp (reg->reg_profile_str, str)) return true; + // we should reset all the arenas before setting the new reg profile + r_reg_arena_pop (reg); // Purge the old registers r_reg_free_internal (reg); @@ -157,6 +159,10 @@ R_API int r_reg_set_profile_string(RReg *reg, const char *str) { reg->size += 8 - (reg->size&7); reg->size >>= 3; // bits to bytes (divide by 8) r_reg_fit_arena (reg); + + // dup the last arena to allow regdiffing + r_reg_arena_push (reg); + // reset arenas return true; }