NT4/private/sdktools/vctools/cvpack/symbols6.c
2020-09-30 17:12:29 +02:00

1571 lines
36 KiB
C

/*** symbols6.c
*
* engine routines for C6 symbols. to convert C6 symbols to C7 (CV4) symbols
*
*/
#include "compact.h"
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);
LOCAL void C6SizeExecModel16 (void);
LOCAL void C6SizeExecModel32 (void);
LOCAL void C6SizeTypeDef (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);
LOCAL void C6RwrtExecModel16 (void);
LOCAL void C6RwrtExecModel32 (void);
LOCAL void C6RwrtUDTSym (void);
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 *);
LOCAL void C6RewriteSymbolStrings (uchar * End);
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 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 *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},
{OSYMCHGEXECMODEL,
S_CEXMODEL16, C6RwrtExecModel16,
S_CEXMODEL32, C6RwrtExecModel32},
{OSYMTYPEDEF,
S_COBOLUDT, C6RwrtUDTSym,
S_COBOLUDT, C6RwrtUDTSym},
{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},
{OSYMCHGEXECMODEL, C6SizeExecModel16,
C6SizeExecModel32},
{OSYMTYPEDEF, C6SizeTypeDef,
C6SizeTypeDef},
};
#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.
*/
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
}
}
if (i == C6SIZESYMCNT) {
// issue a warning and discard the record
// sps - 12/3/92
Warn (WARN_BADSYM, FormatMod (pCurMod), NULL);
}
else 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 MAXPAD 3
#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--;
}
LOCAL void C6SizeLabSym16 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (LABELSYM16) - 1) - (2 + 3);
}
LOCAL void C6SizeLabSym32 (void)
{
SymbolSizeAdd += MAXPAD + (sizeof (LABELSYM32) - 1) - (2 + 5);
}
LOCAL void C6SizeExecModel16 (void)
{
// the first 1 is for the rectype byte already in old symbol
// the 2 + 1 + 4 is offset, model control and flags already in
// old symbol
SymbolSizeAdd += MAXPAD + (sizeof (CEXMSYM16) - 1) - (2 + 1 + 4);
}
LOCAL void C6SizeExecModel32 (void)
{
// I do not expect to ever see one of these
DASSERT (FALSE);
}
LOCAL void C6SizeTypeDef (void)
{
// the 2 is for the additional byte in the size and record type fields
SymbolSizeAdd += MAXPAD + 2;
}
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 four extra because the numeric leaf may grow by prefix plus length;
SymbolSizeAdd += MAXPAD + (sizeof (CONSTSYM) - 2) - (2 + 2) + 4;
}
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);
}
/** 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)TrapMalloc (cbAllocSymbol)) == NULL) {
ErrorExit (ERR_NOMEM, NULL, NULL);
}
pStartSym = NewSymbols = (uchar *) NewSymbolsAddr;
// 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
FinalSymInfoSize += cbNewSymbol;
pMod->SymbolSize = cbNewSymbol;
pMod->SymbolsAddr = (ulong)NewSymbolsAddr;
}
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
}
}
if (i >= C6REWRITESYMCNT) {
// already issued warning in C6CalcNewSizeOfSymbols
// sps 12/7/92
OldSymbols += *OldSymbols + 1; // to next record
}
else 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;
}
// convert length preceeded numeric fields - output only by fortran 4
// as far as i can tell
INLINE void CnvrtLPNumeric (uchar **ppOld, uchar **ppNew, CV_typ_t C8Type)
{
uchar *pOld;
uchar *pNew;
size_t count;
pOld = *ppOld;
pNew = *ppNew;
// if the type is not a primitive emit a lf_varstring
if (!CV_IS_PRIMITIVE(C8Type)) {
*((ushort *) pNew)++ = LF_VARSTRING;
for (count = *((ushort *)pNew)++ = *pOld++;
count > 0;
count --) {
*pNew++ = *pOld++;
}
}
else {
switch( count = (size_t) *pOld++ ){ // length byte
case 1:
if (CV_TYP_IS_SIGNED(C8Type)) {
*((ushort UNALIGNED *) pNew)++ = LF_CHAR;
*((short UNALIGNED *) pNew)++ = (short) *pOld++;
}
else {
*((ushort UNALIGNED *) pNew)++ = (ushort) *pOld++;
}
break;
case 2:
if (*((ushort UNALIGNED *) pOld) >= LF_NUMERIC) {
*((ushort UNALIGNED *) pNew)++ = (CV_TYP_IS_SIGNED(C8Type)) ? LF_SHORT : LF_USHORT;
}
*((ushort UNALIGNED *) pNew)++ = *((ushort UNALIGNED *) pOld)++;
break;
case 4:
if (CV_TYP_IS_REAL(C8Type)) {
*((ushort UNALIGNED *) pNew)++ = LF_REAL32;
}
else {
*((ushort UNALIGNED *) pNew)++ =
CV_TYP_IS_SIGNED(C8Type) ? LF_LONG : LF_ULONG;
}
*((long UNALIGNED *) pNew)++ = *((long UNALIGNED *) pOld)++;
break;
case 8:
if (CV_TYP_IS_COMPLEX(C8Type)) {
*((ushort UNALIGNED *) pNew)++ = LF_COMPLEX32;
}
else if (CV_TYP_IS_REAL(C8Type)) {
*((ushort UNALIGNED *) pNew)++ = LF_REAL64;
}
else {
*((ushort UNALIGNED *) pNew)++ =
CV_TYP_IS_SIGNED(C8Type) ? LF_QUADWORD : LF_UQUADWORD;
}
goto DoMemcpy;
case 10:
DASSERT(CV_TYP_IS_REAL(C8Type));
*((ushort UNALIGNED *) pNew)++ = LF_REAL80;
goto DoMemcpy;
case 16:
if (CV_TYP_IS_COMPLEX(C8Type)) {
*((ushort UNALIGNED *) pNew)++ = LF_COMPLEX64;
}
else {
DASSERT(CV_TYP_IS_REAL(C8Type));
*((ushort UNALIGNED *) pNew)++ = LF_REAL128;
}
DoMemcpy:
memcpy (pNew, pOld, count);
pNew += count;
pOld += count;
break;
default:
// what the hey - best we can do
*((ushort UNALIGNED *) pNew)++ = LF_VARSTRING;
for (*((ushort *)pNew)++ = (ushort) count;
count > 0;
count --) {
*pNew++ = *pOld++;
}
}
}
*ppNew = pNew;
*ppOld = pOld;
}
LOCAL void C6RwrtConstantSym (void)
{
ushort length;
CONSTPTR pSym = (CONSTPTR)NewSymbols;
uchar *pName;
int iPad;
bool_t missing = FALSE;
char *resetOldSymbols = OldSymbols;
// Copy data from old symbol
OldSymbols += 2;
pSym->typind = C6GetCompactedIndex(*((ushort *) OldSymbols)++);
pName = (uchar *)&(pSym->value);
// Copies the Numeric field and advances the pointers
if (*OldSymbols < 0x80) {
CnvrtLPNumeric(&OldSymbols, &pName, pSym->typind);
}
else {
ConvertNumeric (&OldSymbols, &pName);
}
// copy the name
for (length = *pName++ = *OldSymbols++;
length > 0;
length --) {
*pName++ = *OldSymbols++;
}
pSym->reclen = ((ushort) (pName - (uchar *) pSym));
length = iPad = PAD4(pSym->reclen); //because padloop destroys count
PADLOOP (length, pName);
pSym->reclen += iPad - LNGTHSZ;
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 UNALIGNED *) OldSymbols)++;
pSym->len = *((ushort UNALIGNED *) 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->flags.bAll = *((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 UNALIGNED *) OldSymbols)++;
pSym->flags.bAll = *((uchar UNALIGNED *) 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->flags.bAll = *((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->flags.bAll = *((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 C6RwrtUDTSym (void)
{
UDTPTR pSym = (UDTPTR)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 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);
}
LOCAL void C6RwrtExecModel16 (void)
{
CEXMPTR16 pSym = (CEXMPTR16)NewSymbols;
ushort usNTotal; // New length of symbol including length field
ushort length;
int pad;
uchar *pStartNew;
pStartNew = NewSymbols;
length = OldSymbols[0];
// 1 = size of old len field, 2 = larger size of len and leaf
// 2 is segment index, 1 is larger model field
usNTotal = length + 1 + 2 + 2 + 1;
pSym->reclen = ALIGN4 (usNTotal) - LNGTHSZ;
pad = PAD4 (usNTotal);
// Move past length and type bytes
OldSymbols += 2;
pSym->off = *(ushort *)OldSymbols;
OldSymbols += 2;
pSym->seg = segment;
pSym->model = *OldSymbols;
OldSymbols++;
pSym->cobol.subtype = *(ushort *)OldSymbols;
OldSymbols += 2;
pSym->cobol.flag = *(ushort *)OldSymbols;
OldSymbols += 2;
NewSymbols += sizeof (CEXMSYM16);
PADLOOP (pad, NewSymbols);
DASSERT (NewSymbols == pStartNew + ((SYMTYPE *)pStartNew)->reclen + LNGTHSZ);
}
LOCAL void C6RwrtExecModel32 (void)
{
// I never expect to see one of these
DASSERT (FALSE);
}