Several fixes for gdb:// on avr, still wip

This commit is contained in:
pancake 2016-09-13 03:25:15 +02:00
parent a59e0ce083
commit cadb0bd845
7 changed files with 166 additions and 121 deletions

30
doc/avr Normal file
View File

@ -0,0 +1,30 @@
AVR (arduino, atmega128, ..)
============================
Install JTAG serial driver:
http://www.wch.cn/download/CH341SER_MAC_ZIP.html
Install SDK from Arduino:
https://www.arduino.cc/en/Main/Software
echo 'PATH="/Applications/Arduino.app//Contents/Java/hardware/tools/avr/bin/:$PATH"' >> ~/.profile
Install avarice, the gdbserver <-> jtag:
r2pm -i avarice
Run the proxy:
r2pm -r avarice --jtag /dev/tty.wch* --mkI :4242
Using GDB:
(avr-gdb) target remote :4242
In another terminal now run:
r2 -a avr -d gdb://localhost:4242
NOTE: Right now the avr debugger is pretty broken, the memory and register reads result in in correct data.

View File

@ -435,7 +435,7 @@ RAMPX, RAMPY, RAMPZ, RAMPD and EIND:
"gpr z .16 30 0\n"
// special purpose registers
"gpr pc .16 32 0\n"
"gpr sp .16 34 0\n"
"gpr sp .8 34 0\n"
"gpr sreg .8 36 0\n"
// 8bit segment registers to be added to X, Y, Z to get 24bit offsets
"gpr rampx .8 37 0\n"

View File

@ -4,7 +4,7 @@
R_API int r_core_setup_debugger (RCore *r, const char *debugbackend, bool attach) {
int pid, *p = NULL;
ut8 is_gdb = (strcmp (debugbackend, "gdb") == 0);
bool is_gdb = !strcmp (debugbackend, "gdb");
RIODesc * fd = r->file ? r->file->desc : NULL;
const char *prompt = NULL;
@ -15,19 +15,17 @@ R_API int r_core_setup_debugger (RCore *r, const char *debugbackend, bool attach
return false;
}
pid = *p; // 1st element in debugger's struct must be int
r_config_set (r->config, "io.ff", "true");
if (is_gdb) {
r_core_cmd (r, "dh gdb", 0);
} else {
r_core_cmdf (r, "dh %s", debugbackend);
r_core_cmdf (r, "dh %s", debugbackend);
if (!is_gdb) {
pid = *p; // 1st element in debugger's struct must be int
r_core_cmdf (r, "dp=%d", pid);
if (attach) {
r_core_cmdf (r, "dpa %d", pid);
}
}
//this makes to attach twice showing warnings in the output
//we get "resource busy" so it seems isn't an issue
if (attach) {
r_core_cmdf (r, "dpa %d", pid);
}
r_core_cmdf (r, "dp=%d", pid);
r_core_cmd (r, ".dr*", 0);
/* honor dbg.bep */
{

View File

@ -587,91 +587,114 @@ static int cmd_debug_map_snapshot(RCore *core, const char *input) {
NULL
};
switch (*input) {
case 'f':
{
char *file;
RDebugSnap *snap;
if (input[1] == ' ') {
file = strdup (input + 2);
} else {
file = r_str_newf ("0x%08"PFMT64x".dump", core->offset);
}
snap = r_debug_snap_get (core->dbg, core->offset);
if (!snap) {
r_debug_snap (core->dbg, core->offset);
snap = r_debug_snap_get (core->dbg, core->offset);
}
if (snap) {
int fsz = 0;
char *data = r_file_slurp (file, &fsz);
if (data) {
if (fsz >= snap->size) {
memcpy (snap->data, data, snap->size);
} else {
eprintf ("This file is smaller than the snapshot size\n");
}
free (data);
} else eprintf ("Cannot slurp '%s'\n", file);
} else {
eprintf ("Unable to find a snapshot for 0x%08"PFMT64x"\n", core->offset);
}
free (file);
}
break;
case 't':
{
char *file;
RDebugSnap *snap;
if (input[1] == ' ') {
file = strdup (input + 2);
} else {
file = r_str_newf ("0x%08"PFMT64x".dump", core->offset);
}
snap = r_debug_snap_get (core->dbg, core->offset);
if (snap) {
if (!r_file_dump (file, snap->data, snap->size, 0)) {
eprintf ("Cannot slurp '%s'\n", file);
}
} else {
eprintf ("Unable to find a snapshot for 0x%08"PFMT64x"\n", core->offset);
}
free (file);
}
break;
case '?':
r_core_cmd_help (core, help_msg);
break;
case '-':
if (input[1]=='*') {
r_debug_snap_delete (core->dbg, -1);
case 'f':
{
char *file;
RDebugSnap *snap;
if (input[1] == ' ') {
file = strdup (input + 2);
} else {
r_debug_snap_delete (core->dbg, r_num_math (core->num, input + 1));
file = r_str_newf ("0x%08"PFMT64x".dump", core->offset);
}
break;
case ' ':
r_debug_snap (core->dbg, r_num_math (core->num, input + 1));
break;
case 'C':
r_debug_snap_comment (core->dbg, atoi (input + 1), strchr (input, ' '));
break;
case 'd':
__r_debug_snap_diff (core, atoi (input + 1));
break;
case 'a':
r_debug_snap_all (core->dbg, 0);
break;
case 'w':
r_debug_snap_all (core->dbg, R_IO_RW);
break;
case 0:
case 'j':
case '*':
r_debug_snap_list (core->dbg, -1, input[0]);
break;
snap = r_debug_snap_get (core->dbg, core->offset);
if (!snap) {
r_debug_snap (core->dbg, core->offset);
snap = r_debug_snap_get (core->dbg, core->offset);
}
if (snap) {
int fsz = 0;
char *data = r_file_slurp (file, &fsz);
if (data) {
if (fsz >= snap->size) {
memcpy (snap->data, data, snap->size);
} else {
eprintf ("This file is smaller than the snapshot size\n");
}
free (data);
} else eprintf ("Cannot slurp '%s'\n", file);
} else {
eprintf ("Unable to find a snapshot for 0x%08"PFMT64x"\n", core->offset);
}
free (file);
}
break;
case 't':
{
char *file;
RDebugSnap *snap;
if (input[1] == ' ') {
file = strdup (input + 2);
} else {
file = r_str_newf ("0x%08"PFMT64x".dump", core->offset);
}
snap = r_debug_snap_get (core->dbg, core->offset);
if (snap) {
if (!r_file_dump (file, snap->data, snap->size, 0)) {
eprintf ("Cannot slurp '%s'\n", file);
}
} else {
eprintf ("Unable to find a snapshot for 0x%08"PFMT64x"\n", core->offset);
}
free (file);
}
break;
case '?':
r_core_cmd_help (core, help_msg);
break;
case '-':
if (input[1]=='*') {
r_debug_snap_delete (core->dbg, -1);
} else {
r_debug_snap_delete (core->dbg, r_num_math (core->num, input + 1));
}
break;
case ' ':
r_debug_snap (core->dbg, r_num_math (core->num, input + 1));
break;
case 'C':
r_debug_snap_comment (core->dbg, atoi (input + 1), strchr (input, ' '));
break;
case 'd':
__r_debug_snap_diff (core, atoi (input + 1));
break;
case 'a':
r_debug_snap_all (core->dbg, 0);
break;
case 'w':
r_debug_snap_all (core->dbg, R_IO_RW);
break;
case 0:
case 'j':
case '*':
r_debug_snap_list (core->dbg, -1, input[0]);
break;
}
return 0;
}
static int grab_bits(RCore *core, const char *arg, int *pcbits2) {
int pcbits = atoi (arg);
if (pcbits2) {
*pcbits2 = 0;
}
if (pcbits < 1) {
if (!strcmp (r_config_get (core->config, "asm.arch"), "avr")) {
pcbits = 8;
if (pcbits2) {
*pcbits2 = 32;
}
} else {
const char *pcname = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
RRegItem *reg = r_reg_get (core->anal->reg, pcname, 0);
if (reg) {
if (core->assembler->bits != reg->size)
pcbits = reg->size;
}
}
}
return pcbits ? pcbits : core->anal->bits;
}
#define MAX_MAP_SIZE 1024*1024*512
static int dump_maps(RCore *core, int perm, const char *filename) {
RDebugMap *map;
@ -1637,20 +1660,16 @@ static void cmd_debug_reg(RCore *core, const char *str) {
break;
case '=': // "dr="
{
int pcbits = 0;
{
const char *pcname = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
RRegItem *reg = r_reg_get (core->anal->reg, pcname, 0);
if (reg) {
if (core->assembler->bits != reg->size)
pcbits = reg->size;
}
}
int pcbits2, pcbits = grab_bits (core, str + 1, &pcbits2);
if (r_config_get_i (core->config, "cfg.debug")) {
if (r_debug_reg_sync (core->dbg, R_REG_TYPE_GPR, false)) {
if (pcbits && pcbits != bits)
if (pcbits && pcbits != bits) {
r_debug_reg_list (core->dbg, R_REG_TYPE_GPR, pcbits, 2, use_color); // XXX detect which one is current usage
}
r_debug_reg_list (core->dbg, R_REG_TYPE_GPR, bits, 2, use_color); // XXX detect which one is current usage
if (pcbits2) {
r_debug_reg_list (core->dbg, R_REG_TYPE_GPR, pcbits2, 2, use_color); // XXX detect which one is current usage
}
} //else eprintf ("Cannot retrieve registers from pid %d\n", core->dbg->pid);
} else {
RReg *orig = core->dbg->reg;
@ -1664,15 +1683,12 @@ static void cmd_debug_reg(RCore *core, const char *str) {
break;
case '*':
if (r_debug_reg_sync (core->dbg, R_REG_TYPE_GPR, false)) {
int pcbits = core->anal->bits;
const char *pcname = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
RRegItem *reg = r_reg_get (core->anal->reg, pcname, 0);
if (reg) {
if (core->assembler->bits != reg->size)
pcbits = reg->size;
}
int pcbits2, pcbits = grab_bits (core, str + 1, &pcbits2);
r_cons_printf ("fs+regs\n");
r_debug_reg_list (core->dbg, R_REG_TYPE_GPR, pcbits, '*', use_color);
if (pcbits2) {
r_debug_reg_list (core->dbg, R_REG_TYPE_GPR, pcbits2, '*', use_color);
}
r_flag_space_pop (core->flags);
r_cons_printf ("fs-\n");
}

View File

@ -2587,7 +2587,7 @@ static int cmd_print(void *data, const char *input) {
r_list_sort (f->bbs, (RListComparator)bbcmp);
if (input[2] == 'j') {
r_cons_print ("[");
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
for (; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
if (tmp_func->addr > f->addr) {
break;
}
@ -2604,7 +2604,7 @@ static int cmd_print(void *data, const char *input) {
r_cons_print (",");
}
}
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
for (; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
r_list_foreach (tmp_func->bbs, iter, b) {
r_core_cmdf (core, "pDj %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
if (iter->n) {
@ -2617,7 +2617,7 @@ static int cmd_print(void *data, const char *input) {
// TODO: sort by addr
bool asm_lines = r_config_get_i (core->config, "asm.lines");
r_config_set_i (core->config, "asm.lines", 0);
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
for (; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
if (tmp_func->addr < f->addr) {
r_list_foreach (tmp_func->bbs, iter, b) {
r_core_cmdf (core, "pD %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
@ -2649,7 +2649,7 @@ static int cmd_print(void *data, const char *input) {
r_cons_newline ();
#endif
}
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
for (; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
//this should be more advanced
r_list_foreach (tmp_func->bbs, iter, b) {
r_core_cmdf (core, "pD %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
@ -2725,8 +2725,6 @@ static int cmd_print(void *data, const char *input) {
ut32 bsz = core->blocksize;
RAnalFunction *f = r_anal_get_fcn_in (core->anal, core->offset,
R_ANAL_FCN_TYPE_FCN | R_ANAL_FCN_TYPE_SYM);
RListIter *iter;
RAnalBlock *bb;
RAnalFunction *tmp_func;
ut32 cont_size = 0;
RListIter *locs_it = NULL;
@ -2746,7 +2744,7 @@ static int cmd_print(void *data, const char *input) {
func_buf = calloc (cont_size, 1);
if (func_buf) {
//TODO: can loc jump to another locs?
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
for (; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
if (tmp_func->addr > f->addr) {
break;
}
@ -2760,7 +2758,7 @@ static int cmd_print(void *data, const char *input) {
r_io_read_at (core->io, f->addr, func_buf, cont_size);
r_core_print_disasm_json (core, f->addr, func_buf, cont_size, 0);
free (func_buf);
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
for (; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
cont_size = tmp_get_contsize (tmp_func);
loc_buf = calloc (cont_size, 1);;
r_io_read_at (core->io, tmp_func->addr, loc_buf, cont_size);
@ -2773,7 +2771,7 @@ static int cmd_print(void *data, const char *input) {
r_cons_printf ("}\n");
pd_result = 0;
} else if (f) {
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
for (; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
if (tmp_func->addr > f->addr) {
break;
}
@ -2782,7 +2780,7 @@ static int cmd_print(void *data, const char *input) {
}
cont_size = tmp_get_contsize (f);
r_core_cmdf (core, "pD %d @ 0x%08" PFMT64x, cont_size, f->addr);
for (locs_it; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
for (; locs_it && (tmp_func = locs_it->data); locs_it = locs_it->n) {
cont_size = tmp_get_contsize (tmp_func);
r_core_cmdf (core, "pD %d @ 0x%08" PFMT64x, cont_size, tmp_func->addr);
}

View File

@ -486,8 +486,9 @@ R_API int r_debug_select(RDebug *dbg, int pid, int tid) {
}
if (pid != -1 && tid != -1) {
if (pid != dbg->pid || tid != dbg->tid)
eprintf ("attach %d %d\n", pid, tid);
if (pid != dbg->pid || tid != dbg->tid) {
eprintf ("= attach %d %d\n", pid, tid);
}
} else {
if (dbg->pid != -1)
eprintf ("Child %d is dead\n", dbg->pid);

View File

@ -184,8 +184,9 @@ static int r_debug_gdb_attach(RDebug *dbg, int pid) {
if (bits == 16) {
gdbr_set_architecture (&g->desc, AVR);
} else {
eprintf ("Not supported register profile\n");
return false;
gdbr_set_architecture (&g->desc, AVR);
//eprintf ("Not supported register profile\n");
//return false;
}
break;
}
@ -694,6 +695,7 @@ static const char *r_debug_gdb_reg_profile(RDebug *dbg) {
"gpr r31 .8 31 0\n"
"gpr sreg .8 32 0\n"
"gpr sp .16 33 0\n"
"gpr pc2 .32 34 0\n"
"gpr pc .32 35 0\n"
/* "gpr pc .32 39 0\n" */
);