static void debug_fiq(void *data, void *regs) { int c; static int last_c; while ((c = debug_getc()) != -1) { if (!debug_enable) { if ((c == 13) || (c == 10)) { debug_enable = true; debug_count = 0; debug_prompt(); } } else if ((c >= ' ') && (c < 127)) { if (debug_count < (DEBUG_MAX - 1)) { debug_buf[debug_count++] = c; debug_putc(c); } } else if ((c == 8) || (c == 127)) { if (debug_count > 0) { debug_count--; debug_putc(8); debug_putc(' '); debug_putc(8); } } else if ((c == 13) || (c == 10)) { if (c == '\r' || (c == '\n' && last_c != '\r')) { debug_putc('\r'); debug_putc('\n'); } if (debug_count) { debug_buf[debug_count] = 0; debug_count = 0; debug_exec(debug_buf, regs); } else { debug_prompt(); } } last_c = c; } debug_flush(); }
static int gdb_receive(void *x) { struct gdbcontext *ctx = x; int nread; size_t offset; char *packet; size_t packetlen; size_t maxpacklen; char *hash; size_t hashpos; size_t usedlen; char tmpbuf[sizeof(ctx->buf)+1]; if (ctx->bufptr >= sizeof(ctx->buf)) { msg("gdbcomm: Input buffer overflow"); ctx->bufptr = 0; } nread = read(ctx->myfd, ctx->buf + ctx->bufptr, sizeof(ctx->buf) - ctx->bufptr); if (nread <= 0) { if (nread < 0) { msg("gdbcomm: read: %s", strerror(errno)); } else { msg("gdbcomm: read: EOF from debugger"); } close(ctx->myfd); ctx->myfd = -1; return -1; } ctx->bufptr += nread; while ((packet = memchr(ctx->buf, '$', ctx->bufptr)) != NULL) { offset = packet - ctx->buf; Assert(offset < ctx->bufptr); maxpacklen = ctx->bufptr - offset; hash = memchr(packet, '#', maxpacklen); if (hash==NULL) { /* incomplete packet - stop until we get the rest */ break; } /* * There are two additional check characters after the $. * $....#aa * * packetlen is 3 more than hashpos, not 2, because * hashpos, as a length, would not include the hash, * and we need to include both the hash and both check * characters. */ hashpos = hash - packet; packetlen = hashpos+3; if (packetlen > maxpacklen) { /* incomplete packet, come back later */ break; } /* * At this point, we have a packet, and it goes from * 'packet' to 'packet+packetlen'. */ Assert(packetlen+1 < sizeof(tmpbuf)); /* Copy so we can null-terminate without trashing anything. */ memmove(tmpbuf, packet, packetlen); tmpbuf[packetlen] = 0; /* Process it. */ debug_exec(ctx, tmpbuf); /* Keep only the part of the buffer we haven't used yet. */ usedlen = offset+packetlen; Assert(usedlen <= ctx->bufptr); ctx->bufptr -= usedlen; memmove(ctx->buf, ctx->buf+usedlen, ctx->bufptr); /* Loop back and check for another packet */ } return 0; }