aboutsummaryrefslogtreecommitdiff
path: root/sys/gdb
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2019-08-19 22:57:03 +0000
committerConrad Meyer <cem@FreeBSD.org>2019-08-19 22:57:03 +0000
commit130ef1ad119b9f7570ec962474b76f754f8d644b (patch)
tree36eee7baf65b4d5029780945783717d5156cc5fc /sys/gdb
parent2b0ebb77e48f0a7d453e4c01e09f08c1258ea04a (diff)
downloadsrc-130ef1ad119b9f7570ec962474b76f754f8d644b.tar.gz
src-130ef1ad119b9f7570ec962474b76f754f8d644b.zip
Notes
Diffstat (limited to 'sys/gdb')
-rw-r--r--sys/gdb/gdb_int.h1
-rw-r--r--sys/gdb/gdb_main.c57
-rw-r--r--sys/gdb/gdb_packet.c6
3 files changed, 48 insertions, 16 deletions
diff --git a/sys/gdb/gdb_int.h b/sys/gdb/gdb_int.h
index 467ae1670166..9ef83d707be2 100644
--- a/sys/gdb/gdb_int.h
+++ b/sys/gdb/gdb_int.h
@@ -62,6 +62,7 @@ void gdb_tx_begin(char);
int gdb_tx_end(void);
int gdb_tx_mem(const unsigned char *, size_t);
void gdb_tx_reg(int);
+bool gdb_txbuf_has_capacity(size_t);
int gdb_rx_bindata(unsigned char *data, size_t datalen, size_t *amt);
int gdb_search_mem(const unsigned char *addr, size_t size,
const unsigned char *pat, size_t patlen, const unsigned char **found);
diff --git a/sys/gdb/gdb_main.c b/sys/gdb/gdb_main.c
index 206fee4f7566..aabbf983ba25 100644
--- a/sys/gdb/gdb_main.c
+++ b/sys/gdb/gdb_main.c
@@ -123,6 +123,45 @@ gdb_do_mem_search(void)
gdb_tx_err(EIO);
}
+static void
+gdb_do_threadinfo(struct thread **thr_iter)
+{
+ static struct thread * const done_sentinel = (void *)(uintptr_t)1;
+ static const size_t tidsz_hex = sizeof(lwpid_t) * 2;
+ size_t tds_sent;
+
+ if (*thr_iter == NULL) {
+ gdb_tx_err(ENXIO);
+ return;
+ }
+
+ if (*thr_iter == done_sentinel) {
+ gdb_tx_begin('l');
+ *thr_iter = NULL;
+ goto sendit;
+ }
+
+ gdb_tx_begin('m');
+
+ for (tds_sent = 0;
+ *thr_iter != NULL && gdb_txbuf_has_capacity(tidsz_hex + 1);
+ *thr_iter = kdb_thr_next(*thr_iter), tds_sent++) {
+ if (tds_sent > 0)
+ gdb_tx_char(',');
+ gdb_tx_varhex((*thr_iter)->td_tid);
+ }
+
+ /*
+ * Can't send EOF and "some" in same packet, so set a sentinel to send
+ * EOF when GDB asks us next.
+ */
+ if (*thr_iter == NULL && tds_sent > 0)
+ *thr_iter = done_sentinel;
+
+sendit:
+ gdb_tx_end();
+}
+
static int
gdb_trap(int type, int code)
{
@@ -268,23 +307,9 @@ gdb_trap(int type, int code)
case 'q': /* General query. */
if (gdb_rx_equal("fThreadInfo")) {
thr_iter = kdb_thr_first();
- gdb_tx_begin('m');
- gdb_tx_hex((long)thr_iter->td_tid, 8);
- gdb_tx_end();
+ gdb_do_threadinfo(&thr_iter);
} else if (gdb_rx_equal("sThreadInfo")) {
- if (thr_iter == NULL) {
- gdb_tx_err(ENXIO);
- break;
- }
- thr_iter = kdb_thr_next(thr_iter);
- if (thr_iter != NULL) {
- gdb_tx_begin('m');
- gdb_tx_hex((long)thr_iter->td_tid, 8);
- gdb_tx_end();
- } else {
- gdb_tx_begin('l');
- gdb_tx_end();
- }
+ gdb_do_threadinfo(&thr_iter);
} else if (gdb_rx_equal("Search:memory:")) {
gdb_do_mem_search();
} else if (!gdb_cpu_query())
diff --git a/sys/gdb/gdb_packet.c b/sys/gdb/gdb_packet.c
index c74eaaa855b3..73a431830258 100644
--- a/sys/gdb/gdb_packet.c
+++ b/sys/gdb/gdb_packet.c
@@ -327,6 +327,12 @@ gdb_tx_reg(int regnum)
gdb_tx_mem(regp, regsz);
}
+bool
+gdb_txbuf_has_capacity(size_t req)
+{
+ return (((char *)gdb_txbuf + sizeof(gdb_txbuf) - gdb_txp) >= req);
+}
+
/* Read binary data up until the end of the packet or until we have datalen decoded bytes */
int
gdb_rx_bindata(unsigned char *data, size_t datalen, size_t *amt)