Source code of Windows XP (NT5)
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.

1246 lines
24 KiB

  1. /* asmsym.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 "asmtab.h"
  16. #include "dos.h"
  17. #include <ctype.h>
  18. #define TSYMSIZE 451
  19. #define FS_ALLOC 2000 /* far symbol allocation size */
  20. #define CB_CODELABEL 2
  21. #define CB_PROCLABEL 12
  22. #define CB_DATALABEL 5
  23. SYMBOL FARSYM * FARSYM tsym[TSYMSIZE];
  24. static char FARSYM *symaddr;
  25. static SHORT symfree;
  26. static DSCREC descT;
  27. extern USHORT LedataOp;
  28. extern OFFSET ecuroffset;
  29. extern SYMBOL FARSYM *pStrucFirst;
  30. VOID PASCAL CODESIZE putWord(USHORT);
  31. SHORT PASCAL CODESIZE cbNumericLeaf(long);
  32. VOID PASCAL CODESIZE putNumericLeaf(long);
  33. SHORT PASCAL dmpSymbols PARMS((SYMBOL FARSYM *));
  34. SHORT PASCAL dumpTypes PARMS((SYMBOL FARSYM *));
  35. VOID PASCAL CODESIZE putSymbol PARMS((SYMBOL FARSYM *));
  36. VOID PASCAL CODESIZE putFixup PARMS((void));
  37. /*** iskey - look for string in keyword table
  38. *
  39. * iskey (str, table);
  40. *
  41. * Entry str = string to search for
  42. * table = keyword table to search
  43. * Exit
  44. * Returns value defined in keyword table if string found
  45. * NOTFOUND if string not found
  46. * Calls
  47. */
  48. #ifndef M8086OPT /* native coded */
  49. USHORT CODESIZE
  50. iskey (
  51. KEYWORDS FARSYM *table
  52. ){
  53. register KEYSYM FARSYM *p;
  54. register char *uc;
  55. register char *lc;
  56. register SHORT nhash;
  57. char mapstr[SYMMAX + 1];
  58. if (caseflag == CASEL) {
  59. nhash = 0;
  60. for (uc = mapstr, lc = naim.pszName; *lc; ) {
  61. nhash += *uc++ = MAP (*lc++);
  62. }
  63. *uc = 0;
  64. uc = mapstr;
  65. }
  66. else {
  67. nhash = naim.usHash;
  68. uc = naim.pszName;
  69. }
  70. for (p = (table->kt_table)[nhash % table->kt_size]; p; p = p->k_next)
  71. if ((nhash == p->k_hash) && (!STRFFCMP( p->k_name,uc)))
  72. return (p->k_token);
  73. return (NOTFOUND);
  74. }
  75. #endif /* not M8086OPT */
  76. /*** symsrch - search for symbol
  77. *
  78. * flag = symsrch ();
  79. *
  80. * Entry naim = symbol to search for
  81. *
  82. * Exit *symptr = symbol if found
  83. * *symptr = NULL if symbol not found
  84. * Returns TRUE if symbol found
  85. * FALSE if symbol not found
  86. */
  87. #ifndef M8086OPT
  88. char CODESIZE
  89. symsrch ()
  90. {
  91. register SYMBOL FARSYM *p;
  92. if (naim.ucCount && (p = tsym[naim.usHash % TSYMSIZE])){
  93. do {
  94. if (( naim.usHash == p->nampnt->hashval)
  95. && !STRNFCMP (naim.pszName, p->nampnt->id)) {
  96. if( iProcCur ){ /* Check for nested names */
  97. if( p->symkind == CLABEL ){
  98. if( p->symu.clabel.iProc && p->symu.clabel.iProc != iProcCur ){
  99. continue;
  100. }
  101. }else if( p->symkind == EQU ){
  102. if( p->symu.equ.iProc && p->symu.equ.iProc != iProcCur ){
  103. continue;
  104. }
  105. }
  106. }
  107. symptr = p;
  108. if( crefing == CREF_SINGLE ){
  109. crefnew (REF);
  110. crefout ();
  111. }
  112. return (TRUE);
  113. }
  114. } while (p = p->next);
  115. }
  116. return (FALSE);
  117. }
  118. #endif /* M8086OPT */
  119. /*** symsearch - search for symbol
  120. *
  121. * flag = symsearch (sym);
  122. *
  123. * Entry *sym = symbol to search for
  124. * Exit *symptr = symbol if found
  125. * *symptr = NULL if symbol not found
  126. * Returns TRUE if symbol found
  127. * FALSE if symbol not found
  128. */
  129. char PASCAL CODESIZE
  130. symsearch ()
  131. {
  132. char rg[4], *naimSav;
  133. register SHORT i;
  134. register char ret;
  135. FASTNAME save;
  136. ret = FALSE;
  137. if (*naim.pszName)
  138. if (!(ret = symsrch ()))
  139. if (caseflag == CASEL && (i = naim.ucCount) <= 3) {
  140. // Save the name
  141. memcpy( &save, &naim, sizeof( FASTNAME ) );
  142. // Rebuild it in upper case
  143. naim.pszName = rg;
  144. *naim.pszName = '\0';
  145. naim.usHash = 0;
  146. for( ; i >= 0; i--){
  147. naim.usHash += naim.pszName[i] = MAP (save.pszName[i]);
  148. }
  149. // Search for the upper cased name
  150. ret = symsrch ();
  151. // Restore the name
  152. memcpy( &naim, &save, sizeof( FASTNAME ) );
  153. }
  154. return (ret);
  155. }
  156. /*** syFet - symbol Fetch with text macro subsitution
  157. *
  158. * flag = syFet();
  159. *
  160. * Entry naim.pszName - atom to fetch
  161. * Exit *symptr = symbol if found
  162. * *symptr = NULL if symbol not found
  163. * Returns TRUE if symbol found
  164. * FALSE if symbol not found
  165. */
  166. char PASCAL CODESIZE
  167. symFet ()
  168. {
  169. register char ret;
  170. char *lbufSav;
  171. ret = symsrch();
  172. if (ret &&
  173. symptr->symkind == EQU &&
  174. symptr->symu.equ.equtyp == TEXTMACRO){
  175. /* look up the name indirect */
  176. lbufSav = lbufp;
  177. lbufp = symptr->symu.equ.equrec.txtmacro.equtext;
  178. getatom();
  179. lbufp = lbufSav;
  180. ret = symsrch();
  181. }
  182. return(ret);
  183. }
  184. char PASCAL CODESIZE
  185. symFetNoXref()
  186. {
  187. SHORT ret;
  188. xcreflag--;
  189. ret = symFet();
  190. xcreflag++;
  191. return((char)ret);
  192. }
  193. /*** createname - create idtext structure for name
  194. *
  195. * ptr = createname (sym);
  196. *
  197. * Entry *sym = name to create entry for
  198. * Exit none
  199. * Returns address of idtext structure
  200. * Calls malloc, strcpy
  201. */
  202. NAME FAR * PASCAL CODESIZE
  203. createname (
  204. register char *sym
  205. ){
  206. register NAME FAR *ptr;
  207. register UINT i;
  208. register UINT len;
  209. len = strlen (sym );
  210. i = len + sizeof( NAME ) - sizeof( ptr->id );
  211. ptr = (NAME FAR *)falloc ((USHORT)i, "createname");
  212. ptr->hashval = 0;
  213. fMemcpy (ptr->id, sym, len + 1 );
  214. return (ptr);
  215. }
  216. #ifdef M8086
  217. /*** creatlname - create idtext structure for name
  218. *
  219. * ptr = creatlname (sym);
  220. *
  221. * Entry *sym = name to create entry for
  222. * Exit none
  223. * Returns address of idtext structure
  224. * Calls malloc, strcpy
  225. */
  226. NAME * PASCAL CODESIZE
  227. creatlname (
  228. register char *sym
  229. ){
  230. NAME *ptr;
  231. register UINT i;
  232. i = naim.ucCount + sizeof( NAME ) - sizeof( ptr->id );
  233. ptr = (NAME *)nalloc ( (USHORT)i, "creatlname");
  234. memcpy (ptr->id, sym, naim.ucCount + 1 );
  235. return (ptr);
  236. }
  237. #endif
  238. /*** symcreate - create new symbol node
  239. *
  240. * symcreate (symbol, sattr, skind);
  241. *
  242. * Entry symbol = symbol name
  243. * sattr = symbol attribute
  244. * skind = symbol kind
  245. * Exit symptr = pointer to symbol
  246. * symbolcnt incremented
  247. * Returns none
  248. * Calls createname
  249. */
  250. /* Map of Symbol types to additional allocation needed past common header */
  251. UCHAR mpcbSY [] = {
  252. sizeof (struct symbseg), /* SEGMENT */
  253. sizeof (struct symbgrp), /* GROUP */
  254. sizeof (struct symbclabel), /* CLABEL */
  255. sizeof (struct symbproc), /* PROC */
  256. sizeof (struct symbrsm), /* REC */
  257. sizeof (struct symbrsm), /* STRUC */
  258. sizeof (struct symbequ), /* EQU */
  259. sizeof (struct symbext), /* DVAR */
  260. sizeof (struct symbext), /* CLASS*/
  261. sizeof (struct symbrecf), /* RECFIELD */
  262. sizeof (struct symbstrucf), /* STRUCFIELD */
  263. sizeof (struct symbrsm), /* MACRO */
  264. sizeof (struct symbreg) /* REGISTER */
  265. };
  266. VOID PASCAL CODESIZE
  267. symcreate (
  268. UCHAR sattr,
  269. char skind
  270. ){
  271. register USHORT cb;
  272. register SYMBOL FARSYM *p;
  273. register USHORT cbName, pT;
  274. register USHORT cbStruct;
  275. /* Create new symbol entry */
  276. cbName = naim.ucCount + sizeof (char) + sizeof (USHORT);
  277. cbStruct = (SHORT)(&(((SYMBOL FARSYM *)0)->symu)) + mpcbSY[skind];
  278. // Make sure NAME struct starts on double word boundry (required for MIPS)
  279. cbStruct = (cbStruct + 3) & ~3;
  280. cb = cbStruct + cbName;
  281. // Do suballocations on double word boundries, so promote length to a
  282. // multiple of 4.
  283. cb = (cb + 3) & ~3;
  284. if (!symaddr || (cb > symfree)) {
  285. #ifdef FS
  286. symaddr = falloc (FS_ALLOC, "symcreate-EXPR");
  287. #else
  288. symaddr = nalloc (FS_ALLOC, "symcreate-EXPR");
  289. #endif
  290. symfree = FS_ALLOC;
  291. #if !defined FLATMODEL
  292. /* Uses knowledge of fMemcpy to initialize memory by */
  293. /* Repeatedly copying zero to the next word in the buf */
  294. *((SHORT FARSYM *)symaddr) = NULL;
  295. fMemcpy(((char FAR *)symaddr)+2, symaddr, FS_ALLOC-2);
  296. #else
  297. /* Since in small model memset is available use it */
  298. memset( symaddr, 0, FS_ALLOC );
  299. #endif
  300. }
  301. p = (SYMBOL FARSYM *)symaddr;
  302. symaddr += cb;
  303. symfree -= cb;
  304. symbolcnt++;
  305. /* clear out default values and fill in givens */
  306. p->attr = sattr;
  307. p->symkind = skind;
  308. if (skind == EQU)
  309. p->symu.equ.equtyp = equsel;
  310. /* Now create record for name of symbol and link in */
  311. p->nampnt = (NAME FAR *)((char FAR *)p + cbStruct); // Name follows fixed structures and padding
  312. fMemcpy (p->nampnt->id, naim.pszName, (USHORT)(naim.ucCount + 1));
  313. p->nampnt->hashval = naim.usHash;
  314. cb = naim.usHash % TSYMSIZE;
  315. p->next = tsym[cb];
  316. tsym[cb] = symptr = p;
  317. }
  318. /*** muldef - set multidefined bit and output error
  319. *
  320. * muldef ();
  321. *
  322. * Entry *symptr = symbol which is multiply defined
  323. * Exit MULTDEFINED set in symptr->attr
  324. * Returns none
  325. * Calls error
  326. *
  327. * Two bits keep track of multiple definitions:
  328. * MULTDEFINED: is remembered between pass one & two
  329. * BACKREF: set by defining function, unset by uses that are
  330. * forward references. Reset at end of pass 1.
  331. *
  332. * When a symbol is defined, it should:
  333. * - check that BACKREF is off, if not call muldef which
  334. * sets MULTIDEFINED, causes an error in pass 1 & 2
  335. * This causes error on 2nd and on defines
  336. *
  337. * - if not BACKREF then check for MULTDEFINED,
  338. * error message in pass 2 only.
  339. * This in effect prints an error for the first definer only
  340. *
  341. * - set BACKREF to indicate symbol defined
  342. */
  343. VOID PASCAL CODESIZE
  344. muldef ()
  345. {
  346. symptr->attr |= (M_MULTDEFINED);
  347. errorc (E_RSY);
  348. }
  349. /*** labelcreate - create label
  350. *
  351. * labelcreate (labelsize, labelkind);
  352. *
  353. * Entry labelsize = size of label
  354. * labelkind = kind of label
  355. * Exit
  356. * Returns
  357. * Calls
  358. * Note This routine makes symbol table entry and checks for
  359. * * Multiple definitions
  360. * * Phase error (value different between passes)
  361. */
  362. VOID PASCAL CODESIZE
  363. labelcreate (
  364. USHORT labelsize,
  365. char labelkind
  366. ){
  367. char newsym;
  368. register SYMBOL FARSYM *p, FARSYM *pCS;
  369. newsym = TRUE;
  370. checkRes();
  371. xcreflag--;
  372. if (! ((labelkind == EQU)? symsrch (): symFet())){
  373. symcreate (M_DEFINED, labelkind);
  374. }
  375. else if (M_DEFINED & symptr->attr)
  376. newsym = FALSE;
  377. xcreflag++;
  378. p = symptr;
  379. equdef = !newsym;
  380. if (newsym) {
  381. p->offset = pcoffset;
  382. p->symsegptr = pcsegment;
  383. }
  384. if ((p->attr&~M_CDECL) == M_GLOBAL) /* forward referenced global */
  385. if (1 << labelkind & (M_PROC | M_DVAR | M_CLABEL | M_EQU)){
  386. p->symkind = labelkind;
  387. if (labelkind == EQU)
  388. p->symu.equ.equtyp = equsel;
  389. }
  390. else
  391. errorn (E_SDK);
  392. p->attr |= M_DEFINED;
  393. p->symtype = labelsize;
  394. p->length = 1;
  395. /* Check to see if there would be any error in label */
  396. if ((p->symkind != labelkind) || (M_XTERN & p->attr))
  397. errorn (E_SDK);
  398. else if ((M_BACKREF & p->attr) && (p->symkind != EQU))
  399. muldef ();
  400. else if (M_MULTDEFINED & p->attr)
  401. errorn (E_SMD);
  402. else if (M_DEFINED & p->attr)
  403. if (!(1 << labelkind & (M_EQU | M_STRUCFIELD)) &&
  404. (p->offset != pcoffset)) {
  405. errorc (E_PHE);
  406. if (errorcode == E_PHE)
  407. pcoffset = p->offset;
  408. }
  409. else {
  410. p->attr |= M_DEFINED | M_BACKREF;
  411. if ((labelkind != EQU) && emittext)
  412. pcdisplay ();
  413. }
  414. if ((labelkind == p->symkind) &&
  415. !((1 << labelkind) & (M_EQU | M_STRUCFIELD))) {
  416. if (isCodeLabel(p)) {
  417. pCS = regsegment[CSSEG];
  418. #ifndef FEATURE
  419. /* ASSUME CS:FLAT gets assume of current segment */
  420. if (pCS == pFlatGroup)
  421. pCS = pcsegment;
  422. #endif
  423. }
  424. else
  425. pCS = regsegment[DSSEG];
  426. /* CS context for label */
  427. if (!newsym && pCS != p->symu.clabel.csassume)
  428. errorc(E_SPC);
  429. p->symu.clabel.csassume = pCS;
  430. if (labelsize == CSNEAR)
  431. /* This is code label */
  432. if (!pCS)
  433. /* No CS assume, can't define */
  434. errorc (E_NCS);
  435. else
  436. if ((pcsegment != pCS) &&
  437. ((pCS->symkind != GROUP) ||
  438. (pcsegment->symu.segmnt.grouptr != pCS)))
  439. /* Not same segment or CS not seg's grp */
  440. errorc (E_NCS);
  441. }
  442. crefdef ();
  443. }
  444. /*** switchname - switch atom and length between svname and name
  445. *
  446. * switchname ();
  447. *
  448. * Entry none
  449. * Exit svname and name switched
  450. * naim.usHash and svname.usHash switched
  451. * svlcname and lcname switched
  452. * Returns none
  453. * Calls none
  454. */
  455. #ifndef M8086OPT
  456. VOID CODESIZE
  457. switchname ()
  458. {
  459. FASTNAME tmpName;
  460. register char *pNameTmp;
  461. /* Swap naim and svname (str ptrs, hash values and lengths) */
  462. memcpy( &tmpName, &naim, sizeof( FASTNAME ) );
  463. memcpy( &naim, &svname, sizeof( FASTNAME ) );
  464. memcpy( &svname, &tmpName, sizeof( FASTNAME ) );
  465. }
  466. #endif
  467. #if !defined FLATMODEL
  468. # pragma alloc_text (FA_TEXT, scansymbols)
  469. #endif
  470. /*** scansymbols - scan symbol in alpha order and execute function
  471. *
  472. * scansymbols (item);
  473. *
  474. * Entry item = pointer to function to execute
  475. * Exit
  476. * Returns
  477. * Calls
  478. */
  479. VOID PASCAL
  480. scansymbols (
  481. SHORT (PASCAL *item) (SYMBOL FARSYM *)
  482. ){
  483. register USHORT i;
  484. for (i = 0; i < TSYMSIZE; i++)
  485. scanorder (tsym[i], item);
  486. }
  487. #if !defined FLATMODEL
  488. # pragma alloc_text (FA_TEXT, sortalpha)
  489. #endif
  490. /*** sortalpha - sort symbol into alpha ordered list
  491. *
  492. * sortalpha (p);
  493. *
  494. * Entry *p = symbol entry
  495. * Exit symbol sorted into proper alpha list
  496. * Returns none
  497. * Calls none
  498. */
  499. SHORT PASCAL
  500. sortalpha (
  501. register SYMBOL FARSYM *p
  502. ){
  503. register SYMBOL FARSYM *tseg;
  504. register SYMBOL FARSYM * FARSYM *lseg;
  505. char i;
  506. char c;
  507. if (p->symkind == MACRO) {
  508. tseg = macroroot;
  509. lseg = &macroroot;
  510. }
  511. else if ((p->symkind == STRUC) || (p->symkind == REC)) {
  512. tseg = strucroot;
  513. lseg = &strucroot;
  514. }
  515. else {
  516. c = MAP (*(p->nampnt->id));
  517. i = (isalpha (c))? c - 'A': 'Z' - 'A' + 1;
  518. tseg = symroot[i];
  519. lseg = &symroot[i];
  520. }
  521. /* Add symbol to list */
  522. for (; tseg; lseg = &(tseg->alpha), tseg = tseg->alpha) {
  523. if (STRFFCMP (p->nampnt->id, tseg->nampnt->id) < 0)
  524. break;
  525. }
  526. *lseg = p;
  527. p->alpha = tseg;
  528. return 0;
  529. }
  530. /*** typeFet - Fetch the type of the symbol
  531. *
  532. * Entry symtype - the size of the symbol
  533. * Exit prefined symbol type
  534. */
  535. UCHAR mpSizeType[] = {
  536. 0,
  537. makeType(BT_UNSIGNED, BT_DIRECT, BT_sz1), /* db */
  538. makeType(BT_UNSIGNED, BT_DIRECT, BT_sz2), /* dw */
  539. 0,
  540. makeType(BT_UNSIGNED, BT_DIRECT, BT_sz4), /* dd */
  541. 0,
  542. makeType(BT_UNSIGNED, BT_FARP, BT_sz4), /* df */
  543. 0,
  544. makeType(BT_UNSIGNED, BT_DIRECT, BT_sz2), /* dq */
  545. 0,
  546. makeType(BT_UNSIGNED, BT_DIRECT, BT_sz4) /* dt */
  547. };
  548. UCHAR mpRealType[] = {
  549. 0, 0, 0, 0,
  550. makeType(BT_REAL, BT_DIRECT, BT_sz1), /* dd */
  551. 0, 0, 0,
  552. makeType(BT_REAL, BT_DIRECT, BT_sz2), /* dq */
  553. 0,
  554. makeType(BT_REAL, BT_DIRECT, BT_sz4) /* dt */
  555. };
  556. SHORT PASCAL CODESIZE
  557. typeFet (
  558. USHORT symtype
  559. ){
  560. if (symtype <= 10)
  561. return(mpSizeType[symtype]);
  562. else if (symtype == CSNEAR)
  563. return(512);
  564. else if (symtype == CSFAR)
  565. return(513);
  566. else
  567. return(0);
  568. }
  569. char symDefine[] = "$$SYMBOLS segment 'DEBSYM'";
  570. char typeDefine[] = "$$TYPES segment 'DEBTYP'";
  571. char fProcs;
  572. /*** dumpCodeview - dump out codeview symbolic info to the obj file
  573. *
  574. * Entry end of pass one and two
  575. * Exit pass one just computes the segment sizes
  576. * and pass two writes the symbols
  577. */
  578. static SYMBOL FAR *plastSeg; // indicates segIndex of last ChangeSegment
  579. VOID PASCAL
  580. dumpCodeview ()
  581. {
  582. char svlistflag;
  583. char svloption;
  584. if (codeview != CVSYMBOLS || !emittext)
  585. return;
  586. plastSeg = NULL;
  587. svlistflag = listflag;
  588. svloption = loption;
  589. listflag = FALSE;
  590. loption = FALSE;
  591. fProcs = FALSE;
  592. wordszdefault = 2; /* this will vary when CV can do 32 bit segments */
  593. doLine(symDefine);
  594. pcsegment->attr |= M_NOCREF; pcsegment->symu.segmnt.classptr->attr |= M_NOCREF;
  595. scansymbols(dmpSymbols);
  596. fProcs++;
  597. scanSorted(pProcFirst, dmpSymbols);
  598. endCurSeg();
  599. doLine(typeDefine);
  600. pcsegment->attr |= M_NOCREF; pcsegment->symu.segmnt.classptr->attr |= M_NOCREF;
  601. /* First output two types, one for near & far code labels
  602. * Format
  603. * [1][cb][0x72][0x80][0x74|0x73 (near/far)] */
  604. if (pass2) {
  605. putWord(3 << 8 | 1);
  606. putWord(0x72 << 8);
  607. putWord(0x74 << 8 | 0x80);
  608. putWord(3 << 8 | 1);
  609. putWord(0x72 << 8);
  610. putWord(0x73 << 8 | 0x80);
  611. }
  612. else
  613. pcoffset = 12;
  614. scanSorted(pStrucFirst, dumpTypes);
  615. endCurSeg();
  616. listflag = svlistflag;
  617. loption = svloption;
  618. }
  619. /*** dmpSymbols - create the codeview symbol segment
  620. *
  621. * Entry
  622. * Exit
  623. */
  624. static fInProc;
  625. SHORT PASCAL
  626. dmpSymbols(
  627. SYMBOL FARSYM *pSY
  628. ){
  629. SHORT cbName, cbRecord;
  630. char fProcParms;
  631. UCHAR f386; // will be 0 or 0x80 for OR'ing into rectype
  632. fProcParms = 0xB;
  633. if (pSY->symkind == PROC) {
  634. if ( pSY->symu.plabel.pArgs){
  635. if (!fProcs)
  636. return 0;
  637. fProcParms = 1;
  638. }
  639. else if (pSY->attr & (M_GLOBAL | M_XTERN))
  640. return 0;
  641. }
  642. else if (pSY->symkind == CLABEL) {
  643. if (!fInProc && (pSY->symu.clabel.iProc ||
  644. pSY->attr & (M_GLOBAL | M_XTERN)))
  645. return 0;
  646. }
  647. else
  648. return 0;
  649. f386 = (pSY->symsegptr->symu.segmnt.use32 == 4? 0x80 : 0);
  650. cbName = STRFLEN(pSY->nampnt->id) + 1 + (pSY->attr & M_CDECL);
  651. cbRecord = cbName + (f386? 4: 2) +
  652. ((isCodeLabel(pSY))?
  653. ((fProcParms == 1)? CB_PROCLABEL: CB_CODELABEL):
  654. CB_DATALABEL);
  655. if (isCodeLabel(pSY)
  656. && (plastSeg != pSY->symsegptr)) {
  657. plastSeg = pSY->symsegptr;
  658. putWord(0x11 << 8 | 5);
  659. descT.dsckind.opnd.doffset = 0;
  660. descT.dsckind.opnd.dtype = FORTYPE;
  661. descT.dsckind.opnd.dsegment = pSY->symsegptr;
  662. descT.dsckind.opnd.dsize = 2;
  663. descT.dsckind.opnd.fixtype = FBASESEG;
  664. descT.dsckind.opnd.dcontext = pSY->symsegptr;
  665. putFixup();
  666. putWord(0); // 2 bytes reserved
  667. }
  668. descT.dsckind.opnd.doffset = pSY->offset;
  669. descT.dsckind.opnd.dtype = FORTYPE;
  670. descT.dsckind.opnd.dsegment = pSY->symsegptr;
  671. descT.dsckind.opnd.dsize = f386? 4: 2;
  672. emitopcode((UCHAR)cbRecord);
  673. if (isCodeLabel(pSY)) {
  674. /* do the actual outputting for code labels
  675. * FORMAT:
  676. *
  677. * [cb][0xB][offset][0/4][name]
  678. *
  679. * For Proc labels with parms
  680. *
  681. * [cb][0x1][offset][typeIndex][cbProc][startRelOff][endRelOff]
  682. * [0][0/4][name]
  683. */
  684. emitopcode((UCHAR)(fProcParms | f386)); /* contains 0xb or 1 */
  685. /* reserve two bytes and then a fixup to get
  686. * the code labe offset */
  687. descT.dsckind.opnd.fixtype = f386? F32OFFSET: FOFFSET;
  688. descT.dsckind.opnd.dcontext = pSY->symu.clabel.csassume;
  689. putFixup();
  690. if (fProcParms == 1) {
  691. /* type index */
  692. putWord(0);
  693. putWord(pSY->symu.plabel.proclen);
  694. /* starting & ending offset of proc */
  695. putWord(0);
  696. putWord(pSY->symu.plabel.proclen);
  697. putWord(0); /* reservered to 0 */
  698. }
  699. emitopcode((UCHAR)((pSY->symtype == CSNEAR)? 0: 4));
  700. }
  701. else {
  702. /* do the actual outputting for data labels
  703. * FORMAT:
  704. * [cb][0x5][offset:seg][typeIndex][name] */
  705. emitopcode((UCHAR)(0x5|f386));
  706. /* reserve four bytes and then a fixup to get
  707. * the data far address */
  708. descT.dsckind.opnd.fixtype = f386? F32POINTER: FPOINTER;
  709. descT.dsckind.opnd.dsize += 2;
  710. descT.dsckind.opnd.dcontext = NULL;
  711. putFixup();
  712. putWord(pSY->symu.clabel.type);
  713. }
  714. putSymbol(pSY);
  715. if (fProcParms == 1) {
  716. /* Go through the chain of text macro parmeters and output
  717. * the BP relative local symbols.
  718. *
  719. * Format:
  720. * [cb][4][offset][typeIndex][name]
  721. * ...
  722. * [1][2] - end block
  723. */
  724. for (pSY = pSY->symu.plabel.pArgs; pSY; pSY = pSY->alpha){
  725. if (pSY->symkind == CLABEL) {
  726. /* a locally nest label in a procedure */
  727. fInProc++;
  728. dmpSymbols(pSY);
  729. fInProc--;
  730. }
  731. else {
  732. cbName = STRFLEN(pSY->nampnt->id) + 1;
  733. emitopcode((UCHAR)((f386? 7:5) + cbName)); /* cbRecord */
  734. emitopcode((UCHAR)(4 | f386)); /* recType */
  735. if (f386) {
  736. putWord((USHORT) pSY->offset);
  737. putWord(*((USHORT FAR *)&(pSY->offset)+1));
  738. } else
  739. putWord((USHORT) pSY->offset);
  740. putWord(pSY->symu.equ.equrec.txtmacro.type);
  741. putSymbol(pSY);
  742. }
  743. }
  744. putWord(2 << 8 | 1); /* end block record */
  745. }
  746. return 0;
  747. }
  748. /*** dumpTypes - creats a type definition in the codeview type segment
  749. *
  750. * Entry Symbol table pointer to structure or record
  751. * Exit
  752. */
  753. SHORT PASCAL
  754. dumpTypes(
  755. SYMBOL FARSYM *pSY
  756. ){
  757. SHORT cType, cbType, cbNlist, cbName;
  758. SYMBOL FARSYM *pSYField;
  759. /* Scan through the struct field to compute tlist size */
  760. pSYField = pSY->symu.rsmsym.rsmtype.rsmstruc.struclist;
  761. cbNlist = 1;
  762. cType = 0;
  763. if (pSY->symkind == STRUC) {
  764. while (pSYField) {
  765. cbNlist += STRFLEN(pSYField->nampnt->id) + 2 +
  766. cbNumericLeaf(pSYField->offset);
  767. pSYField = pSYField->symu.struk.strucnxt;
  768. cType++;
  769. }
  770. cbName = (SHORT) STRFLEN(pSY->nampnt->id);
  771. cbType = 10 +
  772. cbNumericLeaf(((long) pSY->symtype) * 8) +
  773. cbNumericLeaf((long) cType) +
  774. cbName;
  775. }
  776. else
  777. cbType = -3;
  778. /* A type has the following format
  779. *
  780. * [1][cbType][0x79][cbTypeInBits][cFields][tListIndex][nListIndex]
  781. * [0x82][structureName][0x68]
  782. *
  783. * tList
  784. * nList
  785. */
  786. if (pass2) {
  787. emitopcode(1);
  788. if (pSY->symkind == STRUC) {
  789. putWord(cbType);
  790. emitopcode(0x79);
  791. putNumericLeaf(((long) pSY->symtype) * 8);
  792. putNumericLeaf((long) pSY->symu.rsmsym.rsmtype.rsmstruc.strucfldnum);
  793. emitopcode(0x83); /* tList Index */
  794. putWord((USHORT)(pSY->symu.rsmsym.rsmtype.rsmstruc.type+1));
  795. emitopcode(0x83); /* nList Index */
  796. putWord((USHORT)(pSY->symu.rsmsym.rsmtype.rsmstruc.type+2));
  797. emitopcode(0x82);
  798. putSymbol(pSY);
  799. emitopcode(0x68); /* packed structure */
  800. /* next comes the tList (type index array), it has the following format
  801. *
  802. * [1][cb][0x7f] ([0x83][basicTypeIndex])..repeated..
  803. */
  804. emitopcode(1);
  805. putWord((USHORT)(cType * (USHORT)3 + (USHORT)1));
  806. emitopcode(0x7f);
  807. pSYField = pSY->symu.rsmsym.rsmtype.rsmstruc.struclist;
  808. while(pSYField){
  809. emitopcode(0x83);
  810. putWord(pSYField->symu.struk.type);
  811. pSYField = pSYField->symu.struk.strucnxt;
  812. }
  813. /* next comes the nList (field names), it has the following format
  814. *
  815. * [1][cb][0x7f] ([0x82][cbName][fieldName][offset])..repeated..
  816. */
  817. emitopcode(1);
  818. putWord(cbNlist);
  819. emitopcode(0x7f);
  820. pSYField = pSY->symu.rsmsym.rsmtype.rsmstruc.struclist;
  821. while(pSYField){
  822. emitopcode(0x82);
  823. putSymbol(pSYField);
  824. putNumericLeaf(pSYField->offset);
  825. pSYField = pSYField->symu.struk.strucnxt;
  826. }
  827. }
  828. else {
  829. /* a pointer to type has the following format
  830. *
  831. * [1][5][0x7f] [near/far][0x83][typeIndex]
  832. */
  833. putWord(5);
  834. emitopcode(0x7A);
  835. emitopcode((UCHAR)((pSY->attr)? 0x73: 0x74));
  836. emitopcode(0x83);
  837. putWord(pSY->symtype);
  838. }
  839. }
  840. else
  841. pcoffset += cbType +
  842. cType * 3 +
  843. cbNlist + 10;
  844. return 0;
  845. }
  846. /*** cbNumericLeaf - compute the size for a numeric leaf
  847. *
  848. * Entry long value to output
  849. * Exit size of leaf
  850. */
  851. SHORT PASCAL CODESIZE
  852. cbNumericLeaf(
  853. long aLong
  854. ){
  855. if (aLong & 0xFFFF0000)
  856. return(5);
  857. else if (aLong & 0xFF80)
  858. return(3);
  859. else
  860. return(1);
  861. }
  862. /*** putNumericLeaf - output variable size numeric codeview leaf
  863. *
  864. * Entry long value to output
  865. * Exit numeric leaf on OMF
  866. */
  867. VOID PASCAL CODESIZE
  868. putNumericLeaf(
  869. long aLong
  870. ){
  871. if (aLong & 0xFFFF0000){
  872. emitopcode(0x86);
  873. putWord((USHORT)aLong);
  874. putWord(*((USHORT *)&aLong+1));
  875. }
  876. else if (aLong & 0xFF80){
  877. emitopcode(0x85);
  878. putWord((USHORT)aLong);
  879. }
  880. else
  881. emitopcode((UCHAR)aLong);
  882. }
  883. /*** doLine - feed a text line to parse for processing
  884. *
  885. * Entry pointer to text string
  886. * Exit processed line
  887. */
  888. VOID PASCAL CODESIZE
  889. doLine(
  890. char *pText
  891. ){
  892. USHORT cvSave;
  893. fCrefline = FALSE;
  894. #ifdef BCBOPT
  895. if (fNotStored)
  896. storelinepb ();
  897. #endif
  898. if (fNeedList) {
  899. listline(); /* list out current line */
  900. strcpy(linebuffer, pText);
  901. fSkipList++;
  902. }
  903. lbufp = strcpy(lbuf, pText);
  904. linebp = lbufp + strlen(lbufp);
  905. cvSave = codeview;
  906. codeview = 0;
  907. if (loption || expandflag == LIST)
  908. fSkipList = FALSE;
  909. parse();
  910. codeview = cvSave;
  911. fSkipList++;
  912. fCrefline++;
  913. }
  914. /*** putWord - output a 2 byte word to the current segment
  915. *
  916. * Entry word to output
  917. * Exit increment pcoffset
  918. */
  919. VOID PASCAL CODESIZE
  920. putWord(
  921. USHORT aWord
  922. ){
  923. if (pass2)
  924. emitcword((OFFSET) aWord);
  925. pcoffset += 2;
  926. }
  927. /*** putSymbol - put out the name of a symbol
  928. *
  929. * Entry word to output
  930. * Exit increment pcoffset
  931. */
  932. VOID PASCAL CODESIZE
  933. putSymbol(
  934. SYMBOL FARSYM *pSY
  935. ){
  936. SHORT cbName;
  937. cbName = STRFLEN(pSY->nampnt->id) + 1 + (pSY->attr & M_CDECL);
  938. if (pass2){
  939. if (emitcleanq ((UCHAR)cbName))
  940. emitdumpdata ((UCHAR)LedataOp);
  941. emitSymbol(pSY);
  942. }
  943. pcoffset += cbName;
  944. ecuroffset = pcoffset;
  945. }
  946. /*** putFixup - put out a fixup
  947. *
  948. * Entry golbal descT
  949. * Exit increment pcoffset
  950. */
  951. VOID PASCAL CODESIZE
  952. putFixup()
  953. {
  954. extern UCHAR fNoMap;
  955. fNoMap++;
  956. if (pass2)
  957. emitobject(&descT.dsckind.opnd);
  958. fNoMap--;
  959. pcoffset += descT.dsckind.opnd.dsize;
  960. }