Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1575 lines
42 KiB

/*** symbols6.c
*
* engine routines for C6 symbols. to convert C6 symbols to C7 (CV4) symbols
*
*/
#include "compact.h"
LOCAL void FixupPublics (uchar *, ushort);
LOCAL uchar *RemoveComDat (uchar *Symbols);
LOCAL void RewritePublics (uchar *, DirEntry *, PMOD);
LOCAL void RewriteSrcLnSeg (uchar *, DirEntry *, uchar *, PMOD);
LOCAL void RewriteSymbols (uchar *, DirEntry *, char *, PMOD);
// Called through Fixup function table
LOCAL void C6SizeBlockSym16 (void);
LOCAL void C6SizeBlockSym32 (void);
LOCAL void C6SizeEndSym (void);
LOCAL void C6SizeLabSym16 (void);
LOCAL void C6SizeLabSym32 (void);
LOCAL void C6SizeChgDfltSegSym (void);
LOCAL void C6SizeSkipSym (void);
LOCAL void C6SizeBPRelSym16 (void);
LOCAL void C6SizeBPRelSym32 (void);
LOCAL void C6SizeRegSym (void);
LOCAL void C6SizeConstantSym (void);
LOCAL void C6SizeLocalSym16 (void);
LOCAL void C6SizeLocalSym32 (void);
LOCAL void C6SizeProcSym16 (void);
LOCAL void C6SizeProcSym32 (void);
// Called through Rewrite function table
LOCAL void C6RwrtRegSym (void);
LOCAL void C6RwrtDataSym16 (void);
LOCAL void C6RwrtDataSym32 (void);
LOCAL void C6RwrtBPRelSym16 (void);
LOCAL void C6RwrtBPRelSym32 (void);
LOCAL void C6RwrtBlockSym16 (void);
LOCAL void C6RwrtBlockSym32 (void);
LOCAL void C6RwrtLabSym16 (void);
LOCAL void C6RwrtLabSym32 (void);
LOCAL void C6RwrtChgDfltSeg (void);
LOCAL void C6RwrtProcSym16 (void);
LOCAL void C6RwrtProcSym32 (void);
LOCAL void C6RwrtConstantSym (void);
LOCAL void C6RwrtGenericSym (void);
LOCAL void C6RwrtSkipSym (void);
#ifndef WIN32
#pragma alloc_text (TEXT2, C6RwrtRegSym)
#pragma alloc_text (TEXT2, C6RwrtDataSym16)
#pragma alloc_text (TEXT2, C6RwrtDataSym32)
#pragma alloc_text (TEXT2, C6RwrtBPRelSym16)
#pragma alloc_text (TEXT2, C6RwrtBPRelSym32)
#pragma alloc_text (TEXT2, C6RwrtBlockSym16)
#pragma alloc_text (TEXT2, C6RwrtBlockSym32)
#pragma alloc_text (TEXT2, C6RwrtLabSym16)
#pragma alloc_text (TEXT2, C6RwrtLabSym32)
#pragma alloc_text (TEXT2, C6RwrtChgDfltSeg)
#pragma alloc_text (TEXT2, C6RwrtProcSym16)
#pragma alloc_text (TEXT2, C6RwrtProcSym32)
#pragma alloc_text (TEXT2, C6RwrtConstantSym)
#pragma alloc_text (TEXT2, C6RwrtGenericSym)
#pragma alloc_text (TEXT2, C6RwrtSkipSym)
#endif
LOCAL ushort C6CnvrtRegSym (uchar *, uchar *);
LOCAL ushort C6CnvrtDataSym16 (uchar *, uchar *);
LOCAL ushort C6CnvrtDataSym32 (uchar *, uchar *);
LOCAL ushort C6CnvrtBPRelSym16 (uchar *, uchar *);
LOCAL ushort C6CnvrtBPRelSym32 (uchar *, uchar *);
#ifndef WIN32
#pragma alloc_text (TEXT2, C6CnvrtRegSym)
#pragma alloc_text (TEXT2, C6CnvrtDataSym16)
#pragma alloc_text (TEXT2, C6CnvrtDataSym32)
#pragma alloc_text (TEXT2, C6CnvrtBPRelSym16)
#pragma alloc_text (TEXT2, C6CnvrtBPRelSym32)
#endif
LOCAL void C6RewriteSymbolStrings (uchar * End);
LOCAL short SizeChgNumeric (uchar *);
extern ushort recursive;
extern ushort AddNewSymbols;
extern uchar Signature[];
extern ulong cPublics;
extern uchar ptr32;
extern uchar *SymbolSegment;
extern ushort SymbolSizeAdd;
extern ushort SymbolSizeSub;
extern ushort UDTAdd;
extern uchar **ExtraSymbolLink;
extern uchar *ExtraSymbols;
extern ulong InitialSymInfoSize;
extern ulong FinalSymInfoSize;
extern char *ModAddr;
extern ulong ulCVTypeSignature; // The signature from the modules type segment
// These are shared by the fixup functions
LOCAL uchar *pOldSym; // Old (C6) symbol to fixup, and calc size for
LOCAL int iLevel;
// These are shared by the rewrite functions
LOCAL uchar *NewSymbols; // Where to write next byte of new symbol
LOCAL uchar *StartSymbols; // Where to write next byte of new symbol
LOCAL uchar *OldSymbols; // Where to get next byte of old symbol
LOCAL ushort segment;
typedef struct {
uchar oldsym; // Old C6 Symbol record type
ushort new16sym; // New C7 type (16 bit)
void (*pfcn16) (void);
ushort new32sym; // New C7 type (32 bit)
void (*pfcn32) (void);
} rewritesymfcn;
rewritesymfcn C6RwrtSymFcn[] = {
{OSYMBLOCKSTART,
S_BLOCK16, C6RwrtBlockSym16,
S_BLOCK32, C6RwrtBlockSym32},
{OSYMPROCSTART,
S_LPROC16, C6RwrtProcSym16,
S_LPROC32, C6RwrtProcSym32},
{OSYMEND,
S_END, C6RwrtGenericSym,
S_END, C6RwrtGenericSym},
{OSYMBPREL,
S_BPREL16, C6RwrtBPRelSym16,
S_BPREL32, C6RwrtBPRelSym32},
{OSYMLOCAL,
S_LDATA16, C6RwrtDataSym16,
S_LDATA32, C6RwrtDataSym32},
{OSYMLABEL,
S_LABEL16, C6RwrtLabSym16,
S_LABEL32, C6RwrtLabSym32},
{OSYMWITH,
S_WITH16, C6RwrtBlockSym16, // Structure matches Block Start
S_WITH32, C6RwrtBlockSym32}, // Structure matches Block Start
{OSYMREG,
S_REGISTER, C6RwrtRegSym,
S_REGISTER, C6RwrtRegSym},
{OSYMCONST,
S_CONSTANT, C6RwrtConstantSym,
S_CONSTANT, C6RwrtConstantSym},
//M00 Kludge - Fortran Entry may not map this easy.
{OSYMFORENTRY,
S_LPROC16, C6RwrtProcSym16,
S_LPROC32, C6RwrtProcSym32},
{OSYMNOOP,
0, C6RwrtSkipSym,
0, C6RwrtSkipSym},
{OSYMCHGDFLTSEG,
0, C6RwrtChgDfltSeg,
0, C6RwrtChgDfltSeg},
};
#define C6REWRITESYMCNT (sizeof C6RwrtSymFcn / sizeof (C6RwrtSymFcn[0]))
// This table is used to convert based pointer symbols. The only symbol
// types that can be used as bases are BP relative symbols, data symbols and
// register symbols.
typedef struct {
uchar oldsym; // Old C6 Symbol record type
ushort new16sym; // New C7 type (16 bit)
ushort (*pfcn16) (uchar *, uchar *);
ushort new32sym; // New C7 type (32 bit)
ushort (*pfcn32) (uchar *, uchar *);
} cnvrtsymfcn;
cnvrtsymfcn C6CnvrtSymFcn[] = {
{OSYMBPREL,
S_BPREL16, C6CnvrtBPRelSym16,
S_BPREL32, C6CnvrtBPRelSym32},
{OSYMLOCAL,
S_LDATA16, C6CnvrtDataSym16,
S_LDATA32, C6CnvrtDataSym32},
{OSYMREG,
S_REGISTER, C6CnvrtRegSym,
S_REGISTER, C6CnvrtRegSym},
};
#define C6CNVRTSYMCNT (sizeof C6CnvrtSymFcn / sizeof (C6CnvrtSymFcn[0]))
typedef struct {
uchar oldsym; // Old C6 Symbol record type
void (*pfcn16) (void);
void (*pfcn32) (void);
} fixupsymfcn;
fixupsymfcn C6SizeSymFcn[] = {
{OSYMBLOCKSTART, C6SizeBlockSym16,
C6SizeBlockSym32},
{OSYMPROCSTART, C6SizeProcSym16,
C6SizeProcSym32},
{OSYMEND, C6SizeEndSym,
C6SizeEndSym},
{OSYMBPREL, C6SizeBPRelSym16,
C6SizeBPRelSym32},
{OSYMLOCAL, C6SizeLocalSym16,
C6SizeLocalSym32},
{OSYMLABEL, C6SizeLabSym16,
C6SizeLabSym32},
{OSYMWITH, C6SizeBlockSym16, // Structure matches Block Start
C6SizeBlockSym32}, // Structure matches Block Start
{OSYMREG, C6SizeRegSym,
C6SizeRegSym},
{OSYMCONST, C6SizeConstantSym,
C6SizeConstantSym},
//M00 Kludge - Fortran Entry may not map this easy.
{OSYMFORENTRY, C6SizeProcSym16,
C6SizeProcSym32},
{OSYMNOOP, C6SizeSkipSym,
C6SizeSkipSym},
{OSYMCHGDFLTSEG, C6SizeChgDfltSegSym,
C6SizeChgDfltSegSym},
};
#define C6SIZESYMCNT (sizeof C6SizeSymFcn / sizeof (C6SizeSymFcn[0]))
ushort RegMap[36] = {
CV_REG_AL, // 0
CV_REG_CL, // 1
CV_REG_DL, // 2
CV_REG_BL, // 3
CV_REG_AH, // 4
CV_REG_CH, // 5
CV_REG_DH, // 6
CV_REG_BH, // 7
CV_REG_AX, // 8
CV_REG_CX, // 9
CV_REG_DX, // 10
CV_REG_BX, // 11
CV_REG_SP, // 12
CV_REG_BP, // 13
CV_REG_SI, // 14
CV_REG_DI, // 15
CV_REG_EAX, // 16
CV_REG_ECX, // 17
CV_REG_EDX, // 18
CV_REG_EBX, // 19
CV_REG_ESP, // 20
CV_REG_EBP, // 21
CV_REG_ESI, // 22
CV_REG_EDI, // 23
CV_REG_ES, // 24
CV_REG_CS, // 25
CV_REG_SS, // 26
CV_REG_DS, // 27
CV_REG_FS, // 28
CV_REG_GS, // 29
CV_REG_ST0, // 30
CV_REG_NONE, // 31
((CV_REG_DX<<8) | CV_REG_AX),// 32
((CV_REG_ES<<8) | CV_REG_BX),// 33
CV_REG_IP, // 34
CV_REG_FLAGS // 35
};
/**
*
* C6 CalcNewSizeOfSymbols
*
* Go through the symbols segment calculating the maximum size increase
* from the old C6 symbol segment to the new C7 symbol segment. This
* calculation is the maximum. Many symbols will fit into less space
* and the actual symbol size will be smaller.
*/
//M00 Document comunication with called functions
void C6CalcNewSizeOfSymbols (uchar *Symbols, ulong SymbolCount)
{
uchar * End;
uchar type;
uchar fFlat32;
fixupsymfcn *pFixFcn;
int i;
cSeg = 0;
pOldSym = Symbols;
End = pOldSym + SymbolCount;
while (pOldSym < End)
{
type = *(pOldSym + 1);
if (type & 0x80) {
fFlat32 = TRUE;
}
else {
fFlat32 = FALSE;
}
type &= 0x7f;
for (pFixFcn = C6SizeSymFcn, i = 0; i < C6SIZESYMCNT; i++, pFixFcn++) {
if (pFixFcn->oldsym == type) {
break; // Ok, found the entry
}
}
DASSERT (i != C6SIZESYMCNT); // Make sure type was in the table
if (i == C6SIZESYMCNT) {
ErrorExit (ERR_SYMBOL, FormatMod (pCurMod), NULL);
}
if (fFlat32) {
pFixFcn->pfcn32 (); // Rewrite the symbol
}
else {
pFixFcn->pfcn16 (); // Rewrite the symbol
}
pOldSym += *pOldSym + 1; // to next record
DASSERT (!recursive);
DASSERT (iLevel >= 0);
}
InitialSymInfoSize += SymbolCount;
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
#define FIXEDADD 2 // one for length, one for type
// Also used for OSYMWITH
LOCAL void C6SizeBlockSym16 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (BLOCKSYM16) - 1) - (2 + 4);
iLevel++;
}
// Also used for OSYMWITH
LOCAL void C6SizeBlockSym32 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (BLOCKSYM32) - 1) - (2 + 6);
iLevel++;
}
LOCAL void C6SizeEndSym (void)
{
SymbolSizeAdd += FIXEDADD; // New sym 4 bytes, no pad necessary
iLevel--;
}
// Also used for OSYMCHGEXECMODEL
LOCAL void C6SizeLabSym16 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (LABELSYM16) - 1) - (2 + 3);
}
// Also used for OSYMCHGEXECMODEL
LOCAL void C6SizeLabSym32 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (LABELSYM32) - 1) - (2 + 5);
}
LOCAL void C6SizeChgDfltSegSym (void)
{
// rewrite to start search if necessary
if (!SegmentPresent (*(ushort *)(pOldSym + 2))) {
SymbolSizeAdd += MAXPAD + sizeof(SEARCHSYM) - (2 + 4);
segnum[cSeg++] = *(ushort *)(pOldSym + 2);
if (cSeg > MAXCDF) {
ErrorExit (ERR_TOOMANYSEG, FormatMod (pCurMod), NULL);
}
}
else {
SymbolSizeSub += (2 + 4); // The record will be removed
}
}
LOCAL void C6SizeSkipSym (void)
{
// The skip field will be deleted. No need to allocate space for it.
SymbolSizeSub += *pOldSym + 1;
}
LOCAL void C6SizeBPRelSym16 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (BPRELSYM16) - 1) - (2 + 4);
}
LOCAL void C6SizeBPRelSym32 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (BPRELSYM32) - 1) - (2 + 6);
}
LOCAL void C6SizeRegSym (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (REGSYM) - 1) - (2 + 3);
}
LOCAL void C6SizeConstantSym (void)
{
// Add one extra because the numeric leaf may grow a byte;
SymbolSizeAdd += MAXPAD + (sizeof (CONSTSYM) - 2) - (2 + 2) + 1;
}
LOCAL void C6SizeLocalSym16 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (DATASYM16) - 1) - (2 + 6);
}
LOCAL void C6SizeLocalSym32 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (DATASYM32) - 1) - (2 + 8);
}
LOCAL void C6SizeProcSym16 (void)
{
iLevel++;
SymbolSizeAdd += MAXPAD + (sizeof (PROCSYM16) - 1) - (2 + 13);
}
LOCAL void C6SizeProcSym32 (void)
{
iLevel++;
SymbolSizeAdd += MAXPAD + (sizeof (PROCSYM32) - 1) - (2 + 15);
}
/**
*
* FixupPublicsC6
*
* Fixup type indices in the publics segment similar to symbols segment.
* Not called through Fixup function tables.
*
*/
void FixupPublicsC6 (uchar *Publics, ulong PublicCount)
{
register uchar *End;
register uchar Offset = 4;
if (fLinearExe) {
Offset += 2; // another 2 bytes
}
End = Publics + PublicCount;
while (Publics < End) {
switch (ulCVTypeSignature){
case CV_SIGNATURE_C6:
if (delete == TRUE) {
*(ushort *) (Publics + Offset) = T_NOTYPE;
}
else {
*(ushort *) (Publics + Offset) =
C6GetCompactedIndex(*(ushort *) (Publics + Offset));
}
break;
case CV_SIGNATURE_C7:
if (delete == TRUE) {
*(ushort *) (Publics + Offset) = T_NOTYPE;
}
else {
*(ushort *) (Publics + Offset) =
C7GetCompactedIndex(*(ushort *) (Publics + Offset));
}
break;
default:
*(ushort *) (Publics + Offset) = 0;
}
Publics += Offset + 2; // skip over index
Publics += *Publics + 1; // skip over name
DASSERT (!recursive);
}
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/** RewriteSymbols - reformat symbols to new format and store in VM
*
* RewriteSymbols (addr, pDir, psstMod);
*
* Entry addr = address of publics table
* pDir = address of directory entry
* psstMod = pointer to the module table entry
* pMod = module table entry
*
* Exit pDir->lfo = address of rewritten table
* pDir->Size = size of rewritten table
*
* Return none
*
*/
void C6RewriteAndFixupSymbols (uchar *OldSym, OMFDirEntry *pDir, char *psstMod, PMOD pMod)
{
uchar *End;
_vmhnd_t NewSymbolsAddr;
unsigned int cbNewSymbol; // Count of bytes used by new symbols
unsigned int cbAllocSymbol; // Count of bytes allocate for new symbols
SYMPTR pSym;
ushort i;
uchar *pStartSym;
OldSymbols = OldSym;
if (cSeg == 0) {
// probably asm file without Change Default Segment; pick up
// data from module entry
SymbolSizeAdd += sizeof (SEARCHSYM) + 3; // 3 is maximum amount of pad to add
segnum[cSeg++] = (ushort)((OMFModule *)psstMod)->SegInfo[0].Seg;
}
// Make space for the signature
SymbolSizeAdd += sizeof (ulong);
segment = segnum[0];
End = OldSymbols + pDir->cb;
cbAllocSymbol =
(unsigned int)(pDir->cb + SymbolSizeAdd - SymbolSizeSub + UDTAdd);
if ((NewSymbolsAddr = (_vmhnd_t)VmAlloc (cbAllocSymbol)) == _VM_NULL) {
ErrorExit (ERR_NOVM, NULL, NULL);
}
if ((NewSymbols = (uchar *)VmLock (NewSymbolsAddr)) == NULL) {
ErrorExit (ERR_NOVM, NULL, NULL);
}
pStartSym = NewSymbols;
// Add CV4/C7 debug info format signature.
*((ulong *)NewSymbols)++ = CV_SIGNATURE_C7;
for (i = 0; i < cSeg; i++) {
NewSymbols += AddSearchSym (NewSymbols, segnum[i]);
}
// Rewrite all the symbols from OldSymbols to NewSymbols
C6RewriteSymbolStrings (End);
// ExtraSymbols points to a linked list of symbols.
// Each entry consists of a pointer to the next symbol followed by
// a C7 style symbol.
while (ExtraSymbols != NULL) {
pSym = (SYMPTR)(ExtraSymbols + sizeof (uchar *));
memcpy (NewSymbols, (uchar *)pSym, pSym->reclen + LNGTHSZ);
NewSymbols += pSym->reclen + LNGTHSZ;
End = ExtraSymbols;
ExtraSymbols = *(uchar **)ExtraSymbols; // Get next symbol address
free (End); // Free the symbol just copied
}
// Because we allocated more space than required, calculate true
// symbol segment size.
cbNewSymbol = NewSymbols - pStartSym;
if (LinkScope (pStartSym, cbNewSymbol) == FALSE) {
// error linking scopes, delete symbol table
Warn (WARN_SCOPE, FormatMod (pCurMod), NULL);
cbNewSymbol = 0;
}
pDir->lfo = (ulong)NewSymbolsAddr;
pDir->cb = cbNewSymbol;
//M00 - If a VmRealloc exists it could be used here to free the
//M00 extra memory allocated
VmUnlock (NewSymbolsAddr, _VM_DIRTY);
FinalSymInfoSize += cbNewSymbol;
pMod->SymbolSize = cbNewSymbol;
pMod->SymbolsAddr = (ulong)NewSymbolsAddr;
}
// In TEXT2 segment rather than _TEXT
LOCAL void C6RewriteSymbolStrings (uchar * End)
{
uchar type;
rewritesymfcn * pSymFcn;
uchar fFlat32;
ushort i;
while (OldSymbols < End) {
type = OldSymbols[1];
if (type & 0x80) {
fFlat32 = TRUE;
}
else {
fFlat32 = FALSE;
}
type &= 0x7f; // clear highest bit
for (pSymFcn = C6RwrtSymFcn, i = 0; i < C6REWRITESYMCNT; i++, pSymFcn++) {
if (pSymFcn->oldsym == type) {
break; // Ok, found the entry
}
}
//Note: Fixup should have caught bad input
DASSERT (i != C6REWRITESYMCNT); // Make sure type was in the table
if (fFlat32) {
if (pSymFcn->new32sym != 0) {
((SYMTYPE *)NewSymbols)->rectyp = pSymFcn->new32sym;
}
pSymFcn->pfcn32 (); // Rewrite the symbol
}
else {
if (pSymFcn->new16sym != 0) {
((SYMTYPE *)NewSymbols)->rectyp = pSymFcn->new16sym;
}
pSymFcn->pfcn16 (); // Rewrite the symbol
}
}
}
/** C6CnvtSymbol - reformat a C6 symbol into the buffer passed.
*
* This routine is called only to rewrite a based pointer symbol
* into a type record. The conversion routines do not convert
* the type indices.
*
* C6CnvtSymbol (pC7Sym, pC6Sym);
*
* Entry pC7Sym = A buffer to store the new C7 Symbol in.
* pC6Sym = C6 format symbol to be converted.
*
* Exit OldSymbols - modified, WARNING this will interfere with
* RewriteSymbolsC6 if this routine is called
* a symbols rewrite.
* NewSymbols - modified, WARNING this will interfere with
* RewriteSymbolsC6 if this routine is called
* a symbols rewrite.
*
* Return Size of the new C7 symbol.
*
*/
ushort C6CnvtSymbol (uchar *pC7Sym, uchar *pC6Sym)
{
ushort i;
uchar type;
uchar fFlat32;
cnvrtsymfcn *pSymFcn;
type = pC6Sym[1];
if (type & 0x80) {
fFlat32 = TRUE;
}
else {
fFlat32 = FALSE;
}
type &= 0x7f; // clear highest bit
for (pSymFcn = C6CnvrtSymFcn, i = 0; i < C6CNVRTSYMCNT; i++, pSymFcn++) {
if (pSymFcn->oldsym == type) {
break; // Ok, found the entry
}
}
DASSERT (i != C6CNVRTSYMCNT); // Make sure type was in the table
if (fFlat32) {
return (pSymFcn->pfcn32 (pC7Sym, pC6Sym));
}
else {
return (pSymFcn->pfcn16 (pC7Sym, pC6Sym));
}
}
LOCAL ushort C6CnvrtRegSym (uchar *NewSym, uchar *OldSym)
{
ushort length;
REGPTR pSym = (REGPTR)NewSym;
uchar *pName;
ushort usNTotal; // New length of symbol including length field
int iPad;
// get length of name (including length prefix)
length = (ushort)OldSym[0] - 1 - 3;
// calculate new length
usNTotal = sizeof (REGSYM) - 1 + length;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pSym->rectyp = S_REGISTER;
iPad = PAD4 (usNTotal);
// Copy data from old symbol
OldSym += 2;
pSym->typind = *((ushort *)OldSym)++;
pSym->reg = *((uchar *) OldSym)++;
// Copy the name
for (pName = pSym->name; length > 0; length --) {
*pName++ = *OldSym++;
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSym + pSym->reclen + LNGTHSZ);
return ((ushort)(pName - NewSym));
}
LOCAL ushort C6CnvrtBPRelSym16 (uchar *NewSym, uchar *OldSym)
{
BPRELPTR16 pSym = (BPRELPTR16)NewSym;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
length = OldSym[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pSym->rectyp = S_BPREL16;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSym += 2;
NewSym += sizeof (SYMTYPE);
length--; // Don't copy old type field
for (; length > 0; length --) {
*NewSym++ = *OldSym++;
}
PADLOOP (pad, NewSym);
DASSERT (NewSym == (uchar *)pSym + pSym->reclen + LNGTHSZ);
return (NewSym - (uchar *)pSym);
}
LOCAL ushort C6CnvrtBPRelSym32 (uchar *NewSym, uchar *OldSym)
{
BPRELPTR32 pSym = (BPRELPTR32)NewSym;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
length = OldSym[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pSym->rectyp = S_BPREL32;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSym += 2;
NewSym += sizeof (SYMTYPE);
length--; // Don't copy old type field
for (; length > 0; length --) {
*NewSym++ = *OldSym++;
}
PADLOOP (pad, NewSym);
DASSERT (NewSym == (uchar *)pSym + pSym->reclen + LNGTHSZ);
return (NewSym - (uchar *)pSym);
}
LOCAL ushort C6CnvrtDataSym16 (uchar *NewSym, uchar *OldSym)
{
DATAPTR16 pSym = (DATAPTR16)NewSym;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
length = OldSym[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pSym->rectyp = S_LDATA16;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSym += 2;
NewSym += sizeof (SYMTYPE);
length--; // Don't copy old type field
for (; length > 0; length --) {
*NewSym++ = *OldSym++;
}
PADLOOP (pad, NewSym);
DASSERT (NewSym == (uchar *)pSym + pSym->reclen + LNGTHSZ);
return (NewSym - (uchar *)pSym);
}
LOCAL ushort C6CnvrtDataSym32 (uchar *NewSym, uchar *OldSym)
{
DATAPTR32 pSym = (DATAPTR32)NewSym;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
length = OldSym[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pSym->rectyp = S_LDATA32;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSym += 2;
NewSym += sizeof (SYMTYPE);
length--; // Don't copy old type field
for (; length > 0; length --) {
*NewSym++ = *OldSym++;
}
PADLOOP (pad, NewSym);
DASSERT (NewSym == (uchar *)pSym + pSym->reclen + LNGTHSZ);
return (NewSym - (uchar *)pSym);
}
LOCAL void C6RwrtRegSym (void)
{
ushort length;
REGPTR pSym = (REGPTR)NewSymbols;
uchar *pName;
ushort usNTotal; // New length of symbol including length field
int iPad;
ushort reg;
// get length of name (including length prefix)
length = OldSymbols[0] - 1 - 3;
// calculate new length
usNTotal = sizeof (REGSYM) - 1 + length;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
// Copy data from old symbol
OldSymbols += 2;
pSym->typind = *((ushort *) OldSymbols)++;
if ((reg = *((uchar *) OldSymbols)++) <= CV_REG_FLAGS) {
reg = RegMap[reg];
}
pSym->reg = reg;
// Copy the name
for (pName = pSym->name; length > 0; length --) {
*pName++ = *OldSymbols++;
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSymbols + pSym->reclen + LNGTHSZ);
pSym->typind = C6GetCompactedIndex (pSym->typind);
NewSymbols = pName;
}
LOCAL void C6RwrtConstantSym (void)
{
ushort length;
CONSTPTR pSym = (CONSTPTR)NewSymbols;
uchar *pName;
ushort usNTotal; // New length of symbol including length field
ushort usOldSymSize;
int iPad;
// get length of all variable length data
length = OldSymbols[0] - 1 - 2;
// calculate new length
usNTotal = sizeof (CONSTSYM) - 2 + length + SizeChgNumeric (OldSymbols + 4);
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
// Copy data from old symbol
OldSymbols += 2;
pSym->typind = *((ushort *) OldSymbols)++;
pName = (uchar *)&(pSym->value);
// Copies the Numeric field and advances the pointers
ConvertNumeric (&OldSymbols, &pName, &usOldSymSize);
// Copy the name
for (length -= usOldSymSize; length > 0; length --) {
*pName++ = *OldSymbols++;
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSymbols + pSym->reclen + LNGTHSZ);
pSym->typind = C6GetCompactedIndex (pSym->typind);
NewSymbols = pName;
}
LOCAL void C6RwrtBlockSym16 (void)
{
BLOCKPTR16 pSym = (BLOCKPTR16)NewSymbols;
uchar *pName;
ushort length;
int fNamePresent = TRUE;
ushort usNTotal; // New length of symbol including length field
int iPad;
// get length of name (including length of the length prefix)
length = OldSymbols[0] - 1 - 4;
if (!length) {
// Niether name nor prefix present, prepare to add a 0 length prefix.
fNamePresent = FALSE;
length = 1;
}
// calculate new length
usNTotal = sizeof (BLOCKSYM16) - 1 + length;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
// Set fixed fields of new symbol
pSym->pParent = 0L;
pSym->pEnd = 0L;
pSym->seg = segment;
// Copy data from old symbol
OldSymbols += 2;
pSym->off = *((ushort *) OldSymbols)++;
pSym->len = *((ushort *) OldSymbols)++;
// Copy the optional block name
pName = pSym->name;
if (fNamePresent) {
for (; length > 0; length --) {
*pName++ = *OldSymbols++;
}
}
else {
*pName++ = 0; // Create a length prefixed name
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSymbols + pSym->reclen + LNGTHSZ);
NewSymbols = pName;
}
LOCAL void C6RwrtBlockSym32 (void)
{
ushort length;
BLOCKPTR32 pSym = (BLOCKPTR32)NewSymbols;
uchar *pName;
int fNamePresent = TRUE;
ushort usNTotal; // New length of symbol including length field
int iPad;
// get length of name
length = OldSymbols[0] - 1 - 6;
if (!length) {
// Niether name nor prefix present, prepare to add a 0 length prefix.
fNamePresent = FALSE;
length = 1;
}
// calculate new length
usNTotal = sizeof (BLOCKSYM32) - 1 + length;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
// Set fixed fields of new symbol
pSym->pParent = 0L;
pSym->pEnd = 0L;
pSym->seg = segment;
// Copy data from old symbol
OldSymbols += 2;
pSym->off = *((ulong *) OldSymbols)++;
pSym->len = *((ushort *) OldSymbols)++;
// Copy the optional block name
pName = pSym->name;
if (fNamePresent) {
for (; length > 0; length --) {
*pName++ = *OldSymbols++;
}
}
else {
*pName++ = 0;
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSymbols + pSym->reclen + LNGTHSZ);
NewSymbols = pName;
}
LOCAL void C6RwrtLabSym16 (void)
{
ushort length;
LABELPTR16 pSym = (LABELPTR16)NewSymbols;
uchar *pName;
ushort usNTotal; // New length of symbol including length field
int iPad;
// get length of name (including length prefix)
length = OldSymbols[0] - 1 - 3;
// calculate new length
usNTotal = sizeof (LABELSYM16) - 1 + length;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
// Set fixed fields of new symbol
pSym->seg = segment;
// Copy data from old symbol
OldSymbols += 2;
pSym->off = *((ushort *) OldSymbols)++;
pSym->rtntyp = *((uchar *) OldSymbols)++;
// Copy the name
for (pName = pSym->name; length > 0; length --) {
*pName++ = *OldSymbols++;
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSymbols + pSym->reclen + LNGTHSZ);
NewSymbols = pName;
}
LOCAL void C6RwrtLabSym32 (void)
{
ushort length;
LABELPTR32 pSym = (LABELPTR32)NewSymbols;
uchar *pName;
ushort usNTotal; // New length of symbol including length field
int iPad;
// get length of name
length = OldSymbols[0] - 1 - 5;
// calculate new length
usNTotal = sizeof (LABELSYM32) - 1 + length;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
// Set fixed fields of new symbol
pSym->seg = segment;
// Copy data from old symbol
OldSymbols += 2;
pSym->off = *((ulong *) OldSymbols)++;
pSym->rtntyp = *((uchar *) OldSymbols)++;
// Copy the name
for (pName = pSym->name; length > 0; length --) {
*pName++ = *OldSymbols++;
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSymbols + pSym->reclen + LNGTHSZ);
NewSymbols = pName;
}
LOCAL void C6RwrtChgDfltSeg (void)
{
segment = * (ushort *) (OldSymbols + 2); // Record new segment
OldSymbols += OldSymbols[0] + 1; // Advance to next symbol
}
LOCAL void C6RwrtProcSym16 (void)
{
ushort length;
PROCPTR16 pSym = (PROCPTR16)NewSymbols;
uchar *pName;
ushort usNTotal; // New length of symbol including length field
int iPad;
// get length of name (including length prefix)
length = OldSymbols[0] - 1 - 13;
// calculate new length
usNTotal = sizeof (PROCSYM16) - 1 + length;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
// Set fixed fields of new symbol
pSym->pParent = 0L;
pSym->pEnd = 0L;
pSym->pNext = 0L;
pSym->seg = segment;
// Copy data from old symbol
OldSymbols += 2;
pSym->off = *((ushort *) OldSymbols)++;
pSym->typind = *((ushort *) OldSymbols)++;
pSym->len = *((ushort *) OldSymbols)++;
pSym->DbgStart = *((ushort *) OldSymbols)++;
pSym->DbgEnd = *((ushort *) OldSymbols)++;
// skip reserved
OldSymbols += 2;
pSym->rtntyp = *((uchar *) OldSymbols)++;
// Copy the name
for (pName = pSym->name; length > 0; length --) {
*pName++ = *OldSymbols++;
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSymbols + pSym->reclen + LNGTHSZ);
pSym->typind = C6GetCompactedIndex (pSym->typind);
NewSymbols = pName;
}
LOCAL void C6RwrtProcSym32 (void)
{
ushort length;
PROCPTR32 pSym = (PROCPTR32)NewSymbols;
uchar *pName;
ushort usNTotal; // New length of symbol including length field
int iPad;
// get length of name (including length prefix)
length = OldSymbols[0] - 1 - 15;
// calculate new length
usNTotal = sizeof (PROCSYM32) - 1 + length;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
// Set fixed fields of new symbol
pSym->pParent = 0L;
pSym->pEnd = 0L;
pSym->pNext = 0L;
pSym->seg = segment;
// Copy data from old symbol
OldSymbols += 2;
pSym->off = *((ulong *) OldSymbols)++;
pSym->typind = *((ushort *) OldSymbols)++;
pSym->len = *((ushort *) OldSymbols)++;
pSym->DbgStart = *((ushort *) OldSymbols)++;
pSym->DbgEnd = *((ushort *) OldSymbols)++;
// skip reserved
OldSymbols += 2;
pSym->rtntyp = *((uchar *) OldSymbols)++;
// Copy the name
for (pName = pSym->name; length > 0; length --) {
*pName++ = *OldSymbols++;
}
PADLOOP (iPad, pName);
DASSERT (pName == NewSymbols + pSym->reclen + LNGTHSZ);
pSym->typind = C6GetCompactedIndex (pSym->typind);
NewSymbols = pName;
}
// Skip fields are removed
LOCAL void C6RwrtSkipSym (void)
{
// delete skip record
OldSymbols += OldSymbols[0] + 1;
}
LOCAL void C6RwrtGenericSym (void)
{
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
uchar *pStartNew;
pStartNew = NewSymbols;
length = OldSymbols[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
((SYMTYPE *)NewSymbols)->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSymbols += 2;
NewSymbols += sizeof (SYMTYPE);
length--; // Don't copy old type field
//M00SPEED - This may be faster using a memcpy
for (; length > 0; length --) {
*NewSymbols++ = *OldSymbols++;
}
PADLOOP (pad, NewSymbols);
DASSERT (NewSymbols == pStartNew + ((SYMTYPE *)pStartNew)->reclen + LNGTHSZ);
}
LOCAL void C6RwrtBPRelSym16 (void)
{
BPRELPTR16 pSym = (BPRELPTR16)NewSymbols;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
uchar *pStartNew;
pStartNew = NewSymbols;
length = OldSymbols[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
((SYMTYPE *)NewSymbols)->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSymbols += 2;
NewSymbols += sizeof (SYMTYPE);
length--; // Don't copy old type field
//M00SPEED - This may be faster using a memcpy
for (; length > 0; length --) {
*NewSymbols++ = *OldSymbols++;
}
PADLOOP (pad, NewSymbols);
DASSERT (NewSymbols == pStartNew + ((SYMTYPE *)pStartNew)->reclen + LNGTHSZ);
pSym->typind = C6GetCompactedIndex (pSym->typind);
}
LOCAL void C6RwrtBPRelSym32 (void)
{
BPRELPTR32 pSym = (BPRELPTR32)NewSymbols;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
uchar *pStartNew;
pStartNew = NewSymbols;
length = OldSymbols[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
((SYMTYPE *)NewSymbols)->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSymbols += 2;
NewSymbols += sizeof (SYMTYPE);
length--; // Don't copy old type field
//M00SPEED - This may be faster using a memcpy
for (; length > 0; length --) {
*NewSymbols++ = *OldSymbols++;
}
PADLOOP (pad, NewSymbols);
DASSERT (NewSymbols == pStartNew + ((SYMTYPE *)pStartNew)->reclen + LNGTHSZ);
pSym->typind = C6GetCompactedIndex (pSym->typind);
}
LOCAL void C6RwrtDataSym16 (void)
{
DATAPTR16 pSym = (DATAPTR16)NewSymbols;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
uchar *pStartNew;
pStartNew = NewSymbols;
length = OldSymbols[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
((SYMTYPE *)NewSymbols)->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSymbols += 2;
NewSymbols += sizeof (SYMTYPE);
length--; // Don't copy old type field
//M00SPEED - This may be faster using a memcpy
for (; length > 0; length --) {
*NewSymbols++ = *OldSymbols++;
}
PADLOOP (pad, NewSymbols);
DASSERT (NewSymbols == pStartNew + ((SYMTYPE *)pStartNew)->reclen + LNGTHSZ);
pSym->typind = C6GetCompactedIndex (pSym->typind);
}
LOCAL void C6RwrtDataSym32 (void)
{
DATAPTR32 pSym = (DATAPTR32)NewSymbols;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
uchar *pStartNew;
pStartNew = NewSymbols;
length = OldSymbols[0];
usNTotal = length + 1 + 2; // 1 = size of old len field, 2 = larger size of len and leaf
((SYMTYPE *)NewSymbols)->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSymbols += 2;
NewSymbols += sizeof (SYMTYPE);
length--; // Don't copy old type field
//M00SPEED - This may be faster using a memcpy
for (; length > 0; length --) {
*NewSymbols++ = *OldSymbols++;
}
PADLOOP (pad, NewSymbols);
DASSERT (NewSymbols == pStartNew + ((SYMTYPE *)pStartNew)->reclen + LNGTHSZ);
pSym->typind = C6GetCompactedIndex (pSym->typind);
}
/** RewritePublics - reformat publics to new format and store in VM
*
* RewritePublics (addr, pDir, pMod);
*
* Entry addr = address of publics table
* pDir = address of directory entry
* pMod = module table entry
*
* Exit pDir->lfo = address of rewritten table
* pDir->Size = size of rewritten table
*
* Return none
*
* Note Not called through Symbol Rewrite funtion table.
*/
void RewritePublicsC6 (uchar *OldPublics, OMFDirEntry *pDir)
{
uchar *NewPublics;
uchar *End;
uchar Offset = 4;
uchar length;
ushort usNTotal; // New length of symbol including length field
int iPad;
uchar buf[512];
if ((pDir->cb) == 0) {
// if publics directory entry but no data
return;
}
if (fLinearExe) {
Offset += 2;
}
End = OldPublics + pDir->cb;
while (OldPublics < End) {
NewPublics = buf;
// add in offset, type, name length, name length prefix
length = (uchar)(Offset + 2 + OldPublics[Offset + 2] + 1);
// calculate new length; length size, record type size, length of data
usNTotal = LNGTHSZ + RECTYPSZ + length;
*((ushort *)NewPublics)++ = ALIGN4 (usNTotal) - LNGTHSZ;
iPad = PAD4 (usNTotal);
if (fLinearExe) {
*((ushort *)NewPublics)++ = S_PUB32;
}
else{
*((ushort *)NewPublics)++ = S_PUB16;
}
for (; length > 0; length--) {
*NewPublics++ = *OldPublics++;
}
*NewPublics = 0;
PADLOOP (iPad, NewPublics);
#ifdef NB09
PackPublic ((SYMPTR)buf, DWordXorLrl);
#else
PackPublic ((SYMPTR)buf, SumUCChar);
#endif
}
}
LOCAL uchar *RemoveComDat (uchar *Symbols)
{
int level = 1;
SymbolSizeSub += Symbols[0] + 1;
Symbols[1] = OSYMRESERVED;
Symbols += Symbols[0] + 1;
while (level) {
switch (Symbols[1] & 0x7f) {
case OSYMWITH:
case OSYMBLOCKSTART:
case OSYMTHUNK:
case OSYMCV4BLOCK:
case OSYMCV4WITH:
case OSYMPROCSTART:
case OSYMLOCALPROC:
level++;
break;
case OSYMEND:
level--;
break;
default:
break;
}
SymbolSizeSub += Symbols[0] + 1;
Symbols[1] = OSYMRESERVED;
Symbols += Symbols[0] + 1;
}
return (Symbols);
}
/**
*
* SizeChgNumeric
*
* Calculates the difference in size between an old style numeric leaf and
* a new (C7) style numeric leaf. Below is is the table of the old vs new size.
* Type Range Old New Change
* unsigned 0-127 1 2 1
* unsigned 127-0x7fff 3 2 -1
* unsigned 0x8000-0xffff 3 4 1
* unsigned long 5 6 1
* signed short 3 4 1
* signed long 5 6 1
*
* Input: pOld - Pointer to the old Numeric Leaf
* Output: Return value is how many more bytes the new format will occupy
* than the old format. May be a negative number.
*/
short SizeChgNumeric (uchar *pOld)
{
if (*pOld == 133 && *((ushort *)(pOld + 1)) < LF_NUMERIC){
// An unsigned short that will fit in the leaf indicy
return(2-3); // old takes 24bits, new takes 16bits
}
if (*pOld > 138){
ErrorExit (ERR_INVALIDMOD, FormatMod (pCurMod), NULL);
}
return (1);
}