diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/sdktools/masm/asmsym.c | |
download | NT4.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.c | 1241 |
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 = ¯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; +} |