Commit 880a7578381d1c7ed4d41c7599ae3cc06567a824

Authored by aliguori
1 parent bfa50bc2

gdbstub: manage CPUs as threads (Jan Kiszka)

This patch enhances QEMU's built-in debugger for SMP guest debugging.
Using the thread support of the gdb remote protocol, each VCPU is mapped
on a pseudo thread and exposed to the gdb frontend. This way you can
easy switch the focus of gdb between the VCPUs and observe their states.
On breakpoint hit, the focus is automatically adjusted just as for
normal multi-threaded application under gdb control.

Furthermore, the patch propagates breakpoint and watchpoint insertions
or removals to all CPUs, not just the current one as it was the case so
far. Without this, SMP guest debugging was practically unfeasible.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5743 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 196 additions and 82 deletions
gdbstub.c
... ... @@ -69,7 +69,9 @@ enum RSState {
69 69 RS_SYSCALL,
70 70 };
71 71 typedef struct GDBState {
72   - CPUState *env; /* current CPU */
  72 + CPUState *c_cpu; /* current CPU for step/continue ops */
  73 + CPUState *g_cpu; /* current CPU for other ops */
  74 + CPUState *query_cpu; /* for q{f|s}ThreadInfo */
73 75 enum RSState state; /* parsing state */
74 76 char line_buf[MAX_PACKET_LENGTH];
75 77 int line_buf_index;
... ... @@ -90,6 +92,8 @@ typedef struct GDBState {
90 92 */
91 93 static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
92 94  
  95 +static GDBState *gdbserver_state;
  96 +
93 97 /* This is an ugly hack to cope with both new and old gdb.
94 98 If gdb sends qXfer:features:read then assume we're talking to a newish
95 99 gdb that understands target descriptions. */
... ... @@ -99,9 +103,6 @@ static int gdb_has_xml;
99 103 /* XXX: This is not thread safe. Do we care? */
100 104 static int gdbserver_fd = -1;
101 105  
102   -/* XXX: remove this hack. */
103   -static GDBState gdbserver_state;
104   -
105 106 static int get_char(GDBState *s)
106 107 {
107 108 uint8_t ch;
... ... @@ -126,8 +127,6 @@ static int get_char(GDBState *s)
126 127 }
127 128 #endif
128 129  
129   -/* GDB stub state for use by semihosting syscalls. */
130   -static GDBState *gdb_syscall_state;
131 130 static gdb_syscall_complete_cb gdb_current_syscall_cb;
132 131  
133 132 enum {
... ... @@ -141,8 +140,8 @@ enum {
141 140 int use_gdb_syscalls(void)
142 141 {
143 142 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
144   - gdb_syscall_mode = (gdb_syscall_state ? GDB_SYS_ENABLED
145   - : GDB_SYS_DISABLED);
  143 + gdb_syscall_mode = (gdbserver_state ? GDB_SYS_ENABLED
  144 + : GDB_SYS_DISABLED);
146 145 }
147 146 return gdb_syscall_mode == GDB_SYS_ENABLED;
148 147 }
... ... @@ -1031,7 +1030,7 @@ static int memtox(char *buf, const char *mem, int len)
1031 1030 return p - buf;
1032 1031 }
1033 1032  
1034   -const char *get_feature_xml(CPUState *env, const char *p, const char **newp)
  1033 +const char *get_feature_xml(const char *p, const char **newp)
1035 1034 {
1036 1035 extern const char *const xml_builtin[][2];
1037 1036 size_t len;
... ... @@ -1057,7 +1056,7 @@ const char *get_feature_xml(CPUState *env, const char *p, const char **newp)
1057 1056 "<xi:include href=\"%s\"/>",
1058 1057 GDB_CORE_XML);
1059 1058  
1060   - for (r = env->gdb_regs; r; r = r->next) {
  1059 + for (r = first_cpu->gdb_regs; r; r = r->next) {
1061 1060 strcat(target_xml, "<xi:include href=\"");
1062 1061 strcat(target_xml, r->xml);
1063 1062 strcat(target_xml, "\"/>");
... ... @@ -1160,55 +1159,84 @@ static const int xlat_gdb_type[] = {
1160 1159 };
1161 1160 #endif
1162 1161  
1163   -static int gdb_breakpoint_insert(CPUState *env, target_ulong addr,
1164   - target_ulong len, int type)
  1162 +static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
1165 1163 {
  1164 + CPUState *env;
  1165 + int err = 0;
  1166 +
1166 1167 switch (type) {
1167 1168 case GDB_BREAKPOINT_SW:
1168 1169 case GDB_BREAKPOINT_HW:
1169   - return cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
  1170 + for (env = first_cpu; env != NULL; env = env->next_cpu) {
  1171 + err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
  1172 + if (err)
  1173 + break;
  1174 + }
  1175 + return err;
1170 1176 #ifndef CONFIG_USER_ONLY
1171 1177 case GDB_WATCHPOINT_WRITE:
1172 1178 case GDB_WATCHPOINT_READ:
1173 1179 case GDB_WATCHPOINT_ACCESS:
1174   - return cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
1175   - NULL);
  1180 + for (env = first_cpu; env != NULL; env = env->next_cpu) {
  1181 + err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
  1182 + NULL);
  1183 + if (err)
  1184 + break;
  1185 + }
  1186 + return err;
1176 1187 #endif
1177 1188 default:
1178 1189 return -ENOSYS;
1179 1190 }
1180 1191 }
1181 1192  
1182   -static int gdb_breakpoint_remove(CPUState *env, target_ulong addr,
1183   - target_ulong len, int type)
  1193 +static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
1184 1194 {
  1195 + CPUState *env;
  1196 + int err = 0;
  1197 +
1185 1198 switch (type) {
1186 1199 case GDB_BREAKPOINT_SW:
1187 1200 case GDB_BREAKPOINT_HW:
1188   - return cpu_breakpoint_remove(env, addr, BP_GDB);
  1201 + for (env = first_cpu; env != NULL; env = env->next_cpu) {
  1202 + err = cpu_breakpoint_remove(env, addr, BP_GDB);
  1203 + if (err)
  1204 + break;
  1205 + }
  1206 + return err;
1189 1207 #ifndef CONFIG_USER_ONLY
1190 1208 case GDB_WATCHPOINT_WRITE:
1191 1209 case GDB_WATCHPOINT_READ:
1192 1210 case GDB_WATCHPOINT_ACCESS:
1193   - return cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
  1211 + for (env = first_cpu; env != NULL; env = env->next_cpu) {
  1212 + err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
  1213 + if (err)
  1214 + break;
  1215 + }
  1216 + return err;
1194 1217 #endif
1195 1218 default:
1196 1219 return -ENOSYS;
1197 1220 }
1198 1221 }
1199 1222  
1200   -static void gdb_breakpoint_remove_all(CPUState *env)
  1223 +static void gdb_breakpoint_remove_all(void)
1201 1224 {
1202   - cpu_breakpoint_remove_all(env, BP_GDB);
  1225 + CPUState *env;
  1226 +
  1227 + for (env = first_cpu; env != NULL; env = env->next_cpu) {
  1228 + cpu_breakpoint_remove_all(env, BP_GDB);
1203 1229 #ifndef CONFIG_USER_ONLY
1204   - cpu_watchpoint_remove_all(env, BP_GDB);
  1230 + cpu_watchpoint_remove_all(env, BP_GDB);
1205 1231 #endif
  1232 + }
1206 1233 }
1207 1234  
1208   -static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
  1235 +static int gdb_handle_packet(GDBState *s, const char *line_buf)
1209 1236 {
  1237 + CPUState *env;
1210 1238 const char *p;
1211   - int ch, reg_size, type, res;
  1239 + int ch, reg_size, type, res, thread;
1212 1240 char buf[MAX_PACKET_LENGTH];
1213 1241 uint8_t mem_buf[MAX_PACKET_LENGTH];
1214 1242 uint8_t *registers;
... ... @@ -1222,32 +1250,33 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1222 1250 switch(ch) {
1223 1251 case '?':
1224 1252 /* TODO: Make this return the correct value for user-mode. */
1225   - snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
  1253 + snprintf(buf, sizeof(buf), "T%02xthread:%02x;", SIGTRAP,
  1254 + s->c_cpu->cpu_index+1);
1226 1255 put_packet(s, buf);
1227 1256 /* Remove all the breakpoints when this query is issued,
1228 1257 * because gdb is doing and initial connect and the state
1229 1258 * should be cleaned up.
1230 1259 */
1231   - gdb_breakpoint_remove_all(env);
  1260 + gdb_breakpoint_remove_all();
1232 1261 break;
1233 1262 case 'c':
1234 1263 if (*p != '\0') {
1235 1264 addr = strtoull(p, (char **)&p, 16);
1236 1265 #if defined(TARGET_I386)
1237   - env->eip = addr;
  1266 + s->c_cpu->eip = addr;
1238 1267 #elif defined (TARGET_PPC)
1239   - env->nip = addr;
  1268 + s->c_cpu->nip = addr;
1240 1269 #elif defined (TARGET_SPARC)
1241   - env->pc = addr;
1242   - env->npc = addr + 4;
  1270 + s->c_cpu->pc = addr;
  1271 + s->c_cpu->npc = addr + 4;
1243 1272 #elif defined (TARGET_ARM)
1244   - env->regs[15] = addr;
  1273 + s->c_cpu->regs[15] = addr;
1245 1274 #elif defined (TARGET_SH4)
1246   - env->pc = addr;
  1275 + s->c_cpu->pc = addr;
1247 1276 #elif defined (TARGET_MIPS)
1248   - env->active_tc.PC = addr;
  1277 + s->c_cpu->active_tc.PC = addr;
1249 1278 #elif defined (TARGET_CRIS)
1250   - env->pc = addr;
  1279 + s->c_cpu->pc = addr;
1251 1280 #endif
1252 1281 }
1253 1282 gdb_continue(s);
... ... @@ -1262,7 +1291,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1262 1291 exit(0);
1263 1292 case 'D':
1264 1293 /* Detach packet */
1265   - gdb_breakpoint_remove_all(env);
  1294 + gdb_breakpoint_remove_all();
1266 1295 gdb_continue(s);
1267 1296 put_packet(s, "OK");
1268 1297 break;
... ... @@ -1270,23 +1299,23 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1270 1299 if (*p != '\0') {
1271 1300 addr = strtoull(p, (char **)&p, 16);
1272 1301 #if defined(TARGET_I386)
1273   - env->eip = addr;
  1302 + s->c_cpu->eip = addr;
1274 1303 #elif defined (TARGET_PPC)
1275   - env->nip = addr;
  1304 + s->c_cpu->nip = addr;
1276 1305 #elif defined (TARGET_SPARC)
1277   - env->pc = addr;
1278   - env->npc = addr + 4;
  1306 + s->c_cpu->pc = addr;
  1307 + s->c_cpu->npc = addr + 4;
1279 1308 #elif defined (TARGET_ARM)
1280   - env->regs[15] = addr;
  1309 + s->c_cpu->regs[15] = addr;
1281 1310 #elif defined (TARGET_SH4)
1282   - env->pc = addr;
  1311 + s->c_cpu->pc = addr;
1283 1312 #elif defined (TARGET_MIPS)
1284   - env->active_tc.PC = addr;
  1313 + s->c_cpu->active_tc.PC = addr;
1285 1314 #elif defined (TARGET_CRIS)
1286   - env->pc = addr;
  1315 + s->c_cpu->pc = addr;
1287 1316 #endif
1288 1317 }
1289   - cpu_single_step(env, sstep_flags);
  1318 + cpu_single_step(s->c_cpu, sstep_flags);
1290 1319 gdb_continue(s);
1291 1320 return RS_IDLE;
1292 1321 case 'F':
... ... @@ -1305,7 +1334,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1305 1334 p++;
1306 1335 type = *p;
1307 1336 if (gdb_current_syscall_cb)
1308   - gdb_current_syscall_cb(s->env, ret, err);
  1337 + gdb_current_syscall_cb(s->c_cpu, ret, err);
1309 1338 if (type == 'C') {
1310 1339 put_packet(s, "T02");
1311 1340 } else {
... ... @@ -1316,7 +1345,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1316 1345 case 'g':
1317 1346 len = 0;
1318 1347 for (addr = 0; addr < num_g_regs; addr++) {
1319   - reg_size = gdb_read_register(env, mem_buf + len, addr);
  1348 + reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
1320 1349 len += reg_size;
1321 1350 }
1322 1351 memtohex(buf, mem_buf, len);
... ... @@ -1327,7 +1356,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1327 1356 len = strlen(p) / 2;
1328 1357 hextomem((uint8_t *)registers, p, len);
1329 1358 for (addr = 0; addr < num_g_regs && len > 0; addr++) {
1330   - reg_size = gdb_write_register(env, registers, addr);
  1359 + reg_size = gdb_write_register(s->g_cpu, registers, addr);
1331 1360 len -= reg_size;
1332 1361 registers += reg_size;
1333 1362 }
... ... @@ -1338,7 +1367,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1338 1367 if (*p == ',')
1339 1368 p++;
1340 1369 len = strtoull(p, NULL, 16);
1341   - if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) {
  1370 + if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
1342 1371 put_packet (s, "E14");
1343 1372 } else {
1344 1373 memtohex(buf, mem_buf, len);
... ... @@ -1353,7 +1382,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1353 1382 if (*p == ':')
1354 1383 p++;
1355 1384 hextomem(mem_buf, p, len);
1356   - if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)
  1385 + if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0)
1357 1386 put_packet(s, "E14");
1358 1387 else
1359 1388 put_packet(s, "OK");
... ... @@ -1365,7 +1394,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1365 1394 if (!gdb_has_xml)
1366 1395 goto unknown_command;
1367 1396 addr = strtoull(p, (char **)&p, 16);
1368   - reg_size = gdb_read_register(env, mem_buf, addr);
  1397 + reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);
1369 1398 if (reg_size) {
1370 1399 memtohex(buf, mem_buf, reg_size);
1371 1400 put_packet(s, buf);
... ... @@ -1381,7 +1410,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1381 1410 p++;
1382 1411 reg_size = strlen(p) / 2;
1383 1412 hextomem(mem_buf, p, reg_size);
1384   - gdb_write_register(env, mem_buf, addr);
  1413 + gdb_write_register(s->g_cpu, mem_buf, addr);
1385 1414 put_packet(s, "OK");
1386 1415 break;
1387 1416 case 'Z':
... ... @@ -1394,9 +1423,9 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1394 1423 p++;
1395 1424 len = strtoull(p, (char **)&p, 16);
1396 1425 if (ch == 'Z')
1397   - res = gdb_breakpoint_insert(env, addr, len, type);
  1426 + res = gdb_breakpoint_insert(addr, len, type);
1398 1427 else
1399   - res = gdb_breakpoint_remove(env, addr, len, type);
  1428 + res = gdb_breakpoint_remove(addr, len, type);
1400 1429 if (res >= 0)
1401 1430 put_packet(s, "OK");
1402 1431 else if (res == -ENOSYS)
... ... @@ -1404,6 +1433,45 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1404 1433 else
1405 1434 put_packet(s, "E22");
1406 1435 break;
  1436 + case 'H':
  1437 + type = *p++;
  1438 + thread = strtoull(p, (char **)&p, 16);
  1439 + if (thread == -1 || thread == 0) {
  1440 + put_packet(s, "OK");
  1441 + break;
  1442 + }
  1443 + for (env = first_cpu; env != NULL; env = env->next_cpu)
  1444 + if (env->cpu_index + 1 == thread)
  1445 + break;
  1446 + if (env == NULL) {
  1447 + put_packet(s, "E22");
  1448 + break;
  1449 + }
  1450 + switch (type) {
  1451 + case 'c':
  1452 + s->c_cpu = env;
  1453 + put_packet(s, "OK");
  1454 + break;
  1455 + case 'g':
  1456 + s->g_cpu = env;
  1457 + put_packet(s, "OK");
  1458 + break;
  1459 + default:
  1460 + put_packet(s, "E22");
  1461 + break;
  1462 + }
  1463 + break;
  1464 + case 'T':
  1465 + thread = strtoull(p, (char **)&p, 16);
  1466 +#ifndef CONFIG_USER_ONLY
  1467 + if (thread > 0 && thread < smp_cpus + 1)
  1468 +#else
  1469 + if (thread == 1)
  1470 +#endif
  1471 + put_packet(s, "OK");
  1472 + else
  1473 + put_packet(s, "E22");
  1474 + break;
1407 1475 case 'q':
1408 1476 case 'Q':
1409 1477 /* parse any 'q' packets here */
... ... @@ -1429,10 +1497,39 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1429 1497 sstep_flags = type;
1430 1498 put_packet(s, "OK");
1431 1499 break;
  1500 + } else if (strcmp(p,"C") == 0) {
  1501 + /* "Current thread" remains vague in the spec, so always return
  1502 + * the first CPU (gdb returns the first thread). */
  1503 + put_packet(s, "QC1");
  1504 + break;
  1505 + } else if (strcmp(p,"fThreadInfo") == 0) {
  1506 + s->query_cpu = first_cpu;
  1507 + goto report_cpuinfo;
  1508 + } else if (strcmp(p,"sThreadInfo") == 0) {
  1509 + report_cpuinfo:
  1510 + if (s->query_cpu) {
  1511 + snprintf(buf, sizeof(buf), "m%x", s->query_cpu->cpu_index+1);
  1512 + put_packet(s, buf);
  1513 + s->query_cpu = s->query_cpu->next_cpu;
  1514 + } else
  1515 + put_packet(s, "l");
  1516 + break;
  1517 + } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
  1518 + thread = strtoull(p+16, (char **)&p, 16);
  1519 + for (env = first_cpu; env != NULL; env = env->next_cpu)
  1520 + if (env->cpu_index + 1 == thread) {
  1521 + len = snprintf((char *)mem_buf, sizeof(mem_buf),
  1522 + "CPU#%d [%s]", env->cpu_index,
  1523 + env->halted ? "halted " : "running");
  1524 + memtohex(buf, mem_buf, len);
  1525 + put_packet(s, buf);
  1526 + break;
  1527 + }
  1528 + break;
1432 1529 }
1433 1530 #ifdef CONFIG_LINUX_USER
1434 1531 else if (strncmp(p, "Offsets", 7) == 0) {
1435   - TaskState *ts = env->opaque;
  1532 + TaskState *ts = s->c_cpu->opaque;
1436 1533  
1437 1534 snprintf(buf, sizeof(buf),
1438 1535 "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
... ... @@ -1459,7 +1556,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1459 1556  
1460 1557 gdb_has_xml = 1;
1461 1558 p += 19;
1462   - xml = get_feature_xml(env, p, &p);
  1559 + xml = get_feature_xml(p, &p);
1463 1560 if (!xml) {
1464 1561 snprintf(buf, sizeof(buf), "E00");
1465 1562 put_packet(s, buf);
... ... @@ -1507,10 +1604,17 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1507 1604  
1508 1605 extern void tb_flush(CPUState *env);
1509 1606  
  1607 +void gdb_set_stop_cpu(CPUState *env)
  1608 +{
  1609 + gdbserver_state->c_cpu = env;
  1610 + gdbserver_state->g_cpu = env;
  1611 +}
  1612 +
1510 1613 #ifndef CONFIG_USER_ONLY
1511 1614 static void gdb_vm_stopped(void *opaque, int reason)
1512 1615 {
1513   - GDBState *s = opaque;
  1616 + GDBState *s = gdbserver_state;
  1617 + CPUState *env = s->c_cpu;
1514 1618 char buf[256];
1515 1619 const char *type;
1516 1620 int ret;
... ... @@ -1519,11 +1623,11 @@ static void gdb_vm_stopped(void *opaque, int reason)
1519 1623 return;
1520 1624  
1521 1625 /* disable single step if it was enable */
1522   - cpu_single_step(s->env, 0);
  1626 + cpu_single_step(env, 0);
1523 1627  
1524 1628 if (reason == EXCP_DEBUG) {
1525   - if (s->env->watchpoint_hit) {
1526   - switch (s->env->watchpoint_hit->flags & BP_MEM_ACCESS) {
  1629 + if (env->watchpoint_hit) {
  1630 + switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
1527 1631 case BP_MEM_READ:
1528 1632 type = "r";
1529 1633 break;
... ... @@ -1534,20 +1638,22 @@ static void gdb_vm_stopped(void *opaque, int reason)
1534 1638 type = "";
1535 1639 break;
1536 1640 }
1537   - snprintf(buf, sizeof(buf), "T%02x%swatch:" TARGET_FMT_lx ";",
1538   - SIGTRAP, type, s->env->watchpoint_hit->vaddr);
  1641 + snprintf(buf, sizeof(buf),
  1642 + "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
  1643 + SIGTRAP, env->cpu_index+1, type,
  1644 + env->watchpoint_hit->vaddr);
1539 1645 put_packet(s, buf);
1540   - s->env->watchpoint_hit = NULL;
  1646 + env->watchpoint_hit = NULL;
1541 1647 return;
1542 1648 }
1543   - tb_flush(s->env);
  1649 + tb_flush(env);
1544 1650 ret = SIGTRAP;
1545 1651 } else if (reason == EXCP_INTERRUPT) {
1546 1652 ret = SIGINT;
1547 1653 } else {
1548 1654 ret = 0;
1549 1655 }
1550   - snprintf(buf, sizeof(buf), "S%02x", ret);
  1656 + snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, env->cpu_index+1);
1551 1657 put_packet(s, buf);
1552 1658 }
1553 1659 #endif
... ... @@ -1566,7 +1672,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
1566 1672 uint64_t i64;
1567 1673 GDBState *s;
1568 1674  
1569   - s = gdb_syscall_state;
  1675 + s = gdbserver_state;
1570 1676 if (!s)
1571 1677 return;
1572 1678 gdb_current_syscall_cb = cb;
... ... @@ -1611,15 +1717,14 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
1611 1717 va_end(va);
1612 1718 put_packet(s, buf);
1613 1719 #ifdef CONFIG_USER_ONLY
1614   - gdb_handlesig(s->env, 0);
  1720 + gdb_handlesig(s->c_cpu, 0);
1615 1721 #else
1616   - cpu_interrupt(s->env, CPU_INTERRUPT_EXIT);
  1722 + cpu_interrupt(s->c_cpu, CPU_INTERRUPT_EXIT);
1617 1723 #endif
1618 1724 }
1619 1725  
1620 1726 static void gdb_read_byte(GDBState *s, int ch)
1621 1727 {
1622   - CPUState *env = s->env;
1623 1728 int i, csum;
1624 1729 uint8_t reply;
1625 1730  
... ... @@ -1685,7 +1790,7 @@ static void gdb_read_byte(GDBState *s, int ch)
1685 1790 } else {
1686 1791 reply = '+';
1687 1792 put_buffer(s, &reply, 1);
1688   - s->state = gdb_handle_packet(s, env, s->line_buf);
  1793 + s->state = gdb_handle_packet(s, s->line_buf);
1689 1794 }
1690 1795 break;
1691 1796 default:
... ... @@ -1702,7 +1807,7 @@ gdb_handlesig (CPUState *env, int sig)
1702 1807 char buf[256];
1703 1808 int n;
1704 1809  
1705   - s = &gdbserver_state;
  1810 + s = gdbserver_state;
1706 1811 if (gdbserver_fd < 0 || s->fd < 0)
1707 1812 return sig;
1708 1813  
... ... @@ -1750,7 +1855,7 @@ void gdb_exit(CPUState *env, int code)
1750 1855 GDBState *s;
1751 1856 char buf[4];
1752 1857  
1753   - s = &gdbserver_state;
  1858 + s = gdbserver_state;
1754 1859 if (gdbserver_fd < 0 || s->fd < 0)
1755 1860 return;
1756 1861  
... ... @@ -1759,7 +1864,7 @@ void gdb_exit(CPUState *env, int code)
1759 1864 }
1760 1865  
1761 1866  
1762   -static void gdb_accept(void *opaque)
  1867 +static void gdb_accept(void)
1763 1868 {
1764 1869 GDBState *s;
1765 1870 struct sockaddr_in sockaddr;
... ... @@ -1781,13 +1886,20 @@ static void gdb_accept(void *opaque)
1781 1886 val = 1;
1782 1887 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
1783 1888  
1784   - s = &gdbserver_state;
  1889 + s = qemu_mallocz(sizeof(GDBState));
  1890 + if (!s) {
  1891 + errno = ENOMEM;
  1892 + perror("accept");
  1893 + return;
  1894 + }
  1895 +
1785 1896 memset (s, 0, sizeof (GDBState));
1786   - s->env = first_cpu; /* XXX: allow to change CPU */
  1897 + s->c_cpu = first_cpu;
  1898 + s->g_cpu = first_cpu;
1787 1899 s->fd = fd;
1788 1900 gdb_has_xml = 0;
1789 1901  
1790   - gdb_syscall_state = s;
  1902 + gdbserver_state = s;
1791 1903  
1792 1904 fcntl(fd, F_SETFL, O_NONBLOCK);
1793 1905 }
... ... @@ -1829,7 +1941,7 @@ int gdbserver_start(int port)
1829 1941 if (gdbserver_fd < 0)
1830 1942 return -1;
1831 1943 /* accept connections */
1832   - gdb_accept (NULL);
  1944 + gdb_accept();
1833 1945 return 0;
1834 1946 }
1835 1947 #else
... ... @@ -1842,11 +1954,10 @@ static int gdb_chr_can_receive(void *opaque)
1842 1954  
1843 1955 static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
1844 1956 {
1845   - GDBState *s = opaque;
1846 1957 int i;
1847 1958  
1848 1959 for (i = 0; i < size; i++) {
1849   - gdb_read_byte(s, buf[i]);
  1960 + gdb_read_byte(gdbserver_state, buf[i]);
1850 1961 }
1851 1962 }
1852 1963  
... ... @@ -1855,7 +1966,6 @@ static void gdb_chr_event(void *opaque, int event)
1855 1966 switch (event) {
1856 1967 case CHR_EVENT_RESET:
1857 1968 vm_stop(EXCP_INTERRUPT);
1858   - gdb_syscall_state = opaque;
1859 1969 gdb_has_xml = 0;
1860 1970 break;
1861 1971 default:
... ... @@ -1890,11 +2000,13 @@ int gdbserver_start(const char *port)
1890 2000 if (!s) {
1891 2001 return -1;
1892 2002 }
1893   - s->env = first_cpu; /* XXX: allow to change CPU */
  2003 + s->c_cpu = first_cpu;
  2004 + s->g_cpu = first_cpu;
1894 2005 s->chr = chr;
  2006 + gdbserver_state = s;
1895 2007 qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
1896   - gdb_chr_event, s);
1897   - qemu_add_vm_stop_handler(gdb_vm_stopped, s);
  2008 + gdb_chr_event, NULL);
  2009 + qemu_add_vm_stop_handler(gdb_vm_stopped, NULL);
1898 2010 return 0;
1899 2011 }
1900 2012 #endif
... ...
gdbstub.h
... ... @@ -8,6 +8,7 @@ typedef void (*gdb_syscall_complete_cb)(CPUState *env,
8 8  
9 9 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
10 10 int use_gdb_syscalls(void);
  11 +void gdb_set_stop_cpu(CPUState *env);
11 12 #ifdef CONFIG_USER_ONLY
12 13 int gdb_handlesig (CPUState *, int);
13 14 void gdb_exit(CPUState *, int);
... ...
... ... @@ -3720,6 +3720,7 @@ static int main_loop(void)
3720 3720 ret = EXCP_INTERRUPT;
3721 3721 }
3722 3722 if (unlikely(ret == EXCP_DEBUG)) {
  3723 + gdb_set_stop_cpu(cur_cpu);
3723 3724 vm_stop(EXCP_DEBUG);
3724 3725 }
3725 3726 /* If all cpus are halted then wait until the next IRQ */
... ...