Revision cdb432b2
b/gdbstub.c | ||
---|---|---|
284 | 284 |
RS_GETLINE, |
285 | 285 |
RS_CHKSUM1, |
286 | 286 |
RS_CHKSUM2, |
287 |
RS_SYSCALL, |
|
288 | 287 |
}; |
289 | 288 |
typedef struct GDBState { |
290 | 289 |
CPUArchState *c_cpu; /* current CPU for step/continue ops */ |
... | ... | |
304 | 303 |
CharDriverState *chr; |
305 | 304 |
CharDriverState *mon_chr; |
306 | 305 |
#endif |
306 |
char syscall_buf[256]; |
|
307 |
gdb_syscall_complete_cb current_syscall_cb; |
|
307 | 308 |
} GDBState; |
308 | 309 |
|
309 | 310 |
/* By default use no IRQs and no timers while single stepping so as to |
... | ... | |
346 | 347 |
} |
347 | 348 |
#endif |
348 | 349 |
|
349 |
static gdb_syscall_complete_cb gdb_current_syscall_cb; |
|
350 |
|
|
351 | 350 |
static enum { |
352 | 351 |
GDB_SYS_UNKNOWN, |
353 | 352 |
GDB_SYS_ENABLED, |
... | ... | |
2097 | 2096 |
if (*p == ',') |
2098 | 2097 |
p++; |
2099 | 2098 |
type = *p; |
2100 |
if (gdb_current_syscall_cb) |
|
2101 |
gdb_current_syscall_cb(s->c_cpu, ret, err); |
|
2099 |
if (s->current_syscall_cb) { |
|
2100 |
s->current_syscall_cb(s->c_cpu, ret, err); |
|
2101 |
s->current_syscall_cb = NULL; |
|
2102 |
} |
|
2102 | 2103 |
if (type == 'C') { |
2103 | 2104 |
put_packet(s, "T02"); |
2104 | 2105 |
} else { |
... | ... | |
2398 | 2399 |
const char *type; |
2399 | 2400 |
int ret; |
2400 | 2401 |
|
2401 |
if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) { |
|
2402 |
if (running || s->state == RS_INACTIVE) { |
|
2403 |
return; |
|
2404 |
} |
|
2405 |
/* Is there a GDB syscall waiting to be sent? */ |
|
2406 |
if (s->current_syscall_cb) { |
|
2407 |
put_packet(s, s->syscall_buf); |
|
2402 | 2408 |
return; |
2403 | 2409 |
} |
2404 | 2410 |
switch (state) { |
... | ... | |
2468 | 2474 |
void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) |
2469 | 2475 |
{ |
2470 | 2476 |
va_list va; |
2471 |
char buf[256]; |
|
2472 | 2477 |
char *p; |
2478 |
char *p_end; |
|
2473 | 2479 |
target_ulong addr; |
2474 | 2480 |
uint64_t i64; |
2475 | 2481 |
GDBState *s; |
... | ... | |
2477 | 2483 |
s = gdbserver_state; |
2478 | 2484 |
if (!s) |
2479 | 2485 |
return; |
2480 |
gdb_current_syscall_cb = cb; |
|
2481 |
s->state = RS_SYSCALL; |
|
2486 |
s->current_syscall_cb = cb; |
|
2482 | 2487 |
#ifndef CONFIG_USER_ONLY |
2483 | 2488 |
vm_stop(RUN_STATE_DEBUG); |
2484 | 2489 |
#endif |
2485 |
s->state = RS_IDLE; |
|
2486 | 2490 |
va_start(va, fmt); |
2487 |
p = buf; |
|
2491 |
p = s->syscall_buf; |
|
2492 |
p_end = &s->syscall_buf[sizeof(s->syscall_buf)]; |
|
2488 | 2493 |
*(p++) = 'F'; |
2489 | 2494 |
while (*fmt) { |
2490 | 2495 |
if (*fmt == '%') { |
... | ... | |
2492 | 2497 |
switch (*fmt++) { |
2493 | 2498 |
case 'x': |
2494 | 2499 |
addr = va_arg(va, target_ulong); |
2495 |
p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx, addr);
|
|
2500 |
p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
|
|
2496 | 2501 |
break; |
2497 | 2502 |
case 'l': |
2498 | 2503 |
if (*(fmt++) != 'x') |
2499 | 2504 |
goto bad_format; |
2500 | 2505 |
i64 = va_arg(va, uint64_t); |
2501 |
p += snprintf(p, &buf[sizeof(buf)] - p, "%" PRIx64, i64);
|
|
2506 |
p += snprintf(p, p_end - p, "%" PRIx64, i64);
|
|
2502 | 2507 |
break; |
2503 | 2508 |
case 's': |
2504 | 2509 |
addr = va_arg(va, target_ulong); |
2505 |
p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx "/%x",
|
|
2510 |
p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
|
|
2506 | 2511 |
addr, va_arg(va, int)); |
2507 | 2512 |
break; |
2508 | 2513 |
default: |
... | ... | |
2517 | 2522 |
} |
2518 | 2523 |
*p = 0; |
2519 | 2524 |
va_end(va); |
2520 |
put_packet(s, buf); |
|
2521 | 2525 |
#ifdef CONFIG_USER_ONLY |
2526 |
put_packet(s, s->syscall_buf); |
|
2522 | 2527 |
gdb_handlesig(s->c_cpu, 0); |
2523 | 2528 |
#else |
2529 |
/* In this case wait to send the syscall packet until notification that |
|
2530 |
the CPU has stopped. This must be done because if the packet is sent |
|
2531 |
now the reply from the syscall request could be received while the CPU |
|
2532 |
is still in the running state, which can cause packets to be dropped |
|
2533 |
and state transition 'T' packets to be sent while the syscall is still |
|
2534 |
being processed. */ |
|
2524 | 2535 |
cpu_exit(s->c_cpu); |
2525 | 2536 |
#endif |
2526 | 2537 |
} |
... | ... | |
2919 | 2930 |
s->chr = chr; |
2920 | 2931 |
s->state = chr ? RS_IDLE : RS_INACTIVE; |
2921 | 2932 |
s->mon_chr = mon_chr; |
2933 |
s->current_syscall_cb = NULL; |
|
2922 | 2934 |
|
2923 | 2935 |
return 0; |
2924 | 2936 |
} |
Also available in: Unified diff