trcrun.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * functions for running the debugged process
  3. */
  4. #include "defs.h"
  5. #include "fns.h"
  6. int child;
  7. int msgfd = -1;
  8. int notefd = -1;
  9. int pcspid = -1;
  10. int pcsactive = 0;
  11. void
  12. setpcs(void)
  13. {
  14. char buf[128];
  15. if(pid && pid != pcspid){
  16. if(msgfd >= 0){
  17. close(msgfd);
  18. msgfd = -1;
  19. }
  20. if(notefd >= 0){
  21. close(notefd);
  22. notefd = -1;
  23. }
  24. pcspid = -1;
  25. sprint(buf, "/proc/%d/ctl", pid);
  26. msgfd = open(buf, OWRITE);
  27. if(msgfd < 0)
  28. error("can't open control file");
  29. sprint(buf, "/proc/%d/note", pid);
  30. notefd = open(buf, ORDWR);
  31. if(notefd < 0)
  32. error("can't open note file");
  33. pcspid = pid;
  34. }
  35. }
  36. void
  37. msgpcs(char *msg)
  38. {
  39. char err[ERRMAX];
  40. setpcs();
  41. if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
  42. errstr(err, sizeof err);
  43. if(strcmp(err, "interrupted") != 0)
  44. endpcs();
  45. errors("can't write control file", err);
  46. }
  47. }
  48. /*
  49. * empty the note buffer and toss pending breakpoint notes
  50. */
  51. void
  52. unloadnote(void)
  53. {
  54. char err[ERRMAX];
  55. setpcs();
  56. for(; nnote<NNOTE; nnote++){
  57. switch(read(notefd, note[nnote], sizeof note[nnote])){
  58. case -1:
  59. errstr(err, sizeof err);
  60. if(strcmp(err, "interrupted") != 0)
  61. endpcs();
  62. errors("can't read note file", err);
  63. case 0:
  64. return;
  65. }
  66. note[nnote][ERRMAX-1] = '\0';
  67. if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
  68. --nnote;
  69. }
  70. }
  71. /*
  72. * reload the note buffer
  73. */
  74. void
  75. loadnote(void)
  76. {
  77. int i;
  78. char err[ERRMAX];
  79. setpcs();
  80. for(i=0; i<nnote; i++){
  81. if(write(notefd, note[i], strlen(note[i])) < 0){
  82. errstr(err, sizeof err);
  83. if(strcmp(err, "interrupted") != 0)
  84. endpcs();
  85. errors("can't write note file", err);
  86. }
  87. }
  88. nnote = 0;
  89. }
  90. void
  91. notes(void)
  92. {
  93. int n;
  94. if(nnote == 0)
  95. return;
  96. dprint("notes:\n");
  97. for(n=0; n<nnote; n++)
  98. dprint("%d:\t%s\n", n, note[n]);
  99. }
  100. void
  101. killpcs(void)
  102. {
  103. msgpcs("kill");
  104. }
  105. void
  106. grab(void)
  107. {
  108. flush();
  109. msgpcs("stop");
  110. bpwait();
  111. }
  112. void
  113. ungrab(void)
  114. {
  115. msgpcs("start");
  116. }
  117. void
  118. doexec(void)
  119. {
  120. char *argl[MAXARG];
  121. char args[LINSIZ];
  122. char *p;
  123. char **ap;
  124. char *thisarg;
  125. ap = argl;
  126. p = args;
  127. *ap++ = symfil;
  128. for (rdc(); lastc != EOR;) {
  129. thisarg = p;
  130. if (lastc == '<' || lastc == '>') {
  131. *p++ = lastc;
  132. rdc();
  133. }
  134. while (lastc != EOR && lastc != SPC && lastc != TB) {
  135. *p++ = lastc;
  136. readchar();
  137. }
  138. if (lastc == SPC || lastc == TB)
  139. rdc();
  140. *p++ = 0;
  141. if (*thisarg == '<') {
  142. close(0);
  143. if (open(&thisarg[1], OREAD) < 0) {
  144. print("%s: cannot open\n", &thisarg[1]);
  145. _exits(0);
  146. }
  147. }
  148. else if (*thisarg == '>') {
  149. close(1);
  150. if (create(&thisarg[1], OWRITE, 0666) < 0) {
  151. print("%s: cannot create\n", &thisarg[1]);
  152. _exits(0);
  153. }
  154. }
  155. else
  156. *ap++ = thisarg;
  157. }
  158. *ap = 0;
  159. exec(symfil, argl);
  160. perror(symfil);
  161. }
  162. char procname[100];
  163. void
  164. startpcs(void)
  165. {
  166. if ((pid = fork()) == 0) {
  167. pid = getpid();
  168. msgpcs("hang");
  169. doexec();
  170. exits(0);
  171. }
  172. if (pid == -1)
  173. error("can't fork");
  174. child++;
  175. sprint(procname, "/proc/%d/mem", pid);
  176. corfil = procname;
  177. msgpcs("waitstop");
  178. bpwait();
  179. if (adrflg)
  180. rput(cormap, mach->pc, adrval);
  181. while (rdc() != EOR)
  182. ;
  183. reread();
  184. }
  185. void
  186. runstep(ulong loc, int keepnote)
  187. {
  188. int nfoll;
  189. ulong foll[3];
  190. BKPT bkpt[3];
  191. int i;
  192. if(machdata->foll == 0){
  193. dprint("stepping unimplemented; assuming not a branch\n");
  194. nfoll = 1;
  195. foll[0] = loc+mach->pcquant;
  196. }else {
  197. nfoll = machdata->foll(cormap, loc, rget, foll);
  198. if (nfoll < 0)
  199. error("%r");
  200. }
  201. memset(bkpt, 0, sizeof bkpt);
  202. for(i=0; i<nfoll; i++){
  203. if(foll[i] == loc)
  204. error("can't single step: next instruction is dot");
  205. bkpt[i].loc = foll[i];
  206. bkput(&bkpt[i], 1);
  207. }
  208. runrun(keepnote);
  209. for(i=0; i<nfoll; i++)
  210. bkput(&bkpt[i], 0);
  211. }
  212. void
  213. bpwait(void)
  214. {
  215. setcor();
  216. unloadnote();
  217. }
  218. void
  219. runrun(int keepnote)
  220. {
  221. int on;
  222. on = nnote;
  223. unloadnote();
  224. if(on != nnote){
  225. notes();
  226. error("not running: new notes pending");
  227. }
  228. if(keepnote)
  229. loadnote();
  230. else
  231. nnote = 0;
  232. flush();
  233. msgpcs("startstop");
  234. bpwait();
  235. }
  236. void
  237. bkput(BKPT *bp, int install)
  238. {
  239. char buf[256];
  240. ulong loc;
  241. int ret;
  242. errstr(buf, sizeof buf);
  243. if(machdata->bpfix)
  244. loc = (*machdata->bpfix)(bp->loc);
  245. else
  246. loc = bp->loc;
  247. if(install){
  248. ret = get1(cormap, loc, bp->save, machdata->bpsize);
  249. if (ret > 0)
  250. ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize);
  251. }else
  252. ret = put1(cormap, loc, bp->save, machdata->bpsize);
  253. if(ret < 0){
  254. sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc);
  255. print(buf);
  256. read(0, buf, 100);
  257. }
  258. }