1fa521b03SWarner Losh /*- 2497b6b2aSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3497b6b2aSPedro F. Giffuni * 472d44f31SMarcel Moolenaar * Copyright (c) 2004 Marcel Moolenaar 572d44f31SMarcel Moolenaar * All rights reserved. 672d44f31SMarcel Moolenaar * 772d44f31SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 872d44f31SMarcel Moolenaar * modification, are permitted provided that the following conditions 972d44f31SMarcel Moolenaar * are met: 1072d44f31SMarcel Moolenaar * 1172d44f31SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 1272d44f31SMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 1372d44f31SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 1472d44f31SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 1572d44f31SMarcel Moolenaar * documentation and/or other materials provided with the distribution. 1672d44f31SMarcel Moolenaar * 1772d44f31SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 1872d44f31SMarcel Moolenaar * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1972d44f31SMarcel Moolenaar * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2072d44f31SMarcel Moolenaar * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2172d44f31SMarcel Moolenaar * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2272d44f31SMarcel Moolenaar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2372d44f31SMarcel Moolenaar * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2472d44f31SMarcel Moolenaar * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2572d44f31SMarcel Moolenaar * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2672d44f31SMarcel Moolenaar * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2772d44f31SMarcel Moolenaar */ 2872d44f31SMarcel Moolenaar 2972d44f31SMarcel Moolenaar #include <sys/cdefs.h> 3072d44f31SMarcel Moolenaar __FBSDID("$FreeBSD$"); 3172d44f31SMarcel Moolenaar 3272d44f31SMarcel Moolenaar #include <sys/param.h> 3372d44f31SMarcel Moolenaar #include <sys/systm.h> 3472d44f31SMarcel Moolenaar #include <sys/kdb.h> 3572d44f31SMarcel Moolenaar #include <sys/kernel.h> 3672d44f31SMarcel Moolenaar #include <sys/pcpu.h> 3772d44f31SMarcel Moolenaar #include <sys/proc.h> 3872d44f31SMarcel Moolenaar #include <sys/reboot.h> 3972d44f31SMarcel Moolenaar 4072d44f31SMarcel Moolenaar #include <machine/gdb_machdep.h> 4172d44f31SMarcel Moolenaar #include <machine/kdb.h> 4272d44f31SMarcel Moolenaar 4372d44f31SMarcel Moolenaar #include <gdb/gdb.h> 4472d44f31SMarcel Moolenaar #include <gdb/gdb_int.h> 4572d44f31SMarcel Moolenaar 4672d44f31SMarcel Moolenaar static dbbe_init_f gdb_init; 4772d44f31SMarcel Moolenaar static dbbe_trap_f gdb_trap; 4872d44f31SMarcel Moolenaar 4928926c57SJohn Baldwin KDB_BACKEND(gdb, gdb_init, NULL, NULL, gdb_trap); 5072d44f31SMarcel Moolenaar 51e8d86c0eSPoul-Henning Kamp static struct gdb_dbgport null_gdb_dbgport; 52e8d86c0eSPoul-Henning Kamp DATA_SET(gdb_dbgport_set, null_gdb_dbgport); 5372d44f31SMarcel Moolenaar SET_DECLARE(gdb_dbgport_set, struct gdb_dbgport); 5472d44f31SMarcel Moolenaar 5572d44f31SMarcel Moolenaar struct gdb_dbgport *gdb_cur = NULL; 567d0c6c9fSSam Leffler int gdb_listening = 0; 5772d44f31SMarcel Moolenaar 5827ecc2adSBenno Rice static unsigned char gdb_bindata[64]; 5927ecc2adSBenno Rice 6072d44f31SMarcel Moolenaar static int 6172d44f31SMarcel Moolenaar gdb_init(void) 6272d44f31SMarcel Moolenaar { 6372d44f31SMarcel Moolenaar struct gdb_dbgport *dp, **iter; 6472d44f31SMarcel Moolenaar int cur_pri, pri; 6572d44f31SMarcel Moolenaar 6672d44f31SMarcel Moolenaar gdb_cur = NULL; 6772d44f31SMarcel Moolenaar cur_pri = -1; 6872d44f31SMarcel Moolenaar SET_FOREACH(iter, gdb_dbgport_set) { 6972d44f31SMarcel Moolenaar dp = *iter; 7072d44f31SMarcel Moolenaar pri = (dp->gdb_probe != NULL) ? dp->gdb_probe() : -1; 7172d44f31SMarcel Moolenaar dp->gdb_active = (pri >= 0) ? 0 : -1; 7272d44f31SMarcel Moolenaar if (pri > cur_pri) { 7372d44f31SMarcel Moolenaar cur_pri = pri; 7472d44f31SMarcel Moolenaar gdb_cur = dp; 7572d44f31SMarcel Moolenaar } 7672d44f31SMarcel Moolenaar } 7772d44f31SMarcel Moolenaar if (gdb_cur != NULL) { 7872d44f31SMarcel Moolenaar printf("GDB: debug ports:"); 7972d44f31SMarcel Moolenaar SET_FOREACH(iter, gdb_dbgport_set) { 8072d44f31SMarcel Moolenaar dp = *iter; 8172d44f31SMarcel Moolenaar if (dp->gdb_active == 0) 8272d44f31SMarcel Moolenaar printf(" %s", dp->gdb_name); 8372d44f31SMarcel Moolenaar } 8472d44f31SMarcel Moolenaar printf("\n"); 8572d44f31SMarcel Moolenaar } else 8672d44f31SMarcel Moolenaar printf("GDB: no debug ports present\n"); 8772d44f31SMarcel Moolenaar if (gdb_cur != NULL) { 8872d44f31SMarcel Moolenaar gdb_cur->gdb_init(); 8972d44f31SMarcel Moolenaar printf("GDB: current port: %s\n", gdb_cur->gdb_name); 9072d44f31SMarcel Moolenaar } 917d0c6c9fSSam Leffler if (gdb_cur != NULL) { 9272d44f31SMarcel Moolenaar cur_pri = (boothowto & RB_GDB) ? 2 : 0; 937d0c6c9fSSam Leffler gdb_consinit(); 947d0c6c9fSSam Leffler } else 9572d44f31SMarcel Moolenaar cur_pri = -1; 9672d44f31SMarcel Moolenaar return (cur_pri); 9772d44f31SMarcel Moolenaar } 9872d44f31SMarcel Moolenaar 998a7a6571SRyan Libby static void 1008a7a6571SRyan Libby gdb_do_mem_search(void) 1018a7a6571SRyan Libby { 1028a7a6571SRyan Libby size_t patlen; 1038a7a6571SRyan Libby intmax_t addr, size; 1048a7a6571SRyan Libby const unsigned char *found; 1058a7a6571SRyan Libby 1068a7a6571SRyan Libby if (gdb_rx_varhex(&addr) || gdb_rx_char() != ';' || 1078a7a6571SRyan Libby gdb_rx_varhex(&size) || gdb_rx_char() != ';' || 1088a7a6571SRyan Libby gdb_rx_bindata(gdb_bindata, sizeof(gdb_bindata), &patlen)) { 1098a7a6571SRyan Libby gdb_tx_err(EINVAL); 1108a7a6571SRyan Libby return; 1118a7a6571SRyan Libby } 1128a7a6571SRyan Libby if (gdb_search_mem((char *)(uintptr_t)addr, size, gdb_bindata, 1138a7a6571SRyan Libby patlen, &found)) { 1148a7a6571SRyan Libby if (found == 0ULL) 1158a7a6571SRyan Libby gdb_tx_begin('0'); 1168a7a6571SRyan Libby else { 1178a7a6571SRyan Libby gdb_tx_begin('1'); 1188a7a6571SRyan Libby gdb_tx_char(','); 1198a7a6571SRyan Libby gdb_tx_hex((intmax_t)(uintptr_t)found, 8); 1208a7a6571SRyan Libby } 1218a7a6571SRyan Libby gdb_tx_end(); 1228a7a6571SRyan Libby } else 1238a7a6571SRyan Libby gdb_tx_err(EIO); 1248a7a6571SRyan Libby } 1258a7a6571SRyan Libby 126*130ef1adSConrad Meyer static void 127*130ef1adSConrad Meyer gdb_do_threadinfo(struct thread **thr_iter) 128*130ef1adSConrad Meyer { 129*130ef1adSConrad Meyer static struct thread * const done_sentinel = (void *)(uintptr_t)1; 130*130ef1adSConrad Meyer static const size_t tidsz_hex = sizeof(lwpid_t) * 2; 131*130ef1adSConrad Meyer size_t tds_sent; 132*130ef1adSConrad Meyer 133*130ef1adSConrad Meyer if (*thr_iter == NULL) { 134*130ef1adSConrad Meyer gdb_tx_err(ENXIO); 135*130ef1adSConrad Meyer return; 136*130ef1adSConrad Meyer } 137*130ef1adSConrad Meyer 138*130ef1adSConrad Meyer if (*thr_iter == done_sentinel) { 139*130ef1adSConrad Meyer gdb_tx_begin('l'); 140*130ef1adSConrad Meyer *thr_iter = NULL; 141*130ef1adSConrad Meyer goto sendit; 142*130ef1adSConrad Meyer } 143*130ef1adSConrad Meyer 144*130ef1adSConrad Meyer gdb_tx_begin('m'); 145*130ef1adSConrad Meyer 146*130ef1adSConrad Meyer for (tds_sent = 0; 147*130ef1adSConrad Meyer *thr_iter != NULL && gdb_txbuf_has_capacity(tidsz_hex + 1); 148*130ef1adSConrad Meyer *thr_iter = kdb_thr_next(*thr_iter), tds_sent++) { 149*130ef1adSConrad Meyer if (tds_sent > 0) 150*130ef1adSConrad Meyer gdb_tx_char(','); 151*130ef1adSConrad Meyer gdb_tx_varhex((*thr_iter)->td_tid); 152*130ef1adSConrad Meyer } 153*130ef1adSConrad Meyer 154*130ef1adSConrad Meyer /* 155*130ef1adSConrad Meyer * Can't send EOF and "some" in same packet, so set a sentinel to send 156*130ef1adSConrad Meyer * EOF when GDB asks us next. 157*130ef1adSConrad Meyer */ 158*130ef1adSConrad Meyer if (*thr_iter == NULL && tds_sent > 0) 159*130ef1adSConrad Meyer *thr_iter = done_sentinel; 160*130ef1adSConrad Meyer 161*130ef1adSConrad Meyer sendit: 162*130ef1adSConrad Meyer gdb_tx_end(); 163*130ef1adSConrad Meyer } 164*130ef1adSConrad Meyer 16572d44f31SMarcel Moolenaar static int 16672d44f31SMarcel Moolenaar gdb_trap(int type, int code) 16772d44f31SMarcel Moolenaar { 1683a5d3671SMatthew D Fleming jmp_buf jb; 16972d44f31SMarcel Moolenaar struct thread *thr_iter; 1703a5d3671SMatthew D Fleming void *prev_jb; 1713a5d3671SMatthew D Fleming 1723a5d3671SMatthew D Fleming prev_jb = kdb_jmpbuf(jb); 1733a5d3671SMatthew D Fleming if (setjmp(jb) != 0) { 1743a5d3671SMatthew D Fleming printf("%s bailing, hopefully back to ddb!\n", __func__); 1753a5d3671SMatthew D Fleming gdb_listening = 0; 1763a5d3671SMatthew D Fleming (void)kdb_jmpbuf(prev_jb); 1773a5d3671SMatthew D Fleming return (1); 1783a5d3671SMatthew D Fleming } 17972d44f31SMarcel Moolenaar 1807d0c6c9fSSam Leffler gdb_listening = 0; 18172d44f31SMarcel Moolenaar /* 18272d44f31SMarcel Moolenaar * Send a T packet. We currently do not support watchpoints (the 18372d44f31SMarcel Moolenaar * awatch, rwatch or watch elements). 18472d44f31SMarcel Moolenaar */ 18572d44f31SMarcel Moolenaar gdb_tx_begin('T'); 18672d44f31SMarcel Moolenaar gdb_tx_hex(gdb_cpu_signal(type, code), 2); 18772d44f31SMarcel Moolenaar gdb_tx_varhex(GDB_REG_PC); 18872d44f31SMarcel Moolenaar gdb_tx_char(':'); 18972d44f31SMarcel Moolenaar gdb_tx_reg(GDB_REG_PC); 19072d44f31SMarcel Moolenaar gdb_tx_char(';'); 19172d44f31SMarcel Moolenaar gdb_tx_str("thread:"); 19272d44f31SMarcel Moolenaar gdb_tx_varhex((long)kdb_thread->td_tid); 19372d44f31SMarcel Moolenaar gdb_tx_char(';'); 19472d44f31SMarcel Moolenaar gdb_tx_end(); /* XXX check error condition. */ 19572d44f31SMarcel Moolenaar 19672d44f31SMarcel Moolenaar thr_iter = NULL; 19772d44f31SMarcel Moolenaar while (gdb_rx_begin() == 0) { 19803e62bf3SMarcel Moolenaar /* printf("GDB: got '%s'\n", gdb_rxp); */ 19972d44f31SMarcel Moolenaar switch (gdb_rx_char()) { 20072d44f31SMarcel Moolenaar case '?': /* Last signal. */ 20172d44f31SMarcel Moolenaar gdb_tx_begin('S'); 20272d44f31SMarcel Moolenaar gdb_tx_hex(gdb_cpu_signal(type, code), 2); 20372d44f31SMarcel Moolenaar gdb_tx_end(); 20472d44f31SMarcel Moolenaar break; 20572d44f31SMarcel Moolenaar case 'c': { /* Continue. */ 20672d44f31SMarcel Moolenaar uintmax_t addr; 207bcc5241cSMarcel Moolenaar register_t pc; 208bcc5241cSMarcel Moolenaar if (!gdb_rx_varhex(&addr)) { 209bcc5241cSMarcel Moolenaar pc = addr; 210bcc5241cSMarcel Moolenaar gdb_cpu_setreg(GDB_REG_PC, &pc); 211bcc5241cSMarcel Moolenaar } 21272d44f31SMarcel Moolenaar kdb_cpu_clear_singlestep(); 2137d0c6c9fSSam Leffler gdb_listening = 1; 21472d44f31SMarcel Moolenaar return (1); 21572d44f31SMarcel Moolenaar } 21672d44f31SMarcel Moolenaar case 'C': { /* Continue with signal. */ 21772d44f31SMarcel Moolenaar uintmax_t addr, sig; 218bcc5241cSMarcel Moolenaar register_t pc; 21972d44f31SMarcel Moolenaar if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' && 220bcc5241cSMarcel Moolenaar !gdb_rx_varhex(&addr)) { 221bcc5241cSMarcel Moolenaar pc = addr; 222bcc5241cSMarcel Moolenaar gdb_cpu_setreg(GDB_REG_PC, &pc); 223bcc5241cSMarcel Moolenaar } 22472d44f31SMarcel Moolenaar kdb_cpu_clear_singlestep(); 2257d0c6c9fSSam Leffler gdb_listening = 1; 22672d44f31SMarcel Moolenaar return (1); 22772d44f31SMarcel Moolenaar } 228d412b2deSPeter Grehan case 'D': { /* Detach */ 229d412b2deSPeter Grehan gdb_tx_ok(); 230d412b2deSPeter Grehan kdb_cpu_clear_singlestep(); 231d412b2deSPeter Grehan return (1); 232d412b2deSPeter Grehan } 23372d44f31SMarcel Moolenaar case 'g': { /* Read registers. */ 23472d44f31SMarcel Moolenaar size_t r; 23572d44f31SMarcel Moolenaar gdb_tx_begin(0); 23672d44f31SMarcel Moolenaar for (r = 0; r < GDB_NREGS; r++) 23772d44f31SMarcel Moolenaar gdb_tx_reg(r); 23872d44f31SMarcel Moolenaar gdb_tx_end(); 23972d44f31SMarcel Moolenaar break; 24072d44f31SMarcel Moolenaar } 24172d44f31SMarcel Moolenaar case 'G': /* Write registers. */ 24272d44f31SMarcel Moolenaar gdb_tx_err(0); 24372d44f31SMarcel Moolenaar break; 24472d44f31SMarcel Moolenaar case 'H': { /* Set thread. */ 24572d44f31SMarcel Moolenaar intmax_t tid; 24672d44f31SMarcel Moolenaar struct thread *thr; 24772d44f31SMarcel Moolenaar gdb_rx_char(); 2484af77eceSSam Leffler if (gdb_rx_varhex(&tid)) { 2494af77eceSSam Leffler gdb_tx_err(EINVAL); 2504af77eceSSam Leffler break; 2514af77eceSSam Leffler } 25272d44f31SMarcel Moolenaar if (tid > 0) { 25372d44f31SMarcel Moolenaar thr = kdb_thr_lookup(tid); 25472d44f31SMarcel Moolenaar if (thr == NULL) { 25572d44f31SMarcel Moolenaar gdb_tx_err(ENOENT); 25672d44f31SMarcel Moolenaar break; 25772d44f31SMarcel Moolenaar } 25872d44f31SMarcel Moolenaar kdb_thr_select(thr); 25972d44f31SMarcel Moolenaar } 26072d44f31SMarcel Moolenaar gdb_tx_ok(); 26172d44f31SMarcel Moolenaar break; 26272d44f31SMarcel Moolenaar } 26372d44f31SMarcel Moolenaar case 'k': /* Kill request. */ 26472d44f31SMarcel Moolenaar kdb_cpu_clear_singlestep(); 2657d0c6c9fSSam Leffler gdb_listening = 1; 26672d44f31SMarcel Moolenaar return (1); 26772d44f31SMarcel Moolenaar case 'm': { /* Read memory. */ 26872d44f31SMarcel Moolenaar uintmax_t addr, size; 26972d44f31SMarcel Moolenaar if (gdb_rx_varhex(&addr) || gdb_rx_char() != ',' || 27072d44f31SMarcel Moolenaar gdb_rx_varhex(&size)) { 27172d44f31SMarcel Moolenaar gdb_tx_err(EINVAL); 27272d44f31SMarcel Moolenaar break; 27372d44f31SMarcel Moolenaar } 27472d44f31SMarcel Moolenaar gdb_tx_begin(0); 27572d44f31SMarcel Moolenaar if (gdb_tx_mem((char *)(uintptr_t)addr, size)) 27672d44f31SMarcel Moolenaar gdb_tx_end(); 27772d44f31SMarcel Moolenaar else 27872d44f31SMarcel Moolenaar gdb_tx_err(EIO); 27972d44f31SMarcel Moolenaar break; 28072d44f31SMarcel Moolenaar } 28172d44f31SMarcel Moolenaar case 'M': { /* Write memory. */ 28272d44f31SMarcel Moolenaar uintmax_t addr, size; 28372d44f31SMarcel Moolenaar if (gdb_rx_varhex(&addr) || gdb_rx_char() != ',' || 28472d44f31SMarcel Moolenaar gdb_rx_varhex(&size) || gdb_rx_char() != ':') { 28572d44f31SMarcel Moolenaar gdb_tx_err(EINVAL); 28672d44f31SMarcel Moolenaar break; 28772d44f31SMarcel Moolenaar } 28872d44f31SMarcel Moolenaar if (gdb_rx_mem((char *)(uintptr_t)addr, size) == 0) 28972d44f31SMarcel Moolenaar gdb_tx_err(EIO); 29072d44f31SMarcel Moolenaar else 29172d44f31SMarcel Moolenaar gdb_tx_ok(); 29272d44f31SMarcel Moolenaar break; 29372d44f31SMarcel Moolenaar } 29472d44f31SMarcel Moolenaar case 'P': { /* Write register. */ 295bcc5241cSMarcel Moolenaar char *val; 296bcc5241cSMarcel Moolenaar uintmax_t reg; 297bcc5241cSMarcel Moolenaar val = gdb_rxp; 29872d44f31SMarcel Moolenaar if (gdb_rx_varhex(®) || gdb_rx_char() != '=' || 299bcc5241cSMarcel Moolenaar !gdb_rx_mem(val, gdb_cpu_regsz(reg))) { 30072d44f31SMarcel Moolenaar gdb_tx_err(EINVAL); 30172d44f31SMarcel Moolenaar break; 30272d44f31SMarcel Moolenaar } 30372d44f31SMarcel Moolenaar gdb_cpu_setreg(reg, val); 30472d44f31SMarcel Moolenaar gdb_tx_ok(); 30572d44f31SMarcel Moolenaar break; 30672d44f31SMarcel Moolenaar } 30772d44f31SMarcel Moolenaar case 'q': /* General query. */ 30872d44f31SMarcel Moolenaar if (gdb_rx_equal("fThreadInfo")) { 30972d44f31SMarcel Moolenaar thr_iter = kdb_thr_first(); 310*130ef1adSConrad Meyer gdb_do_threadinfo(&thr_iter); 31172d44f31SMarcel Moolenaar } else if (gdb_rx_equal("sThreadInfo")) { 312*130ef1adSConrad Meyer gdb_do_threadinfo(&thr_iter); 31327ecc2adSBenno Rice } else if (gdb_rx_equal("Search:memory:")) { 3148a7a6571SRyan Libby gdb_do_mem_search(); 31572d44f31SMarcel Moolenaar } else if (!gdb_cpu_query()) 31672d44f31SMarcel Moolenaar gdb_tx_empty(); 31772d44f31SMarcel Moolenaar break; 31872d44f31SMarcel Moolenaar case 's': { /* Step. */ 31972d44f31SMarcel Moolenaar uintmax_t addr; 320bcc5241cSMarcel Moolenaar register_t pc; 321bcc5241cSMarcel Moolenaar if (!gdb_rx_varhex(&addr)) { 322bcc5241cSMarcel Moolenaar pc = addr; 323bcc5241cSMarcel Moolenaar gdb_cpu_setreg(GDB_REG_PC, &pc); 324bcc5241cSMarcel Moolenaar } 32572d44f31SMarcel Moolenaar kdb_cpu_set_singlestep(); 3267d0c6c9fSSam Leffler gdb_listening = 1; 32772d44f31SMarcel Moolenaar return (1); 32872d44f31SMarcel Moolenaar } 32972d44f31SMarcel Moolenaar case 'S': { /* Step with signal. */ 33072d44f31SMarcel Moolenaar uintmax_t addr, sig; 331bcc5241cSMarcel Moolenaar register_t pc; 33272d44f31SMarcel Moolenaar if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' && 333bcc5241cSMarcel Moolenaar !gdb_rx_varhex(&addr)) { 334bcc5241cSMarcel Moolenaar pc = addr; 335bcc5241cSMarcel Moolenaar gdb_cpu_setreg(GDB_REG_PC, &pc); 336bcc5241cSMarcel Moolenaar } 33772d44f31SMarcel Moolenaar kdb_cpu_set_singlestep(); 3387d0c6c9fSSam Leffler gdb_listening = 1; 33972d44f31SMarcel Moolenaar return (1); 34072d44f31SMarcel Moolenaar } 34172d44f31SMarcel Moolenaar case 'T': { /* Thread alive. */ 34272d44f31SMarcel Moolenaar intmax_t tid; 3434af77eceSSam Leffler if (gdb_rx_varhex(&tid)) { 3444af77eceSSam Leffler gdb_tx_err(EINVAL); 3454af77eceSSam Leffler break; 3464af77eceSSam Leffler } 34772d44f31SMarcel Moolenaar if (kdb_thr_lookup(tid) != NULL) 34872d44f31SMarcel Moolenaar gdb_tx_ok(); 34972d44f31SMarcel Moolenaar else 35072d44f31SMarcel Moolenaar gdb_tx_err(ENOENT); 35172d44f31SMarcel Moolenaar break; 35272d44f31SMarcel Moolenaar } 35372d44f31SMarcel Moolenaar case -1: 35472d44f31SMarcel Moolenaar /* Empty command. Treat as unknown command. */ 35572d44f31SMarcel Moolenaar /* FALLTHROUGH */ 35672d44f31SMarcel Moolenaar default: 35772d44f31SMarcel Moolenaar /* Unknown command. Send empty response. */ 35872d44f31SMarcel Moolenaar gdb_tx_empty(); 35972d44f31SMarcel Moolenaar break; 36072d44f31SMarcel Moolenaar } 36172d44f31SMarcel Moolenaar } 3623a5d3671SMatthew D Fleming (void)kdb_jmpbuf(prev_jb); 36372d44f31SMarcel Moolenaar return (0); 36472d44f31SMarcel Moolenaar } 365