void
gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
                         struct gdb_context *ctx)
{
    /* XXX TODO */
    gdb_send_reply("E02", ctx);
}
void 
gdb_arch_resume(struct cpu_user_regs *regs,
                unsigned long addr, unsigned long type,
                struct gdb_context *ctx)
{
    /* XXX */
    if (type == GDB_STEP) {
        gdb_send_reply("S01", ctx);
    }
}
Beispiel #3
0
static void gdb_output_write(const void *buffer, size_t count)
{
	if (!gdb_state.resumed) {
		/* Must be a die_if() in GDB (or a bug), so bail out and die. */
		gdb_exit(-1);
		video_console_init();
		puts("GDB died, redirecting its last words to the screen:\n");
		console_write(buffer, count);
	} else {
		reply.used = 0;
		reply.buf[reply.used++] = 'O';
		gdb_message_encode_bytes(&reply, buffer, count);
		gdb_send_reply(&reply);
	}
}
Beispiel #4
0
void gdb_command_loop(u8 signal)
{
	if (gdb_state.resumed) {
		/* We were just running. Send a stop reply. */
		reply.used = 0;
		gdb_message_add_string(&reply, "S");
		gdb_message_encode_bytes(&reply, &signal, 1);
		gdb_send_reply(&reply);

	}
	gdb_state.signal = signal;
	gdb_state.resumed = 0;
	gdb_state.connected = 1;

	while (1) {
		int i;

		gdb_get_command(&command);

		reply.used = 0;
		for (i = 0; i < gdb_command_count; i++) {
			int clen = strlen(gdb_commands[i].str);
			if (!strncmp(gdb_commands[i].str, (char *)command.buf,
				     MIN(clen, command.used))) {
				gdb_commands[i].handler(&command, clen, &reply);
				break;
			}
		}

		/* If we're resuming, we won't send a reply until we stop. */
		if (gdb_state.resumed)
			return;

		gdb_send_reply(&reply);
	}
}
Beispiel #5
0
void gdb_exit(s8 exit_status)
{
	if (!gdb_state.connected)
		return;

	reply.used = 0;
	gdb_message_add_string(&reply, "W");
	gdb_message_encode_bytes(&reply, &exit_status, 1);
	gdb_send_reply(&reply);

	console_remove_output_driver(&gdb_output_write);
	gdb_transport_teardown();
	gdb_state.connected = 0;
	printf("Detached from GDB connection.\n");
}
void 
gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
                  struct gdb_context *ctx)
{
	struct gdb_callback_arg arg;
	unsigned long reg;
	struct pt_fpreg freg;
	char buf[16 * 2 + 1];

	if (regnum >= NUM_REGS) {
		dbg_printk("%s: regnum %ld\n", __func__, regnum);
		goto out_err;
	}

	arg.regs = regs;
	arg.regnum = regnum;
	arg.reg = &reg;
	arg.freg = &freg;
	arg.error = 0;
	unw_init_running(&gdb_get_reg_callback, (void*)&arg);
	if (arg.error < 0) {
		dbg_printk("%s: gdb_get_reg_callback failed\n", __func__);
		goto out_err;
	}

	if (arg.error > 0) {
		// notify gdb that this register is not supported.
		// see fetch_register_using_p() in gdb/remote.c.
		safe_strcpy(buf, "x");
	} else if (IA64_FR0_REGNUM <= regnum && regnum <= IA64_FR0_REGNUM + 127) {
		snprintf(buf, sizeof(buf), "%.016lx", swab64(freg.u.bits[0]));
		snprintf(buf + 16, sizeof(buf) - 16, "%.016lx", swab64(freg.u.bits[1]));
	} else {
		snprintf(buf, sizeof(buf), "%.016lx", swab64(reg));
	}
out:
	return gdb_send_reply(buf, ctx);

out_err:
	dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
	safe_strcpy(buf, "E0");
	goto out;
}
void
gdb_arch_write_reg(unsigned long regnum, unsigned long val, 
                    struct cpu_user_regs *regs, struct gdb_context *ctx)
{
    gdb_send_reply("", ctx);
}
Beispiel #8
0
/* command dispatcher */
static int 
process_command(struct cpu_user_regs *regs, struct gdb_context *ctx)
{
    const char *ptr;
    unsigned long addr, length, val;
    int resume = 0;
    unsigned long type = GDB_CONTINUE;

    /* XXX check ctx->in_bytes >= 2 or similar. */

    gdb_start_packet(ctx);
    switch ( ctx->in_buf[0] )
    {
    case '?':    /* query signal number */
        gdb_cmd_signum(ctx);
        break;
    case 'H':    /* thread operations */
        gdb_send_reply("OK", ctx);
        break;
    case 'g': /* Read registers */
        gdb_arch_read_reg_array(regs, ctx);
        break;
    case 'G': /* Write registers */
        gdb_arch_write_reg_array(regs, ctx->in_buf + 1, ctx);
        break;
    case 'm': /* Read memory */
        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
        {
            gdb_send_reply("E03", ctx);
            return 0;
        }
        length = simple_strtoul(ptr + 1, &ptr, 16);
        if ( ptr[0] != 0 )
        {
            gdb_send_reply("E04", ctx);
            return 0;
        }
        gdb_cmd_read_mem(addr, length, ctx);
        break;
    case 'M': /* Write memory */
        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
        if ( (ptr == (ctx->in_buf + 1)) || (ptr[0] != ',') )
        {
            gdb_send_reply("E03", ctx);
            return 0;
        }
        length = simple_strtoul(ptr + 1, &ptr, 16);
        if ( ptr[0] != ':')
        {
            gdb_send_reply("E04", ctx);
            return 0;
        }
        gdb_cmd_write_mem(addr, length, ptr + 1, ctx);
        break;
    case 'p': /* read register */
        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
        if ( ptr == (ctx->in_buf + 1) )
        {
            gdb_send_reply("E03", ctx);
            return 0;
        }
        if ( ptr[0] != 0 )
        {
            gdb_send_reply("E04", ctx);
            return 0;
        }
        gdb_arch_read_reg(addr, regs, ctx);
        break;
    case 'P': /* write register */
        addr = simple_strtoul(ctx->in_buf + 1, &ptr, 16);
        if ( ptr == (ctx->in_buf + 1) )
        {
            gdb_send_reply("E03", ctx);
            return 0;
        }
        if ( ptr[0] != '=' )
        {
            gdb_send_reply("E04", ctx);
            return 0;
        }
        ptr++;
        val = str2ulong(ptr, sizeof(unsigned long));
        gdb_arch_write_reg(addr, val, regs, ctx);
        break;
    case 'D':
    case 'k':
        gdbstub_detach(ctx);
        gdb_send_reply("OK", ctx);
        ctx->connected = 0;
        resume = 1;
        break;
    case 's': /* Single step */
        type = GDB_STEP;
    case 'c': /* Resume at current address */
        addr = ~((unsigned long)0);

        if ( ctx->in_buf[1] )
            addr = str2ulong(&ctx->in_buf[1], sizeof(unsigned long));
        gdbstub_attach(ctx);
        resume = 1;
        gdb_arch_resume(regs, addr, type, ctx);
        break;
    default:
        gdb_send_reply("", ctx);
        break;
    }
    return resume;
}
void 
gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
{
    gdb_send_reply("", ctx);
}
void 
gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
                  struct gdb_context *ctx)
{
	unsigned long reg = IA64_IP_REGNUM;
	char buf[9];
	int i;

	dbg_printk("Register read regnum = 0x%lx\n", regnum);
	if (IA64_GR0_REGNUM <= regnum && regnum <= IA64_GR0_REGNUM + 31) {
		for (i = 0; i < gr_reg_to_cpu_user_regs_index_max; i++) {
			if (gr_reg_to_cpu_user_regs_index[i].reg == regnum) {
				reg = *(unsigned long*)(((char*)regs) + gr_reg_to_cpu_user_regs_index[i].ptregoff);
				break;
			}
		}
		if (i == gr_reg_to_cpu_user_regs_index_max) {
			goto out_err;
		}
	} else if (IA64_BR0_REGNUM <= regnum && regnum <= IA64_BR0_REGNUM + 7) {
		for (i = 0; i < br_reg_to_cpu_user_regs_index_max; i++) {
			if (br_reg_to_cpu_user_regs_index[i].reg == regnum) {
				reg = *(unsigned long*)(((char*)regs) + br_reg_to_cpu_user_regs_index[i].ptregoff);
				break;
			}
		}
		if (i == br_reg_to_cpu_user_regs_index_max) {
			goto out_err;
		}
	} else if (IA64_FR0_REGNUM + 6 <= regnum && regnum <= IA64_FR0_REGNUM + 11) {
		for (i = 0; i < fr_reg_to_cpu_user_regs_index_max; i++) {
			if (fr_reg_to_cpu_user_regs_index[i].reg == regnum) {
				reg = *(unsigned long*)(((char*)regs) + fr_reg_to_cpu_user_regs_index[i].ptregoff);
				break;
			}
		}
		if (i == fr_reg_to_cpu_user_regs_index_max) {
			goto out_err;
		}
	} else if (regnum == IA64_CSD_REGNUM) {
		reg = regs->ar_csd;
	} else if (regnum == IA64_SSD_REGNUM) {
		reg = regs->ar_ssd;
	} else if (regnum == IA64_PSR_REGNUM) {
		reg = regs->cr_ipsr;
	} else if (regnum == IA64_IP_REGNUM) {
		reg = regs->cr_iip;
	} else if (regnum == IA64_CFM_REGNUM) {
		reg = regs->cr_ifs;
	} else if (regnum == IA64_UNAT_REGNUM) {
		reg = regs->ar_unat;
	} else if (regnum == IA64_PFS_REGNUM) {
		reg = regs->ar_pfs;
	} else if (regnum == IA64_RSC_REGNUM) {
		reg = regs->ar_rsc;
	} else if (regnum == IA64_RNAT_REGNUM) {
		reg = regs->ar_rnat;
	} else if (regnum == IA64_BSPSTORE_REGNUM) {
		reg = regs->ar_bspstore;
	} else if (regnum == IA64_PR_REGNUM) {
		reg = regs->pr;
	} else if (regnum == IA64_FPSR_REGNUM) {
		reg = regs->ar_fpsr;
	} else if (regnum == IA64_CCV_REGNUM) {
		reg = regs->ar_ccv;
	} else {
		// emul_unat, rfi_pfs
		goto out_err;
	}

	dbg_printk("Register read regnum = 0x%lx, val = 0x%lx\n", regnum, reg);	
	snprintf(buf, sizeof(buf), "%.08lx", swab64(reg));
out:
	return gdb_send_reply(buf, ctx);

out_err:
	dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
	safe_strcpy(buf, "x");
	goto out;
}