void gdb_packet_read(gdb_packet * packet, char * buffer, size_t got) { size_t i; char c; for(i = 0;i < got;i++) { c = buffer[i]; switch(packet->state) { case 0: if ('$' == c) { packet->state = 1; packet->buflen = 0; packet->bufsum = 0; } else if (3 == c) gdb_client_break(packet->client); break; case 1: if ('#' == c) { packet->state = 2; packet->cslen = 0; } else { packet->buffer[packet->buflen++] = c; packet->bufsum += c; } break; case 2: packet->checksum[packet->cslen++] = c; if (2 == packet->cslen) { int checksum; sscanf(packet->checksum, "%2x", &checksum); packet->buffer[packet->buflen] = '\0'; if (packet->bufsum == checksum) gdb_client_received(packet->client, packet); else gdb_client_error(packet->client); packet->state = 0; } break; } } }
void gdb_client_received(gdb_client * client, gdb_packet * packet) { char ack = '+'; printf("packet received: %s\n", packet->buffer); YabSockSend(client->sock, &ack, 1, 0); if (packet->buffer[0] == '?') gdb_client_break(client); else if (packet->buffer[0] == 'c') gdb_client_unlock(client); else if (packet->buffer[0] == 'g') { int i; char buffer[184+1]; for(i = 0;i < 16;i++) sprintf(buffer + 8 * i, "%08x", client->context->regs.R[i]); sprintf(buffer + 8 * 16, "%08x", client->context->regs.PC); sprintf(buffer + 8 * 17, "%08x", client->context->regs.PR); sprintf(buffer + 8 * 18, "%08x", client->context->regs.GBR); sprintf(buffer + 8 * 19, "%08x", client->context->regs.VBR); sprintf(buffer + 8 * 20, "%08x", client->context->regs.MACH); sprintf(buffer + 8 * 21, "%08x", client->context->regs.MACL); sprintf(buffer + 8 * 22, "%08x", client->context->regs.SR); gdb_client_send(client, buffer, 184); } else if (packet->buffer[0] == 'H') gdb_client_send(client, "OK", 2); else if (packet->buffer[0] == 'q') { if (!strncmp(packet->buffer, "qSupported", 10)) gdb_client_send(client, "PacketSize=1024", 15); else if (packet->buffer[1] == 'C') gdb_client_send(client, "", 0); else if (!strncmp(packet->buffer, "qAttached", 9)) gdb_client_send(client, "0", 1); else if (!strncmp(packet->buffer, "qTStatus", 8)) gdb_client_send(client, "T0", 2); else if (!strncmp(packet->buffer, "qTfP", 8)) gdb_client_send(client, "", 0); else if (!strncmp(packet->buffer, "qTfV", 8)) gdb_client_send(client, "", 0); else if (!strncmp(packet->buffer, "qTsP", 8)) gdb_client_send(client, "", 0); } else if (packet->buffer[0] == 'm') { u32 addr; int len, i; char * buffer; char * pos; sscanf(packet->buffer, "m%x,%d", &addr, &len); buffer = malloc(2 * len); pos = buffer; i = 0; while(i < len / 4) { u32 val = MappedMemoryReadLong(addr + 4 * i); sprintf(pos, "%08x", val); i += 1; pos += 8; } switch(len % 4) { case 2: { u16 val = MappedMemoryReadWord(addr + 4 * i); sprintf(pos, "%04x", val); break; } case 1: { u8 val = MappedMemoryReadByte(addr + 4 * i); sprintf(pos, "%02x", val); break; } } gdb_client_send(client, buffer, 2 * len); free(buffer); } else if (packet->buffer[0] == 'v') { if (!strncmp(packet->buffer, "vCont?", 6)) gdb_client_send(client, "", 0); } else if (packet->buffer[0] == 's') gdb_client_step(client); else if (packet->buffer[0] == 'Z') /* insert breakpoint */ { if (packet->buffer[1] == '0') /* code breakpoint */ { u32 addr; int dummy; sscanf(packet->buffer, "Z0,%x,%d", &addr, &dummy); SH2AddCodeBreakpoint(client->context, addr); } gdb_client_send(client, "OK", 2); } else if (packet->buffer[0] == 'z') /* remove breakpoint */ { if (packet->buffer[1] == '0') /* code breakpoint */ { u32 addr; int dummy; sscanf(packet->buffer, "Z0,%x,%d", &addr, &dummy); SH2DelCodeBreakpoint(client->context, addr); } gdb_client_send(client, "OK", 2); } }