From 54c70fc87cf65252cdd9051c18ee6556abb2c5fc Mon Sep 17 00:00:00 2001 From: pancake/fluendo Date: Wed, 3 Feb 2010 18:15:31 +0100 Subject: [PATCH] * Added 'drn' debug register name command - Used to retrieve cross-platform register names from specified role. (pc, sp, bp, a0, ...) * Fix register roles in arm and enhace a bit more the r_reg_profile parser to handle some weird situations. * Fix all build warnings related to libgdbwrap * Added r_reg_get_name_idx .. this way {get,set}_name get the same parameters. --- libr/core/cmd.c | 42 +++++++++++++--------- libr/core/core.c | 5 +++ libr/core/io.c | 6 ++-- libr/debug/p/debug_ptrace.c | 12 +++---- libr/debug/p/gdb.mk | 1 + libr/debug/p/libgdbwrap/include/revm.h | 4 +-- libr/include/r_reg.h | 4 +++ libr/reg/reg.c | 50 ++++++++++++++------------ 8 files changed, 74 insertions(+), 50 deletions(-) diff --git a/libr/core/cmd.c b/libr/core/cmd.c index 6368717d15..4822831f7f 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -44,6 +44,7 @@ static void r_core_cmd_reg (struct r_core_t *core, const char *str) { " drp display current register profile\n" " dr show 'gpr' registers\n" " drt show all register types\n" + " drn [pc] get register name for pc,sp,bp,a0-3\n" " dr all show all registers\n" " dr flg 1 show flag registers ('flg' is type, see drt)\n" " dr 16 show 16 bit registers\n" @@ -69,6 +70,14 @@ static void r_core_cmd_reg (struct r_core_t *core, const char *str) { if (r == NULL) eprintf ("Unknown register (%s)\n", str+1); else r_cons_printf ("0x%08llx\n", r_reg_get_value (core->dbg.reg, r)); break; + case 'n': + { + char *reg = r_reg_get_name (core->dbg.reg, r_reg_get_name_idx (str+2)); + if (reg && *reg) + r_cons_printf ("%s\n", reg); + else eprintf ("Oops. try dn [pc|sp|bp|a0|a1|a2|a3]\n"); + } + break; case '*': r_debug_reg_sync (&core->dbg, R_REG_TYPE_GPR, R_FALSE); r_debug_reg_list (&core->dbg, R_REG_TYPE_GPR, 32, 1); @@ -712,7 +721,7 @@ static int cmd_print(void *data, const char *input) break; } if (tbs != core->blocksize) - r_core_block_size(core, tbs); + r_core_block_size (core, tbs); return 0; } @@ -1938,6 +1947,7 @@ static int cmd_debug(void *data, const char *input) { break; case 'm': // XXX: allow to allocate memory, show memory maps, ... + // TODO: do not export any variable here.. this is a task of r_debug {char pid[16]; sprintf(pid, "%d", core->dbg.pid); r_sys_setenv("PID", pid, 1); r_sys_cmd ("cat /proc/$PID/maps"); } @@ -1960,21 +1970,21 @@ static int cmd_debug(void *data, const char *input) { break; default: r_cons_printf("Usage: d[sbhcrbo] [arg]\n" - " dh [handler] ; list or set debugger handler\n" - " dH [handler] ; transplant process to a new handler\n" - " ds ; perform one step\n" - " df ; file descriptors\n" - " ds 3 ; perform 3 steps\n" - " do 3 ; perform 3 steps overs\n" - " dp [pid] ; list or set pid\n" - " dt [tid] ; select thread id\n" - " dc ; continue execution\n" - " dr[?] ; cpu registers, dr? for extended help\n" - " db[?] ; breakpoints\n" - " dm ; show memory maps\n" - " dm 4096 ; allocate 4KB in child process\n" - " dm rw- esp 9K; set 9KB of the stack as read+write (no exec)\n" - " dk pid sig ; send signal to a process ID\n"); + " dh [handler] list or set debugger handler\n" + " dH [handler] transplant process to a new handler\n" + " ds perform one step\n" + " df file descriptors\n" + " ds 3 perform 3 steps\n" + " do 3 perform 3 steps overs\n" + " dp [pid] list or set pid\n" + " dt [tid] select thread id\n" + " dc continue execution\n" + " dr[?] cpu registers, dr? for extended help\n" + " db[?] breakpoints\n" + " dm show memory maps\n" + " dm 4096 allocate 4KB in child process\n" + " dm rw- esp 9K set 9KB of the stack as read+write (no exec)\n" + " dk pid sig send signal to a process ID\n"); break; } return 0; diff --git a/libr/core/core.c b/libr/core/core.c index 6f4c18c2b8..4f076bfca6 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -146,6 +146,11 @@ R_API int r_core_init(struct r_core_t *core) core->offset = 0LL; core->blocksize = R_CORE_BLOCKSIZE; core->block = (ut8*)malloc (R_CORE_BLOCKSIZE); + if (core->block == NULL) { + eprintf ("Cannot allocate %d bytes\n", R_CORE_BLOCKSIZE); + /* XXX memory leak */ + return R_FALSE; + } r_core_cmd_init (core); r_flag_init (&core->flags); r_debug_init (&core->dbg, R_TRUE); diff --git a/libr/core/io.c b/libr/core/io.c index 4bb222b5e3..5f71186f8e 100644 --- a/libr/core/io.c +++ b/libr/core/io.c @@ -21,8 +21,8 @@ R_API int r_core_write_op(struct r_core_t *core, const char *arg, char op) buf = (ut8 *)malloc (core->blocksize); str = (char *)malloc (strlen(arg)); if (buf == NULL || str == NULL) { - free(buf); - free(str); + free (buf); + free (str); return 0; } memcpy (buf, core->block, core->blocksize); @@ -45,7 +45,7 @@ R_API int r_core_write_op(struct r_core_t *core, const char *arg, char op) } break; default: - for (i=j=0;iblocksize;i++) { + for (i=j=0; iblocksize; i++) { switch (op) { case 'x': buf[i] ^= str[j]; break; case 'a': buf[i] += str[j]; break; diff --git a/libr/debug/p/debug_ptrace.c b/libr/debug/p/debug_ptrace.c index c6856655ec..62631f913e 100644 --- a/libr/debug/p/debug_ptrace.c +++ b/libr/debug/p/debug_ptrace.c @@ -159,12 +159,12 @@ static const char *r_debug_ptrace_reg_profile() ); #elif __arm__ return strdup( - "=pc r15" - "=sp r14" // XXX - "=a0 r0" - "=a1 r1" - "=a2 r2" - "=a3 r3" + "=pc r15\n" + "=sp r14\n" // XXX + "=a0 r0\n" + "=a1 r1\n" + "=a2 r2\n" + "=a3 r3\n" "gpr lr .32 56 0\n" // r14 "gpr pc .32 60 0\n" // r15 diff --git a/libr/debug/p/gdb.mk b/libr/debug/p/gdb.mk index 2be8ef2d9e..d053044ae6 100644 --- a/libr/debug/p/gdb.mk +++ b/libr/debug/p/gdb.mk @@ -1,4 +1,5 @@ include ../../config.mk +BINDEPS=r_reg r_bp r_util CFLAGS+=-Ilibgdbwrap/include ifeq (${OSTYPE},windows) diff --git a/libr/debug/p/libgdbwrap/include/revm.h b/libr/debug/p/libgdbwrap/include/revm.h index a41d93867f..e71139083a 100644 --- a/libr/debug/p/libgdbwrap/include/revm.h +++ b/libr/debug/p/libgdbwrap/include/revm.h @@ -21,8 +21,8 @@ #define BYTE_IN_CHAR 2 #define TRUE 1 #define FALSE 0 -#define ASSERT // -#define assert // +#define ASSERT(x) // +#define assert(x) // #define LOBYTE(_w) ((_w) & 0xff) #define NEXT_CHAR(_x) _x + 1 #define PROFILER_IN(fd,fun,line) // diff --git a/libr/include/r_reg.h b/libr/include/r_reg.h index cfa0b0c9f7..527a17faa8 100644 --- a/libr/include/r_reg.h +++ b/libr/include/r_reg.h @@ -64,7 +64,11 @@ 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 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); + +R_API int r_reg_get_name_idx(const char *type); 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 int r_reg_type_by_name(const char *str); diff --git a/libr/reg/reg.c b/libr/reg/reg.c index 9891965e9c..ed12524a4b 100644 --- a/libr/reg/reg.c +++ b/libr/reg/reg.c @@ -13,7 +13,7 @@ static void r_reg_free_internal(struct r_reg_t *reg) { struct r_reg_item_t *r; int i; - for (i=0;iregset[i].regs) { r = list_entry (pos, struct r_reg_item_t, list); list_del (&r->list); @@ -22,14 +22,7 @@ static void r_reg_free_internal(struct r_reg_t *reg) { } } -R_API const char *r_reg_get_name(struct r_reg_t *reg, int role) { - if (role>=0 && rolename[role]; - return ""; -} - -R_API int r_reg_set_name(struct r_reg_t *reg, const char *type, const char *name) { - int ret = R_TRUE; +R_API int r_reg_get_name_idx(const char *type) { int role = type[0] + (type[1]<<8); switch (role) { case 'p'+('c'<<8): @@ -54,14 +47,26 @@ R_API int r_reg_set_name(struct r_reg_t *reg, const char *type, const char *name role = R_REG_NAME_A3; break; default: - ret = R_FALSE; - break; + role = -1; } - if (ret) + return role; +} + +R_API int r_reg_set_name(struct r_reg_t *reg, int role, const char *name) { + int ret = R_TRUE; + // TODO: ensure this range check in a define.. somewhere + if (role>=0 && rolename[role] = r_str_dup (reg->name[role], name); + } else ret = R_FALSE; return ret; } +R_API const char *r_reg_get_name(struct r_reg_t *reg, int role) { + if (role>=0 && rolename[role]; + return ""; +} + R_API struct r_reg_t *r_reg_free(struct r_reg_t *reg) { if (reg) { @@ -136,7 +141,7 @@ static int r_reg_set_word(struct r_reg_item_t *item, int idx, char *word) { else item->packed_size = atoi (word)*8; break; default: - eprintf ("register set fail\n"); + eprintf ("register set fail (%s)\n", word); ret = R_FALSE; } return ret; @@ -146,8 +151,7 @@ static int r_reg_set_word(struct r_reg_item_t *item, int idx, char *word) { R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *str) { RRegisterItem *item; - int setname = R_FALSE; - char *name = NULL; + int setname = -1; int ret = R_FALSE; int lastchar = 0; int chidx = 0; @@ -172,19 +176,20 @@ R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *str) case '\t': // UGLY PASTAFARIAN TO PARSE if (word==0 && *buf=='=') { - setname = R_TRUE; - name = r_str_dup (name, buf+1); + setname = r_reg_get_name_idx (buf+1); + if (setname == -1) + eprintf ("Invalid register type: '%s'\n", buf+1); } else if (lastchar != ' ' && lastchar != '\t') { r_reg_set_word (item, word, buf); - } + } chidx = 0; word++; break; case '\n': - if (setname) - r_reg_set_name (reg, name, buf); - else + if (setname != -1) { + r_reg_set_name (reg, setname, buf); + } else if (word>3) { r_reg_set_word (item, word, buf); if (item->name != NULL) { @@ -193,7 +198,7 @@ R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *str) } } chidx = word = 0; - setname = R_FALSE; + setname = -1; break; default: if (chidx > 128) // WTF!! @@ -207,7 +212,6 @@ R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *str) } free (item->name); free (item); - free (name); r_reg_fit_arena (reg); /* do we reach the end ? */