2012-02-05 23:47:16 +01:00
|
|
|
/* radare - LGPL - Copyright 2009-2012 pancake<nopcode.org> */
|
2009-04-15 11:09:36 +00:00
|
|
|
|
|
|
|
#include <r_debug.h>
|
2011-12-05 09:55:44 +01:00
|
|
|
#include <r_cons.h>
|
2009-09-15 00:06:37 +02:00
|
|
|
#include <r_reg.h>
|
2009-04-15 11:09:36 +00:00
|
|
|
|
2010-02-28 22:58:21 +01:00
|
|
|
R_API int r_debug_reg_sync(struct r_debug_t *dbg, int type, int write) {
|
2010-02-21 20:24:28 +01:00
|
|
|
ut8 buf[4096]; // XXX hacky!
|
2010-01-19 11:25:17 +01:00
|
|
|
int size, ret = R_FALSE;
|
2011-01-21 09:17:14 +01:00
|
|
|
if (!dbg || !dbg->reg || dbg->pid == -1)
|
2010-06-23 13:43:08 +02:00
|
|
|
return R_FALSE;
|
2009-04-15 11:09:36 +00:00
|
|
|
if (write) {
|
2010-01-19 11:25:17 +01:00
|
|
|
if (dbg && dbg->h && dbg->h->reg_write) {
|
|
|
|
ut8 *buf = r_reg_get_bytes (dbg->reg, type, &size);
|
2011-10-09 04:15:32 +02:00
|
|
|
if (!dbg->h->reg_write (dbg, type, buf, sizeof (buf)))
|
2010-03-04 01:46:25 +01:00
|
|
|
eprintf ("r_debug_reg: error writing registers\n");
|
2010-01-19 11:25:17 +01:00
|
|
|
} else eprintf ("r_debug_reg: cannot set registers\n");
|
2009-04-15 11:09:36 +00:00
|
|
|
} else {
|
|
|
|
/* read registers from debugger backend to dbg->regs */
|
2009-04-16 20:49:18 +00:00
|
|
|
if (dbg && dbg->h && dbg->h->reg_read) {
|
2010-01-19 11:25:17 +01:00
|
|
|
size = dbg->h->reg_read (dbg, type, buf, sizeof (buf));
|
2012-07-05 16:02:12 +00:00
|
|
|
if (size == 0) {
|
2010-03-04 01:46:25 +01:00
|
|
|
eprintf ("r_debug_reg: error reading registers pid=%d\n", dbg->pid);
|
2012-07-05 16:02:12 +00:00
|
|
|
} else {
|
|
|
|
ret = r_reg_set_bytes (dbg->reg, type, buf, size);
|
|
|
|
}
|
2010-01-19 11:25:17 +01:00
|
|
|
} else eprintf ("r_debug_reg: cannot read registers\n");
|
2009-04-15 11:09:36 +00:00
|
|
|
}
|
2009-09-20 02:16:14 +02:00
|
|
|
return ret;
|
2009-04-15 11:09:36 +00:00
|
|
|
}
|
|
|
|
|
2010-02-28 22:58:21 +01:00
|
|
|
R_API int r_debug_reg_list(struct r_debug_t *dbg, int type, int size, int rad) {
|
2010-09-24 16:45:56 +02:00
|
|
|
ut64 diff;
|
|
|
|
int cols, n = 0;
|
2010-09-18 02:51:17 +02:00
|
|
|
RList *head; //struct list_head *pos, *head;
|
|
|
|
RListIter *iter;
|
|
|
|
RRegItem *item;
|
2010-03-12 18:46:11 +01:00
|
|
|
const char *fmt, *fmt2;
|
2010-09-18 02:51:17 +02:00
|
|
|
|
2010-06-23 13:43:08 +02:00
|
|
|
if (!dbg || !dbg->reg)
|
|
|
|
return R_FALSE;
|
2010-09-24 04:09:39 +02:00
|
|
|
head = r_reg_get_list (dbg->reg, type);
|
2012-06-07 03:41:21 +02:00
|
|
|
//if (dbg->h && dbg->h->bits & R_SYS_BITS_64) {
|
|
|
|
if (dbg->bits & R_SYS_BITS_64) {
|
2010-04-14 13:02:23 +02:00
|
|
|
fmt = "%s = 0x%016"PFMT64x"%s";
|
|
|
|
fmt2 = "%4s 0x%016"PFMT64x"%s";
|
2010-03-04 12:43:16 +01:00
|
|
|
cols = 3;
|
|
|
|
} else {
|
2010-04-14 13:02:23 +02:00
|
|
|
fmt = "%s = 0x%08"PFMT64x"%s";
|
|
|
|
fmt2 = "%4s 0x%08"PFMT64x"%s";
|
2010-03-04 12:43:16 +01:00
|
|
|
cols = 4;
|
|
|
|
}
|
2010-09-24 04:09:39 +02:00
|
|
|
if (head)
|
2010-09-18 02:51:17 +02:00
|
|
|
r_list_foreach (head, iter, item) {
|
2010-03-08 00:18:58 +01:00
|
|
|
ut64 value;
|
2009-09-20 02:16:14 +02:00
|
|
|
if (type != -1 && type != item->type)
|
|
|
|
continue;
|
|
|
|
if (size != 0 && size != item->size)
|
|
|
|
continue;
|
2010-03-08 00:18:58 +01:00
|
|
|
value = r_reg_get_value (dbg->reg, item);
|
2010-09-24 16:45:56 +02:00
|
|
|
diff = (ut64)r_reg_cmp (dbg->reg, item);
|
2010-03-04 02:11:54 +01:00
|
|
|
if (rad==1)
|
2011-11-25 09:40:28 +01:00
|
|
|
dbg->printf ("f %s 1 0x%"PFMT64x"\n", item->name, value);
|
2010-09-23 20:42:35 +02:00
|
|
|
else if (rad==2) {
|
|
|
|
if (diff) // TODO: DO NOT COLORIZE ALWAYS ..do debug knows about console?? use inverse colors
|
2011-12-05 09:55:44 +01:00
|
|
|
dbg->printf (Color_BWHITE); //INVERT); //Color_BWHITE);
|
2010-09-24 04:09:39 +02:00
|
|
|
if (item->flags) {
|
|
|
|
char *str = r_reg_get_bvalue (dbg->reg, item);
|
|
|
|
dbg->printf ("%s = %s%s", item->name, str, ((n+1)%cols)?" ":"\n");
|
|
|
|
free (str);
|
|
|
|
} else dbg->printf (fmt2, item->name, value, ((n+1)%cols)?" ":"\n");
|
2010-09-23 20:42:35 +02:00
|
|
|
if (diff) // TODO: use inverse colors
|
2011-12-05 09:55:44 +01:00
|
|
|
//dbg->printf (Color_INVERT_RESET); //Color_RESET);
|
|
|
|
dbg->printf (Color_RESET); //Color_RESET);
|
2010-09-24 16:45:56 +02:00
|
|
|
} else if (rad==3) {
|
|
|
|
if (diff) {
|
|
|
|
char woot[32];
|
2011-06-21 00:33:29 +02:00
|
|
|
snprintf (woot, sizeof (woot), " was 0x%08"PFMT64x"\n", diff);
|
2010-09-24 16:45:56 +02:00
|
|
|
dbg->printf (fmt, item->name, value, woot);
|
|
|
|
}
|
2010-09-23 20:42:35 +02:00
|
|
|
} else dbg->printf (fmt, item->name, value, "\n");
|
2009-09-20 02:16:14 +02:00
|
|
|
n++;
|
2009-04-15 11:09:36 +00:00
|
|
|
}
|
2011-05-25 09:56:29 +02:00
|
|
|
if (n>0 && rad==2 && ((n%cols)))
|
2010-03-04 02:11:54 +01:00
|
|
|
dbg->printf ("\n");
|
2009-09-20 02:16:14 +02:00
|
|
|
return n;
|
2009-04-15 11:09:36 +00:00
|
|
|
}
|
2010-02-28 22:58:21 +01:00
|
|
|
|
|
|
|
R_API int r_debug_reg_set(struct r_debug_t *dbg, const char *name, ut64 num) {
|
2010-09-18 02:51:17 +02:00
|
|
|
RRegItem *ri;
|
2010-02-28 22:58:21 +01:00
|
|
|
int role = r_reg_get_name_idx (name);
|
2010-06-23 13:43:08 +02:00
|
|
|
if (!dbg || !dbg->reg)
|
|
|
|
return R_FALSE;
|
2010-02-28 22:58:21 +01:00
|
|
|
if (role != -1)
|
|
|
|
name = r_reg_get_name (dbg->reg, role);
|
|
|
|
ri = r_reg_get (dbg->reg, name, R_REG_TYPE_GPR);
|
|
|
|
if (ri) {
|
|
|
|
r_reg_set_value (dbg->reg, ri, num);
|
|
|
|
r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_TRUE);
|
|
|
|
}
|
|
|
|
return (ri!=NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API ut64 r_debug_reg_get(struct r_debug_t *dbg, const char *name) {
|
2010-09-18 02:51:17 +02:00
|
|
|
RRegItem *ri = NULL;
|
2010-02-28 22:58:21 +01:00
|
|
|
ut64 ret = 0LL;
|
|
|
|
int role = r_reg_get_name_idx (name);
|
2011-05-24 15:25:52 +02:00
|
|
|
const char *pname = name;
|
2010-06-23 13:43:08 +02:00
|
|
|
if (!dbg || !dbg->reg)
|
|
|
|
return R_FALSE;
|
2010-02-28 22:58:21 +01:00
|
|
|
if (role != -1) {
|
|
|
|
name = r_reg_get_name (dbg->reg, role);
|
2010-03-19 02:49:30 +01:00
|
|
|
if (name == NULL || *name == '\0') {
|
2011-05-24 15:25:52 +02:00
|
|
|
eprintf ("No debug register profile defined for '%s'.\n", pname);
|
2010-06-22 20:27:14 +02:00
|
|
|
return 0LL;
|
2010-02-28 22:58:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ri = r_reg_get (dbg->reg, name, R_REG_TYPE_GPR);
|
|
|
|
if (ri) {
|
|
|
|
r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
|
|
|
|
ret = r_reg_get_value (dbg->reg, ri);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|