1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 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 AUTHOR ``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 AUTHOR 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 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/ctype.h> 33 #include <sys/kdb.h> 34 #include <sys/libkern.h> 35 #include <sys/ttydefaults.h> 36 37 #include <machine/gdb_machdep.h> 38 #include <machine/kdb.h> 39 40 #include <gdb/gdb.h> 41 #include <gdb/gdb_int.h> 42 43 static char gdb_rxbuf[GDB_BUFSZ]; 44 char *gdb_rxp = NULL; 45 size_t gdb_rxsz = 0; 46 47 /* 48 * The goal here is to allow in-place framing without making the math around 49 * 'gdb_txbuf' more complicated. A generous reading of union special rule for 50 * "common initial sequence" suggests this may be valid in standard C99 and 51 * later. 52 */ 53 static union { 54 struct _midbuf { 55 char mb_pad1; 56 char mb_buf[GDB_BUFSZ]; 57 char mb_pad2[4]; 58 } __packed txu_midbuf; 59 /* sizeof includes trailing nul byte and this is intentional. */ 60 char txu_fullbuf[GDB_BUFSZ + sizeof("$#..")]; 61 } gdb_tx_u; 62 #define gdb_txbuf gdb_tx_u.txu_midbuf.mb_buf 63 #define gdb_tx_fullbuf gdb_tx_u.txu_fullbuf 64 _Static_assert(sizeof(gdb_tx_u.txu_midbuf) == sizeof(gdb_tx_u.txu_fullbuf) && 65 offsetof(struct _midbuf, mb_buf) == 1, 66 "assertions necessary for correctness"); 67 char *gdb_txp = NULL; /* Used in inline functions. */ 68 69 #define C2N(c) (((c) < 'A') ? (c) - '0' : \ 70 10 + (((c) < 'a') ? (c) - 'A' : (c) - 'a')) 71 #define N2C(n) (((n) < 10) ? (n) + '0' : (n) + 'a' - 10) 72 73 /* 74 * Get a single character 75 */ 76 77 static int 78 gdb_getc(void) 79 { 80 int c; 81 82 do 83 c = gdb_cur->gdb_getc(); 84 while (c == -1); 85 86 if (c == CTRL('C')) { 87 printf("Received ^C; trying to switch back to ddb.\n"); 88 89 if (gdb_cur->gdb_dbfeatures & GDB_DBGP_FEAT_WANTTERM) 90 gdb_cur->gdb_term(); 91 92 if (kdb_dbbe_select("ddb") != 0) 93 printf("The ddb backend could not be selected.\n"); 94 else { 95 printf("using longjmp, hope it works!\n"); 96 kdb_reenter(); 97 } 98 } 99 return (c); 100 } 101 102 /* 103 * Functions to receive and extract from a packet. 104 */ 105 106 int 107 gdb_rx_begin(void) 108 { 109 int c, cksum; 110 111 gdb_rxp = NULL; 112 do { 113 /* 114 * Wait for the start character, ignore all others. 115 * XXX needs a timeout. 116 */ 117 while ((c = gdb_getc()) != '$') 118 ; 119 120 /* Read until a # or end of buffer is found. */ 121 cksum = 0; 122 gdb_rxsz = 0; 123 while (gdb_rxsz < sizeof(gdb_rxbuf) - 1) { 124 c = gdb_getc(); 125 if (c == '#') 126 break; 127 gdb_rxbuf[gdb_rxsz++] = c; 128 cksum += c; 129 } 130 gdb_rxbuf[gdb_rxsz] = 0; 131 cksum &= 0xff; 132 133 /* Bail out on a buffer overflow. */ 134 if (c != '#') { 135 gdb_nack(); 136 return (ENOSPC); 137 } 138 139 /* 140 * In Not-AckMode, we can assume reliable transport and neither 141 * need to verify checksums nor send Ack/Nack. 142 */ 143 if (!gdb_ackmode) 144 break; 145 146 c = gdb_getc(); 147 cksum -= (C2N(c) << 4) & 0xf0; 148 c = gdb_getc(); 149 cksum -= C2N(c) & 0x0f; 150 if (cksum == 0) { 151 gdb_ack(); 152 } else { 153 gdb_nack(); 154 printf("GDB: packet `%s' has invalid checksum\n", 155 gdb_rxbuf); 156 } 157 } while (cksum != 0); 158 159 gdb_rxp = gdb_rxbuf; 160 return (0); 161 } 162 163 int 164 gdb_rx_equal(const char *str) 165 { 166 int len; 167 168 len = strlen(str); 169 if (len > gdb_rxsz || strncmp(str, gdb_rxp, len) != 0) 170 return (0); 171 gdb_rxp += len; 172 gdb_rxsz -= len; 173 return (1); 174 } 175 176 int 177 gdb_rx_mem(unsigned char *addr, size_t size) 178 { 179 unsigned char *p; 180 void *prev; 181 void *wctx; 182 jmp_buf jb; 183 size_t cnt; 184 int ret; 185 unsigned char c; 186 187 if (size * 2 != gdb_rxsz) 188 return (-1); 189 190 wctx = gdb_begin_write(); 191 prev = kdb_jmpbuf(jb); 192 ret = setjmp(jb); 193 if (ret == 0) { 194 p = addr; 195 cnt = size; 196 while (cnt-- > 0) { 197 c = (C2N(gdb_rxp[0]) << 4) & 0xf0; 198 c |= C2N(gdb_rxp[1]) & 0x0f; 199 *p++ = c; 200 gdb_rxsz -= 2; 201 gdb_rxp += 2; 202 } 203 kdb_cpu_sync_icache(addr, size); 204 } 205 (void)kdb_jmpbuf(prev); 206 gdb_end_write(wctx); 207 return ((ret == 0) ? 1 : 0); 208 } 209 210 int 211 gdb_rx_varhex(uintmax_t *vp) 212 { 213 uintmax_t v; 214 int c, neg; 215 216 c = gdb_rx_char(); 217 neg = (c == '-') ? 1 : 0; 218 if (neg == 1) 219 c = gdb_rx_char(); 220 if (!isxdigit(c)) { 221 gdb_rxp -= ((c == -1) ? 0 : 1) + neg; 222 gdb_rxsz += ((c == -1) ? 0 : 1) + neg; 223 return (-1); 224 } 225 v = 0; 226 do { 227 v <<= 4; 228 v += C2N(c); 229 c = gdb_rx_char(); 230 } while (isxdigit(c)); 231 if (c != EOF) { 232 gdb_rxp--; 233 gdb_rxsz++; 234 } 235 *vp = (neg) ? -v : v; 236 return (0); 237 } 238 239 /* 240 * Function to build and send a package. 241 */ 242 243 void 244 gdb_tx_begin(char tp) 245 { 246 247 gdb_txp = gdb_txbuf; 248 if (tp != '\0') 249 gdb_tx_char(tp); 250 } 251 252 /* 253 * Take raw packet buffer and perform typical GDB packet framing, but not run- 254 * length encoding, before forwarding to driver ::gdb_sendpacket() routine. 255 */ 256 static void 257 gdb_tx_sendpacket(void) 258 { 259 size_t msglen, i; 260 unsigned char csum; 261 262 msglen = gdb_txp - gdb_txbuf; 263 264 /* Add GDB packet framing */ 265 gdb_tx_fullbuf[0] = '$'; 266 267 csum = 0; 268 for (i = 0; i < msglen; i++) 269 csum += (unsigned char)gdb_txbuf[i]; 270 snprintf(&gdb_tx_fullbuf[1 + msglen], 4, "#%02x", (unsigned)csum); 271 272 gdb_cur->gdb_sendpacket(gdb_tx_fullbuf, msglen + 4); 273 } 274 275 int 276 gdb_tx_end(void) 277 { 278 const char *p; 279 int runlen; 280 unsigned char c, cksum; 281 282 do { 283 if (gdb_cur->gdb_sendpacket != NULL) { 284 gdb_tx_sendpacket(); 285 goto getack; 286 } 287 288 gdb_cur->gdb_putc('$'); 289 290 cksum = 0; 291 p = gdb_txbuf; 292 while (p < gdb_txp) { 293 /* Send a character and start run-length encoding. */ 294 c = *p++; 295 gdb_cur->gdb_putc(c); 296 cksum += c; 297 runlen = 0; 298 /* Determine run-length and update checksum. */ 299 while (p < gdb_txp && *p == c) { 300 runlen++; 301 p++; 302 } 303 /* Emit the run-length encoded string. */ 304 while (runlen >= 97) { 305 gdb_cur->gdb_putc('*'); 306 cksum += '*'; 307 gdb_cur->gdb_putc(97+29); 308 cksum += 97+29; 309 runlen -= 97; 310 if (runlen > 0) { 311 gdb_cur->gdb_putc(c); 312 cksum += c; 313 runlen--; 314 } 315 } 316 /* Don't emit '$', '#', '+', '-' or a run length below 3. */ 317 while (runlen == 1 || runlen == 2 || 318 runlen + 29 == '$' || runlen + 29 == '#' || 319 runlen + 29 == '+' || runlen + 29 == '-') { 320 gdb_cur->gdb_putc(c); 321 cksum += c; 322 runlen--; 323 } 324 if (runlen == 0) 325 continue; 326 gdb_cur->gdb_putc('*'); 327 cksum += '*'; 328 gdb_cur->gdb_putc(runlen+29); 329 cksum += runlen+29; 330 } 331 332 gdb_cur->gdb_putc('#'); 333 c = cksum >> 4; 334 gdb_cur->gdb_putc(N2C(c)); 335 c = cksum & 0x0f; 336 gdb_cur->gdb_putc(N2C(c)); 337 338 getack: 339 /* 340 * In NoAckMode, it is assumed that the underlying transport is 341 * reliable and thus neither conservant sends acknowledgements; 342 * there is nothing to wait for here. 343 */ 344 if (!gdb_ackmode) 345 break; 346 347 c = gdb_getc(); 348 } while (c != '+'); 349 350 return (0); 351 } 352 353 int 354 gdb_tx_mem(const unsigned char *addr, size_t size) 355 { 356 void *prev; 357 jmp_buf jb; 358 int ret; 359 360 prev = kdb_jmpbuf(jb); 361 ret = setjmp(jb); 362 if (ret == 0) { 363 while (size-- > 0) { 364 *gdb_txp++ = N2C(*addr >> 4); 365 *gdb_txp++ = N2C(*addr & 0x0f); 366 addr++; 367 } 368 } 369 (void)kdb_jmpbuf(prev); 370 return ((ret == 0) ? 1 : 0); 371 } 372 373 void 374 gdb_tx_reg(int regnum) 375 { 376 unsigned char *regp; 377 size_t regsz; 378 379 regp = gdb_cpu_getreg(regnum, ®sz); 380 if (regp == NULL) { 381 /* Register unavailable. */ 382 while (regsz--) { 383 gdb_tx_char('x'); 384 gdb_tx_char('x'); 385 } 386 } else 387 gdb_tx_mem(regp, regsz); 388 } 389 390 bool 391 gdb_txbuf_has_capacity(size_t req) 392 { 393 return (((char *)gdb_txbuf + sizeof(gdb_txbuf) - gdb_txp) >= req); 394 } 395 396 /* Read binary data up until the end of the packet or until we have datalen decoded bytes */ 397 int 398 gdb_rx_bindata(unsigned char *data, size_t datalen, size_t *amt) 399 { 400 int c; 401 402 *amt = 0; 403 404 while (*amt < datalen) { 405 c = gdb_rx_char(); 406 if (c == EOF) 407 break; 408 /* Escaped character up next */ 409 if (c == '}') { 410 /* Malformed packet. */ 411 if ((c = gdb_rx_char()) == EOF) 412 return (1); 413 c ^= 0x20; 414 } 415 *(data++) = c & 0xff; 416 (*amt)++; 417 } 418 419 return (0); 420 } 421 422 int 423 gdb_search_mem(const unsigned char *addr, size_t size, const unsigned char *pat, size_t patlen, const unsigned char **found) 424 { 425 void *prev; 426 jmp_buf jb; 427 int ret; 428 429 prev = kdb_jmpbuf(jb); 430 ret = setjmp(jb); 431 if (ret == 0) 432 *found = memmem(addr, size, pat, patlen); 433 434 (void)kdb_jmpbuf(prev); 435 return ((ret == 0) ? 1 : 0); 436 } 437