#include <signal.h>
#include "config.h"
-#ifdef TARGET_I386
-#include "cpu-i386.h"
-#endif
-#ifdef TARGET_ARM
-#include "cpu-arm.h"
-#endif
+#include "cpu.h"
#include "thunk.h"
-#include "exec.h"
+#include "exec-all.h"
//#define DEBUG_GDB
}
/* port = 0 means default port */
-int cpu_gdbstub(void *opaque, void (*main_loop)(void *opaque), int port)
+int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port)
{
CPUState *env;
const char *p;
- int ret, ch, nb_regs, i;
+ int ret, ch, nb_regs, i, type;
char buf[4096];
uint8_t mem_buf[2000];
uint32_t *registers;
put_packet(buf);
break;
case 'c':
- main_loop(opaque);
- snprintf(buf, sizeof(buf), "S%02x", 0);
+ if (*p != '\0') {
+ addr = strtoul(p, (char **)&p, 16);
+ env = cpu_gdbstub_get_env(opaque);
+#if defined(TARGET_I386)
+ env->eip = addr;
+#endif
+ }
+ ret = main_loop(opaque);
+ if (ret == EXCP_DEBUG)
+ ret = SIGTRAP;
+ else
+ ret = 0;
+ snprintf(buf, sizeof(buf), "S%02x", ret);
+ put_packet(buf);
+ break;
+ case 's':
+ env = cpu_gdbstub_get_env(opaque);
+ if (*p != '\0') {
+ addr = strtoul(p, (char **)&p, 16);
+#if defined(TARGET_I386)
+ env->eip = addr;
+#endif
+ }
+ cpu_single_step(env, 1);
+ ret = main_loop(opaque);
+ cpu_single_step(env, 0);
+ if (ret == EXCP_DEBUG)
+ ret = SIGTRAP;
+ else
+ ret = 0;
+ snprintf(buf, sizeof(buf), "S%02x", ret);
put_packet(buf);
break;
case 'g':
}
env->eip = registers[8];
env->eflags = registers[9];
+#if defined(CONFIG_USER_ONLY)
#define LOAD_SEG(index, sreg)\
if (tswapl(registers[index]) != env->segs[sreg].selector)\
cpu_x86_load_seg(env, sreg, tswapl(registers[index]));
LOAD_SEG(14, R_FS);
LOAD_SEG(15, R_GS);
#endif
+#endif
put_packet("OK");
break;
case 'm':
else
put_packet("OK");
break;
+ case 'Z':
+ type = strtoul(p, (char **)&p, 16);
+ if (*p == ',')
+ p++;
+ addr = strtoul(p, (char **)&p, 16);
+ if (*p == ',')
+ p++;
+ len = strtoul(p, (char **)&p, 16);
+ if (type == 0 || type == 1) {
+ env = cpu_gdbstub_get_env(opaque);
+ if (cpu_breakpoint_insert(env, addr) < 0)
+ goto breakpoint_error;
+ put_packet("OK");
+ } else {
+ breakpoint_error:
+ put_packet("ENN");
+ }
+ break;
+ case 'z':
+ type = strtoul(p, (char **)&p, 16);
+ if (*p == ',')
+ p++;
+ addr = strtoul(p, (char **)&p, 16);
+ if (*p == ',')
+ p++;
+ len = strtoul(p, (char **)&p, 16);
+ if (type == 0 || type == 1) {
+ env = cpu_gdbstub_get_env(opaque);
+ cpu_breakpoint_remove(env, addr);
+ put_packet("OK");
+ } else {
+ goto breakpoint_error;
+ }
+ break;
+ case 'Q':
+ if (!strncmp(p, "Tinit", 5)) {
+ /* init traces */
+ put_packet("OK");
+ } else if (!strncmp(p, "TStart", 6)) {
+ /* start log (gdb 'tstart' command) */
+ cpu_set_log(CPU_LOG_ALL);
+ put_packet("OK");
+ } else if (!strncmp(p, "TStop", 5)) {
+ /* stop log (gdb 'tstop' command) */
+ cpu_set_log(0);
+ put_packet("OK");
+ } else {
+ goto unknown_command;
+ }
+ break;
default:
+ unknown_command:
/* put empty packet */
buf[0] = '\0';
put_packet(buf);