cmd.c 8.7 KB

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