summaryrefslogtreecommitdiffstats
path: root/private/sdktools/masm/asmsym.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/sdktools/masm/asmsym.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/sdktools/masm/asmsym.c')
-rw-r--r--private/sdktools/masm/asmsym.c1241
1 files changed, 1241 insertions, 0 deletions
diff --git a/private/sdktools/masm/asmsym.c b/private/sdktools/masm/asmsym.c
new file mode 100644
index 000000000..79ff5ad8c
--- /dev/null
+++ b/private/sdktools/masm/asmsym.c
@@ -0,0 +1,1241 @@
+/* asmsym.c -- microsoft 80x86 assembler
+**
+** microsoft (r) macro assembler
+** copyright (c) microsoft corp 1986. all rights reserved
+**
+** randy nevin
+**
+** 10/90 - Quick conversion to 32 bit by Jeff Spencer
+*/
+
+#include <stdio.h>
+#include "asm86.h"
+#include "asmfcn.h"
+#include "asmctype.h"
+#include "asmtab.h"
+#include "dos.h"
+#include <ctype.h>
+
+#define TSYMSIZE 451
+#define FS_ALLOC 2000 /* far symbol allocation size */
+
+#define CB_CODELABEL 2
+#define CB_PROCLABEL 12
+#define CB_DATALABEL 5
+
+SYMBOL FARSYM * FARSYM tsym[TSYMSIZE];
+static char FARSYM *symaddr;
+static SHORT symfree;
+static DSCREC descT;
+
+extern USHORT LedataOp;
+extern OFFSET ecuroffset;
+extern SYMBOL FARSYM *pStrucFirst;
+
+VOID PASCAL CODESIZE putWord(USHORT);
+SHORT PASCAL CODESIZE cbNumericLeaf(long);
+VOID PASCAL CODESIZE putNumericLeaf(long);
+
+VOID PASCAL dmpSymbols PARMS((SYMBOL FARSYM *));
+VOID PASCAL dumpTypes PARMS((SYMBOL FARSYM *));
+VOID PASCAL CODESIZE putSymbol PARMS((SYMBOL FARSYM *));
+VOID PASCAL CODESIZE putFixup PARMS((void));
+
+
+
+/*** iskey - look for string in keyword table
+ *
+ * iskey (str, table);
+ *
+ * Entry str = string to search for
+ * table = keyword table to search
+ * Exit
+ * Returns value defined in keyword table if string found
+ * NOTFOUND if string not found
+ * Calls
+ */
+
+#ifndef M8086OPT /* native coded */
+
+USHORT CODESIZE
+iskey (
+ KEYWORDS FARSYM *table
+){
+ register KEYSYM FARSYM *p;
+ register char *uc;
+ register char *lc;
+ register SHORT nhash;
+ char mapstr[SYMMAX + 1];
+
+ if (caseflag == CASEL) {
+ nhash = 0;
+ for (uc = mapstr, lc = naim.pszName; *lc; ) {
+ nhash += *uc++ = MAP (*lc++);
+ }
+ *uc = 0;
+ uc = mapstr;
+ }
+ else {
+ nhash = naim.usHash;
+ uc = naim.pszName;
+ }
+ for (p = (table->kt_table)[nhash % table->kt_size]; p; p = p->k_next)
+ if ((nhash == p->k_hash) && (!STRFFCMP( p->k_name,uc)))
+ return (p->k_token);
+ return (NOTFOUND);
+}
+
+#endif /* not M8086OPT */
+
+
+/*** symsrch - search for symbol
+ *
+ * flag = symsrch ();
+ *
+ * Entry naim = symbol to search for
+ *
+ * Exit *symptr = symbol if found
+ * *symptr = NULL if symbol not found
+ * Returns TRUE if symbol found
+ * FALSE if symbol not found
+ */
+
+#ifndef M8086OPT
+
+char CODESIZE
+symsrch ()
+{
+ register SYMBOL FARSYM *p;
+
+ if (naim.ucCount && (p = tsym[naim.usHash % TSYMSIZE])){
+ do {
+ if (( naim.usHash == p->nampnt->hashval)
+ && !STRNFCMP (naim.pszName, p->nampnt->id)) {
+ if( iProcCur ){ /* Check for nested names */
+ if( p->symkind == CLABEL ){
+ if( p->symu.clabel.iProc && p->symu.clabel.iProc != iProcCur ){
+ continue;
+ }
+ }else if( p->symkind == EQU ){
+ if( p->symu.equ.iProc && p->symu.equ.iProc != iProcCur ){
+ continue;
+ }
+ }
+ }
+ symptr = p;
+ if( crefing == CREF_SINGLE ){
+ crefnew (REF);
+ crefout ();
+ }
+ return (TRUE);
+ }
+ } while (p = p->next);
+ }
+ return (FALSE);
+}
+
+#endif /* M8086OPT */
+
+/*** symsearch - search for symbol
+ *
+ * flag = symsearch (sym);
+ *
+ * Entry *sym = symbol to search for
+ * Exit *symptr = symbol if found
+ * *symptr = NULL if symbol not found
+ * Returns TRUE if symbol found
+ * FALSE if symbol not found
+ */
+
+
+char PASCAL CODESIZE
+symsearch ()
+{
+ char rg[4], *naimSav;
+ register SHORT i;
+ register char ret;
+ FASTNAME save;
+
+ ret = FALSE;
+ if (*naim.pszName)
+ if (!(ret = symsrch ()))
+ if (caseflag == CASEL && (i = naim.ucCount) <= 3) {
+
+ // Save the name
+ memcpy( &save, &naim, sizeof( FASTNAME ) );
+
+ // Rebuild it in upper case
+ naim.pszName = rg;
+ *naim.pszName = '\0';
+ naim.usHash = 0;
+ for( ; i >= 0; i--){
+ naim.usHash += naim.pszName[i] = MAP (save.pszName[i]);
+ }
+
+ // Search for the upper cased name
+ ret = symsrch ();
+
+ // Restore the name
+ memcpy( &naim, &save, sizeof( FASTNAME ) );
+ }
+ return (ret);
+}
+
+
+
+/*** syFet - symbol Fetch with text macro subsitution
+ *
+ * flag = syFet();
+ *
+ * Entry naim.pszName - atom to fetch
+ * Exit *symptr = symbol if found
+ * *symptr = NULL if symbol not found
+ * Returns TRUE if symbol found
+ * FALSE if symbol not found
+ */
+
+
+char PASCAL CODESIZE
+symFet ()
+{
+ register char ret;
+ char *lbufSav;
+
+ ret = symsrch();
+
+ if (ret &&
+ symptr->symkind == EQU &&
+ symptr->symu.equ.equtyp == TEXTMACRO){
+
+ /* look up the name indirect */
+
+ lbufSav = lbufp;
+ lbufp = symptr->symu.equ.equrec.txtmacro.equtext;
+ getatom();
+
+ lbufp = lbufSav;
+
+ ret = symsrch();
+ }
+ return(ret);
+}
+
+char PASCAL CODESIZE
+symFetNoXref()
+{
+ SHORT ret;
+
+ xcreflag--;
+ ret = symFet();
+ xcreflag++;
+ return(ret);
+}
+
+
+
+/*** createname - create idtext structure for name
+ *
+ * ptr = createname (sym);
+ *
+ * Entry *sym = name to create entry for
+ * Exit none
+ * Returns address of idtext structure
+ * Calls malloc, strcpy
+ */
+
+NAME FAR * PASCAL CODESIZE
+createname (
+ register char *sym
+){
+ register NAME FAR *ptr;
+ register UINT i;
+ register UINT len;
+
+ len = strlen (sym );
+ i = len + sizeof( NAME ) - sizeof( ptr->id );
+ ptr = (NAME FAR *)falloc ((USHORT)i, "createname");
+ ptr->hashval = 0;
+ fMemcpy (ptr->id, sym, len + 1 );
+ return (ptr);
+}
+
+
+#ifdef M8086
+
+/*** creatlname - create idtext structure for name
+ *
+ * ptr = creatlname (sym);
+ *
+ * Entry *sym = name to create entry for
+ * Exit none
+ * Returns address of idtext structure
+ * Calls malloc, strcpy
+ */
+
+NAME * PASCAL CODESIZE
+creatlname (
+ register char *sym
+){
+ NAME *ptr;
+ register UINT i;
+
+ i = naim.ucCount + sizeof( NAME ) - sizeof( ptr->id );
+ ptr = (NAME *)nalloc ( (USHORT)i, "creatlname");
+
+ memcpy (ptr->id, sym, naim.ucCount + 1 );
+ return (ptr);
+}
+#endif
+
+
+/*** symcreate - create new symbol node
+ *
+ * symcreate (symbol, sattr, skind);
+ *
+ * Entry symbol = symbol name
+ * sattr = symbol attribute
+ * skind = symbol kind
+ * Exit symptr = pointer to symbol
+ * symbolcnt incremented
+ * Returns none
+ * Calls createname
+ */
+
+/* Map of Symbol types to additional allocation needed past common header */
+
+UCHAR mpcbSY [] = {
+
+ sizeof (struct symbseg), /* SEGMENT */
+ sizeof (struct symbgrp), /* GROUP */
+ sizeof (struct symbclabel), /* CLABEL */
+ sizeof (struct symbproc), /* PROC */
+ sizeof (struct symbrsm), /* REC */
+ sizeof (struct symbrsm), /* STRUC */
+ sizeof (struct symbequ), /* EQU */
+ sizeof (struct symbext), /* DVAR */
+ sizeof (struct symbext), /* CLASS*/
+ sizeof (struct symbrecf), /* RECFIELD */
+ sizeof (struct symbstrucf), /* STRUCFIELD */
+ sizeof (struct symbrsm), /* MACRO */
+ sizeof (struct symbreg) /* REGISTER */
+};
+
+VOID PASCAL CODESIZE
+symcreate (
+ UCHAR sattr,
+ char skind
+){
+ register USHORT cb;
+ register SYMBOL FARSYM *p;
+ register USHORT cbName, pT;
+ register USHORT cbStruct;
+
+ /* Create new symbol entry */
+
+ cbName = naim.ucCount + sizeof (char) + sizeof (USHORT);
+ cbStruct = (SHORT)(&(((SYMBOL FARSYM *)0)->symu)) + mpcbSY[skind];
+ // Make sure NAME struct starts on double word boundry (required for MIPS)
+ cbStruct = (cbStruct + 3) & ~3;
+ cb = cbStruct + cbName;
+ // Do suballocations on double word boundries, so promote length to a
+ // multiple of 4.
+ cb = (cb + 3) & ~3;
+
+ if (!symaddr || (cb > symfree)) {
+#ifdef FS
+ symaddr = falloc (FS_ALLOC, "symcreate-EXPR");
+#else
+ symaddr = nalloc (FS_ALLOC, "symcreate-EXPR");
+#endif
+ symfree = FS_ALLOC;
+
+#if !defined FLATMODEL
+ /* Uses knowledge of fMemcpy to initialize memory by */
+ /* Repeatedly copying zero to the next word in the buf */
+ *((SHORT FARSYM *)symaddr) = NULL;
+ fMemcpy(((char FAR *)symaddr)+2, symaddr, FS_ALLOC-2);
+#else
+ /* Since in small model memset is available use it */
+ memset( symaddr, 0, FS_ALLOC );
+#endif
+
+ }
+
+ p = (SYMBOL FARSYM *)symaddr;
+ symaddr += cb;
+ symfree -= cb;
+ symbolcnt++;
+
+ /* clear out default values and fill in givens */
+
+ p->attr = sattr;
+ p->symkind = skind;
+
+ if (skind == EQU)
+ p->symu.equ.equtyp = equsel;
+
+ /* Now create record for name of symbol and link in */
+ p->nampnt = (NAME FAR *)((char FAR *)p + cbStruct); // Name follows fixed structures and padding
+ fMemcpy (p->nampnt->id, naim.pszName, (USHORT)(naim.ucCount + 1));
+ p->nampnt->hashval = naim.usHash;
+ cb = naim.usHash % TSYMSIZE;
+
+ p->next = tsym[cb];
+ tsym[cb] = symptr = p;
+}
+
+
+
+/*** muldef - set multidefined bit and output error
+ *
+ * muldef ();
+ *
+ * Entry *symptr = symbol which is multiply defined
+ * Exit MULTDEFINED set in symptr->attr
+ * Returns none
+ * Calls error
+ *
+ * Two bits keep track of multiple definitions:
+ * MULTDEFINED: is remembered between pass one & two
+ * BACKREF: set by defining function, unset by uses that are
+ * forward references. Reset at end of pass 1.
+ *
+ * When a symbol is defined, it should:
+ * - check that BACKREF is off, if not call muldef which
+ * sets MULTIDEFINED, causes an error in pass 1 & 2
+ * This causes error on 2nd and on defines
+ *
+ * - if not BACKREF then check for MULTDEFINED,
+ * error message in pass 2 only.
+ * This in effect prints an error for the first definer only
+ *
+ * - set BACKREF to indicate symbol defined
+ */
+
+
+VOID PASCAL CODESIZE
+muldef ()
+{
+ symptr->attr |= (M_MULTDEFINED);
+ errorc (E_RSY);
+}
+
+
+
+
+/*** labelcreate - create label
+ *
+ * labelcreate (labelsize, labelkind);
+ *
+ * Entry labelsize = size of label
+ * labelkind = kind of label
+ * Exit
+ * Returns
+ * Calls
+ * Note This routine makes symbol table entry and checks for
+ * * Multiple definitions
+ * * Phase error (value different between passes)
+ */
+
+
+VOID PASCAL CODESIZE
+labelcreate (
+ USHORT labelsize,
+ char labelkind
+){
+ char newsym;
+ register SYMBOL FARSYM *p, FARSYM *pCS;
+
+ newsym = TRUE;
+
+ checkRes();
+ xcreflag--;
+
+ if (! ((labelkind == EQU)? symsrch (): symFet())){
+ symcreate (M_DEFINED, labelkind);
+ }
+ else if (M_DEFINED & symptr->attr)
+ newsym = FALSE;
+
+ xcreflag++;
+ p = symptr;
+ equdef = !newsym;
+
+ if (newsym) {
+ p->offset = pcoffset;
+ p->symsegptr = pcsegment;
+ }
+
+ if ((p->attr&~M_CDECL) == M_GLOBAL) /* forward referenced global */
+
+ if (1 << labelkind & (M_PROC | M_DVAR | M_CLABEL | M_EQU)){
+ p->symkind = labelkind;
+
+ if (labelkind == EQU)
+ p->symu.equ.equtyp = equsel;
+ }
+ else
+ errorn (E_SDK);
+
+ p->attr |= M_DEFINED;
+ p->symtype = labelsize;
+ p->length = 1;
+
+ /* Check to see if there would be any error in label */
+
+ if ((p->symkind != labelkind) || (M_XTERN & p->attr))
+ errorn (E_SDK);
+
+ else if ((M_BACKREF & p->attr) && (p->symkind != EQU))
+ muldef ();
+
+ else if (M_MULTDEFINED & p->attr)
+ errorn (E_SMD);
+
+ else if (M_DEFINED & p->attr)
+ if (!(1 << labelkind & (M_EQU | M_STRUCFIELD)) &&
+ (p->offset != pcoffset)) {
+ errorc (E_PHE);
+ if (errorcode == E_PHE)
+ pcoffset = p->offset;
+ }
+ else {
+ p->attr |= M_DEFINED | M_BACKREF;
+ if ((labelkind != EQU) && emittext)
+ pcdisplay ();
+ }
+
+ if ((labelkind == p->symkind) &&
+ !((1 << labelkind) & (M_EQU | M_STRUCFIELD))) {
+
+ if (isCodeLabel(p)) {
+
+ pCS = regsegment[CSSEG];
+
+#ifndef FEATURE
+ /* ASSUME CS:FLAT gets assume of current segment */
+
+ if (pCS == pFlatGroup)
+ pCS = pcsegment;
+#endif
+ }
+ else
+ pCS = regsegment[DSSEG];
+
+ /* CS context for label */
+ if (!newsym && pCS != p->symu.clabel.csassume)
+ errorc(E_SPC);
+
+ p->symu.clabel.csassume = pCS;
+
+ if (labelsize == CSNEAR)
+
+ /* This is code label */
+ if (!pCS)
+ /* No CS assume, can't define */
+ errorc (E_NCS);
+ else
+ if ((pcsegment != pCS) &&
+ ((pCS->symkind != GROUP) ||
+ (pcsegment->symu.segmnt.grouptr != pCS)))
+
+ /* Not same segment or CS not seg's grp */
+ errorc (E_NCS);
+ }
+ crefdef ();
+}
+
+
+
+
+/*** switchname - switch atom and length between svname and name
+ *
+ * switchname ();
+ *
+ * Entry none
+ * Exit svname and name switched
+ * naim.usHash and svname.usHash switched
+ * svlcname and lcname switched
+ * Returns none
+ * Calls none
+ */
+
+#ifndef M8086OPT
+VOID CODESIZE
+switchname ()
+{
+ FASTNAME tmpName;
+
+ register char *pNameTmp;
+
+ /* Swap naim and svname (str ptrs, hash values and lengths) */
+ memcpy( &tmpName, &naim, sizeof( FASTNAME ) );
+ memcpy( &naim, &svname, sizeof( FASTNAME ) );
+ memcpy( &svname, &tmpName, sizeof( FASTNAME ) );
+}
+#endif
+
+#if !defined FLATMODEL
+# pragma alloc_text (FA_TEXT, scansymbols)
+#endif
+
+/*** scansymbols - scan symbol in alpha order and execute function
+ *
+ * scansymbols (item);
+ *
+ * Entry item = pointer to function to execute
+ * Exit
+ * Returns
+ * Calls
+ */
+
+VOID PASCAL
+scansymbols (
+ SHORT (PASCAL *item) (SYMBOL FARSYM *)
+){
+ register USHORT i;
+
+ for (i = 0; i < TSYMSIZE; i++)
+ scanorder (tsym[i], item);
+}
+
+
+#if !defined FLATMODEL
+# pragma alloc_text (FA_TEXT, sortalpha)
+#endif
+
+/*** sortalpha - sort symbol into alpha ordered list
+ *
+ * sortalpha (p);
+ *
+ * Entry *p = symbol entry
+ * Exit symbol sorted into proper alpha list
+ * Returns none
+ * Calls none
+ */
+
+
+VOID PASCAL
+sortalpha (
+ register SYMBOL FARSYM *p
+){
+ register SYMBOL FARSYM *tseg;
+ register SYMBOL FARSYM * FARSYM *lseg;
+ char i;
+ char c;
+
+ if (p->symkind == MACRO) {
+ tseg = macroroot;
+ lseg = &macroroot;
+ }
+ else if ((p->symkind == STRUC) || (p->symkind == REC)) {
+ tseg = strucroot;
+ lseg = &strucroot;
+ }
+ else {
+ c = MAP (*(p->nampnt->id));
+ i = (isalpha (c))? c - 'A': 'Z' - 'A' + 1;
+ tseg = symroot[i];
+ lseg = &symroot[i];
+ }
+
+
+ /* Add symbol to list */
+ for (; tseg; lseg = &(tseg->alpha), tseg = tseg->alpha) {
+ if (STRFFCMP (p->nampnt->id, tseg->nampnt->id) < 0)
+ break;
+ }
+
+ *lseg = p;
+ p->alpha = tseg;
+}
+
+
+/*** typeFet - Fetch the type of the symbol
+ *
+ * Entry symtype - the size of the symbol
+ * Exit prefined symbol type
+ */
+
+UCHAR mpSizeType[] = {
+
+ 0,
+ makeType(BT_UNSIGNED, BT_DIRECT, BT_sz1), /* db */
+ makeType(BT_UNSIGNED, BT_DIRECT, BT_sz2), /* dw */
+ 0,
+ makeType(BT_UNSIGNED, BT_DIRECT, BT_sz4), /* dd */
+ 0,
+ makeType(BT_UNSIGNED, BT_FARP, BT_sz4), /* df */
+ 0,
+ makeType(BT_UNSIGNED, BT_DIRECT, BT_sz2), /* dq */
+ 0,
+ makeType(BT_UNSIGNED, BT_DIRECT, BT_sz4) /* dt */
+};
+
+UCHAR mpRealType[] = {
+
+ 0, 0, 0, 0,
+ makeType(BT_REAL, BT_DIRECT, BT_sz1), /* dd */
+ 0, 0, 0,
+ makeType(BT_REAL, BT_DIRECT, BT_sz2), /* dq */
+ 0,
+ makeType(BT_REAL, BT_DIRECT, BT_sz4) /* dt */
+};
+
+SHORT PASCAL CODESIZE
+typeFet (
+ USHORT symtype
+){
+ if (symtype <= 10)
+
+ return(mpSizeType[symtype]);
+
+ else if (symtype == CSNEAR)
+ return(512);
+
+ else if (symtype == CSFAR)
+ return(513);
+
+ else
+ return(0);
+}
+
+
+char symDefine[] = "$$SYMBOLS segment 'DEBSYM'";
+char typeDefine[] = "$$TYPES segment 'DEBTYP'";
+char fProcs;
+
+/*** dumpCodeview - dump out codeview symbolic info to the obj file
+ *
+ * Entry end of pass one and two
+ * Exit pass one just computes the segment sizes
+ * and pass two writes the symbols
+ */
+
+
+static SYMBOL FAR *plastSeg; // indicates segIndex of last ChangeSegment
+
+VOID PASCAL
+dumpCodeview ()
+{
+ char svlistflag;
+ char svloption;
+
+ if (codeview != CVSYMBOLS || !emittext)
+ return;
+
+ plastSeg = NULL;
+ svlistflag = listflag;
+ svloption = loption;
+ listflag = FALSE;
+ loption = FALSE;
+ fProcs = FALSE;
+
+ wordszdefault = 2; /* this will vary when CV can do 32 bit segments */
+
+ doLine(symDefine);
+ pcsegment->attr |= M_NOCREF; pcsegment->symu.segmnt.classptr->attr |= M_NOCREF;
+
+ scansymbols(dmpSymbols);
+
+ fProcs++;
+ scanSorted(pProcFirst, dmpSymbols);
+ endCurSeg();
+
+ doLine(typeDefine);
+ pcsegment->attr |= M_NOCREF; pcsegment->symu.segmnt.classptr->attr |= M_NOCREF;
+
+ /* First output two types, one for near & far code labels
+ * Format
+ * [1][cb][0x72][0x80][0x74|0x73 (near/far)] */
+
+ if (pass2) {
+
+ putWord(3 << 8 | 1);
+ putWord(0x72 << 8);
+ putWord(0x74 << 8 | 0x80);
+
+ putWord(3 << 8 | 1);
+ putWord(0x72 << 8);
+ putWord(0x73 << 8 | 0x80);
+ }
+ else
+ pcoffset = 12;
+
+ scanSorted(pStrucFirst, dumpTypes);
+
+ endCurSeg();
+
+ listflag = svlistflag;
+ loption = svloption;
+}
+
+
+
+/*** dmpSymbols - create the codeview symbol segment
+ *
+ * Entry
+ * Exit
+ */
+
+
+static fInProc;
+
+VOID PASCAL
+dmpSymbols(
+ SYMBOL FARSYM *pSY
+){
+ SHORT cbName, cbRecord;
+ char fProcParms;
+ UCHAR f386; // will be 0 or 0x80 for OR'ing into rectype
+
+ fProcParms = 0xB;
+
+ if (pSY->symkind == PROC) {
+ if ( pSY->symu.plabel.pArgs){
+
+ if (!fProcs)
+ return;
+
+ fProcParms = 1;
+ }
+ else if (pSY->attr & (M_GLOBAL | M_XTERN))
+ return;
+ }
+ else if (pSY->symkind == CLABEL) {
+
+ if (!fInProc && (pSY->symu.clabel.iProc ||
+ pSY->attr & (M_GLOBAL | M_XTERN)))
+
+ return;
+
+ }
+ else
+ return;
+
+ f386 = (pSY->symsegptr->symu.segmnt.use32 == 4? 0x80 : 0);
+
+ cbName = STRFLEN(pSY->nampnt->id) + 1 + (pSY->attr & M_CDECL);
+ cbRecord = cbName + (f386? 4: 2) +
+ ((isCodeLabel(pSY))?
+ ((fProcParms == 1)? CB_PROCLABEL: CB_CODELABEL):
+ CB_DATALABEL);
+
+ if (isCodeLabel(pSY)
+ && (plastSeg != pSY->symsegptr)) {
+
+ plastSeg = pSY->symsegptr;
+
+ putWord(0x11 << 8 | 5);
+
+ descT.dsckind.opnd.doffset = 0;
+ descT.dsckind.opnd.dtype = FORTYPE;
+ descT.dsckind.opnd.dsegment = pSY->symsegptr;
+ descT.dsckind.opnd.dsize = 2;
+ descT.dsckind.opnd.fixtype = FBASESEG;
+ descT.dsckind.opnd.dcontext = pSY->symsegptr;
+ putFixup();
+
+ putWord(0); // 2 bytes reserved
+ }
+
+ descT.dsckind.opnd.doffset = pSY->offset;
+ descT.dsckind.opnd.dtype = FORTYPE;
+ descT.dsckind.opnd.dsegment = pSY->symsegptr;
+ descT.dsckind.opnd.dsize = f386? 4: 2;
+
+ emitopcode((UCHAR)cbRecord);
+
+ if (isCodeLabel(pSY)) {
+
+ /* do the actual outputting for code labels
+ * FORMAT:
+ *
+ * [cb][0xB][offset][0/4][name]
+ *
+ * For Proc labels with parms
+ *
+ * [cb][0x1][offset][typeIndex][cbProc][startRelOff][endRelOff]
+ * [0][0/4][name]
+ */
+
+ emitopcode((UCHAR)(fProcParms | f386)); /* contains 0xb or 1 */
+
+ /* reserve two bytes and then a fixup to get
+ * the code labe offset */
+
+ descT.dsckind.opnd.fixtype = f386? F32OFFSET: FOFFSET;
+ descT.dsckind.opnd.dcontext = pSY->symu.clabel.csassume;
+
+ putFixup();
+
+ if (fProcParms == 1) {
+ /* type index */
+ putWord(0);
+ putWord(pSY->symu.plabel.proclen);
+
+ /* starting & ending offset of proc */
+
+ putWord(0);
+ putWord(pSY->symu.plabel.proclen);
+
+ putWord(0); /* reservered to 0 */
+
+ }
+ emitopcode((UCHAR)((pSY->symtype == CSNEAR)? 0: 4));
+
+ }
+ else {
+
+ /* do the actual outputting for data labels
+ * FORMAT:
+ * [cb][0x5][offset:seg][typeIndex][name] */
+
+ emitopcode((UCHAR)(0x5|f386));
+
+ /* reserve four bytes and then a fixup to get
+ * the data far address */
+
+ descT.dsckind.opnd.fixtype = f386? F32POINTER: FPOINTER;
+ descT.dsckind.opnd.dsize += 2;
+ descT.dsckind.opnd.dcontext = NULL;
+
+ putFixup();
+
+ putWord(pSY->symu.clabel.type);
+ }
+
+ putSymbol(pSY);
+
+ if (fProcParms == 1) {
+
+ /* Go through the chain of text macro parmeters and output
+ * the BP relative local symbols.
+ *
+ * Format:
+ * [cb][4][offset][typeIndex][name]
+ * ...
+ * [1][2] - end block
+ */
+
+ for (pSY = pSY->symu.plabel.pArgs; pSY; pSY = pSY->alpha){
+
+ if (pSY->symkind == CLABEL) {
+
+ /* a locally nest label in a procedure */
+
+ fInProc++;
+ dmpSymbols(pSY);
+ fInProc--;
+ }
+ else {
+
+ cbName = STRFLEN(pSY->nampnt->id) + 1;
+
+ emitopcode((UCHAR)((f386? 7:5) + cbName)); /* cbRecord */
+ emitopcode((UCHAR)(4 | f386)); /* recType */
+
+ if (f386) {
+ putWord((USHORT) pSY->offset);
+ putWord(*((USHORT FAR *)&(pSY->offset)+1));
+ } else
+ putWord((USHORT) pSY->offset);
+
+ putWord(pSY->symu.equ.equrec.txtmacro.type);
+ putSymbol(pSY);
+ }
+ }
+
+ putWord(2 << 8 | 1); /* end block record */
+ }
+}
+
+
+/*** dumpTypes - creats a type definition in the codeview type segment
+ *
+ * Entry Symbol table pointer to structure or record
+ * Exit
+ */
+
+VOID PASCAL
+dumpTypes(
+ SYMBOL FARSYM *pSY
+){
+ SHORT cType, cbType, cbNlist, cbName;
+ SYMBOL FARSYM *pSYField;
+
+ /* Scan through the struct field to compute tlist size */
+
+ pSYField = pSY->symu.rsmsym.rsmtype.rsmstruc.struclist;
+ cbNlist = 1;
+ cType = 0;
+
+ if (pSY->symkind == STRUC) {
+
+ while (pSYField) {
+
+ cbNlist += STRFLEN(pSYField->nampnt->id) + 2 +
+ cbNumericLeaf(pSYField->offset);
+ pSYField = pSYField->symu.struk.strucnxt;
+ cType++;
+ }
+
+ cbName = STRFLEN(pSY->nampnt->id);
+
+ cbType = 10 +
+ cbNumericLeaf(((long) pSY->symtype) * 8) +
+ cbNumericLeaf((long) cType) +
+ cbName;
+
+ }
+ else
+ cbType = -3;
+
+ /* A type has the following format
+ *
+ * [1][cbType][0x79][cbTypeInBits][cFields][tListIndex][nListIndex]
+ * [0x82][structureName][0x68]
+ *
+ * tList
+ * nList
+ */
+
+ if (pass2) {
+
+ emitopcode(1);
+
+ if (pSY->symkind == STRUC) {
+
+ putWord(cbType);
+ emitopcode(0x79);
+
+ putNumericLeaf(((long) pSY->symtype) * 8);
+ putNumericLeaf((long) pSY->symu.rsmsym.rsmtype.rsmstruc.strucfldnum);
+
+ emitopcode(0x83); /* tList Index */
+ putWord((USHORT)(pSY->symu.rsmsym.rsmtype.rsmstruc.type+1));
+
+ emitopcode(0x83); /* nList Index */
+ putWord((USHORT)(pSY->symu.rsmsym.rsmtype.rsmstruc.type+2));
+
+ emitopcode(0x82);
+ putSymbol(pSY);
+
+ emitopcode(0x68); /* packed structure */
+
+ /* next comes the tList (type index array), it has the following format
+ *
+ * [1][cb][0x7f] ([0x83][basicTypeIndex])..repeated..
+ */
+
+ emitopcode(1);
+ putWord((USHORT)(cType * (USHORT)3 + (USHORT)1));
+ emitopcode(0x7f);
+
+ pSYField = pSY->symu.rsmsym.rsmtype.rsmstruc.struclist;
+
+ while(pSYField){
+
+ emitopcode(0x83);
+ putWord(pSYField->symu.struk.type);
+
+ pSYField = pSYField->symu.struk.strucnxt;
+ }
+
+ /* next comes the nList (field names), it has the following format
+ *
+ * [1][cb][0x7f] ([0x82][cbName][fieldName][offset])..repeated..
+ */
+
+ emitopcode(1);
+ putWord(cbNlist);
+ emitopcode(0x7f);
+
+ pSYField = pSY->symu.rsmsym.rsmtype.rsmstruc.struclist;
+
+ while(pSYField){
+
+ emitopcode(0x82);
+
+ putSymbol(pSYField);
+ putNumericLeaf(pSYField->offset);
+
+ pSYField = pSYField->symu.struk.strucnxt;
+ }
+ }
+ else {
+
+ /* a pointer to type has the following format
+ *
+ * [1][5][0x7f] [near/far][0x83][typeIndex]
+ */
+
+ putWord(5);
+ emitopcode(0x7A);
+ emitopcode((UCHAR)((pSY->attr)? 0x73: 0x74));
+
+ emitopcode(0x83);
+ putWord(pSY->symtype);
+ }
+ }
+ else
+ pcoffset += cbType +
+ cType * 3 +
+ cbNlist + 10;
+
+}
+
+/*** cbNumericLeaf - compute the size for a numeric leaf
+ *
+ * Entry long value to output
+ * Exit size of leaf
+ */
+
+SHORT PASCAL CODESIZE
+cbNumericLeaf(
+ long aLong
+){
+ if (aLong & 0xFFFF0000)
+ return(5);
+
+ else if (aLong & 0xFF80)
+ return(3);
+
+ else
+ return(1);
+}
+
+
+/*** putNumericLeaf - output variable size numeric codeview leaf
+ *
+ * Entry long value to output
+ * Exit numeric leaf on OMF
+ */
+
+VOID PASCAL CODESIZE
+putNumericLeaf(
+ long aLong
+){
+ if (aLong & 0xFFFF0000){
+
+ emitopcode(0x86);
+ putWord((USHORT)aLong);
+ putWord(*((USHORT *)&aLong+1));
+ }
+ else if (aLong & 0xFF80){
+
+ emitopcode(0x85);
+ putWord((USHORT)aLong);
+ }
+
+ else
+ emitopcode((UCHAR)aLong);
+}
+
+
+
+/*** doLine - feed a text line to parse for processing
+ *
+ * Entry pointer to text string
+ * Exit processed line
+ */
+
+VOID PASCAL CODESIZE
+doLine(
+ char *pText
+){
+
+ USHORT cvSave;
+
+ fCrefline = FALSE;
+
+#ifdef BCBOPT
+ if (fNotStored)
+ storelinepb ();
+#endif
+
+ if (fNeedList) {
+
+ listline(); /* list out current line */
+
+ strcpy(linebuffer, pText);
+ fSkipList++;
+ }
+
+ lbufp = strcpy(lbuf, pText);
+ linebp = lbufp + strlen(lbufp);
+ cvSave = codeview;
+ codeview = 0;
+
+ if (loption || expandflag == LIST)
+ fSkipList = FALSE;
+
+ parse();
+
+ codeview = cvSave;
+ fSkipList++;
+ fCrefline++;
+}
+
+/*** putWord - output a 2 byte word to the current segment
+ *
+ * Entry word to output
+ * Exit increment pcoffset
+ */
+
+VOID PASCAL CODESIZE
+putWord(
+ USHORT aWord
+){
+ if (pass2)
+ emitcword((OFFSET) aWord);
+
+ pcoffset += 2;
+}
+
+
+/*** putSymbol - put out the name of a symbol
+ *
+ * Entry word to output
+ * Exit increment pcoffset
+ */
+
+VOID PASCAL CODESIZE
+putSymbol(
+ SYMBOL FARSYM *pSY
+){
+ SHORT cbName;
+
+ cbName = STRFLEN(pSY->nampnt->id) + 1 + (pSY->attr & M_CDECL);
+
+ if (pass2){
+
+ if (emitcleanq ((UCHAR)cbName))
+ emitdumpdata ((UCHAR)LedataOp);
+
+ emitSymbol(pSY);
+ }
+
+ pcoffset += cbName;
+ ecuroffset = pcoffset;
+}
+
+/*** putFixup - put out a fixup
+ *
+ * Entry golbal descT
+ * Exit increment pcoffset
+ */
+
+VOID PASCAL CODESIZE
+putFixup()
+{
+extern UCHAR fNoMap;
+
+ fNoMap++;
+
+ if (pass2)
+ emitobject(&descT.dsckind.opnd);
+
+ fNoMap--;
+ pcoffset += descT.dsckind.opnd.dsize;
+}