command.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. *
  3. * debugger
  4. *
  5. */
  6. #include "defs.h"
  7. #include "fns.h"
  8. char BADEQ[] = "unexpected `='";
  9. BOOL executing;
  10. extern Rune *lp;
  11. char eqformat[ARB] = "z";
  12. char stformat[ARB] = "zMi";
  13. ADDR ditto;
  14. ADDR dot;
  15. WORD dotinc;
  16. WORD adrval, cntval, loopcnt;
  17. int adrflg, cntflg;
  18. /* command decoding */
  19. command(char *buf, int defcom)
  20. {
  21. char *reg;
  22. char savc;
  23. Rune *savlp=lp;
  24. char savlc = lastc;
  25. char savpc = peekc;
  26. static char lastcom = '=', savecom = '=';
  27. if (defcom == 0)
  28. defcom = lastcom;
  29. if (buf) {
  30. if (*buf==EOR)
  31. return(FALSE);
  32. clrinp();
  33. lp=(Rune*)buf;
  34. }
  35. do {
  36. adrflg=expr(0); /* first address */
  37. if (adrflg){
  38. dot=expv;
  39. ditto=expv;
  40. }
  41. adrval=dot;
  42. if (rdc()==',' && expr(0)) { /* count */
  43. cntflg=TRUE;
  44. cntval=expv;
  45. } else {
  46. cntflg=FALSE;
  47. cntval=1;
  48. reread();
  49. }
  50. if (!eol(rdc()))
  51. lastcom=lastc; /* command */
  52. else {
  53. if (adrflg==0)
  54. dot=inkdot(dotinc);
  55. reread();
  56. lastcom=defcom;
  57. }
  58. switch(lastcom) {
  59. case '/':
  60. case '=':
  61. case '?':
  62. savecom = lastcom;
  63. acommand(lastcom);
  64. break;
  65. case '>':
  66. lastcom = savecom;
  67. savc=rdc();
  68. if (reg=regname(savc))
  69. rput(cormap, reg, dot);
  70. else
  71. error("bad variable");
  72. break;
  73. case '!':
  74. lastcom=savecom;
  75. shell();
  76. break;
  77. case '$':
  78. lastcom=savecom;
  79. printtrace(nextchar());
  80. break;
  81. case ':':
  82. if (!executing) {
  83. executing=TRUE;
  84. subpcs(nextchar());
  85. executing=FALSE;
  86. lastcom=savecom;
  87. }
  88. break;
  89. case 0:
  90. prints(DBNAME);
  91. break;
  92. default:
  93. error("bad command");
  94. }
  95. flushbuf();
  96. } while (rdc()==';');
  97. if (buf == 0)
  98. reread();
  99. else {
  100. clrinp();
  101. lp=savlp;
  102. lastc = savlc;
  103. peekc = savpc;
  104. }
  105. if(adrflg)
  106. return dot;
  107. return 1;
  108. }
  109. /*
  110. * [/?][wml]
  111. */
  112. void
  113. acommand(int pc)
  114. {
  115. int eqcom;
  116. Map *map;
  117. char *fmt;
  118. char buf[512];
  119. if (pc == '=') {
  120. eqcom = 1;
  121. fmt = eqformat;
  122. map = dotmap;
  123. } else {
  124. eqcom = 0;
  125. fmt = stformat;
  126. if (pc == '/')
  127. map = cormap;
  128. else
  129. map = symmap;
  130. }
  131. if (!map) {
  132. sprint(buf, "no map for %c", pc);
  133. error(buf);
  134. }
  135. switch (rdc())
  136. {
  137. case 'm':
  138. if (eqcom)
  139. error(BADEQ);
  140. cmdmap(map);
  141. break;
  142. case 'L':
  143. case 'l':
  144. if (eqcom)
  145. error(BADEQ);
  146. cmdsrc(lastc, map);
  147. break;
  148. case 'W':
  149. case 'w':
  150. if (eqcom)
  151. error(BADEQ);
  152. cmdwrite(lastc, map);
  153. break;
  154. default:
  155. reread();
  156. getformat(fmt);
  157. scanform(cntval, !eqcom, fmt, map, eqcom);
  158. }
  159. }
  160. void
  161. cmdsrc(int c, Map *map)
  162. {
  163. long w;
  164. long locval, locmsk;
  165. ADDR savdot;
  166. ushort sh;
  167. char buf[512];
  168. int ret;
  169. if (c == 'L')
  170. dotinc = 4;
  171. else
  172. dotinc = 2;
  173. savdot=dot;
  174. expr(1);
  175. locval=expv;
  176. if (expr(0))
  177. locmsk=expv;
  178. else
  179. locmsk = ~0;
  180. if (c == 'L')
  181. while ((ret = get4(map, dot, &w)) > 0 && (w&locmsk) != locval)
  182. dot = inkdot(dotinc);
  183. else
  184. while ((ret = get2(map, dot, &sh)) > 0 && (sh&locmsk) != locval)
  185. dot = inkdot(dotinc);
  186. if (ret < 0) {
  187. dot=savdot;
  188. error("%r");
  189. }
  190. symoff(buf, 512, dot, CANY);
  191. dprint(buf);
  192. }
  193. static char badwrite[] = "can't write process memory or text image";
  194. void
  195. cmdwrite(int wcom, Map *map)
  196. {
  197. ADDR savdot;
  198. char *format;
  199. int pass;
  200. if (wcom == 'w')
  201. format = "x";
  202. else
  203. format = "X";
  204. expr(1);
  205. pass = 0;
  206. do {
  207. pass++;
  208. savdot=dot;
  209. exform(1, 1, format, map, 0, pass);
  210. dot=savdot;
  211. if (wcom == 'W') {
  212. if (put4(map, dot, expv) <= 0)
  213. error(badwrite);
  214. } else {
  215. if (put2(map, dot, expv) <= 0)
  216. error(badwrite);
  217. }
  218. savdot=dot;
  219. dprint("=%8t");
  220. exform(1, 0, format, map, 0, pass);
  221. newline();
  222. } while (expr(0));
  223. dot=savdot;
  224. }
  225. /*
  226. * collect a register name; return register offset
  227. * this is not what i'd call a good division of labour
  228. */
  229. char *
  230. regname(int regnam)
  231. {
  232. static char buf[64];
  233. char *p;
  234. int c;
  235. p = buf;
  236. *p++ = regnam;
  237. while (isalnum(c = readchar())) {
  238. if (p >= buf+sizeof(buf)-1)
  239. error("register name too long");
  240. *p++ = c;
  241. }
  242. *p = 0;
  243. reread();
  244. return (buf);
  245. }
  246. /*
  247. * shell escape
  248. */
  249. void
  250. shell(void)
  251. {
  252. int rc, unixpid;
  253. char *argp = (char*)lp;
  254. while (lastc!=EOR)
  255. rdc();
  256. if ((unixpid=fork())==0) {
  257. *lp=0;
  258. execl("/bin/rc", "rc", "-c", argp, nil);
  259. exits("execl"); /* botch */
  260. } else if (unixpid == -1) {
  261. error("cannot fork");
  262. } else {
  263. mkfault = 0;
  264. while ((rc = waitpid()) != unixpid){
  265. if(rc == -1 && mkfault){
  266. mkfault = 0;
  267. continue;
  268. }
  269. break;
  270. }
  271. prints("!");
  272. reread();
  273. }
  274. }