예제 #1
0
파일: gdb.c 프로젝트: jrcatbagan/umon-old
int
Gdb(int argc, char *argv)
{
	int		state, quit;
	uchar	*lp, c;
	static	uchar	line[1024];

	printf("Entering GDB mode, to exit manually type: '$k#00'\n");

	lp = (uchar *)0;
	quit = 0;
	state = 0;
	gdbUdp = 0;
	gdbTrace = Mtrace;
	while(!quit) {
		c = getchar();
		switch(state) {
			case 0:				/* Wait for start of message */
				if (c == '$') {
					lp = line;
					*lp++ = c;
					state = 1;
				}
				break;
			case 1:	
				*lp++ = c;		/* This is the command character */
				state = 2;
				break;
			case 2:
				if (c == '#') {
					state = 3;
					*lp++ = c;
				}
				else {
					*lp++ = c;
				}
				break;
			case 3:
				*lp++ = c;
				state = 4;
				break;
			case 4:
				*lp++ = c;
				*lp = 0;
				state = 0;
				if (line[1] == 'k')
					quit = 1;
				gdb_cmd(line);
				break;
			default:
				break;
		}
	}
	putchar('\n');
	return(CMD_SUCCESS);
}
예제 #2
0
void
gdbstub_interactive(void)
{
	bool processed_any = true;
	char *bp, *ep;
	ssize_t rd;
	int rc;

	execute = false;
	ASSERT(csock != -1, "x");

	do {
		if (!processed_any) {
			struct pollfd pfd = { 0 };

			pfd.fd = csock;
			pfd.events = POLLIN;
			rc = poll(&pfd, 1, -1);

			ASSERT(rc >= 0, "poll: %s", strerror(errno));
		}

		rd = recv(csock, &clientbuf[cblen], sizeof clientbuf - cblen,
		    MSG_DONTWAIT);
		if (rd == 0) {
			printf("Client dropped, exiting.\n");
			exit(0);
		}

		if (rd < 0) {
			if (errno != EAGAIN && errno != EWOULDBLOCK)
				err(1, "recv");
			goto process;
		}

		cblen += (size_t)rd;

process:
		processed_any = false;
		bp = clientbuf;
		ep = &clientbuf[cblen];
		// We have cblen valid bytes of protocol at p.
		// Process as many full packets as possible...
		while (bp < ep) {
			char *pound;

			if (*bp == '+' || *bp == '-') {
				bp++;
				cblen--;
				processed_any = true;
				continue;
			}

			pound = memchr(bp, '#', ep - bp);
			if (pound && (pound + 2) < ep) {
				gdb_cmd(bp, pound);

				processed_any = true;
				bp = pound + 3;

				if (execute)
					break;
			}
		}

		if (bp != clientbuf) {
			cblen = ep - bp;
			memmove(clientbuf, bp, cblen);
		}
	} while (!execute);

	ASSERT(execute,
	    "we shouldn't leave GDB interactive until we are told to");
}
예제 #3
0
파일: gdb.c 프로젝트: jrcatbagan/umon-old
/* processGDB():
 * This is the function that allows a remote gdb host to connect to
 * the monitor with gdb at the udp level.  The connection command in
 * gdb to do this is:
 *
 *	target remote udp:TARGET_IP:TARGET_PORT
 */
int
processGDB(struct ether_header *ehdr,ushort size)
{
	char	*gdbp;
	struct	ip *ihdr, *ti, *ri;
	struct	Udphdr *uhdr, *tu, *ru;
	struct	ether_header *te;

	/* If SHOW_GDB is set (via ether -vg), then we dump the trace to
	 * the console; otherwise, we use mtrace.
	 */
#if INCLUDE_ETHERVERBOSE
	if (EtherVerbose & SHOW_GDB)
		gdbTrace = printf;
	else
#endif
		gdbTrace = Mtrace;

	ihdr = (struct ip *)(ehdr + 1);
	uhdr = (struct Udphdr *)((char *)ihdr + IP_HLEN(ihdr));
	gdbp = (char *)(uhdr + 1);
	size = ecs(uhdr->uh_ulen) - sizeof(struct Udphdr);

	/* Check for ACK/NAK here:
	 */
	if (size == 1) {
		if ((*gdbp == '+') || (*gdbp == '-')) {
			gdbTrace("GDB_%s\n",*gdbp == '+' ? "ACK" : "NAK");
			return(0);
		}
	}

	/* Copy the incoming udp payload (the gdb command) to gdbIbuf[]
	 * and NULL terminate it...
	 */
	memcpy((char *)gdbIbuf,(char *)gdbp,size);
	gdbIbuf[size] = 0;

	/* Now that we've stored away the GDB command request, we
	 * initially respond with the GDB acknowledgement ('+')...
	 */
	te = EtherCopy(ehdr);
	ti = (struct ip *) (te + 1);
	ri = (struct ip *) (ehdr + 1);
	ti->ip_vhl = ri->ip_vhl;
	ti->ip_tos = ri->ip_tos;
	ti->ip_len = ecs((1 + (sizeof(struct ip) + sizeof(struct Udphdr))));
	ti->ip_id = ipId();
	ti->ip_off = ri->ip_off;
	ti->ip_ttl = UDP_TTL;
	ti->ip_p = IP_UDP;
	memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr,
		sizeof(struct in_addr));
	memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr),
		sizeof(struct in_addr));
	tu = (struct Udphdr *) (ti + 1);
	ru = (struct Udphdr *) (ri + 1);
	tu->uh_sport = ru->uh_dport;
	tu->uh_dport = ru->uh_sport;
	tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + 1));
	gdbp = (char *)(tu+1);
	*gdbp = '+';

	ipChksum(ti);		/* Compute checksum of ip hdr */
	udpChksum(ti);		/* Compute UDP checksum */

	sendBuffer(sizeof(struct ether_header) + sizeof(struct ip) + 
		sizeof(struct Udphdr) + 1);

	/* Wrap the processing of the incoming packet with a set/clear
	 * of the gdbUdp flag so that the other gdb code can act 
	 * accordingly.
	 */
	gdbUdp = 1;
	if (gdb_cmd(gdbIbuf) == 0) {
		gdbUdp = 0;
		return(0);
	}
	gdbUdp = 0;

	/* Add 1 to the gdbRlen to include the NULL termination.
	 */
	gdbRlen++;	


	/* The second respons is only done if gdb_cmd returns non-zero.
	 * It is the response to the gdb command issued by the debugger
	 * on the host.
	 */
	te = EtherCopy(ehdr);
	ti = (struct ip *) (te + 1);
	ri = (struct ip *) (ehdr + 1);
	ti->ip_vhl = ri->ip_vhl;
	ti->ip_tos = ri->ip_tos;
	ti->ip_len = ecs((gdbRlen + (sizeof(struct ip) + sizeof(struct Udphdr))));
	ti->ip_id = ipId();
	ti->ip_off = ri->ip_off;
	ti->ip_ttl = UDP_TTL;
	ti->ip_p = IP_UDP;
	memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr,
		sizeof(struct in_addr));
	memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr),
		sizeof(struct in_addr));

	tu = (struct Udphdr *) (ti + 1);
	ru = (struct Udphdr *) (ri + 1);
	tu->uh_sport = ru->uh_dport;
	tu->uh_dport = ru->uh_sport;
	tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + gdbRlen));
	memcpy((char *)(tu+1),(char *)gdbRbuf,gdbRlen);

	ipChksum(ti);		/* Compute checksum of ip hdr */
	udpChksum(ti);		/* Compute UDP checksum */

	sendBuffer(sizeof(struct ether_header) + sizeof(struct ip) + 
		sizeof(struct Udphdr) + gdbRlen);

	return(1);
}