Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1211 lines
21 KiB

  1. /* asmlst.c -- microsoft 80x86 assembler
  2. **
  3. ** microsoft (r) macro assembler
  4. ** copyright (c) microsoft corp 1986. all rights reserved
  5. **
  6. ** randy nevin
  7. **
  8. ** 10/90 - Quick conversion to 32 bit by Jeff Spencer
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include "asm86.h"
  13. #include "asmfcn.h"
  14. #include "asmctype.h"
  15. #include "asmmsg.h"
  16. #define setpassed(sym) (sym)->attr |= (M_PASSED)
  17. VOID PASCAL CODESIZE listPuts(char *);
  18. #ifdef BCBOPT
  19. extern UCHAR fNoCompact;
  20. #endif
  21. char fBigNum;
  22. /* size names */
  23. static char byte[] = "BYTE";
  24. static char word[] = "WORD";
  25. static char dword[] = "DWORD";
  26. static char none[] = "NONE";
  27. char hexchar[] = "0123456789ABCDEF";
  28. char *siznm[] = {
  29. 0,
  30. byte,
  31. word,
  32. 0,
  33. dword,
  34. 0,
  35. "FWORD",
  36. 0,
  37. "QWORD",
  38. 0,
  39. "TBYTE",
  40. "NEAR",
  41. "FAR",
  42. };
  43. char *alignName[] = {
  44. "AT",
  45. byte,
  46. word,
  47. "PARA",
  48. "PAGE",
  49. dword
  50. };
  51. char *combineName[] = {
  52. none,
  53. "MEMORY", /* Memory is mapped to PUBLIC in fnspar */
  54. "PUBLIC",
  55. 0,
  56. 0,
  57. "STACK",
  58. "COMMON",
  59. none
  60. };
  61. char headSegment[] = "Segments and Groups:";
  62. static char *head1[] = {
  63. headSegment,
  64. "Symbols: ",
  65. headSegment
  66. };
  67. char headSeg[] = "\tSize\tLength\t Align\tCombine Class";
  68. static char *head2[] = {
  69. &headSeg[5],
  70. "\tType\t Value\t Attr",
  71. headSeg
  72. };
  73. /*** offsetAscii - display dword in hex
  74. *
  75. * offsetAscii(v);
  76. *
  77. * Entry v = dword to be displayed
  78. * Exit objectascii = converted value of v zero terminated
  79. * Returns none
  80. * Calls
  81. */
  82. VOID PASCAL
  83. offsetAscii (
  84. OFFSET v
  85. ){
  86. register USHORT t;
  87. register char *p = objectascii;
  88. #ifdef V386
  89. if (highWord(v)) {
  90. t = highWord(v);
  91. p[3] = hexchar[t & 15];
  92. t >>= 4;
  93. p[2] = hexchar[t & 15];
  94. t >>= 4;
  95. p[1] = hexchar[t & 15];
  96. t >>= 4;
  97. p[0] = hexchar[t & 15];
  98. p += 4;
  99. }
  100. #endif
  101. p[4] = 0;
  102. t = (USHORT)v;
  103. p[3] = hexchar[t & 15];
  104. t >>= 4;
  105. p[2] = hexchar[t & 15];
  106. t >>= 4;
  107. p[1] = hexchar[t & 15];
  108. p[0] = hexchar[(t >> 4) & 15];
  109. }
  110. /*** dispsym - display symbol
  111. *
  112. * routine ();
  113. *
  114. * Entry
  115. * Exit
  116. * Returns
  117. * Calls
  118. */
  119. VOID PASCAL CODESIZE
  120. dispsym (
  121. USHORT indent,
  122. SYMBOL FARSYM *sym
  123. ){
  124. register char *p = listbuffer;
  125. strcpy (p, " . . . . . . . . . . . . . . . . \t");
  126. while (indent--)
  127. *p++ = ' ';
  128. if (caseflag == CASEX && (sym->attr & (M_GLOBAL | M_XTERN)))
  129. strcpy (p, sym->lcnamp->id);
  130. else
  131. STRNFCPY (p, sym->nampnt->id);
  132. p[STRFLEN (sym->nampnt->id)] = ' ';
  133. listPuts (listbuffer);
  134. }
  135. /*** dispword - display word value in current radix
  136. *
  137. * dispword (v);
  138. *
  139. * Entry v = value to display
  140. * Exit
  141. * Returns
  142. * Calls
  143. */
  144. VOID PASCAL CODESIZE
  145. dispword (
  146. OFFSET v
  147. ){
  148. /* Convert value to text */
  149. offsetAscii (v);
  150. if (symptr->symkind == EQU && symptr->symu.equ.equrec.expr.esign)
  151. listPuts ("-");
  152. listPuts(objectascii);
  153. fBigNum = objectascii[4]; /* remember if you put a 8 digit # */
  154. }
  155. /*** chkheading - display heading if needed
  156. *
  157. * chkheading (code);
  158. *
  159. * Entry code = index to heading to be printed
  160. * Exit
  161. * Returns
  162. * Calls
  163. */
  164. VOID PASCAL CODESIZE
  165. chkheading (
  166. USHORT code
  167. ){
  168. if (!listed && lsting) {
  169. if (pagelength - pageline < 8)
  170. pageheader ();
  171. else
  172. skipline ();
  173. listPuts (head1[code]);
  174. skipline ();
  175. skipline ();
  176. listPuts(" N a m e ");
  177. listPuts(head2[code]);
  178. skipline ();
  179. skipline ();
  180. listed = TRUE;
  181. }
  182. }
  183. /*** disptab - output tab character to listing
  184. *
  185. * disptab ();
  186. *
  187. * Entry
  188. * Exit
  189. * Returns
  190. * Calls
  191. */
  192. VOID PASCAL CODESIZE
  193. disptab ()
  194. {
  195. putc ((fBigNum)? ' ': '\t', lst.fil);
  196. fBigNum = FALSE;
  197. }
  198. /*** skipline - output blank line
  199. *
  200. * skipline ();
  201. *
  202. * Entry
  203. * Exit
  204. * Returns
  205. * Calls
  206. */
  207. VOID PASCAL CODESIZE
  208. skipline ()
  209. {
  210. fputs(NLINE, lst.fil);
  211. bumpline ();
  212. }
  213. /*** bumpline - bump line count
  214. *
  215. * bumpline ();
  216. *
  217. * Entry pageline = current line number
  218. * pagelength = number of lines per page
  219. * Exit pageline incremented
  220. * new page started if pageline > pagelength
  221. * Returns none
  222. * Calls pageheader
  223. */
  224. VOID PASCAL
  225. bumpline ()
  226. {
  227. pageline++;
  228. if (pagelength <= pageline)
  229. pageheader ();
  230. }
  231. /*** newpage - start newpage
  232. *
  233. * newpage ();
  234. *
  235. * Entry none
  236. * Exit pagemajor incremented
  237. * pageminor = 0
  238. * pageline set to pagelength - 1
  239. * Returns none
  240. * Calls none
  241. */
  242. VOID PASCAL
  243. newpage ()
  244. {
  245. pagemajor++;
  246. pageminor = 0;
  247. pageline = pagelength - 1;
  248. }
  249. /*** pageheader - output page header
  250. *
  251. * pageheader ();
  252. *
  253. * Entry
  254. * Exit
  255. * Returns
  256. * Calls
  257. */
  258. VOID PASCAL
  259. pageheader ()
  260. {
  261. if (lsting) {
  262. pageminor++;
  263. pageline = 4;
  264. #if defined MSDOS && !defined FLATMODEL
  265. atime[20] = '\0'; /* get rid of '\n' */
  266. #else
  267. atime[24] = '\0'; /* get rid of '\n' */
  268. #endif
  269. fprintf (lst.fil, "\f\b%s%s" NLINE "%s", titlefn, atime + 4, titlebuf);
  270. if (pagemajor == 0)
  271. listPuts("Symbols");
  272. else {
  273. fprintf (lst.fil, "Page %5hd", pagemajor);
  274. }
  275. if (pageminor)
  276. fprintf (lst.fil, "-%hd", pageminor);
  277. fprintf (lst.fil, NLINE "%s" NLINE NLINE, subttlbuf);
  278. }
  279. }
  280. /*** testlist - test for listing of line
  281. *
  282. * testlist ()
  283. *
  284. * Entry
  285. * Exit
  286. * Returns
  287. * Calls
  288. */
  289. UCHAR PASCAL CODESIZE
  290. testlist ()
  291. {
  292. if (fPass1Err)
  293. /* list pass 1 errors regardless of listing status */
  294. return (TRUE);
  295. if (pass2 || debug) {
  296. if (errorcode)
  297. /* list error in pass 2 regardless of listing status */
  298. return (TRUE);
  299. if (fSkipList) {
  300. fSkipList = FALSE;
  301. return (FALSE);
  302. }
  303. if (loption)
  304. return (TRUE);
  305. /* list line in pass 1 or pass 2 if listing enabled */
  306. if (listflag &&
  307. (generate || condflag) &&
  308. (!macrolevel ||
  309. expandflag == LIST ||
  310. !(expandflag == SUPPRESS ||
  311. expandflag == LISTGEN &&
  312. (listbuffer[1] == '=' || listbuffer[1] == ' ') &&
  313. handler != HSTRUC)) )
  314. return (TRUE);
  315. }
  316. return (FALSE);
  317. }
  318. /*** listline - list line on device for user
  319. *
  320. * listline ();
  321. *
  322. * Entry listbuffer = object part of line
  323. * linebuffer = source line
  324. * crefcount = cross reference line count
  325. * Exit crefcount incremented
  326. * Returns none
  327. * Calls
  328. */
  329. VOID PASCAL
  330. listline ()
  331. {
  332. register char *p;
  333. char *q;
  334. char *r;
  335. register SHORT i;
  336. register SHORT j;
  337. register SHORT k;
  338. #ifdef BCBOPT
  339. if (errorcode)
  340. goodlbufp = FALSE;
  341. #endif
  342. crefline ();
  343. if (testlist ()) {
  344. if (listconsole || lsting) {
  345. p = listbuffer + LISTMAX - 3;
  346. #ifdef FEATURE
  347. #ifdef BCBOPT
  348. if (fNoCompact)
  349. #endif
  350. *p++ = '\\';
  351. else {
  352. if (pFCBCur->pFCBParent)
  353. *p++ = 'C';
  354. if (macrolevel)
  355. *p = (macrolevel > 9)? '+': '0' + macrolevel;
  356. }
  357. #else
  358. if (pFCBCur->pFCBParent)
  359. p[0] = 'C';
  360. #ifdef BCBOPT
  361. if (fNoCompact && *linebuffer)
  362. #else
  363. if (*linebuffer)
  364. #endif
  365. p[1] = '\\';
  366. else if (macrolevel)
  367. p[1] = (macrolevel > 9)? '+': '0' + macrolevel;
  368. #endif
  369. listbuffer [LISTMAX] = 0;
  370. }
  371. if (lsting) {
  372. bumpline ();
  373. k = LISTMAX;
  374. /** Put out line # * */
  375. if (pass2 && crefing == CREF_SINGLE) {
  376. fprintf (lst.fil, "%8hd", crefcount+crefinc);
  377. k += 8;
  378. }
  379. p = listbuffer;
  380. while (!memcmp(p," ",8)) { /* leading tabs */
  381. putc('\t',lst.fil);
  382. p += 8;
  383. }
  384. q = r = p + strlen(p) - 1; /* last char of p */
  385. if (q >= p && *q == ' ') {
  386. /* coalesce end spaces to tabs */
  387. while (q != p && *(q - 1) == ' ')
  388. /* gather spaces */
  389. q--;
  390. /* now q points at the first trailing space and
  391. * r points at the last trailing space */
  392. *q = '\0';
  393. listPuts(p);
  394. *q = ' ';
  395. i = (short)((q - p) & 7); /* residual = strlen MOD 8 */
  396. j = 8 - i; /* filler to next tab stop */
  397. if (j != 8 && j <= (r - q + 1)) {
  398. putc('\t',lst.fil);
  399. q += j;
  400. }
  401. while (r >= q + 7) {
  402. putc('\t',lst.fil);
  403. q += 8;
  404. }
  405. while (r >= q++)
  406. putc(' ',lst.fil);
  407. }
  408. else
  409. listPuts(p);
  410. p = linebuffer;
  411. i = k; /* number of columns already put out */
  412. while (*p) {
  413. while (*p && i < pagewidth) {
  414. if (*p == '\t') {
  415. if ((i = (((i+8)>>3)<<3))
  416. >= pagewidth)
  417. /* won't fit */
  418. break;
  419. }
  420. else
  421. i++;
  422. putc(*p, lst.fil );
  423. p++;
  424. }
  425. if (*p) {
  426. skipline ();
  427. listPuts ( pass2 && crefing == CREF_SINGLE ?
  428. "\t\t\t\t\t" : "\t\t\t\t");
  429. i = k;
  430. }
  431. }
  432. fputs(NLINE, lst.fil);
  433. }
  434. crefinc++;
  435. if (errorcode) {
  436. if (listconsole)
  437. /* display line */
  438. fprintf (ERRFILE,"%s%s\n", listbuffer, linebuffer);
  439. errordisplay ();
  440. }
  441. }
  442. if (fNeedList)
  443. memset(listbuffer, ' ', LISTMAX);
  444. errorcode = 0;
  445. fPass1Err = 0;
  446. }
  447. /*** storetitle - copy text of line to title buffer
  448. *
  449. * storetitle (buf)
  450. *
  451. * Entry buf = pointer to buffer to hold title
  452. * Exit up to TITLEWIDTH - 1 characters move to *buf* and *buf* blank
  453. * filled and zero terminated
  454. * Returns none
  455. * Calls none
  456. */
  457. VOID PASCAL
  458. storetitle (
  459. register char *buf
  460. ){
  461. register SHORT L_count = 0;
  462. for (; (L_count < TITLEWIDTH - 1); L_count++) {
  463. if (PEEKC () == 0)
  464. break;
  465. else
  466. *buf++ = NEXTC ();
  467. }
  468. /* skip to end of title */
  469. while (PEEKC ())
  470. SKIPC ();
  471. /* blank fill buffer */
  472. for (; L_count < TITLEWIDTH - 1; L_count++)
  473. *buf++ = ' ';
  474. *buf = 0;
  475. }
  476. /*** displength - display value as LENGTH = value
  477. *
  478. * displength (v);
  479. *
  480. * Entry
  481. * Exit
  482. * Returns
  483. * Calls
  484. */
  485. VOID PASCAL CODESIZE
  486. displength (
  487. OFFSET v
  488. ){
  489. offsetAscii (v);
  490. listPuts("\tLength = ");
  491. listPuts(objectascii);
  492. }
  493. /*** dispdatasize - display data size
  494. *
  495. * dispdatasize (sym);
  496. *
  497. * Entry *sym = symbol
  498. * Exit
  499. * Returns
  500. * Calls
  501. */
  502. VOID PASCAL
  503. dispdatasize (
  504. SYMBOL FARSYM *sym
  505. ){
  506. register USHORT idx;
  507. idx = sym->symtype;
  508. if (idx == CLABEL && sym->symu.clabel.type > 514)
  509. dispword((OFFSET) idx);
  510. else{
  511. if (idx == CSFAR)
  512. idx = 12;
  513. else if (idx == CSNEAR)
  514. idx = 11;
  515. else if (idx > 10 || siznm[idx] == NULL){
  516. return;
  517. }
  518. listPuts(siznm[idx]);
  519. }
  520. }
  521. /*** listopen - list blocks open at end of pass
  522. *
  523. * listopen ();
  524. *
  525. * Entry
  526. * Exit
  527. * Returns
  528. * Calls
  529. * Note Format is:
  530. * Open segments: <list>
  531. * Open procedures: <list>
  532. * Open conditionals: <n>
  533. */
  534. VOID PASCAL
  535. listopen ()
  536. {
  537. SYMBOL FARSYM *sym;
  538. if (pcsegment) {
  539. if (!listquiet)
  540. fprintf (ERRFILE,"%s:", __NMSG_TEXT(ER_SEG));
  541. if (lsting) {
  542. fprintf (lst.fil, "%s:", __NMSG_TEXT(ER_SEG));
  543. bumpline ();
  544. skipline ();
  545. }
  546. sym = pcsegment;
  547. while (sym) {
  548. /* Count as an error */
  549. if (pass2)
  550. errornum++;
  551. if (lsting) {
  552. dispsym (0, sym);
  553. skipline ();
  554. }
  555. if (!listquiet) {
  556. STRNFCPY (save, sym->nampnt->id);
  557. fprintf (ERRFILE," %s", save);
  558. }
  559. /* Point to previous seg */
  560. sym = sym->symu.segmnt.lastseg;
  561. }
  562. if (!listquiet)
  563. fprintf (ERRFILE,"\n");
  564. }
  565. if (iProcStack > 0) {
  566. if (!listquiet)
  567. fprintf (ERRFILE,"%s:", __NMSG_TEXT(ER_PRO));
  568. if (lsting) {
  569. fprintf (lst.fil, "%s:", __NMSG_TEXT(ER_PRO));
  570. bumpline ();
  571. skipline ();
  572. }
  573. while (iProcStack > 0) {
  574. sym = procStack[iProcStack--];
  575. /* Count as an error */
  576. if (pass2)
  577. errornum++;
  578. if (lsting) {
  579. dispsym (0, sym);
  580. skipline ();
  581. }
  582. if (!listquiet) {
  583. STRNFCPY (save, sym->nampnt->id);
  584. fprintf (ERRFILE," %s", save);
  585. }
  586. }
  587. if (!listquiet)
  588. fprintf (ERRFILE,"\n");
  589. }
  590. if (condlevel) {
  591. /* Count as an error */
  592. if (pass2)
  593. errornum++;
  594. if (!listquiet)
  595. fprintf (ERRFILE,"%s%hd\n", __NMSG_TEXT(ER_CON), condlevel);
  596. if (lsting) {
  597. fprintf (lst.fil, "%s%hd" NLINE, __NMSG_TEXT(ER_CON), condlevel);
  598. bumpline ();
  599. }
  600. }
  601. }
  602. /*** symbollist - list symbol
  603. *
  604. * symbollist (sym)
  605. *
  606. * Entry *sym = symbol
  607. * Exit count = number of symbols listed
  608. * Returns
  609. * Calls
  610. */
  611. VOID PASCAL
  612. symbollist ()
  613. {
  614. SYMBOL FARSYM *sym;
  615. SHORT i;
  616. listed = FALSE;
  617. for (i = 0; i < MAXCHR; i++) {
  618. count = 0;
  619. for(sym = symroot[i]; sym; sym = sym->alpha)
  620. if (!((M_NOCREF|M_PASSED) & sym->attr)) {
  621. symptr = sym;
  622. count++;
  623. chkheading (1);
  624. setpassed (sym);
  625. dispsym (0, sym);
  626. dispstandard (sym);
  627. if (sym->symkind == PROC)
  628. displength ((OFFSET) sym->symu.plabel.proclen);
  629. else if (sym->length != 1 &&
  630. (sym->symkind == DVAR || sym->symkind == CLABEL))
  631. displength ((OFFSET) sym->length);
  632. skipline ();
  633. }
  634. if (count)
  635. skipline ();
  636. }
  637. }
  638. /*** dispstandard - display standard
  639. *
  640. * dispstandard ();
  641. *
  642. * Entry
  643. * Exit
  644. * Returns
  645. * Calls
  646. * Note Format is:
  647. * PROC: N/F PROC offset Segment
  648. * CLABEL L NEAR|FAR offset Segment
  649. * DVAR V SIZE offset Segment
  650. * REGISTR REG name
  651. */
  652. VOID PASCAL CODESIZE
  653. dispstandard (
  654. SYMBOL FARSYM *sym
  655. ){
  656. NAME FAR *tp;
  657. register SHORT width;
  658. SHORT cbTM;
  659. switch (sym->symkind) {
  660. case PROC:
  661. if (sym->symtype == CSNEAR)
  662. listPuts("N PROC");
  663. else
  664. listPuts("F PROC");
  665. break;
  666. case CLABEL:
  667. if (sym->symtype == CSNEAR)
  668. listPuts("L NEAR");
  669. else if (sym->symtype == CSFAR)
  670. listPuts("L FAR ");
  671. else {
  672. fprintf (lst.fil, "L ");
  673. dispdatasize (sym);
  674. }
  675. break;
  676. case DVAR:
  677. /* Data associated label */
  678. listPuts("V ");
  679. /**Display keyword or size * */
  680. dispdatasize (sym);
  681. break;
  682. case REGISTER:
  683. listPuts("REG ");
  684. break;
  685. case EQU:
  686. if (sym->symu.equ.equtyp == EXPR)
  687. if (sym->symtype == 0)
  688. listPuts("NUMBER");
  689. else
  690. dispdatasize (sym);
  691. else if (sym->symu.equ.equtyp == ALIAS) {
  692. if (sym->symu.equ.equrec.alias.equptr)
  693. tp = sym->symu.equ.equrec.alias.equptr->nampnt;
  694. else
  695. tp = NULL;
  696. listPuts("ALIAS\t ");
  697. if (tp) {
  698. STRNFCPY (save, tp->id);
  699. listPuts(save);
  700. }
  701. } else {
  702. listPuts("TEXT ");
  703. cbTM = (SHORT) strlen(sym->symu.equ.equrec.txtmacro.equtext);
  704. width = pagewidth - 46;
  705. while (cbTM > width) {
  706. memcpy(save, sym->symu.equ.equrec.txtmacro.equtext,
  707. width);
  708. save[width] = 0;
  709. listPuts(save);
  710. skipline ();
  711. listPuts("\t\t\t\t\t ");
  712. sym->symu.equ.equrec.txtmacro.equtext += width;
  713. cbTM -= width;
  714. }
  715. listPuts(sym->symu.equ.equrec.txtmacro.equtext);
  716. }
  717. break;
  718. }
  719. disptab ();
  720. if ((sym->symkind != EQU) || (sym->symu.equ.equtyp == EXPR))
  721. if (sym->symkind != REGISTER)
  722. dispword (((sym->attr & M_XTERN) && sym->offset)?
  723. (OFFSET) sym->length * sym->symtype:
  724. sym->offset);
  725. else {
  726. STRNFCPY (save, sym->nampnt->id);
  727. listPuts(save);
  728. }
  729. disptab ();
  730. if (sym->symsegptr) {
  731. STRNFCPY (save, sym->symsegptr->nampnt->id);
  732. listPuts(save);
  733. }
  734. if (M_XTERN & sym->attr)
  735. listPuts((sym->symu.ext.commFlag)? "\tCommunal": "\tExternal");
  736. if (M_GLOBAL & sym->attr)
  737. listPuts("\tGlobal");
  738. }
  739. /*** macrolist - list macro names and lengths
  740. *
  741. * macrolist (sym);
  742. *
  743. * Entry *sym = macro symbol entry
  744. * Exit
  745. * Returns
  746. * Calls
  747. */
  748. SHORT PASCAL
  749. macrolist (
  750. SYMBOL FARSYM *sym
  751. ){
  752. SHORT i;
  753. TEXTSTR FAR *p;
  754. if (!(M_NOCREF & sym->attr)) {
  755. if (!listed) {
  756. listed = TRUE;
  757. /* # on line is 1 */
  758. skipline ();
  759. listPuts("Macros:");
  760. /** Display header * */
  761. skipline ();
  762. skipline ();
  763. listPuts("\t\tN a m e\t\t\tLines");
  764. skipline ();
  765. skipline ();
  766. }
  767. /* Display name of macro */
  768. dispsym (0, sym);
  769. for (i = 0, p = sym->symu.rsmsym.rsmtype.rsmmac.macrotext; p; p = p->strnext, i++)
  770. ;
  771. fprintf (lst.fil, "%4hd", i);
  772. skipline ();
  773. setpassed (sym);
  774. }
  775. return 0;
  776. }
  777. /*** struclist - display structure and record names
  778. *
  779. * struclist (sym);
  780. *
  781. * Entry *sym = symbol
  782. * Exit
  783. * Returns
  784. * Calls
  785. * Note Format is:
  786. * <structure name> <length> <# fields>
  787. * <field name> <offset>
  788. * Or
  789. * <Record name> <width> <# fields>
  790. * <Field name> <offset> <width> <mask> <init>
  791. */
  792. SHORT PASCAL
  793. struclist (
  794. SYMBOL FARSYM *sym
  795. ){
  796. char f32bit;
  797. if (!(M_NOCREF & sym->attr)) {
  798. if (!listed) {
  799. listed = TRUE;
  800. if (pagelength - pageline < 8)
  801. pageheader ();
  802. else
  803. skipline ();
  804. listPuts("Structures and Records:");
  805. skipline ();
  806. skipline ();
  807. listPuts(" N a m e Width # fields");
  808. skipline ();
  809. listPuts(" Shift Width Mask Initial");
  810. skipline ();
  811. skipline ();
  812. }
  813. setpassed (sym);
  814. /* Display name */
  815. dispsym (0, sym);
  816. if (sym->symkind == REC) {
  817. /* # bits in record */
  818. dispword ((OFFSET) sym->length);
  819. disptab ();
  820. /* # of fields */
  821. dispword ((OFFSET) sym->symu.rsmsym.rsmtype.rsmrec.recfldnum);
  822. }
  823. else {
  824. /* Length of structure */
  825. dispword ((OFFSET) sym->symtype);
  826. disptab ();
  827. /* # of fields */
  828. dispword ((OFFSET) sym->symu.rsmsym.rsmtype.rsmstruc.strucfldnum);
  829. }
  830. skipline ();
  831. if (sym->symkind == REC) {
  832. #ifdef V386
  833. f32bit = (symptr->length > 16);
  834. #endif
  835. /* Point to 1st rec */
  836. symptr = symptr->symu.rsmsym.rsmtype.rsmrec.reclist;
  837. while (symptr) {
  838. dispsym (2, symptr);
  839. /* Shift count */
  840. dispword (symptr->offset);
  841. disptab ();
  842. /* Width */
  843. dispword ((OFFSET) symptr->symu.rec.recwid);
  844. disptab ();
  845. /* Mask */
  846. #ifdef V386
  847. if (f32bit && symptr->symu.rec.recmsk <= 0xffff)
  848. dispword((OFFSET) 0);
  849. #endif
  850. dispword (symptr->symu.rec.recmsk);
  851. disptab ();
  852. /* Initial value */
  853. #ifdef V386
  854. if (f32bit && symptr->symu.rec.recinit <= 0xffff)
  855. dispword((OFFSET) 0);
  856. #endif
  857. dispword (symptr->symu.rec.recinit);
  858. skipline ();
  859. setpassed (sym);
  860. symptr = symptr->symu.rec.recnxt;
  861. }
  862. }
  863. else {
  864. /* Point to 1st field */
  865. symptr = symptr->symu.rsmsym.rsmtype.rsmstruc.struclist;
  866. while (symptr) {
  867. dispsym (2, symptr);
  868. /* offset from start */
  869. dispword (symptr->offset);
  870. skipline ();
  871. setpassed (symptr);
  872. symptr = symptr->symu.struk.strucnxt;
  873. }
  874. }
  875. }
  876. return 0;
  877. }
  878. /* output a string to the listing file */
  879. VOID PASCAL CODESIZE
  880. listPuts(
  881. char *pString
  882. ){
  883. fputs(pString, lst.fil);
  884. }
  885. /*** segdisplay - display segment name, size, align, combine and class
  886. *
  887. * segdisplay ();
  888. *
  889. * Entry
  890. * Exit
  891. * Returns
  892. * Calls
  893. */
  894. VOID PASCAL CODESIZE
  895. segdisplay (
  896. USHORT indent,
  897. SYMBOL FARSYM *sym
  898. ){
  899. dispsym (indent, sym);
  900. #ifdef V386
  901. if (f386already){
  902. listPuts((sym->symu.segmnt.use32 == 4)? "32": "16");
  903. listPuts(" Bit\t");
  904. }
  905. #endif
  906. /* Length of segment */
  907. dispword (sym->symu.segmnt.seglen);
  908. disptab ();
  909. listPuts (alignName[sym->symu.segmnt.align]);
  910. disptab ();
  911. if (sym->symu.segmnt.align == 0 && sym->symu.segmnt.combine == 0)
  912. dispword ((OFFSET) sym->symu.segmnt.locate);
  913. else
  914. listPuts (combineName[sym->symu.segmnt.combine]);
  915. disptab ();
  916. if (sym->symu.segmnt.classptr) {
  917. /* Have class name */
  918. setpassed (sym->symu.segmnt.classptr);
  919. #ifdef XENIX286
  920. fputc('\'', lst.fil);
  921. farPuts(lst.fil, sym->symu.segmnt.classptr->nampnt->id);
  922. fputc('\'', lst.fil);
  923. #else
  924. # ifdef FLATMODEL
  925. fprintf (lst.fil, "\'%s\'",
  926. # else
  927. fprintf (lst.fil, "\'%Fs\'",
  928. # endif
  929. sym->symu.segmnt.classptr->nampnt->id);
  930. #endif
  931. }
  932. setpassed (sym);
  933. skipline ();
  934. }
  935. /*** seglist - list segment
  936. *
  937. * seglist (sym);
  938. *
  939. * Entry
  940. * Exit
  941. * Returns
  942. * Calls
  943. * Note Format is:
  944. * <Group name> <# segments>
  945. * <segment> <size> <align> <combine> <class>
  946. * Or
  947. * <segment> <size> <align> <combine> <class>
  948. */
  949. VOID PASCAL
  950. seglist ()
  951. {
  952. SYMBOL FARSYM *sym;
  953. SHORT i;
  954. listed = FALSE;
  955. for (i = 0; i < MAXCHR; i++) {
  956. for(sym = symroot[i]; sym; sym = sym->alpha)
  957. if (1 << sym->symkind & (M_SEGMENT | M_GROUP) &&
  958. !((M_NOCREF|M_PASSED) & sym->attr)) {
  959. #ifdef V386
  960. chkheading ((USHORT) ((f386already)? 2: 0) );
  961. #else
  962. chkheading (0);
  963. #endif
  964. symptr = sym;
  965. setpassed (sym);
  966. if (sym->symkind == SEGMENT) {
  967. if (!sym->symu.segmnt.grouptr)
  968. /*Display segment */
  969. segdisplay (0, sym);
  970. }
  971. else {
  972. /* Display group name */
  973. dispsym (0, sym);
  974. listPuts ("GROUP" NLINE);
  975. bumpline ();
  976. bumpline ();
  977. /* Point to 1st seg */
  978. symptr = sym->symu.grupe.segptr;
  979. while (symptr) {
  980. segdisplay (2, symptr);
  981. symptr = symptr->symu.segmnt.nxtseg;
  982. }
  983. }
  984. }
  985. }
  986. }