]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/gdb/gdb_main.c
MFV r355071: libbsdxml (expat) 2.2.9.
[FreeBSD/FreeBSD.git] / sys / gdb / gdb_main.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2004 Marcel Moolenaar
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kdb.h>
35 #include <sys/kernel.h>
36 #include <sys/pcpu.h>
37 #include <sys/proc.h>
38 #include <sys/reboot.h>
39 #include <sys/sbuf.h>
40
41 #include <machine/gdb_machdep.h>
42 #include <machine/kdb.h>
43
44 #include <gdb/gdb.h>
45 #include <gdb/gdb_int.h>
46
47 SYSCTL_NODE(_debug, OID_AUTO, gdb, CTLFLAG_RW, 0, "GDB settings");
48
49 static dbbe_init_f gdb_init;
50 static dbbe_trap_f gdb_trap;
51
52 KDB_BACKEND(gdb, gdb_init, NULL, NULL, gdb_trap);
53
54 static struct gdb_dbgport null_gdb_dbgport;
55 DATA_SET(gdb_dbgport_set, null_gdb_dbgport);
56 SET_DECLARE(gdb_dbgport_set, struct gdb_dbgport);
57
58 struct gdb_dbgport *gdb_cur = NULL;
59 int gdb_listening = 0;
60 bool gdb_ackmode = true;
61
62 static unsigned char gdb_bindata[64];
63
64 #ifdef DDB
65 bool gdb_return_to_ddb = false;
66 #endif
67
68 static int
69 gdb_init(void)
70 {
71         struct gdb_dbgport *dp, **iter;
72         int cur_pri, pri;
73
74         gdb_cur = NULL;
75         cur_pri = -1;
76         SET_FOREACH(iter, gdb_dbgport_set) {
77                 dp = *iter;
78                 pri = (dp->gdb_probe != NULL) ? dp->gdb_probe() : -1;
79                 dp->gdb_active = (pri >= 0) ? 0 : -1;
80                 if (pri > cur_pri) {
81                         cur_pri = pri;
82                         gdb_cur = dp;
83                 }
84         }
85         if (gdb_cur != NULL) {
86                 printf("GDB: debug ports:");
87                 SET_FOREACH(iter, gdb_dbgport_set) {
88                         dp = *iter;
89                         if (dp->gdb_active == 0)
90                                 printf(" %s", dp->gdb_name);
91                 }
92                 printf("\n");
93         } else
94                 printf("GDB: no debug ports present\n");
95         if (gdb_cur != NULL) {
96                 gdb_cur->gdb_init();
97                 printf("GDB: current port: %s\n", gdb_cur->gdb_name);
98         }
99         if (gdb_cur != NULL) {
100                 cur_pri = (boothowto & RB_GDB) ? 2 : 0;
101                 gdb_consinit();
102         } else
103                 cur_pri = -1;
104         return (cur_pri);
105 }
106
107 static void
108 gdb_do_mem_search(void)
109 {
110         size_t patlen;
111         intmax_t addr, size;
112         const unsigned char *found;
113
114         if (gdb_rx_varhex(&addr) || gdb_rx_char() != ';' ||
115             gdb_rx_varhex(&size) || gdb_rx_char() != ';' ||
116             gdb_rx_bindata(gdb_bindata, sizeof(gdb_bindata), &patlen)) {
117                 gdb_tx_err(EINVAL);
118                 return;
119         }
120         if (gdb_search_mem((char *)(uintptr_t)addr, size, gdb_bindata,
121             patlen, &found)) {
122                 if (found == 0ULL)
123                         gdb_tx_begin('0');
124                 else {
125                         gdb_tx_begin('1');
126                         gdb_tx_char(',');
127                         gdb_tx_hex((intmax_t)(uintptr_t)found, 8);
128                 }
129                 gdb_tx_end();
130         } else
131                 gdb_tx_err(EIO);
132 }
133
134 static void
135 gdb_do_threadinfo(struct thread **thr_iter)
136 {
137         static struct thread * const done_sentinel = (void *)(uintptr_t)1;
138         static const size_t tidsz_hex = sizeof(lwpid_t) * 2;
139         size_t tds_sent;
140
141         if (*thr_iter == NULL) {
142                 gdb_tx_err(ENXIO);
143                 return;
144         }
145
146         if (*thr_iter == done_sentinel) {
147                 gdb_tx_begin('l');
148                 *thr_iter = NULL;
149                 goto sendit;
150         }
151
152         gdb_tx_begin('m');
153
154         for (tds_sent = 0;
155             *thr_iter != NULL && gdb_txbuf_has_capacity(tidsz_hex + 1);
156             *thr_iter = kdb_thr_next(*thr_iter), tds_sent++) {
157                 if (tds_sent > 0)
158                         gdb_tx_char(',');
159                 gdb_tx_varhex((*thr_iter)->td_tid);
160         }
161
162         /*
163          * Can't send EOF and "some" in same packet, so set a sentinel to send
164          * EOF when GDB asks us next.
165          */
166         if (*thr_iter == NULL && tds_sent > 0)
167                 *thr_iter = done_sentinel;
168
169 sendit:
170         gdb_tx_end();
171 }
172
173 #define BIT(n)  (1ull << (n))
174 enum {
175         GDB_MULTIPROCESS,
176         GDB_SWBREAK,
177         GDB_HWBREAK,
178         GDB_QRELOCINSN,
179         GDB_FORK_EVENTS,
180         GDB_VFORK_EVENTS,
181         GDB_EXEC_EVENTS,
182         GDB_VCONT_SUPPORTED,
183         GDB_QTHREADEVENTS,
184         GDB_NO_RESUMED,
185 };
186 static const char * const gdb_feature_names[] = {
187         [GDB_MULTIPROCESS] = "multiprocess",
188         [GDB_SWBREAK] = "swbreak",
189         [GDB_HWBREAK] = "hwbreak",
190         [GDB_QRELOCINSN] = "qRelocInsn",
191         [GDB_FORK_EVENTS] = "fork-events",
192         [GDB_VFORK_EVENTS] = "vfork-events",
193         [GDB_EXEC_EVENTS] = "exec-events",
194         [GDB_VCONT_SUPPORTED] = "vContSupported",
195         [GDB_QTHREADEVENTS] = "QThreadEvents",
196         [GDB_NO_RESUMED] = "no-resumed",
197 };
198 static void
199 gdb_do_qsupported(uint32_t *feat)
200 {
201         char *tok, *delim, ok;
202         size_t i, toklen;
203
204         /* Parse supported host features */
205         *feat = 0;
206         if (gdb_rx_char() != ':')
207                 goto error;
208
209         while (gdb_rxsz > 0) {
210                 tok = gdb_rxp;
211                 delim = strchrnul(gdb_rxp, ';');
212                 toklen = (delim - tok);
213
214                 gdb_rxp += toklen;
215                 gdb_rxsz -= toklen;
216                 if (*delim != '\0') {
217                         *delim = '\0';
218                         gdb_rxp += 1;
219                         gdb_rxsz -= 1;
220                 }
221
222                 if (toklen < 2)
223                         goto error;
224
225                 ok = tok[toklen - 1];
226                 if (ok != '-' && ok != '+') {
227                         /*
228                          * GDB only has one KV-pair feature, and we don't
229                          * support it, so ignore and move on.
230                          */
231                         if (strchr(tok, '=') != NULL)
232                                 continue;
233                         /* Not a KV-pair, and not a +/- flag?  Malformed. */
234                         goto error;
235                 }
236                 if (ok != '+')
237                         continue;
238                 tok[toklen - 1] = '\0';
239
240                 for (i = 0; i < nitems(gdb_feature_names); i++)
241                         if (strcmp(gdb_feature_names[i], tok) == 0)
242                                 break;
243
244                 if (i == nitems(gdb_feature_names)) {
245                         /* Unknown GDB feature. */
246                         continue;
247                 }
248
249                 *feat |= BIT(i);
250         }
251
252         /* Send a supported feature list back */
253         gdb_tx_begin(0);
254
255         gdb_tx_str("PacketSize");
256         gdb_tx_char('=');
257         /*
258          * We don't buffer framing bytes, but we do need to retain a byte for a
259          * trailing nul.
260          */
261         gdb_tx_varhex(GDB_BUFSZ + strlen("$#nn") - 1);
262
263         gdb_tx_str(";qXfer:threads:read+");
264
265         /*
266          * If the debugport is a reliable transport, request No Ack mode from
267          * the server.  The server may or may not choose to enter No Ack mode.
268          * https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html
269          */
270         if (gdb_cur->gdb_dbfeatures & GDB_DBGP_FEAT_RELIABLE)
271                 gdb_tx_str(";QStartNoAckMode+");
272
273         /*
274          * Future consideration:
275          *   - vCont
276          *   - multiprocess
277          */
278         gdb_tx_end();
279         return;
280
281 error:
282         *feat = 0;
283         gdb_tx_err(EINVAL);
284 }
285
286 /*
287  * A qXfer_context provides a vaguely generic way to generate a multi-packet
288  * response on the fly, making some assumptions about the size of sbuf writes
289  * vs actual packet length constraints.  A non-byzantine gdb host should allow
290  * hundreds of bytes per packet or more.
291  *
292  * Upper layers are considered responsible for escaping the four forbidden
293  * characters '# $ } *'.
294  */
295 struct qXfer_context {
296         struct sbuf sb;
297         size_t last_offset;
298         bool flushed;
299         bool lastmessage;
300         char xfer_buf[GDB_BUFSZ];
301 };
302
303 static int
304 qXfer_drain(void *v, const char *buf, int len)
305 {
306         struct qXfer_context *qx;
307
308         if (len < 0)
309                 return (-EINVAL);
310
311         qx = v;
312         if (qx->flushed) {
313                 /*
314                  * Overflow.  We lost some message.  Maybe the packet size is
315                  * ridiculously small.
316                  */
317                 printf("%s: Overflow in qXfer detected.\n", __func__);
318                 return (-ENOBUFS);
319         }
320
321         qx->last_offset += len;
322         qx->flushed = true;
323
324         if (qx->lastmessage)
325                 gdb_tx_begin('l');
326         else
327                 gdb_tx_begin('m');
328
329         memcpy(gdb_txp, buf, len);
330         gdb_txp += len;
331
332         gdb_tx_end();
333         return (len);
334 }
335
336 static int
337 init_qXfer_ctx(struct qXfer_context *qx, uintmax_t len)
338 {
339
340         /* Protocol (max) length field includes framing overhead. */
341         if (len < sizeof("$m#nn"))
342                 return (ENOSPC);
343
344         len -= 4;
345         len = ummin(len, GDB_BUFSZ - 1);
346
347         qx->last_offset = 0;
348         qx->flushed = false;
349         qx->lastmessage = false;
350         sbuf_new(&qx->sb, qx->xfer_buf, len, SBUF_FIXEDLEN);
351         sbuf_set_drain(&qx->sb, qXfer_drain, qx);
352         return (0);
353 }
354
355 /*
356  * dst must be 2x strlen(max_src) + 1.
357  *
358  * Squashes invalid XML characters down to _.  Sorry.  Then escapes for GDB.
359  */
360 static void
361 qXfer_escape_xmlattr_str(char *dst, size_t dstlen, const char *src)
362 {
363         static const char *forbidden = "#$}*";
364
365         size_t i;
366         char c;
367
368         for (i = 0; i < dstlen - 1 && *src != 0; src++, i++) {
369                 c = *src;
370                 /* XML attr filter */
371                 if (c < 32)
372                         c = '_';
373                 /* We assume attributes will be "" quoted. */
374                 if (c == '<' || c == '&' || c == '"')
375                         c = '_';
376
377                 /* GDB escape. */
378                 if (strchr(forbidden, c) != NULL) {
379                         *dst++ = '}';
380                         c ^= 0x20;
381                 }
382                 *dst++ = c;
383         }
384         if (*src != 0)
385                 printf("XXX%s: overflow; API misuse\n", __func__);
386
387         *dst = 0;
388 }
389
390 /*
391  * Dynamically generate qXfer:threads document, one packet at a time.
392  *
393  * The format is loosely described[0], although it does not seem that the
394  * <?xml?> mentioned on that page is required.
395  *
396  * [0]: https://sourceware.org/gdb/current/onlinedocs/gdb/Thread-List-Format.html
397  */
398 static void
399 do_qXfer_threads_read(void)
400 {
401         /* Kludgy context */
402         static struct {
403                 struct qXfer_context qXfer;
404                 /* Kludgy state machine */
405                 struct thread *iter;
406                 enum {
407                         XML_START_THREAD,       /* '<thread' */
408                         XML_THREAD_ID,          /* ' id="xxx"' */
409                         XML_THREAD_CORE,        /* ' core="yyy"' */
410                         XML_THREAD_NAME,        /* ' name="zzz"' */
411                         XML_THREAD_EXTRA,       /* '> ...' */
412                         XML_END_THREAD,         /* '</thread>' */
413                         XML_SENT_END_THREADS,   /* '</threads>' */
414                 } next_step;
415         } ctx;
416         static char td_name_escape[MAXCOMLEN * 2 + 1];
417
418         const char *name_src;
419         uintmax_t offset, len;
420         int error;
421
422         /* Annex part must be empty. */
423         if (gdb_rx_char() != ':')
424                 goto misformed_request;
425
426         if (gdb_rx_varhex(&offset) != 0 ||
427             gdb_rx_char() != ',' ||
428             gdb_rx_varhex(&len) != 0)
429                 goto misformed_request;
430
431         /*
432          * Validate resume xfers.
433          */
434         if (offset != 0) {
435                 if (offset != ctx.qXfer.last_offset) {
436                         printf("%s: Resumed offset %ju != expected %zu\n",
437                             __func__, offset, ctx.qXfer.last_offset);
438                         error = ESPIPE;
439                         goto request_error;
440                 }
441                 ctx.qXfer.flushed = false;
442         }
443
444         if (offset == 0) {
445                 ctx.iter = kdb_thr_first();
446                 ctx.next_step = XML_START_THREAD;
447                 error = init_qXfer_ctx(&ctx.qXfer, len);
448                 if (error != 0)
449                         goto request_error;
450
451                 sbuf_cat(&ctx.qXfer.sb, "<threads>");
452         }
453
454         while (!ctx.qXfer.flushed && ctx.iter != NULL) {
455                 switch (ctx.next_step) {
456                 case XML_START_THREAD:
457                         ctx.next_step = XML_THREAD_ID;
458                         sbuf_cat(&ctx.qXfer.sb, "<thread");
459                         continue;
460
461                 case XML_THREAD_ID:
462                         ctx.next_step = XML_THREAD_CORE;
463                         sbuf_printf(&ctx.qXfer.sb, " id=\"%jx\"",
464                             (uintmax_t)ctx.iter->td_tid);
465                         continue;
466
467                 case XML_THREAD_CORE:
468                         ctx.next_step = XML_THREAD_NAME;
469                         if (ctx.iter->td_oncpu != NOCPU) {
470                                 sbuf_printf(&ctx.qXfer.sb, " core=\"%d\"",
471                                     ctx.iter->td_oncpu);
472                         }
473                         continue;
474
475                 case XML_THREAD_NAME:
476                         ctx.next_step = XML_THREAD_EXTRA;
477
478                         if (ctx.iter->td_name[0] != 0)
479                                 name_src = ctx.iter->td_name;
480                         else if (ctx.iter->td_proc != NULL &&
481                             ctx.iter->td_proc->p_comm[0] != 0)
482                                 name_src = ctx.iter->td_proc->p_comm;
483                         else
484                                 continue;
485
486                         qXfer_escape_xmlattr_str(td_name_escape,
487                             sizeof(td_name_escape), name_src);
488                         sbuf_printf(&ctx.qXfer.sb, " name=\"%s\"",
489                             td_name_escape);
490                         continue;
491
492                 case XML_THREAD_EXTRA:
493                         ctx.next_step = XML_END_THREAD;
494
495                         sbuf_putc(&ctx.qXfer.sb, '>');
496
497                         if (ctx.iter->td_state == TDS_RUNNING)
498                                 sbuf_cat(&ctx.qXfer.sb, "Running");
499                         else if (ctx.iter->td_state == TDS_RUNQ)
500                                 sbuf_cat(&ctx.qXfer.sb, "RunQ");
501                         else if (ctx.iter->td_state == TDS_CAN_RUN)
502                                 sbuf_cat(&ctx.qXfer.sb, "CanRun");
503                         else if (TD_ON_LOCK(ctx.iter))
504                                 sbuf_cat(&ctx.qXfer.sb, "Blocked");
505                         else if (TD_IS_SLEEPING(ctx.iter))
506                                 sbuf_cat(&ctx.qXfer.sb, "Sleeping");
507                         else if (TD_IS_SWAPPED(ctx.iter))
508                                 sbuf_cat(&ctx.qXfer.sb, "Swapped");
509                         else if (TD_AWAITING_INTR(ctx.iter))
510                                 sbuf_cat(&ctx.qXfer.sb, "IthreadWait");
511                         else if (TD_IS_SUSPENDED(ctx.iter))
512                                 sbuf_cat(&ctx.qXfer.sb, "Suspended");
513                         else
514                                 sbuf_cat(&ctx.qXfer.sb, "???");
515                         continue;
516
517                 case XML_END_THREAD:
518                         ctx.next_step = XML_START_THREAD;
519                         sbuf_cat(&ctx.qXfer.sb, "</thread>");
520                         ctx.iter = kdb_thr_next(ctx.iter);
521                         continue;
522
523                 /*
524                  * This one isn't part of the looping state machine,
525                  * but GCC complains if you leave an enum value out of the
526                  * select.
527                  */
528                 case XML_SENT_END_THREADS:
529                         /* NOTREACHED */
530                         break;
531                 }
532         }
533         if (ctx.qXfer.flushed)
534                 return;
535
536         if (ctx.next_step != XML_SENT_END_THREADS) {
537                 ctx.next_step = XML_SENT_END_THREADS;
538                 sbuf_cat(&ctx.qXfer.sb, "</threads>");
539         }
540         if (ctx.qXfer.flushed)
541                 return;
542
543         ctx.qXfer.lastmessage = true;
544         sbuf_finish(&ctx.qXfer.sb);
545         sbuf_delete(&ctx.qXfer.sb);
546         ctx.qXfer.last_offset = 0;
547         return;
548
549 misformed_request:
550         /*
551          * GDB "General-Query-Packets.html" qXfer-read anchor specifically
552          * documents an E00 code for malformed requests or invalid annex.
553          * Non-zero codes indicate invalid offset or "error reading the data."
554          */
555         error = 0;
556 request_error:
557         gdb_tx_err(error);
558         return;
559 }
560
561 /*
562  * A set of standardized transfers from "special data areas."
563  *
564  * We've already matched on "qXfer:" and advanced the rx packet buffer past
565  * that bit.  Parse out the rest of the packet and generate an appropriate
566  * response.
567  */
568 static void
569 do_qXfer(void)
570 {
571         if (!gdb_rx_equal("threads:"))
572                 goto unrecognized;
573
574         if (!gdb_rx_equal("read:"))
575                 goto unrecognized;
576
577         do_qXfer_threads_read();
578         return;
579
580 unrecognized:
581         gdb_tx_empty();
582         return;
583 }
584
585 static void
586 gdb_handle_detach(void)
587 {
588         kdb_cpu_clear_singlestep();
589         gdb_listening = 0;
590
591         if (gdb_cur->gdb_dbfeatures & GDB_DBGP_FEAT_WANTTERM)
592                 gdb_cur->gdb_term();
593
594 #ifdef DDB
595         if (!gdb_return_to_ddb)
596                 return;
597
598         gdb_return_to_ddb = false;
599
600         if (kdb_dbbe_select("ddb") != 0)
601                 printf("The ddb backend could not be selected.\n");
602 #endif
603 }
604
605 static int
606 gdb_trap(int type, int code)
607 {
608         jmp_buf jb;
609         struct thread *thr_iter;
610         void *prev_jb;
611         uint32_t host_features;
612
613         prev_jb = kdb_jmpbuf(jb);
614         if (setjmp(jb) != 0) {
615                 printf("%s bailing, hopefully back to ddb!\n", __func__);
616                 gdb_listening = 0;
617                 (void)kdb_jmpbuf(prev_jb);
618                 return (1);
619         }
620
621         gdb_listening = 0;
622         gdb_ackmode = true;
623
624         /*
625          * Send a T packet. We currently do not support watchpoints (the
626          * awatch, rwatch or watch elements).
627          */
628         gdb_tx_begin('T');
629         gdb_tx_hex(gdb_cpu_signal(type, code), 2);
630         gdb_tx_varhex(GDB_REG_PC);
631         gdb_tx_char(':');
632         gdb_tx_reg(GDB_REG_PC);
633         gdb_tx_char(';');
634         gdb_tx_str("thread:");
635         gdb_tx_varhex((long)kdb_thread->td_tid);
636         gdb_tx_char(';');
637         gdb_tx_end();                   /* XXX check error condition. */
638
639         thr_iter = NULL;
640         while (gdb_rx_begin() == 0) {
641                 /* printf("GDB: got '%s'\n", gdb_rxp); */
642                 switch (gdb_rx_char()) {
643                 case '?':       /* Last signal. */
644                         gdb_tx_begin('T');
645                         gdb_tx_hex(gdb_cpu_signal(type, code), 2);
646                         gdb_tx_str("thread:");
647                         gdb_tx_varhex((long)kdb_thread->td_tid);
648                         gdb_tx_char(';');
649                         gdb_tx_end();
650                         break;
651                 case 'c': {     /* Continue. */
652                         uintmax_t addr;
653                         register_t pc;
654                         if (!gdb_rx_varhex(&addr)) {
655                                 pc = addr;
656                                 gdb_cpu_setreg(GDB_REG_PC, &pc);
657                         }
658                         kdb_cpu_clear_singlestep();
659                         gdb_listening = 1;
660                         return (1);
661                 }
662                 case 'C': {     /* Continue with signal. */
663                         uintmax_t addr, sig;
664                         register_t pc;
665                         if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
666                             !gdb_rx_varhex(&addr)) {
667                                 pc = addr;
668                                 gdb_cpu_setreg(GDB_REG_PC, &pc);
669                         }
670                         kdb_cpu_clear_singlestep();
671                         gdb_listening = 1;
672                         return (1);
673                 }
674                 case 'D': {     /* Detach */
675                         gdb_tx_ok();
676                         gdb_handle_detach();
677                         return (1);
678                 }
679                 case 'g': {     /* Read registers. */
680                         size_t r;
681                         gdb_tx_begin(0);
682                         for (r = 0; r < GDB_NREGS; r++)
683                                 gdb_tx_reg(r);
684                         gdb_tx_end();
685                         break;
686                 }
687                 case 'G':       /* Write registers. */
688                         gdb_tx_err(0);
689                         break;
690                 case 'H': {     /* Set thread. */
691                         intmax_t tid;
692                         struct thread *thr;
693
694                         /* Ignore 'g' (general) or 'c' (continue) flag. */
695                         (void) gdb_rx_char();
696
697                         if (gdb_rx_varhex(&tid)) {
698                                 gdb_tx_err(EINVAL);
699                                 break;
700                         }
701                         if (tid > 0) {
702                                 thr = kdb_thr_lookup(tid);
703                                 if (thr == NULL) {
704                                         gdb_tx_err(ENOENT);
705                                         break;
706                                 }
707                                 kdb_thr_select(thr);
708                         }
709                         gdb_tx_ok();
710                         break;
711                 }
712                 case 'k':       /* Kill request. */
713                         gdb_handle_detach();
714                         return (1);
715                 case 'm': {     /* Read memory. */
716                         uintmax_t addr, size;
717                         if (gdb_rx_varhex(&addr) || gdb_rx_char() != ',' ||
718                             gdb_rx_varhex(&size)) {
719                                 gdb_tx_err(EINVAL);
720                                 break;
721                         }
722                         gdb_tx_begin(0);
723                         if (gdb_tx_mem((char *)(uintptr_t)addr, size))
724                                 gdb_tx_end();
725                         else
726                                 gdb_tx_err(EIO);
727                         break;
728                 }
729                 case 'M': {     /* Write memory. */
730                         uintmax_t addr, size;
731                         if (gdb_rx_varhex(&addr) || gdb_rx_char() != ',' ||
732                             gdb_rx_varhex(&size) || gdb_rx_char() != ':') {
733                                 gdb_tx_err(EINVAL);
734                                 break;
735                         }
736                         if (gdb_rx_mem((char *)(uintptr_t)addr, size) == 0)
737                                 gdb_tx_err(EIO);
738                         else
739                                 gdb_tx_ok();
740                         break;
741                 }
742                 case 'P': {     /* Write register. */
743                         char *val;
744                         uintmax_t reg;
745                         val = gdb_rxp;
746                         if (gdb_rx_varhex(&reg) || gdb_rx_char() != '=' ||
747                             !gdb_rx_mem(val, gdb_cpu_regsz(reg))) {
748                                 gdb_tx_err(EINVAL);
749                                 break;
750                         }
751                         gdb_cpu_setreg(reg, val);
752                         gdb_tx_ok();
753                         break;
754                 }
755                 case 'q':       /* General query. */
756                         if (gdb_rx_equal("C")) {
757                                 gdb_tx_begin('Q');
758                                 gdb_tx_char('C');
759                                 gdb_tx_varhex((long)kdb_thread->td_tid);
760                                 gdb_tx_end();
761                         } else if (gdb_rx_equal("Supported")) {
762                                 gdb_do_qsupported(&host_features);
763                         } else if (gdb_rx_equal("fThreadInfo")) {
764                                 thr_iter = kdb_thr_first();
765                                 gdb_do_threadinfo(&thr_iter);
766                         } else if (gdb_rx_equal("sThreadInfo")) {
767                                 gdb_do_threadinfo(&thr_iter);
768                         } else if (gdb_rx_equal("Xfer:")) {
769                                 do_qXfer();
770                         } else if (gdb_rx_equal("Search:memory:")) {
771                                 gdb_do_mem_search();
772                         } else if (!gdb_cpu_query())
773                                 gdb_tx_empty();
774                         break;
775                 case 'Q':
776                         if (gdb_rx_equal("StartNoAckMode")) {
777                                 if ((gdb_cur->gdb_dbfeatures &
778                                     GDB_DBGP_FEAT_RELIABLE) == 0) {
779                                         /*
780                                          * Shouldn't happen if we didn't
781                                          * advertise support.  Reject.
782                                          */
783                                         gdb_tx_empty();
784                                         break;
785                                 }
786                                 gdb_ackmode = false;
787                                 gdb_tx_ok();
788                         } else
789                                 gdb_tx_empty();
790                         break;
791                 case 's': {     /* Step. */
792                         uintmax_t addr;
793                         register_t pc;
794                         if (!gdb_rx_varhex(&addr)) {
795                                 pc = addr;
796                                 gdb_cpu_setreg(GDB_REG_PC, &pc);
797                         }
798                         kdb_cpu_set_singlestep();
799                         gdb_listening = 1;
800                         return (1);
801                 }
802                 case 'S': {     /* Step with signal. */
803                         uintmax_t addr, sig;
804                         register_t pc;
805                         if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
806                             !gdb_rx_varhex(&addr)) {
807                                 pc = addr;
808                                 gdb_cpu_setreg(GDB_REG_PC, &pc);
809                         }
810                         kdb_cpu_set_singlestep();
811                         gdb_listening = 1;
812                         return (1);
813                 }
814                 case 'T': {     /* Thread alive. */
815                         intmax_t tid;
816                         if (gdb_rx_varhex(&tid)) {
817                                 gdb_tx_err(EINVAL);
818                                 break;
819                         }
820                         if (kdb_thr_lookup(tid) != NULL)
821                                 gdb_tx_ok();
822                         else
823                                 gdb_tx_err(ENOENT);
824                         break;
825                 }
826                 case EOF:
827                         /* Empty command. Treat as unknown command. */
828                         /* FALLTHROUGH */
829                 default:
830                         /* Unknown command. Send empty response. */
831                         gdb_tx_empty();
832                         break;
833                 }
834         }
835         (void)kdb_jmpbuf(prev_jb);
836         return (0);
837 }