Commit dd32aa10476d04853b71657d5345e812915d87ed
Committed by
Anthony Liguori
1 parent
8389e7f4
gdbstub: Add vCont support
This patch adds support for the vCont remote gdb command. It is used by gdb 6.8 or better to switch the debugging focus for single-stepping multi-threaded targets, ie. multi-threaded application in user mode emulation or VCPUs in system emulation. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
1 changed file
with
58 additions
and
0 deletions
gdbstub.c
@@ -1631,6 +1631,64 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) | @@ -1631,6 +1631,64 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) | ||
1631 | s->signal = 0; | 1631 | s->signal = 0; |
1632 | gdb_continue(s); | 1632 | gdb_continue(s); |
1633 | return RS_IDLE; | 1633 | return RS_IDLE; |
1634 | + case 'v': | ||
1635 | + if (strncmp(p, "Cont", 4) == 0) { | ||
1636 | + int res_signal, res_thread; | ||
1637 | + | ||
1638 | + p += 4; | ||
1639 | + if (*p == '?') { | ||
1640 | + put_packet(s, "vCont;c;C;s;S"); | ||
1641 | + break; | ||
1642 | + } | ||
1643 | + res = 0; | ||
1644 | + res_signal = 0; | ||
1645 | + res_thread = 0; | ||
1646 | + while (*p) { | ||
1647 | + int action, signal; | ||
1648 | + | ||
1649 | + if (*p++ != ';') { | ||
1650 | + res = 0; | ||
1651 | + break; | ||
1652 | + } | ||
1653 | + action = *p++; | ||
1654 | + signal = 0; | ||
1655 | + if (action == 'C' || action == 'S') { | ||
1656 | + signal = strtoul(p, (char **)&p, 16); | ||
1657 | + } else if (action != 'c' && action != 's') { | ||
1658 | + res = 0; | ||
1659 | + break; | ||
1660 | + } | ||
1661 | + thread = 0; | ||
1662 | + if (*p == ':') { | ||
1663 | + thread = strtoull(p+1, (char **)&p, 16); | ||
1664 | + } | ||
1665 | + action = tolower(action); | ||
1666 | + if (res == 0 || (res == 'c' && action == 's')) { | ||
1667 | + res = action; | ||
1668 | + res_signal = signal; | ||
1669 | + res_thread = thread; | ||
1670 | + } | ||
1671 | + } | ||
1672 | + if (res) { | ||
1673 | + if (res_thread != -1 && res_thread != 0) { | ||
1674 | + env = find_cpu(res_thread); | ||
1675 | + if (env == NULL) { | ||
1676 | + put_packet(s, "E22"); | ||
1677 | + break; | ||
1678 | + } | ||
1679 | + s->c_cpu = env; | ||
1680 | + } | ||
1681 | + if (res == 's') { | ||
1682 | + cpu_single_step(s->c_cpu, sstep_flags); | ||
1683 | + } | ||
1684 | + s->signal = res_signal; | ||
1685 | + gdb_continue(s); | ||
1686 | + return RS_IDLE; | ||
1687 | + } | ||
1688 | + break; | ||
1689 | + } else { | ||
1690 | + goto unknown_command; | ||
1691 | + } | ||
1634 | case 'k': | 1692 | case 'k': |
1635 | /* Kill the target */ | 1693 | /* Kill the target */ |
1636 | fprintf(stderr, "\nQEMU: Terminated via GDBstub\n"); | 1694 | fprintf(stderr, "\nQEMU: Terminated via GDBstub\n"); |