1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-12 14:29:28 +00:00

gdb(4): Add basic 'qSupported' support

This is where the host GDB tells us what features it supports, and we
respond with the list we support.  For now, just report PacketSize.
This commit is contained in:
Conrad Meyer 2019-08-22 00:19:41 +00:00
parent 76c8c0902c
commit c4fbbfaa47
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=351366

View File

@ -162,12 +162,117 @@ gdb_do_threadinfo(struct thread **thr_iter)
gdb_tx_end();
}
#define BIT(n) (1ull << (n))
enum {
GDB_MULTIPROCESS,
GDB_SWBREAK,
GDB_HWBREAK,
GDB_QRELOCINSN,
GDB_FORK_EVENTS,
GDB_VFORK_EVENTS,
GDB_EXEC_EVENTS,
GDB_VCONT_SUPPORTED,
GDB_QTHREADEVENTS,
GDB_NO_RESUMED,
};
static const char * const gdb_feature_names[] = {
[GDB_MULTIPROCESS] = "multiprocess",
[GDB_SWBREAK] = "swbreak",
[GDB_HWBREAK] = "hwbreak",
[GDB_QRELOCINSN] = "qRelocInsn",
[GDB_FORK_EVENTS] = "fork-events",
[GDB_VFORK_EVENTS] = "vfork-events",
[GDB_EXEC_EVENTS] = "exec-events",
[GDB_VCONT_SUPPORTED] = "vContSupported",
[GDB_QTHREADEVENTS] = "QThreadEvents",
[GDB_NO_RESUMED] = "no-resumed",
};
static void
gdb_do_qsupported(uint32_t *feat)
{
char *tok, *delim, ok;
size_t i, toklen;
/* Parse supported host features */
*feat = 0;
if (gdb_rx_char() != ':')
goto error;
while (gdb_rxsz > 0) {
tok = gdb_rxp;
delim = strchrnul(gdb_rxp, ';');
toklen = (delim - tok);
gdb_rxp += toklen;
gdb_rxsz -= toklen;
if (*delim != '\0') {
*delim = '\0';
gdb_rxp += 1;
gdb_rxsz -= 1;
}
if (toklen < 2)
goto error;
ok = tok[toklen - 1];
if (ok != '-' && ok != '+') {
/*
* GDB only has one KV-pair feature, and we don't
* support it, so ignore and move on.
*/
if (strchr(tok, '=') != NULL)
continue;
/* Not a KV-pair, and not a +/- flag? Malformed. */
goto error;
}
if (ok != '+')
continue;
tok[toklen - 1] = '\0';
for (i = 0; i < nitems(gdb_feature_names); i++)
if (strcmp(gdb_feature_names[i], tok) == 0)
break;
if (i == nitems(gdb_feature_names)) {
/* Unknown GDB feature. */
continue;
}
*feat |= BIT(i);
}
/* Send a supported feature list back */
gdb_tx_begin(0);
gdb_tx_str("PacketSize");
gdb_tx_char('=');
/*
* We don't buffer framing bytes, but we do need to retain a byte for a
* trailing nul.
*/
gdb_tx_varhex(GDB_BUFSZ + strlen("$#nn") - 1);
/*
* Future consideration:
* - vCont
* - multiprocess
* - qXfer:threads:read
*/
gdb_tx_end();
return;
error:
*feat = 0;
gdb_tx_err(EINVAL);
}
static int
gdb_trap(int type, int code)
{
jmp_buf jb;
struct thread *thr_iter;
void *prev_jb;
uint32_t host_features;
prev_jb = kdb_jmpbuf(jb);
if (setjmp(jb) != 0) {
@ -313,6 +418,8 @@ gdb_trap(int type, int code)
gdb_tx_char('C');
gdb_tx_varhex((long)kdb_thread->td_tid);
gdb_tx_end();
} else if (gdb_rx_equal("Supported")) {
gdb_do_qsupported(&host_features);
} else if (gdb_rx_equal("fThreadInfo")) {
thr_iter = kdb_thr_first();
gdb_do_threadinfo(&thr_iter);