/* 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 #include "asm86.h" #include "asmfcn.h" #include "asmctype.h" #include "asmtab.h" #include "dos.h" #include #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 = ¯oroot; } 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; }