dump.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /*
  2. For dumping the stack, GDA, heap and text segment.
  3. */
  4. /* $Id$ */
  5. #include <ctype.h>
  6. #include <em_abs.h>
  7. #include "logging.h"
  8. #include "global.h"
  9. #include "log.h"
  10. #include "memdirect.h"
  11. #include "mem.h"
  12. #include "fra.h"
  13. #include "text.h"
  14. #include "proctab.h"
  15. #include "shadow.h"
  16. #include "linfil.h"
  17. #include "rsb.h"
  18. extern long inr; /* from log.c */
  19. /****************************************************************
  20. * Dumping routines for debugging, in human-readable form. *
  21. ****************************************************************/
  22. #ifdef LOGGING
  23. /* The file is repetitive and should probably be partly generated,
  24. although it is not directly evident how.
  25. */
  26. PRIVATE char *displ_undefs(), *displ_fil(), *displ_sh(), *displ_code();
  27. PRIVATE ptr std_raw(), std_rsb();
  28. PRIVATE int std_bytes(), dtd_bytes(), FRAd_bytes();
  29. PRIVATE std_item(), std_left_undefs();
  30. PRIVATE gdad_item(), gdad_left_undefs();
  31. PRIVATE hpd_item(), hpd_left_undefs();
  32. PRIVATE FRA_dump(), FRA_item();
  33. /******** Stack Dump ********/
  34. std_all(sz, rawfl)
  35. long sz;
  36. int rawfl;
  37. {
  38. register ptr addr;
  39. if (!check_log(" d1 "))
  40. return;
  41. LOG((" d2 "));
  42. LOG((" d2 . . STACK_DUMP[%ld/%ld%s] . . INR = %lu . . STACK_DUMP . .",
  43. wsize, psize, rawfl ? ", raw" : "", inr));
  44. LOG((" d2 ----------------------------------------------------------------"));
  45. /* find a good start address */
  46. addr = (sz && sz < ML - SP ? SP + sz : ML);
  47. /* find RSB backwards */
  48. while (in_stack(addr) && !is_st_prot(addr)) {
  49. addr++;
  50. }
  51. /* find end of RSB backwards */
  52. while (in_stack(addr) && is_st_prot(addr)) {
  53. addr++;
  54. }
  55. addr--;
  56. /* dump the stack */
  57. while (in_stack(addr)) {
  58. addr = std_raw(addr, rawfl);
  59. addr = std_rsb(addr);
  60. }
  61. FRA_dump();
  62. LOG((" d1 >> AB = %lu, LB = %lu, SP = %lu, HP = %lu, LIN = %lu, FIL = %s",
  63. AB, LB, SP, HP, getLIN(), displ_fil(getFIL())));
  64. LOG((" d2 ----------------------------------------------------------------"));
  65. LOG((" d2 "));
  66. }
  67. PRIVATE ptr
  68. std_raw(addr, rawfl)
  69. ptr addr;
  70. int rawfl;
  71. { /* Produces a formatted dump of the stack segment starting
  72. at addr, up to the Return Status Block (identified
  73. by protection bits)
  74. */
  75. register int nundef = 0;
  76. LOG((" d2 ADDRESS BYTE ITEM VALUE SHADOW"));
  77. while ( in_stack(addr)
  78. && (!is_st_prot(addr) || rawfl)
  79. ) {
  80. if (st_sh(addr) == UNDEFINED) {
  81. if (nundef++ == 0)
  82. LOG((" d2 %10lu undef", addr));
  83. }
  84. else {
  85. if (nundef) {
  86. std_left_undefs(nundef, addr + 1);
  87. nundef = 0;
  88. }
  89. std_item(addr);
  90. }
  91. addr--;
  92. }
  93. if (nundef)
  94. std_left_undefs(nundef, addr + 1);
  95. return addr;
  96. }
  97. PRIVATE std_item(addr)
  98. ptr addr;
  99. {
  100. if ( is_wordaligned(addr)
  101. && is_in_stack(addr, psize)
  102. && std_bytes(addr, addr + psize, SH_DATAP|SH_INSP)
  103. ) {
  104. /* print a pointer value */
  105. LOG((" d2 %10lu %3lu [%10lu] (%-s)",
  106. addr,
  107. btol(stack_loc(addr)),
  108. p_in_stack(addr),
  109. displ_sh(st_sh(addr), stack_loc(addr))));
  110. }
  111. else
  112. if ( is_wordaligned(addr)
  113. && w_is_in_stack(addr)
  114. && std_bytes(addr, addr + wsize, SH_INT)
  115. ) {
  116. /* print a word value */
  117. LOG((" d2 %10lu %3lu [%10ld] (%-s)",
  118. addr,
  119. btol(stack_loc(addr)),
  120. w_in_stack(addr),
  121. displ_sh(st_sh(addr), stack_loc(addr))));
  122. }
  123. else {
  124. /* just print the byte */
  125. LOG((" d2 %10lu %3lu (%-s)",
  126. addr,
  127. btol(stack_loc(addr)),
  128. displ_sh(st_sh(addr), stack_loc(addr))));
  129. }
  130. }
  131. PRIVATE ptr
  132. std_rsb(addr)
  133. ptr addr;
  134. { /* Dumps the Return Status Block */
  135. ptr dmp_lb;
  136. int code;
  137. long pi;
  138. ptr pc;
  139. ptr lb;
  140. long lin;
  141. ptr fil;
  142. char pr_descr[300];
  143. if (!in_stack(addr))
  144. return addr;
  145. dmp_lb = addr - (rsbsize-1); /* pseudo local base */
  146. if (!in_stack(dmp_lb)) {
  147. LOG((" d1 >>RSB: >>>> INCOMPLETE <<<<"));
  148. return dmp_lb;
  149. }
  150. code = (int)w_in_stack(dmp_lb + rsb_rsbcode);
  151. pi = (long)p_in_stack(dmp_lb + rsb_PI);
  152. pc = p_in_stack(dmp_lb + rsb_PC);
  153. lb = p_in_stack(dmp_lb + rsb_LB);
  154. lin = LIN_in_stack(dmp_lb + rsb_LIN);
  155. fil = p_in_stack(dmp_lb + rsb_FIL);
  156. if (pi == -1) {
  157. sprintf(pr_descr, "uninit");
  158. }
  159. else
  160. if (pi < NProc) {
  161. sprintf(pr_descr, "(%ld,%ld)",
  162. pi, (long)proctab[pi].pr_nloc);
  163. }
  164. else {
  165. sprintf(pr_descr, "%ld >>>> ILLEGAL <<<<", pi);
  166. }
  167. LOG((" d1 >> RSB: code = %s, PI = %s, PC = %lu, LB = %lu, LIN = %lu, FIL = %s",
  168. displ_code(code), pr_descr, pc, lb, lin, displ_fil(fil)));
  169. LOG((" d2 "));
  170. return addr - rsbsize;
  171. }
  172. PRIVATE char *displ_code(rsbcode)
  173. int rsbcode;
  174. {
  175. switch (rsbcode) {
  176. case RSB_STP: return "STP";
  177. case RSB_CAL: return "CAL";
  178. case RSB_RTT: return "RTT";
  179. case RSB_NRT: return "NRT";
  180. default: return ">>Bad RSB code<<";
  181. }
  182. /*NOTREACHED*/
  183. }
  184. PRIVATE std_left_undefs(nundef, addr)
  185. int nundef;
  186. ptr addr;
  187. {
  188. /* handle pending undefineds */
  189. switch (nundef) {
  190. case 1:
  191. break;
  192. case 2:
  193. LOG((" d2 %10lu undef", addr));
  194. break;
  195. default:
  196. LOG((" d2 | | | | | |"));
  197. LOG((" d2 %10lu undef (%s)",
  198. addr, displ_undefs(nundef, addr)));
  199. break;
  200. }
  201. }
  202. PRIVATE FRA_dump()
  203. {
  204. register int addr;
  205. LOG((" d2 FRA: size = %d, %s",
  206. FRASize, FRA_def ? "defined" : "undefined"));
  207. for (addr = 0; addr < FRASize; addr++) {
  208. FRA_item(addr);
  209. }
  210. }
  211. PRIVATE FRA_item(addr)
  212. int addr;
  213. {
  214. if ( is_wordaligned(addr)
  215. && is_in_FRA(addr, psize)
  216. && FRAd_bytes(addr, (int)(addr + psize), SH_DATAP|SH_INSP)
  217. ) {
  218. /* print a pointer value */
  219. LOG((" d2 FRA[%1d] %3lu [%10lu] (%-s)",
  220. addr,
  221. btol(FRA[addr]),
  222. p_in_FRA(addr),
  223. displ_sh(FRA_sh[addr], FRA[addr])));
  224. }
  225. else
  226. if ( is_wordaligned(addr)
  227. && is_in_FRA(addr, wsize)
  228. && FRAd_bytes(addr, (int)(addr + wsize), SH_INT)
  229. ) {
  230. /* print a word value */
  231. LOG((" d2 FRA[%1d] %3lu [%10ld] (%-s)",
  232. addr,
  233. btol(FRA[addr]),
  234. w_in_FRA(addr),
  235. displ_sh(FRA_sh[addr], FRA[addr])));
  236. }
  237. else {
  238. /* just print the byte */
  239. LOG((" d2 FRA[%1d] %3lu (%-s)",
  240. addr,
  241. btol(FRA[addr]),
  242. displ_sh(FRA_sh[addr], FRA[addr])));
  243. }
  244. }
  245. /******** Global Data Area Dump ********/
  246. gdad_all(low, high)
  247. ptr low, high;
  248. {
  249. register ptr addr;
  250. register int nundef = 0;
  251. if (!check_log(" +1 "))
  252. return;
  253. if (low == 0 && high == 0)
  254. high = HB;
  255. LOG((" +1 "));
  256. LOG((" +1 . . GDA_DUMP[%ld/%ld] . . INR = %lu . . GDA_DUMP . .",
  257. wsize, psize, inr));
  258. LOG((" +1 ----------------------------------------------------------------"));
  259. LOG((" +1 ADDRESS BYTE WORD VALUE SHADOW"));
  260. /* dump global data area contents */
  261. addr = low;
  262. while (addr < min(HB, high)) {
  263. if (dt_sh(addr) == UNDEFINED) {
  264. if (nundef++ == 0)
  265. LOG((" +1 %10lu undef", addr));
  266. }
  267. else {
  268. if (nundef) {
  269. gdad_left_undefs(nundef, addr-1);
  270. nundef = 0;
  271. }
  272. gdad_item(addr);
  273. }
  274. addr++;
  275. }
  276. if (nundef)
  277. gdad_left_undefs(nundef, addr-1);
  278. LOG((" +1 ----------------------------------------------------------------"));
  279. LOG((" +1 "));
  280. }
  281. PRIVATE gdad_item(addr)
  282. ptr addr;
  283. {
  284. if ( is_wordaligned(addr)
  285. && is_in_data(addr, psize)
  286. && dtd_bytes(addr, addr + psize, SH_DATAP|SH_INSP)
  287. ) {
  288. /* print a pointer value */
  289. LOG((" +1 %10lu %3lu [%10lu] (%-s)",
  290. addr,
  291. btol(data_loc(addr)),
  292. p_in_data(addr),
  293. displ_sh(dt_sh(addr), data_loc(addr))));
  294. }
  295. else
  296. if ( is_wordaligned(addr)
  297. && is_in_data(addr, wsize)
  298. && dtd_bytes(addr, addr + wsize, SH_INT)
  299. ) {
  300. /* print a word value */
  301. LOG((" +1 %10lu %3lu [%10ld] (%-s)",
  302. addr,
  303. btol(data_loc(addr)),
  304. w_in_data(addr),
  305. displ_sh(dt_sh(addr), data_loc(addr))));
  306. }
  307. else {
  308. /* just print the byte */
  309. LOG((" +1 %10lu %3lu (%-s)",
  310. addr,
  311. btol(data_loc(addr)),
  312. displ_sh(dt_sh(addr), data_loc(addr))));
  313. }
  314. }
  315. PRIVATE gdad_left_undefs(nundef, addr)
  316. int nundef;
  317. ptr addr;
  318. {
  319. /* handle pending undefineds */
  320. switch (nundef) {
  321. case 1:
  322. break;
  323. case 2:
  324. LOG((" +1 %10lu undef", addr));
  325. break;
  326. default:
  327. LOG((" +1 | | | | | |"));
  328. LOG((" +1 %10lu undef (%s)",
  329. addr, displ_undefs(nundef, addr)));
  330. break;
  331. }
  332. }
  333. /******** Heap Area Dump ********/
  334. hpd_all()
  335. {
  336. register ptr addr;
  337. register int nundef = 0;
  338. if (!check_log(" *1 "))
  339. return;
  340. LOG((" *1 "));
  341. LOG((" *1 . . HEAP_DUMP[%ld/%ld] . . INR = %lu . . HEAP_DUMP . .",
  342. wsize, psize, inr));
  343. LOG((" *1 ----------------------------------------------------------------"));
  344. LOG((" *1 ADDRESS BYTE WORD VALUE SHADOW"));
  345. /* dump heap contents */
  346. for (addr = HB; addr < HP; addr++) {
  347. if (dt_sh(addr) == UNDEFINED) {
  348. if (nundef++ == 0)
  349. LOG((" *1 %10lu undef", addr));
  350. }
  351. else {
  352. if (nundef) {
  353. hpd_left_undefs(nundef, addr-1);
  354. nundef = 0;
  355. }
  356. hpd_item(addr);
  357. }
  358. }
  359. if (nundef)
  360. hpd_left_undefs(nundef, addr-1);
  361. LOG((" *1 ----------------------------------------------------------------"));
  362. LOG((" *1 "));
  363. }
  364. PRIVATE hpd_item(addr)
  365. ptr addr;
  366. {
  367. if ( is_wordaligned(addr)
  368. && is_in_data(addr, psize)
  369. && dtd_bytes(addr, addr + psize, SH_DATAP|SH_INSP)
  370. ) {
  371. /* print a pointer value */
  372. LOG((" *1 %10lu %3lu [%10lu] (%-s)",
  373. addr,
  374. btol(data_loc(addr)),
  375. p_in_data(addr),
  376. displ_sh(dt_sh(addr), data_loc(addr))));
  377. }
  378. else
  379. if ( is_wordaligned(addr)
  380. && is_in_data(addr, wsize)
  381. && dtd_bytes(addr, addr + wsize, SH_INT)
  382. ) {
  383. /* print a word value */
  384. LOG((" *1 %10lu %3lu [%10ld] (%-s)",
  385. addr,
  386. btol(data_loc(addr)),
  387. w_in_data(addr),
  388. displ_sh(dt_sh(addr), data_loc(addr))));
  389. }
  390. else {
  391. /* just print the byte */
  392. LOG((" *1 %10lu %3lu (%-s)",
  393. addr,
  394. btol(data_loc(addr)),
  395. displ_sh(dt_sh(addr), data_loc(addr))));
  396. }
  397. }
  398. PRIVATE hpd_left_undefs(nundef, addr)
  399. int nundef;
  400. ptr addr;
  401. {
  402. /* handle pending undefineds */
  403. switch (nundef) {
  404. case 1:
  405. break;
  406. case 2:
  407. LOG((" *1 %10lu undef", addr));
  408. break;
  409. default:
  410. LOG((" *1 | | | | | |"));
  411. LOG((" *1 %10lu undef (%s)",
  412. addr, displ_undefs(nundef, addr)));
  413. break;
  414. }
  415. }
  416. /* Service routines */
  417. PRIVATE int std_bytes(low, high, bits)
  418. ptr low, high;
  419. int bits;
  420. {
  421. /* True if all stack bytes from low to high-1 have one of the
  422. bits in bits on.
  423. */
  424. int byte = bits;
  425. while (low < high) {
  426. byte &= st_sh(low);
  427. low++;
  428. }
  429. return byte & bits;
  430. }
  431. PRIVATE int dtd_bytes(low, high, bits)
  432. ptr low, high;
  433. int bits;
  434. {
  435. /* True if all data bytes from low to high-1 have one of the
  436. bits in bits on.
  437. */
  438. int byte = bits;
  439. while (low < high) {
  440. byte &= dt_sh(low);
  441. low++;
  442. }
  443. return byte & bits;
  444. }
  445. PRIVATE int FRAd_bytes(low, high, bits)
  446. int low, high;
  447. int bits;
  448. {
  449. /* True if all data bytes from low to high-1 have one of the
  450. bits in bits on.
  451. */
  452. int byte = bits;
  453. while (low < high) {
  454. byte &= FRA_sh[low];
  455. low++;
  456. }
  457. return byte & bits;
  458. }
  459. PRIVATE char * /* transient */
  460. displ_undefs(nundef, addr)
  461. int nundef;
  462. ptr addr;
  463. {
  464. /* Given the number of undefineds, we want to report the number
  465. of words with the left-over numbers of bytes on both sides:
  466. | nundef |
  467. |left| wrds |right
  468. .....|........|........|........|...
  469. a
  470. d
  471. d
  472. r
  473. This takes some arithmetic.
  474. */
  475. static char buf[30];
  476. register int left = wsize - 1 - p2i(addr-1) % wsize;
  477. register int wrds = (nundef-left) / wsize;
  478. register int right = nundef - left - wrds*wsize;
  479. if (wrds == 0) {
  480. sprintf(buf, "%d byte%s",
  481. nundef, nundef == 1 ? "" : "s");
  482. }
  483. else if (left == 0 && right == 0) {
  484. sprintf(buf, "%d word%s",
  485. wrds, wrds == 1 ? "" : "s");
  486. }
  487. else if (left == 0) {
  488. sprintf(buf, "%d word%s + %d byte%s",
  489. wrds, wrds == 1 ? "" : "s",
  490. right, right == 1 ? "" : "s");
  491. }
  492. else if (right == 0) {
  493. sprintf(buf, "%d byte%s + %d word%s",
  494. left, left == 1 ? "" : "s",
  495. wrds, wrds == 1 ? "" : "s");
  496. }
  497. else {
  498. sprintf(buf, "%d byte%s + %d word%s + %d byte%s",
  499. left, left == 1 ? "" : "s",
  500. wrds, wrds == 1 ? "" : "s",
  501. right, right == 1 ? "" : "s");
  502. }
  503. return buf;
  504. }
  505. PRIVATE char *
  506. displ_fil(fil) /* transient */
  507. ptr fil;
  508. { /* Returns a buffer containing a representation of the
  509. filename derived from FIL-value fil.
  510. */
  511. static char buf[40];
  512. char *bp = &buf[0];
  513. int ch;
  514. if (!fil)
  515. return "NULL";
  516. if (fil >= HB)
  517. return "***NOT IN GDA***";
  518. *bp++ = '"';
  519. while (in_gda(fil) && (ch = data_loc(fil))) {
  520. if (bp < &buf[sizeof buf-1]) {
  521. *bp++ = (ch < 040 || ch > 126 ? '?' : ch);
  522. }
  523. fil++;
  524. }
  525. if (bp < &buf[sizeof buf-1])
  526. *bp++ = '"';
  527. *bp++ = '\0';
  528. return &buf[0];
  529. }
  530. PRIVATE char *
  531. displ_sh(shadow, byte) /* transient */
  532. char shadow;
  533. int byte;
  534. { /* Returns a buffer containing a description of the
  535. shadow byte.
  536. */
  537. static char buf[32];
  538. register char *bufp;
  539. int check = 0;
  540. bufp = buf;
  541. if (shadow & SH_INT) {
  542. *bufp++ = 'I';
  543. *bufp++ = 'n';
  544. check++;
  545. }
  546. if (shadow & SH_FLOAT) {
  547. *bufp++ = 'F';
  548. *bufp++ = 'l';
  549. }
  550. if (shadow & SH_DATAP) {
  551. *bufp++ = 'D';
  552. *bufp++ = 'p';
  553. }
  554. if (shadow & SH_INSP) {
  555. *bufp++ = 'I';
  556. *bufp++ = 'p';
  557. }
  558. if (shadow & SH_PROT) {
  559. *bufp++ = ',';
  560. *bufp++ = ' ';
  561. *bufp++ = 'P';
  562. *bufp++ = 'r';
  563. *bufp++ = 'o';
  564. *bufp++ = 't';
  565. }
  566. if (check && isascii(byte) && isprint(byte)) {
  567. *bufp++ = ',';
  568. *bufp++ = ' ';
  569. *bufp++ = byte;
  570. *bufp++ = ' ';
  571. }
  572. *bufp = 0;
  573. return (buf);
  574. }
  575. #endif /* LOGGING */