Esempio n. 1
0
int stub_main(int arch_reason)
{
        int ret;
        int gdb_signal;

        gdb_signal = decode_signal(arch_reason);
        /* Do not announce stop reply if we were detached. */
        if (isattached) {
                send_stop_reply(gdb_signal);
        }
        /* We are now attached. */
        isattached = 1;

        do {
                int cmd;
                char *p;

                while (getpkt(&pktbuf[0], sizeof(pktbuf)) < 1);

                p = &pktbuf[0];
                cmd = *p;
                if ('?' == cmd) {
                        send_stop_reply(gdb_signal);
                        ret = 0;
                } else if ('c' == cmd) {
                        ret = handle_c(p);
                } else if ('s' == cmd) {
                        ret = handle_s(p);
                } else if ('D' == cmd) {
                        ret = handle_D(p);
                        if (ret & CMD_LEAVE) {
                                isattached = 0;
                        }
                } else if ('g' == cmd) {
                        ret = handle_g(p);
                } else if ('G' == cmd) {
                        ret = handle_G(p);
                } else if ('P' == cmd) {
                        ret = handle_P(p);
                } else if ('m' == cmd) {
                        ret = handle_m(p);
                } else if ('M' == cmd) {
                        ret = handle_M(p);
                } else {
                        /*
                         * For any command not supported by the stub, an empty
                         * response ('$#00') should be returned.
                         */
                        p = "";
                        ret = CMD_REPLY;
                }

                if (ret & CMD_REPLY) {
                        putpkt(p);
                }
        } while (!(ret & CMD_LEAVE));

        return ret;
}
Esempio n. 2
0
void gdbstub_loop(void) {
	int addr;
	int length;
	char *ptr, *ptr1;
	void *ramaddr;
	unsigned long regbuf[NUMREGS];
	bool reply, set;
	
	while (1)	{
		remcomOutBuffer[0] = 0;

		ptr = getpacket();
		if (!ptr) {
			gdbstub_disconnect();
			return;
		}
		reply = true;
		switch (*ptr++) 	{
			case '?':
				send_stop_reply(SIGNAL_TRAP, NULL, 0);
				reply = false; // already done
				break;

			case 'g':  /* return the value of the CPU registers */
				get_registers(regbuf);
				ptr = remcomOutBuffer;
				ptr = mem2hex(regbuf, ptr, NUMREGS * sizeof(unsigned long)); 
				break;
		
			case 'G':  /* set the value of the CPU registers - return OK */
				hex2mem(ptr, regbuf, NUMREGS * sizeof(unsigned long));
				set_registers(regbuf);
				strcpy(remcomOutBuffer,"OK");
				break;
				
			case 'p': /* pn Read the value of register n */
				if (hexToInt(&ptr, &addr) && (size_t)addr < sizeof(regbuf)) {
					mem2hex(get_registers(regbuf) + addr, remcomOutBuffer, sizeof(unsigned long));
				} else {
					strcpy(remcomOutBuffer,"E01");
				}
				break;
				
			case 'P': /* Pn=r Write register n with value r */
				ptr = strtok(ptr, "=");
				if (hexToInt(&ptr, &addr)
					  && (ptr=strtok(NULL, ""))
					  && (size_t)addr < sizeof(regbuf)
					  // TODO hex2mem doesn't check the format
					  && hex2mem((char*)ptr, &get_registers(regbuf)[addr], sizeof(u32))
					  ) {
					set_registers(regbuf);
					strcpy(remcomOutBuffer, "OK");
				} else {
					strcpy(remcomOutBuffer,"E01");
				}
				break;
		
			case 'm':  /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
				/* Try to read %x,%x */
				if (hexToInt(&ptr, &addr)
				    && *ptr++ == ','
				    && hexToInt(&ptr, &length)) {
					ramaddr = virt_mem_ptr(addr, length);
					if (!ramaddr || mem2hex(ramaddr, remcomOutBuffer, length))
						break;
					strcpy(remcomOutBuffer, "E03");
				}	else
					strcpy(remcomOutBuffer,"E01");
				break;
		
			case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA  */
				/* Try to read '%x,%x:' */
				if (hexToInt(&ptr, &addr)
				    && *ptr++ == ','
				    && hexToInt(&ptr, &length)
				    && *ptr++ == ':')	{
				  ramaddr = virt_mem_ptr(addr, length);
				  if (!ramaddr) {
				  	strcpy(remcomOutBuffer, "E03");
				  	break;
				  }
				  if (range_translated((u32)ramaddr, (u32)((char *)ramaddr + length)))
				  	flush_translations();
					if (hex2mem(ptr, ramaddr, length))
						strcpy(remcomOutBuffer, "OK");
					else
						strcpy(remcomOutBuffer, "E03");
				}	else
					strcpy(remcomOutBuffer, "E02");
				break;
		
			case 'S': /* Ssig[;AA..AA] Step with signal at address AA..AA(optional). Same as 's' for us. */
				ptr = strchr(ptr, ';'); /* skip the signal */
				if (ptr)
					ptr++;
			case 's': /* s[AA..AA]  Step at address AA..AA(optional) */
				cpu_events |= EVENT_DEBUG_STEP;
				goto parse_new_pc;
			case 'C': /* Csig[;AA..AA] Continue with signal at address AA..AA(optional). Same as 'c' for us. */
				ptr = strchr(ptr, ';'); /* skip the signal */
				if (ptr)
					ptr++;
			case 'c':    /* c[AA..AA]    Continue at address AA..AA(optional) */
parse_new_pc:
				if (ptr && hexToInt(&ptr, &addr)) {
					arm.reg[15] = addr;
				}
				return;
			case 'q':
				if (!strcmp("Offsets", ptr)) {
					sprintf(remcomOutBuffer, "Text=%x;Data=%x;Bss=%x",
						ndls_debug_alloc_block, ndls_debug_alloc_block,	ndls_debug_alloc_block);
				}
				break;
			case 'Z': /* 0|1|2|3|4,addr,kind  */
				set = true;
				goto z;
			case 'z': /* 0|1|2|3|4,addr,kind  */
				set = false;
			// kinds other than 4 aren't supported
z:
				ptr1 = ptr++;
				ptr = strtok(ptr, ","); 
				if (ptr && hexToInt(&ptr, &addr) && (ramaddr = virt_mem_ptr(addr & ~3, 4))) {
					u32 *flags = &RAM_FLAGS(ramaddr);
					switch (*ptr1) {
						case '0': // mem breakpoint
						case '1': // hw breakpoint
							if (set) {
								if (*flags & RF_CODE_TRANSLATED) flush_translations();
								*flags |= RF_EXEC_BREAKPOINT;
							} else
								*flags &= ~RF_EXEC_BREAKPOINT;
							break;
						case '2': // write watchpoint
						case '4': // access watchpoint
							if (set) *flags |= RF_WRITE_BREAKPOINT;
							else *flags &= ~RF_WRITE_BREAKPOINT;
							if (*ptr1 != 4)
								break;
						case '3': // read watchpoint, access watchpoint
							if (set) *flags |= RF_READ_BREAKPOINT;
							else *flags &= ~RF_READ_BREAKPOINT;
							break;
						default:
							goto reply;
					}
					strcpy(remcomOutBuffer, "OK");
				} else
					strcpy(remcomOutBuffer, "E01");
				break;
		}			/* switch */

reply:
		/* reply to the request */
		if (reply)
			putpacket(remcomOutBuffer);
	}
}