int gdb_rx_begin(void) { int c, cksum; gdb_rxp = NULL; do { /* * Wait for the start character, ignore all others. * XXX needs a timeout. */ while ((c = gdb_getc()) != '$') ; /* Read until a # or end of buffer is found. */ cksum = 0; gdb_rxsz = 0; while (gdb_rxsz < sizeof(gdb_rxbuf) - 1) { c = gdb_getc(); if (c == '#') break; gdb_rxbuf[gdb_rxsz++] = c; cksum += c; } gdb_rxbuf[gdb_rxsz] = 0; cksum &= 0xff; /* Bail out on a buffer overflow. */ if (c != '#') { gdb_cur->gdb_putc('-'); return (ENOSPC); } c = gdb_getc(); cksum -= (C2N(c) << 4) & 0xf0; c = gdb_getc(); cksum -= C2N(c) & 0x0f; gdb_cur->gdb_putc((cksum == 0) ? '+' : '-'); if (cksum != 0) printf("GDB: packet `%s' has invalid checksum\n", gdb_rxbuf); } while (cksum != 0); gdb_rxp = gdb_rxbuf; return (0); }
static int run(struct gdb_data *data, char *buf) { printc("Running\n"); if (run_set_pc(data, buf) < 0 || device_ctl(DEVICE_CTL_RUN) < 0) return gdb_send(data, "E00"); for (;;) { device_status_t status = device_poll(); if (status == DEVICE_STATUS_ERROR) return gdb_send(data, "E00"); if (status == DEVICE_STATUS_HALTED) { printc("Target halted\n"); goto out; } if (status == DEVICE_STATUS_INTR) goto out; while (gdb_peek(data, 0)) { int c = gdb_getc(data); if (c < 0) return -1; if (c == 3) { printc("Interrupted by gdb\n"); goto out; } } } out: if (device_ctl(DEVICE_CTL_HALT) < 0) return gdb_send(data, "E00"); return run_final_status(data); }
int gdb_tx_end(void) { const char *p; int runlen; unsigned char c, cksum; do { gdb_cur->gdb_putc('$'); cksum = 0; p = gdb_txbuf; while (p < gdb_txp) { /* Send a character and start run-length encoding. */ c = *p++; gdb_cur->gdb_putc(c); cksum += c; runlen = 0; /* Determine run-length and update checksum. */ while (p < gdb_txp && *p == c) { runlen++; p++; } /* Emit the run-length encoded string. */ while (runlen >= 97) { gdb_cur->gdb_putc('*'); cksum += '*'; gdb_cur->gdb_putc(97+29); cksum += 97+29; runlen -= 97; if (runlen > 0) { gdb_cur->gdb_putc(c); cksum += c; runlen--; } } if (runlen == 1) { gdb_cur->gdb_putc(c); cksum += c; runlen--; } if (runlen == 0) continue; /* Don't emit '$', '#', '+' or '-'. */ if (runlen == 7) { gdb_cur->gdb_putc(c); cksum += c; runlen--; } if (runlen == 6 || runlen == 14 || runlen == 16) { gdb_cur->gdb_putc(c); cksum += c; runlen--; } gdb_cur->gdb_putc('*'); cksum += '*'; gdb_cur->gdb_putc(runlen+29); cksum += runlen+29; } gdb_cur->gdb_putc('#'); c = cksum >> 4; gdb_cur->gdb_putc(N2C(c)); c = cksum & 0x0f; gdb_cur->gdb_putc(N2C(c)); c = gdb_getc(); } while (c != '+'); return (0); }