static gdb_syscall_complete_cb gdb_current_syscall_cb;
-enum {
+static enum {
GDB_SYS_UNKNOWN,
GDB_SYS_ENABLED,
GDB_SYS_DISABLED,
GDB_CORE_XML);
for (r = first_cpu->gdb_regs; r; r = r->next) {
- strcat(target_xml, "<xi:include href=\"");
- strcat(target_xml, r->xml);
- strcat(target_xml, "\"/>");
+ pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
+ pstrcat(target_xml, sizeof(target_xml), r->xml);
+ pstrcat(target_xml, sizeof(target_xml), "\"/>");
}
- strcat(target_xml, "</target>");
+ pstrcat(target_xml, sizeof(target_xml), "</target>");
}
return target_xml;
}
}
}
+static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
+{
+#if defined(TARGET_I386)
+ s->c_cpu->eip = pc;
+ cpu_synchronize_state(s->c_cpu, 1);
+#elif defined (TARGET_PPC)
+ s->c_cpu->nip = pc;
+#elif defined (TARGET_SPARC)
+ s->c_cpu->pc = pc;
+ s->c_cpu->npc = pc + 4;
+#elif defined (TARGET_ARM)
+ s->c_cpu->regs[15] = pc;
+#elif defined (TARGET_SH4)
+ s->c_cpu->pc = pc;
+#elif defined (TARGET_MIPS)
+ s->c_cpu->active_tc.PC = pc;
+#elif defined (TARGET_CRIS)
+ s->c_cpu->pc = pc;
+#elif defined (TARGET_ALPHA)
+ s->c_cpu->pc = pc;
+#endif
+}
+
static int gdb_handle_packet(GDBState *s, const char *line_buf)
{
CPUState *env;
case 'c':
if (*p != '\0') {
addr = strtoull(p, (char **)&p, 16);
-#if defined(TARGET_I386)
- s->c_cpu->eip = addr;
- cpu_synchronize_state(s->c_cpu, 1);
-#elif defined (TARGET_PPC)
- s->c_cpu->nip = addr;
-#elif defined (TARGET_SPARC)
- s->c_cpu->pc = addr;
- s->c_cpu->npc = addr + 4;
-#elif defined (TARGET_ARM)
- s->c_cpu->regs[15] = addr;
-#elif defined (TARGET_SH4)
- s->c_cpu->pc = addr;
-#elif defined (TARGET_MIPS)
- s->c_cpu->active_tc.PC = addr;
-#elif defined (TARGET_CRIS)
- s->c_cpu->pc = addr;
-#elif defined (TARGET_ALPHA)
- s->c_cpu->pc = addr;
-#endif
+ gdb_set_cpu_pc(s, addr);
}
s->signal = 0;
gdb_continue(s);
case 's':
if (*p != '\0') {
addr = strtoull(p, (char **)&p, 16);
-#if defined(TARGET_I386)
- s->c_cpu->eip = addr;
- cpu_synchronize_state(s->c_cpu, 1);
-#elif defined (TARGET_PPC)
- s->c_cpu->nip = addr;
-#elif defined (TARGET_SPARC)
- s->c_cpu->pc = addr;
- s->c_cpu->npc = addr + 4;
-#elif defined (TARGET_ARM)
- s->c_cpu->regs[15] = addr;
-#elif defined (TARGET_SH4)
- s->c_cpu->pc = addr;
-#elif defined (TARGET_MIPS)
- s->c_cpu->active_tc.PC = addr;
-#elif defined (TARGET_CRIS)
- s->c_cpu->pc = addr;
-#elif defined (TARGET_ALPHA)
- s->c_cpu->pc = addr;
-#endif
+ gdb_set_cpu_pc(s, addr);
}
cpu_single_step(s->c_cpu, sstep_flags);
gdb_continue(s);
if (strncmp(p, "Supported", 9) == 0) {
snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
#ifdef GDB_CORE_XML
- strcat(buf, ";qXfer:features:read+");
+ pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
#endif
put_packet(s, buf);
break;
return len;
}
-int gdbserver_start(const char *port)
+#ifndef _WIN32
+static void gdb_sigterm_handler(int signal)
+{
+ if (vm_running)
+ vm_stop(EXCP_INTERRUPT);
+}
+#endif
+
+int gdbserver_start(const char *device)
{
GDBState *s;
- char gdbstub_port_name[128];
- int port_num;
- char *p;
+ char gdbstub_device_name[128];
CharDriverState *chr = NULL;
CharDriverState *mon_chr;
- if (!port || !*port)
- return -1;
- if (strcmp(port, "none") != 0) {
- port_num = strtol(port, &p, 10);
- if (*p == 0) {
- /* A numeric value is interpreted as a port number. */
- snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
- "tcp::%d,nowait,nodelay,server", port_num);
- port = gdbstub_port_name;
+ if (!device)
+ return -1;
+ if (strcmp(device, "none") != 0) {
+ if (strstart(device, "tcp:", NULL)) {
+ /* enforce required TCP attributes */
+ snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
+ "%s,nowait,nodelay,server", device);
+ device = gdbstub_device_name;
}
+#ifndef _WIN32
+ else if (strcmp(device, "stdio") == 0) {
+ struct sigaction act;
- chr = qemu_chr_open("gdb", port, NULL);
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = gdb_sigterm_handler;
+ sigaction(SIGINT, &act, NULL);
+ }
+#endif
+ chr = qemu_chr_open("gdb", device, NULL);
if (!chr)
return -1;