1 #include <u.h> 2 #include <libc.h> 3 #include <ctype.h> 4 #include <bio.h> 5 #include <mach.h> 6 #define Extern extern 7 #include "sparc.h" 8 9 char buf[128], lastcmd[128]; 10 char fmt = 'X'; 11 int width = 60; 12 int inc; 13 14 ulong expr(char*); 15 ulong expr1(char*); 16 char* term(char*, ulong*); 17 18 char * 19 nextc(char *p) 20 { 21 while(*p && (*p == ' ' || *p == '\t') && *p != '\n') 22 p++; 23 24 if(*p == '\n') 25 *p = '\0'; 26 27 return p; 28 } 29 30 char * 31 numsym(char *addr, ulong *val) 32 { 33 char tsym[128], *t; 34 static char *delim = "`'<>/\\@*|-~+-/=?\n"; 35 Symbol s; 36 char c; 37 38 t = tsym; 39 while(c = *addr) { 40 if(strchr(delim, c)) 41 break; 42 *t++ = c; 43 addr++; 44 } 45 t[0] = '\0'; 46 47 if(strcmp(tsym, ".") == 0) { 48 *val = dot; 49 return addr; 50 } 51 52 if(lookup(0, tsym, &s)) 53 *val = s.value; 54 else { 55 if(tsym[0] == '#') 56 *val = strtoul(tsym+1, 0, 16); 57 else 58 *val = strtoul(tsym, 0, 0); 59 } 60 return addr; 61 } 62 63 ulong 64 expr(char *addr) 65 { 66 ulong t, t2; 67 char op; 68 69 if(*addr == '\0') 70 return dot; 71 72 addr = numsym(addr, &t); 73 74 if(*addr == '\0') 75 return t; 76 77 addr = nextc(addr); 78 op = *addr++; 79 numsym(addr, &t2); 80 switch(op) { 81 default: 82 Bprint(bioout, "expr syntax\n"); 83 return 0; 84 case '+': 85 t += t2; 86 break; 87 case '-': 88 t -= t2; 89 break; 90 case '%': 91 t /= t2; 92 break; 93 case '&': 94 t &= t2; 95 break; 96 case '|': 97 t |= t2; 98 break; 99 } 100 101 return t; 102 } 103 104 int 105 buildargv(char *str, char **args, int max) 106 { 107 int na = 0; 108 109 while (na < max) { 110 while((*str == ' ' || *str == '\t' || *str == '\n') && *str != '\0') 111 str++; 112 113 if(*str == '\0') 114 return na; 115 116 args[na++] = str; 117 while(!(*str == ' ' || *str == '\t'|| *str == '\n') && *str != '\0') 118 str++; 119 120 if(*str == '\n') 121 *str = '\0'; 122 123 if(*str == '\0') 124 break; 125 126 *str++ = '\0'; 127 } 128 return na; 129 } 130 131 void 132 colon(char *addr, char *cp) 133 { 134 int argc; 135 char *argv[100]; 136 char tbuf[512]; 137 138 cp = nextc(cp); 139 switch(*cp) { 140 default: 141 Bprint(bioout, "?\n"); 142 return; 143 case 'b': 144 breakpoint(addr, cp+1); 145 return; 146 147 case 'd': 148 delbpt(addr); 149 return; 150 151 /* These fall through to print the stopped address */ 152 case 'r': 153 reset(); 154 argc = buildargv(cp+1, argv, 100); 155 initstk(argc, argv); 156 count = 0; 157 atbpt = 0; 158 run(); 159 break; 160 case 'c': 161 count = 0; 162 atbpt = 0; 163 run(); 164 break; 165 case 's': 166 cp = nextc(cp+1); 167 count = 0; 168 if(*cp) 169 count = strtoul(cp, 0, 0); 170 if(count == 0) 171 count = 1; 172 atbpt = 0; 173 run(); 174 break; 175 } 176 177 dot = reg.pc; 178 Bprint(bioout, "%s at #%lux ", atbpt ? "breakpoint" : "stopped", dot); 179 symoff(tbuf, sizeof(tbuf), dot, CTEXT); 180 Bprint(bioout, tbuf); 181 if(fmt == 'z') 182 printsource(dot); 183 184 Bprint(bioout, "\n"); 185 } 186 187 188 void 189 dollar(char *cp) 190 { 191 cp = nextc(cp); 192 switch(*cp) { 193 default: 194 Bprint(bioout, "?\n"); 195 break; 196 197 case 'c': 198 case 'C': 199 stktrace(*cp); 200 break; 201 202 case 'b': 203 dobplist(); 204 break; 205 206 case 'r': 207 dumpreg(); 208 break; 209 210 case 'R': 211 dumpreg(); 212 /* fall through */ 213 214 case 'f': 215 dumpfreg(); 216 break; 217 218 case 'F': 219 dumpdreg(); 220 break; 221 222 case 'q': 223 exits(0); 224 break; 225 226 case 'Q': 227 isum(); 228 segsum(); 229 break; 230 231 case 't': 232 cp++; 233 switch(*cp) { 234 default: 235 Bprint(bioout, ":t[0sic]\n"); 236 break; 237 case '\0': 238 trace = 1; 239 break; 240 case '0': 241 trace = 0; 242 sysdbg = 0; 243 calltree = 0; 244 break; 245 case 's': 246 sysdbg = 1; 247 break; 248 case 'i': 249 trace = 1; 250 break; 251 case 'c': 252 calltree = 1; 253 break; 254 } 255 break; 256 257 case 'i': 258 cp++; 259 switch(*cp) { 260 default: 261 Bprint(bioout, "$i[isa]\n"); 262 break; 263 case 'i': 264 isum(); 265 break; 266 case 's': 267 segsum(); 268 break; 269 case 'a': 270 isum(); 271 segsum(); 272 iprofile(); 273 break; 274 case 'p': 275 iprofile(); 276 break; 277 } 278 } 279 } 280 281 int 282 pfmt(char fmt, int mem, ulong val) 283 { 284 int c, i; 285 Symbol s; 286 char *p, ch, str[1024]; 287 288 c = 0; 289 switch(fmt) { 290 default: 291 Bprint(bioout, "bad modifier\n"); 292 return 0; 293 case 'o': 294 c = Bprint(bioout, "%-4o ", mem ? (ushort)getmem_2(dot) : val); 295 inc = 2; 296 break; 297 298 case 'O': 299 c = Bprint(bioout, "%-8o ", mem ? getmem_4(dot) : val); 300 inc = 4; 301 break; 302 303 case 'q': 304 c = Bprint(bioout, "%-4o ", mem ? (short)getmem_2(dot) : val); 305 inc = 2; 306 break; 307 308 case 'Q': 309 c = Bprint(bioout, "%-8o ", mem ? (long)getmem_4(dot) : val); 310 inc = 4; 311 break; 312 313 case 'd': 314 c = Bprint(bioout, "%-5ld ", mem ? (short)getmem_2(dot) : val); 315 inc = 2; 316 break; 317 318 319 case 'D': 320 c = Bprint(bioout, "%-8ld ", mem ? (long)getmem_4(dot) : val); 321 inc = 4; 322 break; 323 324 case 'x': 325 c = Bprint(bioout, "#%-4lux ", mem ? (long)getmem_2(dot) : val); 326 inc = 2; 327 break; 328 329 case 'X': 330 c = Bprint(bioout, "#%-8lux ", mem ? (long)getmem_4(dot) : val); 331 inc = 4; 332 break; 333 334 case 'u': 335 c = Bprint(bioout, "%-5ld ", mem ? (ushort)getmem_2(dot) : val); 336 inc = 2; 337 break; 338 339 case 'U': 340 c = Bprint(bioout, "%-8ld ", mem ? (ulong)getmem_4(dot) : val); 341 inc = 4; 342 break; 343 344 case 'b': 345 c = Bprint(bioout, "%-3d ", mem ? getmem_b(dot) : val); 346 inc = 1; 347 break; 348 349 case 'c': 350 c = Bprint(bioout, "%c ", mem ? getmem_b(dot) : val); 351 inc = 1; 352 break; 353 354 case 'C': 355 ch = mem ? getmem_b(dot) : val; 356 if(isprint(ch)) 357 c = Bprint(bioout, "%c ", ch); 358 else 359 c = Bprint(bioout, "\\x%.2x ", ch); 360 inc = 1; 361 break; 362 363 case 's': 364 i = 0; 365 while(ch = getmem_b(dot+i)) 366 str[i++] = ch; 367 str[i] = '\0'; 368 dot += i; 369 c = Bprint(bioout, "%s", str); 370 inc = 0; 371 break; 372 373 case 'S': 374 i = 0; 375 while(ch = getmem_b(dot+i)) 376 str[i++] = ch; 377 str[i] = '\0'; 378 dot += i; 379 for(p = str; *p; p++) 380 if(isprint(*p)) 381 c += Bprint(bioout, "%c", *p); 382 else 383 c += Bprint(bioout, "\\x%.2lux", *p); 384 inc = 0; 385 break; 386 387 case 'Y': 388 p = ctime(mem ? getmem_b(dot) : val); 389 p[30] = '\0'; 390 c = Bprint(bioout, "%s", p); 391 inc = 4; 392 break; 393 394 case 'a': 395 symoff(str, sizeof(str), dot, CTEXT); 396 Bprint(bioout, "%s", str); 397 inc = 0; 398 break; 399 400 case 'e': 401 for (i = 0; globalsym(&s, i); i++) 402 Bprint(bioout, "%-15s #%lux\n", s.name, getmem_4(s.value)); 403 inc = 0; 404 break; 405 406 case 'I': 407 case 'i': 408 inc = machdata->das(symmap, dot, fmt, str, sizeof(str)); 409 if (inc < 0) { 410 Bprint(bioout, "ki: %r\n"); 411 return 0; 412 } 413 c = Bprint(bioout, "\t%s", str); 414 break; 415 416 case 'n': 417 c = width+1; 418 inc = 0; 419 break; 420 421 case '-': 422 c = 0; 423 inc = -1; 424 break; 425 426 case '+': 427 c = 0; 428 inc = 1; 429 break; 430 431 case '^': 432 c = 0; 433 if(inc > 0) 434 inc = -inc; 435 break; 436 437 case 'z': 438 if (findsym(dot, CTEXT, &s)) 439 Bprint(bioout, " %s() ", s.name); 440 printsource(dot); 441 inc = 0; 442 break; 443 } 444 return c; 445 } 446 447 void 448 eval(char *addr, char *p) 449 { 450 ulong val; 451 452 val = expr(addr); 453 p = nextc(p); 454 if(*p == '\0') { 455 p[0] = fmt; 456 p[1] = '\0'; 457 } 458 pfmt(*p, 0, val); 459 Bprint(bioout, "\n"); 460 } 461 462 void 463 quesie(char *p) 464 { 465 int c, count, i; 466 char tbuf[512]; 467 468 c = 0; 469 symoff(tbuf, sizeof(tbuf), dot, CTEXT); 470 Bprint(bioout, "%s?\t", tbuf); 471 472 while(*p) { 473 p = nextc(p); 474 if(*p == '"') { 475 for(p++; *p && *p != '"'; p++) { 476 Bputc(bioout, *p); 477 c++; 478 } 479 if(*p) 480 p++; 481 continue; 482 } 483 count = 0; 484 while(*p >= '0' && *p <= '9') 485 count = count*10 + (*p++ - '0'); 486 if(count == 0) 487 count = 1; 488 p = nextc(p); 489 if(*p == '\0') { 490 p[0] = fmt; 491 p[1] = '\0'; 492 } 493 for(i = 0; i < count; i++) { 494 c += pfmt(*p, 1, 0); 495 dot += inc; 496 if(c > width) { 497 Bprint(bioout, "\n"); 498 symoff(tbuf, sizeof(tbuf), dot, CTEXT); 499 Bprint(bioout, "%s?\t", tbuf); 500 c = 0; 501 } 502 } 503 fmt = *p++; 504 p = nextc(p); 505 } 506 Bprint(bioout, "\n"); 507 } 508 509 void 510 catcher(void *a, char *msg) 511 { 512 USED(a); 513 if(strcmp(msg, "interrupt") != 0) 514 noted(NDFLT); 515 516 count = 1; 517 print("ki\n"); 518 noted(NCONT); 519 } 520 521 void 522 setreg(char *addr, char *cp) 523 { 524 int rn; 525 526 dot = expr(addr); 527 cp = nextc(cp); 528 if(strcmp(cp, "pc") == 0) { 529 reg.pc = dot; 530 return; 531 } 532 if(strcmp(cp, "sp") == 0) { 533 reg.r[1] = dot; 534 return; 535 } 536 if(strcmp(cp, "y") == 0) { 537 reg.Y = dot; 538 return; 539 } 540 if(strcmp(cp, "psr") == 0) { 541 reg.psr = dot; 542 return; 543 } 544 if(*cp++ == 'r') { 545 rn = strtoul(cp, 0, 10); 546 if(rn > 0 && rn < 32) { 547 reg.r[rn] = dot; 548 return; 549 } 550 } 551 Bprint(bioout, "bad register\n"); 552 } 553 554 void 555 cmd(void) 556 { 557 char *p, *a, *cp, *gotint; 558 char addr[128]; 559 static char *cmdlet = ":$?/=>"; 560 int n, i; 561 562 notify(catcher); 563 564 dot = reg.pc; 565 setjmp(errjmp); 566 567 for(;;) { 568 Bflush(bioout); 569 p = buf; 570 n = 0; 571 for(;;) { 572 i = Bgetc(bin); 573 if(i < 0) 574 exits(0); 575 *p++ = i; 576 n++; 577 if(i == '\n') 578 break; 579 } 580 581 if(buf[0] == '\n') 582 strcpy(buf, lastcmd); 583 else { 584 buf[n-1] = '\0'; 585 strcpy(lastcmd, buf); 586 } 587 p = buf; 588 a = addr; 589 590 for(;;) { 591 p = nextc(p); 592 if(*p == 0 || strchr(cmdlet, *p)) 593 break; 594 *a++ = *p++; 595 } 596 597 *a = '\0'; 598 cmdcount = 1; 599 cp = strchr(addr, ','); 600 if(cp != 0) { 601 if(cp[1] == '#') 602 cmdcount = strtoul(cp+2, &gotint, 16); 603 else 604 cmdcount = strtoul(cp+1, &gotint, 0); 605 *cp = '\0'; 606 } 607 608 switch(*p) { 609 case '$': 610 dollar(p+1); 611 break; 612 case ':': 613 colon(addr, p+1); 614 break; 615 case '/': 616 case '?': 617 dot = expr(addr); 618 for(i = 0; i < cmdcount; i++) 619 quesie(p+1); 620 break; 621 case '=': 622 eval(addr, p+1); 623 break; 624 case '>': 625 setreg(addr, p+1); 626 break; 627 default: 628 Bprint(bioout, "?\n"); 629 break; 630 } 631 } 632 } 633