command.c 4.7 KB

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