print.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. *
  3. * debugger
  4. *
  5. */
  6. #include "defs.h"
  7. #include "fns.h"
  8. extern int infile;
  9. extern int outfile;
  10. extern int maxpos;
  11. /* general printing routines ($) */
  12. char *Ipath = INCDIR;
  13. static int tracetype;
  14. static void printfp(Map*, int);
  15. /*
  16. * callback on stack trace
  17. */
  18. static void
  19. ptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
  20. {
  21. char buf[512];
  22. USED(map);
  23. dprint("%s(", sym->name);
  24. printparams(sym, sp);
  25. dprint(") ");
  26. printsource(sym->value);
  27. dprint(" called from ");
  28. symoff(buf, 512, pc, CTEXT);
  29. dprint("%s ", buf);
  30. printsource(pc);
  31. dprint("\n");
  32. if(tracetype == 'C')
  33. printlocals(sym, sp);
  34. }
  35. void
  36. printtrace(int modif)
  37. {
  38. int i;
  39. uvlong pc, sp, link;
  40. ulong w;
  41. BKPT *bk;
  42. Symbol s;
  43. int stack;
  44. char *fname;
  45. char buf[512];
  46. if (cntflg==0)
  47. cntval = -1;
  48. switch (modif) {
  49. case '<':
  50. if (cntval == 0) {
  51. while (readchar() != EOR)
  52. ;
  53. reread();
  54. break;
  55. }
  56. if (rdc() == '<')
  57. stack = 1;
  58. else {
  59. stack = 0;
  60. reread();
  61. }
  62. fname = getfname();
  63. redirin(stack, fname);
  64. break;
  65. case '>':
  66. fname = getfname();
  67. redirout(fname);
  68. break;
  69. case 'a':
  70. attachprocess();
  71. break;
  72. case 'k':
  73. kmsys();
  74. break;
  75. case 'q':
  76. case 'Q':
  77. done();
  78. case 'w':
  79. maxpos=(adrflg?adrval:MAXPOS);
  80. break;
  81. case 'S':
  82. printsym();
  83. break;
  84. case 's':
  85. maxoff=(adrflg?adrval:MAXOFF);
  86. break;
  87. case 'm':
  88. printmap("? map", symmap);
  89. printmap("/ map", cormap);
  90. break;
  91. case 0:
  92. case '?':
  93. if (pid)
  94. dprint("pid = %d\n",pid);
  95. else
  96. prints("no process\n");
  97. flushbuf();
  98. case 'r':
  99. case 'R':
  100. printregs(modif);
  101. return;
  102. case 'f':
  103. case 'F':
  104. printfp(cormap, modif);
  105. return;
  106. case 'c':
  107. case 'C':
  108. tracetype = modif;
  109. if (machdata->ctrace) {
  110. if (adrflg) {
  111. /*
  112. * trace from jmpbuf for multi-threaded code.
  113. * assume sp and pc are in adjacent locations
  114. * and mach->szaddr in size.
  115. */
  116. if (geta(cormap, adrval, &sp) < 0 ||
  117. geta(cormap, adrval+mach->szaddr, &pc) < 0)
  118. error("%r");
  119. } else {
  120. sp = rget(cormap, mach->sp);
  121. pc = rget(cormap, mach->pc);
  122. }
  123. if(mach->link)
  124. link = rget(cormap, mach->link);
  125. else
  126. link = 0;
  127. if (machdata->ctrace(cormap, pc, sp, link, ptrace) <= 0)
  128. error("no stack frame");
  129. }
  130. break;
  131. /*print externals*/
  132. case 'e':
  133. for (i = 0; globalsym(&s, i); i++) {
  134. if (get4(cormap, s.value, &w) > 0)
  135. dprint("%s/%12t%#lux\n", s.name, w);
  136. }
  137. break;
  138. /*print breakpoints*/
  139. case 'b':
  140. case 'B':
  141. for (bk=bkpthead; bk; bk=bk->nxtbkpt)
  142. if (bk->flag) {
  143. symoff(buf, 512, (WORD)bk->loc, CTEXT);
  144. dprint(buf);
  145. if (bk->count != 1)
  146. dprint(",%d", bk->count);
  147. dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm);
  148. }
  149. break;
  150. case 'M':
  151. fname = getfname();
  152. if (machbyname(fname) == 0)
  153. dprint("unknown name\n");;
  154. break;
  155. default:
  156. error("bad `$' command");
  157. }
  158. }
  159. char *
  160. getfname(void)
  161. {
  162. static char fname[ARB];
  163. char *p;
  164. if (rdc() == EOR) {
  165. reread();
  166. return (0);
  167. }
  168. p = fname;
  169. do {
  170. *p++ = lastc;
  171. if (p >= &fname[ARB-1])
  172. error("filename too long");
  173. } while (rdc() != EOR);
  174. *p = 0;
  175. reread();
  176. return (fname);
  177. }
  178. static void
  179. printfp(Map *map, int modif)
  180. {
  181. Reglist *rp;
  182. int i;
  183. int ret;
  184. char buf[512];
  185. for (i = 0, rp = mach->reglist; rp->rname; rp += ret) {
  186. ret = 1;
  187. if (!(rp->rflags&RFLT))
  188. continue;
  189. ret = fpformat(map, rp, buf, sizeof(buf), modif);
  190. if (ret < 0) {
  191. werrstr("Register %s: %r", rp->rname);
  192. error("%r");
  193. }
  194. /* double column print */
  195. if (i&0x01)
  196. dprint("%40t%-8s%-12s\n", rp->rname, buf);
  197. else
  198. dprint("\t%-8s%-12s", rp->rname, buf);
  199. i++;
  200. }
  201. }
  202. void
  203. redirin(int stack, char *file)
  204. {
  205. char *pfile;
  206. if (file == 0) {
  207. iclose(-1, 0);
  208. return;
  209. }
  210. iclose(stack, 0);
  211. if ((infile = open(file, 0)) < 0) {
  212. pfile = smprint("%s/%s", Ipath, file);
  213. infile = open(pfile, 0);
  214. free(pfile);
  215. if(infile < 0) {
  216. infile = STDIN;
  217. error("cannot open");
  218. }
  219. }
  220. }
  221. void
  222. printmap(char *s, Map *map)
  223. {
  224. int i;
  225. if (!map)
  226. return;
  227. if (map == symmap)
  228. dprint("%s%12t`%s'\n", s, fsym < 0 ? "-" : symfil);
  229. else if (map == cormap)
  230. dprint("%s%12t`%s'\n", s, fcor < 0 ? "-" : corfil);
  231. else
  232. dprint("%s\n", s);
  233. for (i = 0; i < map->nsegs; i++) {
  234. if (map->seg[i].inuse)
  235. dprint("%s%8t%-16#llux %-16#llux %-16#llux\n",
  236. map->seg[i].name, map->seg[i].b,
  237. map->seg[i].e, map->seg[i].f);
  238. }
  239. }
  240. /*
  241. * dump the raw symbol table
  242. */
  243. void
  244. printsym(void)
  245. {
  246. int i;
  247. Sym *sp;
  248. for (i = 0; sp = getsym(i); i++) {
  249. switch(sp->type) {
  250. case 't':
  251. case 'l':
  252. dprint("%16#llux t %s\n", sp->value, sp->name);
  253. break;
  254. case 'T':
  255. case 'L':
  256. dprint("%16#llux T %s\n", sp->value, sp->name);
  257. break;
  258. case 'D':
  259. case 'd':
  260. case 'B':
  261. case 'b':
  262. case 'a':
  263. case 'p':
  264. case 'm':
  265. dprint("%16#llux %c %s\n", sp->value, sp->type, sp->name);
  266. break;
  267. default:
  268. break;
  269. }
  270. }
  271. }
  272. #define STRINGSZ 128
  273. /*
  274. * print the value of dot as file:line
  275. */
  276. void
  277. printsource(ADDR dot)
  278. {
  279. char str[STRINGSZ];
  280. if (fileline(str, STRINGSZ, dot))
  281. dprint("%s", str);
  282. }
  283. void
  284. printpc(void)
  285. {
  286. char buf[512];
  287. dot = rget(cormap, mach->pc);
  288. if(dot){
  289. printsource((long)dot);
  290. printc(' ');
  291. symoff(buf, sizeof(buf), (long)dot, CTEXT);
  292. dprint("%s/", buf);
  293. if (machdata->das(cormap, dot, 'i', buf, sizeof(buf)) < 0)
  294. error("%r");
  295. dprint("%16t%s\n", buf);
  296. }
  297. }
  298. void
  299. printlocals(Symbol *fn, ADDR fp)
  300. {
  301. int i;
  302. ulong w;
  303. Symbol s;
  304. s = *fn;
  305. for (i = 0; localsym(&s, i); i++) {
  306. if (s.class != CAUTO)
  307. continue;
  308. if (get4(cormap, fp-s.value, &w) > 0)
  309. dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, w);
  310. else
  311. dprint("%8t%s.%s/%10t?\n", fn->name, s.name);
  312. }
  313. }
  314. void
  315. printparams(Symbol *fn, ADDR fp)
  316. {
  317. int i;
  318. Symbol s;
  319. ulong w;
  320. int first = 0;
  321. fp += mach->szaddr; /* skip saved pc */
  322. s = *fn;
  323. for (i = 0; localsym(&s, i); i++) {
  324. if (s.class != CPARAM)
  325. continue;
  326. if (first++)
  327. dprint(", ");
  328. if (get4(cormap, fp+s.value, &w) > 0)
  329. dprint("%s=%#lux", s.name, w);
  330. }
  331. }