radare2/libr/debug/p/debug_gdb.c
Damien Zammit 1a593a6318 GDB debug for lm32 architecture (#4696)
Signed-off-by: Damien Zammit <damien@zamaudio.com>

* Missing a couple of things in previous commit

Signed-off-by: Damien Zammit <damien@zamaudio.com>
2016-04-24 23:13:00 +02:00

746 lines
18 KiB
C

/* radare - LGPL - Copyright 2009-2016 - pancake, defragger */
#include <r_asm.h>
#include <r_debug.h>
#include <libgdbr.h>
typedef struct {
libgdbr_t desc;
} RIOGdb;
#define UNKNOWN -1
#define UNSUPPORTED 0
#define SUPPORTED 1
static libgdbr_t *desc = NULL;
static ut8* reg_buf = NULL;
static int buf_size = 0;
static int support_sw_bp = UNKNOWN;
static int support_hw_bp = UNKNOWN;
static int r_debug_gdb_step(RDebug *dbg) {
gdbr_step (desc, -1); // TODO handle thread specific step?
return true;
}
static int r_debug_gdb_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
int copy_size;
int buflen = 0;
gdbr_read_registers (desc);
if (!desc) {
return -1;
}
// read the len of the current area
free (r_reg_get_bytes (dbg->reg, type, &buflen));
if (size < desc->data_len) {
eprintf ("r_debug_gdb_reg_read: small buffer %d vs %d\n",
(int)size, (int)desc->data_len);
// return -1;
}
copy_size = R_MIN (desc->data_len, size);
buflen = R_MAX (desc->data_len, buflen);
if (reg_buf) {
if (buf_size < copy_size) { //desc->data_len) {
ut8* new_buf = realloc (reg_buf, copy_size);
if (!new_buf)
return -1;
reg_buf = new_buf;
buflen = copy_size;
buf_size = desc->data_len;
}
} else {
reg_buf = calloc (buflen, 1);
if (!reg_buf)
return -1;
buf_size = buflen;
}
memset ((void*)(volatile void*)buf, 0, size);
memcpy ((void*)(volatile void*)buf, desc->data, copy_size);
memset ((void*)(volatile void*)reg_buf, 0, buflen);
memcpy ((void*)(volatile void*)reg_buf, desc->data, copy_size);
#if 0
int i;
//for(i=0;i<168;i++) {
for(i=0;i<copy_size;i++) {
if (!(i%16)) printf ("\n0x%08x ", i);
printf ("%02x ", buf[i]); //(ut8)desc->data[i]);
}
printf("\n");
#endif
return desc->data_len;
}
static RList *r_debug_gdb_map_get(RDebug* dbg) { //TODO
//TODO
return NULL;
}
static int r_debug_gdb_reg_write(RDebug *dbg, int type, const ut8 *buf, int size) {
if (!reg_buf) {
// we cannot write registers before we once read them
return -1;
}
int buflen = 0;
int bits = dbg->anal->bits;
const char *pcname = r_reg_get_name (dbg->anal->reg, R_REG_NAME_PC);
RRegItem *reg = r_reg_get (dbg->anal->reg, pcname, 0);
if (reg) {
if (dbg->anal->bits != reg->size)
bits = reg->size;
}
free (r_reg_get_bytes (dbg->reg, type, &buflen));
// some implementations of the gdb protocol are acting weird.
// so winedbg is not able to write registers through the <G> packet
// and also it does not return the whole gdb register profile after
// calling <g>
// so this workaround resizes the small register profile buffer
// to the whole set and fills the rest with 0
if (buf_size < buflen) {
ut8* new_buf = realloc (reg_buf, buflen * sizeof (ut8));
if (!new_buf) {
return -1;
}
reg_buf = new_buf;
memset (new_buf + buf_size, 0, buflen - buf_size);
}
RRegItem* current = NULL;
for (;;) {
current = r_reg_next_diff (dbg->reg, type, reg_buf, buflen, current, bits);
if (!current) break;
ut64 val = r_reg_get_value (dbg->reg, current);
int bytes = bits / 8;
gdbr_write_reg (desc, current->name, (char*)&val, bytes);
}
return true;
}
static int r_debug_gdb_continue(RDebug *dbg, int pid, int tid, int sig) {
gdbr_continue (desc, -1);
return true;
}
static int r_debug_gdb_wait(RDebug *dbg, int pid) {
/* do nothing */
return true;
}
static int r_debug_gdb_attach(RDebug *dbg, int pid) {
RIODesc *d = dbg->iob.io->desc;
// TODO: the core must update the dbg.swstep config var when this var is changed
dbg->swstep = false;
//eprintf ("XWJSTEP TOFALSE\n");
if (d && d->plugin && d->plugin->name && d->data) {
if (!strcmp ("gdb", d->plugin->name)) {
RIOGdb *g = d->data;
support_sw_bp = UNKNOWN;
support_hw_bp = UNKNOWN;
int arch = r_sys_arch_id (dbg->arch);
int bits = dbg->anal->bits;
if (( desc = &g->desc ))
switch (arch) {
case R_SYS_ARCH_X86:
if (bits == 16 || bits == 32) {
gdbr_set_architecture (&g->desc, X86_32);
} else if (bits == 64) {
gdbr_set_architecture (&g->desc, X86_64);
} else {
eprintf ("Not supported register %s %d profile\n", dbg->arch, bits);
return false;
}
break;
case R_SYS_ARCH_SH:
// TODO
break;
case R_SYS_ARCH_ARM:
if (bits == 16 || bits == 32) {
gdbr_set_architecture (&g->desc, ARM_32);
} else if (bits == 64) {
gdbr_set_architecture (&g->desc, ARM_64);
} else {
eprintf ("Not supported register %s %d profile\n", dbg->arch, bits);
return false;
}
break;
case R_SYS_ARCH_LM32:
if (bits == 32) {
gdbr_set_architecture(&g->desc, LM32);
} else {
eprintf ("Not supported register %s %d profile\n", dbg->arch, bits);
return false;
}
break;
case R_SYS_ARCH_MIPS:
if (bits == 32 || bits == 64) {
gdbr_set_architecture (&g->desc, MIPS);
} else {
eprintf ("Not supported register %s %d profile\n", dbg->arch, bits);
return false;
}
break;
case R_SYS_ARCH_AVR:
if (bits == 16) {
gdbr_set_architecture (&g->desc, AVR);
} else {
eprintf ("Not supported register profile\n");
return false;
}
break;
}
} else {
eprintf ("ERROR: Underlaying IO descriptor is not a GDB one..\n");
}
}
return true;
}
static int r_debug_gdb_detach(RDebug *dbg, int pid) {
gdbr_disconnect (desc);
free (reg_buf);
return true;
}
static const char *r_debug_gdb_reg_profile(RDebug *dbg) {
int arch = r_sys_arch_id (dbg->arch);
int bits = dbg->anal->bits;
switch (arch) {
case R_SYS_ARCH_X86:
if (bits == 16 || bits == 32) {
return strdup (
"=PC eip\n"
"=SP esp\n"
"=BP ebp\n"
"=A0 eax\n"
"=A1 ebx\n"
"=A2 ecx\n"
"=A3 edi\n"
"=SN oeax\n"
"gpr eax .32 0 0\n"
"gpr ecx .32 4 0\n"
"gpr edx .32 8 0\n"
"gpr ebx .32 12 0\n"
"gpr esp .32 16 0\n"
"gpr ebp .32 20 0\n"
"gpr esi .32 24 0\n"
"gpr edi .32 28 0\n"
"gpr eip .32 32 0\n"
"gpr eflags .32 36 0\n"
"seg cs .32 40 0\n"
"seg ss .32 44 0\n"
"seg ds .32 48 0\n"
"seg es .32 52 0\n"
"seg fs .32 56 0\n"
"seg gs .32 60 0\n"
"gpr st0 .80 64 0\n"
"gpr st1 .80 74 0\n"
"gpr st2 .80 84 0\n"
"gpr st3 .80 94 0\n"
"gpr st4 .80 104 0\n"
"gpr st5 .80 114 0\n"
"gpr st6 .80 124 0\n"
"gpr st7 .80 134 0\n"
"gpr fctrl .32 144 0\n"
"gpr fstat .32 148 0\n"
"gpr ftag .32 152 0\n"
"gpr fiseg .32 156 0\n"
"gpr fioff .32 160 0\n"
"gpr foseg .32 164 0\n"
"gpr fooff .32 168 0\n"
"gpr fop .32 172 0\n"
/* Commented until the long registers will be implemented
"gpr xmm0 .128 176 0\n"
"gpr xmm1 .128 192 0\n"
"gpr xmm2 .128 208 0\n"
"gpr xmm3 .128 224 0\n"
"gpr xmm4 .128 240 0\n"
"gpr xmm5 .128 256 0\n"
"gpr xmm6 .128 272 0\n"
"gpr xmm7 .128 288 0\n"
"gpr mxcsr .32 304 0\n"
*/
);
} else if (dbg->anal->bits == 64) {
return strdup (
"=PC rip\n"
"=SP rsp\n"
"=BP rbp\n"
"=A0 rax\n"
"=A1 rbx\n"
"=A2 rcx\n"
"=A3 rdx\n"
"=SN orax\n"
"gpr fake .64 795 0\n"
"gpr rax .64 0 0\n"
"gpr rbx .64 8 0\n"
"gpr rcx .64 16 0\n"
"gpr rdx .64 24 0\n"
"gpr rsi .64 32 0\n"
"gpr rdi .64 40 0\n"
"gpr rbp .64 48 0\n"
"gpr rsp .64 56 0\n"
"gpr r8 .64 64 0\n"
"gpr r9 .64 72 0\n"
"gpr r10 .64 80 0\n"
"gpr r11 .64 88 0\n"
"gpr r12 .64 96 0\n"
"gpr r13 .64 104 0\n"
"gpr r14 .64 112 0\n"
"gpr r15 .64 120 0\n"
"gpr rip .64 128 0\n"
"gpr eflags .32 136 0\n"
"seg cs .32 140 0\n"
"seg ss .32 144 0\n"
"seg ds .32 148 0\n"
"seg es .32 152 0\n"
"seg fs .32 156 0\n"
"seg gs .32 160 0\n"
"gpr st0 .80 164 0\n"
"gpr st1 .80 174 0\n"
"gpr st2 .80 184 0\n"
"gpr st3 .80 194 0\n"
"gpr st4 .80 204 0\n"
"gpr st5 .80 214 0\n"
"gpr st6 .80 224 0\n"
"gpr st7 .80 234 0\n"
"gpr fctrl .32 244 0\n"
"gpr fstat .32 248 0\n"
"gpr ftag .32 252 0\n"
"gpr fiseg .32 256 0\n"
"gpr fioff .32 260 0\n"
"gpr foseg .32 264 0\n"
"gpr fooff .32 268 0\n"
"gpr fop .32 272 0\n"
/* Commented until the long registers will be implemented
"gpr xmm0 .128 276 0\n"
"gpr xmm1 .128 292 0\n"
"gpr xmm2 .128 308 0\n"
"gpr xmm3 .128 324 0\n"
"gpr xmm4 .128 340 0\n"
"gpr xmm5 .128 356 0\n"
"gpr xmm6 .128 372 0\n"
"gpr xmm7 .128 388 0\n"
"gpr xmm8 .128 404 0\n"
"gpr xmm9 .128 420 0\n"
"gpr xmm10 .128 436 0\n"
"gpr xmm11 .128 452 0\n"
"gpr xmm12 .128 468 0\n"
"gpr xmm13 .128 484 0\n"
"gpr xmm14 .128 500 0\n"
"gpr xmm15 .128 516 0\n"
"gpr mxcsr .32 532 0\n"
*/
);
} else {
return strdup (
"=PC eip\n"
"=SP esp\n"
"=BP ebp\n"
"=A0 eax\n"
"=A1 ebx\n"
"=A2 ecx\n"
"=A3 edi\n"
"gpr eax .32 0 0\n"
"gpr ecx .32 4 0\n"
"gpr edx .32 8 0\n"
"gpr ebx .32 12 0\n"
"gpr esp .32 16 0\n"
"gpr ebp .32 20 0\n"
"gpr esi .32 24 0\n"
"gpr edi .32 28 0\n"
"gpr eip .32 32 0\n"
"gpr eflags .32 36 0\n"
"seg cs .32 40 0\n"
"seg ss .32 44 0\n"
"seg ds .32 48 0\n"
"seg es .32 52 0\n"
"seg fs .32 56 0\n"
"seg gs .32 60 0\n"
);
}
break;
case R_SYS_ARCH_ARM:
if (bits == 64) {
return strdup (
"=PC pc\n"
"=SP sp\n"
"=A0 r0\n"
"=A1 r1\n"
"=A2 r2\n"
"=A3 r3\n"
"gpr x0 .64 0 0\n"
"gpr x1 .64 8 0\n"
"gpr x2 .64 16 0\n"
"gpr x3 .64 24 0\n"
"gpr x4 .64 32 0\n"
"gpr x5 .64 40 0\n"
"gpr x6 .64 48 0\n"
"gpr x7 .64 56 0\n"
"gpr x8 .64 64 0\n"
"gpr x9 .64 72 0\n"
"gpr x10 .64 80 0\n"
"gpr x11 .64 88 0\n"
"gpr x12 .64 96 0\n"
"gpr x13 .64 104 0\n"
"gpr x14 .64 112 0\n"
"gpr x15 .64 120 0\n"
"gpr x16 .64 128 0\n"
"gpr x17 .64 136 0\n"
"gpr x18 .64 144 0\n"
"gpr x19 .64 152 0\n"
"gpr x20 .64 160 0\n"
"gpr x21 .64 168 0\n"
"gpr x22 .64 176 0\n"
"gpr x23 .64 184 0\n"
"gpr x24 .64 192 0\n"
"gpr x25 .64 200 0\n"
"gpr x26 .64 208 0\n"
"gpr x27 .64 216 0\n"
"gpr x28 .64 224 0\n"
"gpr x29 .64 232 0\n"
"gpr x30 .64 240 0\n"
"gpr sp .64 248 0\n"
"gpr pc .64 256 0\n"
"gpr pstate .64 264 0\n"
);
} else {
return strdup (
#if 0
"=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
"gpr r0 .32 0 0\n"
"gpr r1 .32 4 0\n"
"gpr r2 .32 8 0\n"
"gpr r3 .32 12 0\n"
"gpr r4 .32 16 0\n"
"gpr r5 .32 20 0\n"
"gpr r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr f0 .96 64 0\n"
"gpr f1 .96 76 0\n"
"gpr f2 .96 88 0\n"
"gpr f3 .96 100 0\n"
"gpr f4 .96 112 0\n"
"gpr f5 .96 124 0\n"
"gpr f6 .96 136 0\n"
"gpr f7 .96 148 0\n"
"gpr fps .96 160 0\n"
"gpr cpsr .32 172 0\n"
#else
"=PC r15\n"
"=SP r14\n" // XXX
"=A0 r0\n"
"=A1 r1\n"
"=A2 r2\n"
"=A3 r3\n"
"gpr r0 .32 0 0\n"
"gpr r1 .32 4 0\n"
"gpr r2 .32 8 0\n"
"gpr r3 .32 12 0\n"
"gpr r4 .32 16 0\n"
"gpr r5 .32 20 0\n"
"gpr r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr sp .32 52 0\n" // r13
"gpr lr .32 56 0\n" // r14
"gpr pc .32 60 0\n" // r15
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr cpsr .96 64 0\n"
"mmx d0 .64 68 0\n" // neon
"mmx d1 .64 76 0\n" // neon
"mmx d2 .64 84 0\n" // neon
"mmx d3 .64 92 0\n" // neon
"mmx d4 .64 100 0\n" // neon
"mmx d5 .64 108 0\n" // neon
"mmx d6 .64 116 0\n" // neon
"mmx d7 .64 124 0\n" // neon
"mmx d8 .64 132 0\n" // neon
"mmx d9 .64 140 0\n" // neon
"mmx d10 .64 148 0\n" // neon
"mmx d11 .64 156 0\n" // neon
"mmx d12 .64 164 0\n" // neon
"mmx d13 .64 172 0\n" // neon
"mmx d14 .64 180 0\n" // neon
"mmx d15 .64 188 0\n" // neon
"mmx d16 .64 196 0\n" // neon
"mmx d17 .64 204 0\n" // neon
"mmx d18 .64 212 0\n" // neon
"mmx d19 .64 220 0\n" // neon
"mmx d20 .64 228 0\n" // neon
"mmx d21 .64 236 0\n" // neon
"mmx d22 .64 244 0\n" // neon
"mmx d23 .64 252 0\n" // neon
"mmx d24 .64 260 0\n" // neon
"mmx d25 .64 268 0\n" // neon
"mmx d26 .64 276 0\n" // neon
"mmx d27 .64 284 0\n" // neon
"mmx d28 .64 292 0\n" // neon
"mmx d29 .64 300 0\n" // neon
"mmx d30 .64 308 0\n" // neon
"mmx d31 .64 316 0\n" // neon
"mmx fpscr .32 324 0\n" // neon
#endif
);
}
case R_SYS_ARCH_SH:
return strdup (
"=PC pc\n"
"=SP r15\n"
"=BP r14\n"
"gpr r0 .32 0 0\n"
"gpr r1 .32 4 0\n"
"gpr r2 .32 8 0\n"
"gpr r3 .32 12 0\n"
"gpr r4 .32 16 0\n"
"gpr r5 .32 20 0\n"
"gpr r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr pc .32 64 0\n"
"gpr pr .32 68 0\n"
"gpr sr .32 72 0\n"
"gpr gbr .32 76 0\n"
"gpr mach .32 80 0\n"
"gpr macl .32 84 0\n"
);
case R_SYS_ARCH_LM32:
return strdup (
"=PC PC\n"
"=SP sp\n"
"=BP gp\n"
"gpr r0 .32 0 0\n"
"gpr r1 .32 4 0\n"
"gpr r2 .32 8 0\n"
"gpr r3 .32 12 0\n"
"gpr r4 .32 16 0\n"
"gpr r5 .32 20 0\n"
"gpr r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr r16 .32 64 0\n"
"gpr r17 .32 68 0\n"
"gpr r18 .32 72 0\n"
"gpr r19 .32 76 0\n"
"gpr r20 .32 80 0\n"
"gpr r21 .32 84 0\n"
"gpr r22 .32 88 0\n"
"gpr r23 .32 92 0\n"
"gpr r24 .32 96 0\n"
"gpr r25 .32 100 0\n"
"gpr gp .32 104 0\n"
"gpr fp .32 108 0\n"
"gpr sp .32 112 0\n"
"gpr ra .32 116 0\n"
"gpr ea .32 120 0\n"
"gpr ba .32 124 0\n"
"gpr PC .32 128 0\n"
"gpr EID .32 132 0\n"
"gpr EBA .32 136 0\n"
"gpr DEBA .32 140 0\n"
"gpr IE .32 144 0\n"
"gpr IM .32 148 0\n"
"gpr IP .32 152 0\n"
);
case R_SYS_ARCH_MIPS:
return strdup (
"=PC pc\n"
"=SP sp\n"
"=BP gp\n"
"gpr zero .32 0 0\n"
"gpr at .32 4 0\n"
"gpr v0 .32 8 0\n"
"gpr v1 .32 12 0\n"
"gpr a0 .32 16 0\n"
"gpr a1 .32 20 0\n"
"gpr a2 .32 24 0\n"
"gpr a3 .32 28 0\n"
"gpr t0 .32 32 0\n"
"gpr t1 .32 36 0\n"
"gpr t2 .32 40 0\n"
"gpr t3 .32 44 0\n"
"gpr t4 .32 48 0\n"
"gpr t5 .32 52 0\n"
"gpr t6 .32 56 0\n"
"gpr t7 .32 60 0\n"
"gpr s0 .32 64 0\n"
"gpr s1 .32 68 0\n"
"gpr s2 .32 72 0\n"
"gpr s3 .32 76 0\n"
"gpr s4 .32 80 0\n"
"gpr s5 .32 84 0\n"
"gpr s6 .32 88 0\n"
"gpr s7 .32 92 0\n"
"gpr t8 .32 96 0\n"
"gpr t9 .32 100 0\n"
"gpr k0 .32 104 0\n"
"gpr k1 .32 108 0\n"
"gpr gp .32 112 0\n"
"gpr sp .32 116 0\n"
"gpr s8 .32 120 0\n"
"gpr ra .32 124 0\n"
"gpr sr .32 128 0\n"
"gpr lo .32 132 0\n"
"gpr hi .32 134 0\n"
"gpr bad .32 140 0\n"
"gpr cause .32 144 0\n"
"gpr pc .32 148 0\n"
"gpr f0 .32 152 0\n"
"gpr f1 .32 156 0\n"
"gpr f2 .32 160 0\n"
"gpr f3 .32 164 0\n"
"gpr f4 .32 168 0\n"
"gpr f5 .32 172 0\n"
"gpr f6 .32 176 0\n"
"gpr f7 .32 180 0\n"
"gpr f8 .32 184 0\n"
"gpr f9 .32 188 0\n"
"gpr f10 .32 192 0\n"
"gpr f11 .32 196 0\n"
"gpr f12 .32 200 0\n"
"gpr f13 .32 204 0\n"
"gpr f14 .32 208 0\n"
"gpr f15 .32 212 0\n"
"gpr f16 .32 216 0\n"
"gpr f17 .32 220 0\n"
"gpr f18 .32 224 0\n"
"gpr f19 .32 228 0\n"
"gpr f20 .32 232 0\n"
"gpr f21 .32 236 0\n"
"gpr f22 .32 240 0\n"
"gpr f23 .32 244 0\n"
"gpr f24 .32 248 0\n"
"gpr f25 .32 252 0\n"
"gpr f26 .32 256 0\n"
"gpr f27 .32 260 0\n"
"gpr f28 .32 264 0\n"
"gpr f29 .32 268 0\n"
"gpr f30 .32 272 0\n"
"gpr f31 .32 276 0\n"
"gpr fsr .32 280 0\n"
"gpr fir .32 284 0\n"
"gpr unknw .32 288 0\n" //Not documented what this part of the register packet is
);
case R_SYS_ARCH_AVR:
return strdup (
"=PC pc\n"
"=SP sp\n"
"gpr r0 .8 0 0\n"
"gpr r1 .8 1 0\n"
"gpr r2 .8 2 0\n"
"gpr r3 .8 3 0\n"
"gpr r4 .8 4 0\n"
"gpr r5 .8 5 0\n"
"gpr r6 .8 6 0\n"
"gpr r7 .8 7 0\n"
"gpr r8 .8 8 0\n"
"gpr r9 .8 9 0\n"
"gpr r10 .8 10 0\n"
"gpr r11 .8 11 0\n"
"gpr r12 .8 12 0\n"
"gpr r13 .8 13 0\n"
"gpr r14 .8 14 0\n"
"gpr r15 .8 15 0\n"
"gpr r16 .8 16 0\n"
"gpr r17 .8 17 0\n"
"gpr r18 .8 18 0\n"
"gpr r19 .8 19 0\n"
"gpr r20 .8 20 0\n"
"gpr r21 .8 21 0\n"
"gpr r22 .8 22 0\n"
"gpr r23 .8 23 0\n"
"gpr r24 .8 24 0\n"
"gpr r25 .8 25 0\n"
"gpr r26 .8 26 0\n"
"gpr r27 .8 27 0\n"
"gpr r28 .8 28 0\n"
"gpr r29 .8 29 0\n"
"gpr r30 .8 30 0\n"
"gpr r31 .8 31 0\n"
"gpr sreg .8 32 0\n"
"gpr sp .16 33 0\n"
"gpr pc .32 35 0\n"
/* "gpr pc .32 39 0\n" */
);
}
return NULL;
}
static int r_debug_gdb_breakpoint (RBreakpointItem *bp, int set, void *user) {
int ret;
if (!bp) return false;
// TODO handle rwx and conditions
if (set)
ret = bp->hw?
gdbr_set_hwbp (desc, bp->addr, ""):
gdbr_set_bp (desc, bp->addr, "");
else
ret = bp->hw?
gdbr_remove_hwbp (desc, bp->addr):
gdbr_remove_bp (desc, bp->addr);
return !ret;
}
struct r_debug_plugin_t r_debug_plugin_gdb = {
.name = "gdb",
/* TODO: Add support for more architectures here */
.license = "LGPL3",
.arch = "x86,arm,sh,mips,avr,lm32",
.bits = R_SYS_BITS_16 | R_SYS_BITS_32 | R_SYS_BITS_64,
.step = r_debug_gdb_step,
.cont = r_debug_gdb_continue,
.attach = &r_debug_gdb_attach,
.detach = &r_debug_gdb_detach,
.canstep = 1,
.wait = &r_debug_gdb_wait,
.map_get = r_debug_gdb_map_get,
.breakpoint = &r_debug_gdb_breakpoint,
.reg_read = &r_debug_gdb_reg_read,
.reg_write = &r_debug_gdb_reg_write,
.reg_profile = (void *)r_debug_gdb_reg_profile,
//.bp_write = &r_debug_gdb_bp_write,
//.bp_read = &r_debug_gdb_bp_read,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_DBG,
.data = &r_debug_plugin_gdb,
.version = R2_VERSION
};
#endif