mirror of https://github.com/lianthony/NT4.0
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.
1042 lines
27 KiB
1042 lines
27 KiB
/*** symbols7.c
|
|
*
|
|
* engine routines for C7 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);
|
|
LOCAL void CheckSearchSym (ushort, ushort *);
|
|
|
|
// Called through Fixup function table
|
|
LOCAL void C7DecLevel (void);
|
|
LOCAL void C7IncLevel (void);
|
|
LOCAL void BPRelSym16 (void);
|
|
LOCAL void BPRelSym32 (void);
|
|
LOCAL void RegRel16 (void);
|
|
LOCAL void RegRel32 (void);
|
|
LOCAL void ProcSym16 (void);
|
|
LOCAL void ProcSym32 (void);
|
|
LOCAL void ProcSymMips (void);
|
|
LOCAL void LData16 (void);
|
|
LOCAL void LData32 (void);
|
|
LOCAL void GData16 (void);
|
|
LOCAL void GData32 (void);
|
|
LOCAL void LThread32 (void);
|
|
LOCAL void GThread32 (void);
|
|
LOCAL void ExeModelSym16 (void);
|
|
LOCAL void ExeModelSym32 (void);
|
|
LOCAL void RegSym (void);
|
|
LOCAL void ConstantSym (void);
|
|
LOCAL void ObjNameSym (void);
|
|
LOCAL void UDTSym (void);
|
|
LOCAL void SkipSym (void);
|
|
|
|
|
|
extern ushort recursive;
|
|
extern ushort AddNewSymbols;
|
|
extern uchar Signature[];
|
|
extern ulong PublicSymbols;
|
|
|
|
extern uchar ptr32;
|
|
extern uchar *SymbolSegment;
|
|
|
|
extern ushort SymbolSizeAdd;
|
|
extern ushort SymbolSizeSub;
|
|
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
|
|
|
|
extern ushort segnum[MAXCDF];
|
|
|
|
// These are shared by the fixup functions
|
|
LOCAL uchar *pNewSym; // Where the symbol is that needs to be fixed up
|
|
LOCAL int iLevel;
|
|
LOCAL uchar *pOldSym;
|
|
|
|
typedef struct {
|
|
SYMPTR pSymbol;
|
|
int cb;
|
|
int fAllocated:1;
|
|
int fBlockStart:1;
|
|
} C7ItemPtr;
|
|
|
|
int CStackLimit = 0;
|
|
int IStackPtr = 0;
|
|
C7ItemPtr * RgStack;
|
|
int FInParams = FALSE;
|
|
ushort Pb_S_END[] = {2, S_ENDARG};
|
|
|
|
typedef struct {
|
|
ushort sym; // Old C7 Symbol record type
|
|
void (*pfcn) (void);
|
|
} C7fixupsymfcn;
|
|
|
|
C7fixupsymfcn C7FixSymFcn[] = {
|
|
{S_BPREL16, BPRelSym16},
|
|
{S_BPREL32, BPRelSym32},
|
|
|
|
|
|
{S_REGREL16, RegRel16},
|
|
{S_REGREL32, RegRel32},
|
|
|
|
{S_BLOCK16, C7IncLevel},
|
|
{S_BLOCK32, C7IncLevel},
|
|
|
|
{S_LPROC16, ProcSym16},
|
|
{S_LPROC32, ProcSym32},
|
|
{S_LPROCMIPS, ProcSymMips},
|
|
|
|
{S_GPROC16, ProcSym16},
|
|
{S_GPROC32, ProcSym32},
|
|
{S_GPROCMIPS, ProcSymMips},
|
|
|
|
{S_END, C7DecLevel},
|
|
{S_ENDARG, NULL},
|
|
|
|
{S_LDATA16, LData16},
|
|
{S_LDATA32, LData32},
|
|
|
|
{S_GDATA16, GData16},
|
|
{S_GDATA32, GData32},
|
|
|
|
{S_PUB16, LData16},
|
|
{S_PUB32, LData32},
|
|
|
|
{S_LABEL16, NULL},
|
|
{S_LABEL32, NULL},
|
|
|
|
{S_WITH16, C7IncLevel},
|
|
{S_WITH32, C7IncLevel},
|
|
|
|
{S_THUNK16, C7IncLevel},
|
|
{S_THUNK32, C7IncLevel},
|
|
|
|
{S_CEXMODEL16, NULL},
|
|
{S_CEXMODEL32, NULL},
|
|
|
|
{S_GTHREAD32, GThread32},
|
|
{S_LTHREAD32, LThread32},
|
|
|
|
{S_REGISTER, RegSym},
|
|
|
|
{S_CONSTANT, ConstantSym},
|
|
|
|
{S_UDT, UDTSym},
|
|
|
|
{S_SSEARCH, NULL},
|
|
|
|
{S_SKIP, NULL},
|
|
|
|
{S_COMPILE, NULL},
|
|
|
|
{S_OBJNAME, ObjNameSym},
|
|
};
|
|
|
|
|
|
/***
|
|
*
|
|
*/
|
|
|
|
int __cdecl LocalCmp(const void * lpv1, const void * lpv2)
|
|
{
|
|
SYMPTR pSym1 = ((C7ItemPtr *) lpv1)->pSymbol;
|
|
SYMPTR pSym2 = ((C7ItemPtr *) lpv2)->pSymbol;
|
|
|
|
switch( pSym1->rectyp ) {
|
|
case S_BPREL16:
|
|
switch (pSym2->rectyp) {
|
|
case S_BPREL16:
|
|
return strnicmp(&((BPRELSYM16 *) pSym1)->name[1],
|
|
&((BPRELSYM16 *) pSym2)->name[1],
|
|
((BPRELSYM16 *) pSym1)->name[0]+1);
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
case S_BPREL32:
|
|
switch (pSym2->rectyp) {
|
|
case S_BPREL32:
|
|
return strnicmp(&((BPRELSYM32 *) pSym1)->name[1],
|
|
&((BPRELSYM32 *) pSym2)->name[1],
|
|
((BPRELSYM32 *) pSym1)->name[0]+1);
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
case S_BLOCK16:
|
|
switch( pSym2->rectyp) {
|
|
case S_BPREL16:
|
|
return 1;
|
|
|
|
case S_BLOCK16:
|
|
return ((BLOCKSYM16 *) pSym1)->off - ((BLOCKSYM16 *) pSym2)->off;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
case S_BLOCK32:
|
|
switch( pSym2->rectyp) {
|
|
case S_BPREL32:
|
|
return 1;
|
|
|
|
case S_BLOCK32:
|
|
return ((BLOCKSYM32 *) pSym1)->off - ((BLOCKSYM32 *) pSym2)->off;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
case S_LDATA16:
|
|
switch( pSym2->rectyp ) {
|
|
case S_LDATA16:
|
|
return strnicmp(&((DATASYM16 *) pSym1)->name[1],
|
|
&((DATASYM16 *) pSym2)->name[2],
|
|
((DATASYM16 *) pSym1)->name[0]+1);
|
|
|
|
case S_BPREL16:
|
|
return 1;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
case S_LDATA32:
|
|
switch( pSym2->rectyp ) {
|
|
case S_LDATA32:
|
|
return strnicmp(&((DATASYM32 *) pSym1)->name[1],
|
|
&((DATASYM32 *) pSym2)->name[2],
|
|
((DATASYM32 *) pSym1)->name[0]+1);
|
|
|
|
case S_BPREL32:
|
|
return 1;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
case S_END:
|
|
return 1;
|
|
|
|
default:
|
|
switch ( pSym2->rectyp ) {
|
|
case S_BPREL16:
|
|
case S_BPREL32:
|
|
return 1;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
} /* LocalCmp() */
|
|
|
|
void PushItem(uchar * pSymbol, int fBlock)
|
|
{
|
|
if (((SYMPTR) pOldSym)->rectyp == S_CVRESERVE) {
|
|
return;
|
|
}
|
|
|
|
|
|
if (IStackPtr == CStackLimit) {
|
|
CStackLimit += 100;
|
|
RgStack = realloc(RgStack, CStackLimit*sizeof(C7ItemPtr));
|
|
}
|
|
|
|
RgStack[IStackPtr].pSymbol = (SYMPTR) pSymbol;
|
|
RgStack[IStackPtr].cb = ((SYMPTR) pSymbol)->reclen + LNGTHSZ;
|
|
RgStack[IStackPtr].fAllocated = FALSE;
|
|
RgStack[IStackPtr].fBlockStart = fBlock;
|
|
IStackPtr += 1;
|
|
|
|
return;
|
|
} /* PushItem() */
|
|
|
|
void PopBlock(uchar * pSymbol)
|
|
{
|
|
int cb;
|
|
int i;
|
|
int iPad;
|
|
int j;
|
|
int iStackPtrNew;
|
|
char * pb;
|
|
char * pbStart;
|
|
|
|
/*
|
|
* If the previous item was a block starter, and it was
|
|
* a S_BLOCK16 or S_BLOCK32 -- then elimate the block as it
|
|
* does not need to exist
|
|
*/
|
|
|
|
if (RgStack[IStackPtr-1].fBlockStart) {
|
|
if ((RgStack[IStackPtr-1].pSymbol->rectyp == S_BLOCK16) ||
|
|
(RgStack[IStackPtr-1].pSymbol->rectyp == S_BLOCK32)) {
|
|
IStackPtr--;
|
|
return;
|
|
}
|
|
}
|
|
|
|
RgStack[IStackPtr].pSymbol = (SYMPTR) pSymbol;
|
|
RgStack[IStackPtr].cb = ((SYMPTR) pSymbol)->reclen + LNGTHSZ;
|
|
RgStack[IStackPtr].fAllocated = FALSE;
|
|
RgStack[IStackPtr].fBlockStart = FALSE;
|
|
IStackPtr++;
|
|
|
|
/*
|
|
* Find the start of the block
|
|
*/
|
|
|
|
for (iStackPtrNew = IStackPtr-1; iStackPtrNew>=0; iStackPtrNew--) {
|
|
if (RgStack[iStackPtrNew].fBlockStart) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (iStackPtrNew == -1) {
|
|
DASSERT( iStackPtrNew != -1 );
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Now, do the sort for the block
|
|
*/
|
|
|
|
if ((RgStack[iStackPtrNew].pSymbol->rectyp == S_GPROC16) ||
|
|
(RgStack[iStackPtrNew].pSymbol->rectyp == S_LPROC16) ||
|
|
(RgStack[iStackPtrNew].pSymbol->rectyp == S_GPROC32) ||
|
|
(RgStack[iStackPtrNew].pSymbol->rectyp == S_LPROC32) ||
|
|
(RgStack[iStackPtrNew].pSymbol->rectyp == S_LPROCMIPS) ||
|
|
(RgStack[iStackPtrNew].pSymbol->rectyp == S_GPROCMIPS)) {
|
|
|
|
for (i=iStackPtrNew; i < IStackPtr; i++) {
|
|
if (RgStack[i].pSymbol->rectyp == S_ENDARG) {
|
|
i++;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
i = iStackPtrNew + 1;
|
|
}
|
|
|
|
if (i < IStackPtr) {
|
|
qsort(&RgStack[i], IStackPtr - i, sizeof(C7ItemPtr), LocalCmp);
|
|
}
|
|
|
|
/*
|
|
* Now write out the block. If we went to level 0 then really
|
|
* write it out, otherwise build a new primitive item
|
|
*/
|
|
|
|
if (iStackPtrNew == 0) {
|
|
for (i=0; i<IStackPtr; i++) {
|
|
memcpy(pNewSym, RgStack[i].pSymbol, RgStack[i].cb);
|
|
iPad = PAD4(RgStack[i].cb);
|
|
if (iPad != 0) {
|
|
((SYMTYPE *) pNewSym)->reclen = RgStack[i].cb + iPad - LNGTHSZ;
|
|
}
|
|
pNewSym += RgStack[i].cb;
|
|
for (j=0; j<iPad; j++) {
|
|
*pNewSym++ = 0;
|
|
}
|
|
|
|
if (RgStack[i].fAllocated) {
|
|
free(RgStack[i].pSymbol);
|
|
}
|
|
}
|
|
} else {
|
|
for (i=iStackPtrNew, cb=0; i<IStackPtr; i++) {
|
|
cb += ALIGN4( RgStack[i].cb );
|
|
}
|
|
|
|
pb = pbStart = malloc(cb);
|
|
|
|
for (i=iStackPtrNew; i<IStackPtr; i++) {
|
|
memcpy(pb, RgStack[i].pSymbol, RgStack[i].cb);
|
|
iPad = PAD4(RgStack[i].cb);
|
|
if (iPad != 0) {
|
|
((SYMTYPE *) pb)->reclen = RgStack[i].cb + iPad - LNGTHSZ;
|
|
}
|
|
pb += RgStack[i].cb;
|
|
for (j=0; j<iPad; j++) {
|
|
*pb++ = 0;
|
|
}
|
|
|
|
if (RgStack[i].fAllocated) {
|
|
free(RgStack[i].pSymbol);
|
|
}
|
|
}
|
|
|
|
RgStack[iStackPtrNew].pSymbol = (SYMPTR) pbStart;
|
|
RgStack[iStackPtrNew].cb = cb;
|
|
RgStack[iStackPtrNew].fAllocated = TRUE;
|
|
RgStack[iStackPtrNew].fBlockStart = FALSE;
|
|
|
|
iStackPtrNew++;
|
|
}
|
|
|
|
IStackPtr = iStackPtrNew;
|
|
return;
|
|
} /* PopBlock() */
|
|
|
|
void CopyItem(uchar * pSymbol)
|
|
{
|
|
int j;
|
|
int cb = ((SYMTYPE *) pOldSym)->reclen + LNGTHSZ;
|
|
int iPad;
|
|
|
|
if (((SYMPTR) pOldSym)->rectyp == S_CVRESERVE) {
|
|
return;
|
|
}
|
|
|
|
memcpy(pNewSym, pSymbol, cb);
|
|
iPad = PAD4( cb );
|
|
if (iPad != 0) {
|
|
((SYMTYPE *) pNewSym)->reclen = cb + iPad - LNGTHSZ;
|
|
}
|
|
pNewSym += cb;
|
|
for (j=0; j<iPad; j++) {
|
|
*pNewSym++ = 0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#define C7FIXUPSYMCNT (sizeof C7FixSymFcn / sizeof (C7FixSymFcn[0]))
|
|
|
|
|
|
/** C7CalcNewSizeOfSymbols - calculate amount of space needed for padding
|
|
*
|
|
* Takes a buffer containing unaligned C7 symbol records and calculates
|
|
* how much additional space will be required on write for pad bytes.
|
|
* In preperation for a RISC processor misaligned memory reads are avoided.
|
|
*
|
|
* C7CalcNewSizeOfSymbols (Symbols, SymbolCount)
|
|
*
|
|
* Entry Symbols = Buffer containing C7 unaligned symbols
|
|
* SymbolCount = count of bytes in buffer
|
|
*
|
|
* Exit *Add = increased by the num of pad bytes to add
|
|
* *Sub = increased by the num of bytes in S_SKIP records
|
|
*/
|
|
|
|
void C7CalcNewSizeOfSymbols (uchar *Symbols, ulong SymbolCount,
|
|
ushort *Add, ushort *Sub)
|
|
{
|
|
uchar * pOldSym;
|
|
uchar * End;
|
|
ushort usRecSize; // Size of symbol including the length field
|
|
ushort usRecType; // Symbol record type
|
|
|
|
cSeg = 0;
|
|
pOldSym = Symbols;
|
|
End = pOldSym + SymbolCount;
|
|
pOldSym += sizeof (ulong); //Skip signature
|
|
while (pOldSym < End) {
|
|
if (!((ulong)pOldSym & 0x1)){
|
|
// if this record aligned on a word boundry
|
|
// Read by words because data aligned on word bounderies
|
|
usRecSize = ((SYMPTR)pOldSym)->reclen + LNGTHSZ;
|
|
usRecType = ((SYMPTR)pOldSym)->rectyp;
|
|
}
|
|
else {
|
|
// Just make sure bytewise read remains correct
|
|
DASSERT ((sizeof (((SYMPTR)pOldSym)->reclen) == 2) &&
|
|
(sizeof (((SYMPTR)pOldSym)->rectyp) == 2) &&
|
|
(offsetof (SYMTYPE, reclen) == 0) &&
|
|
(offsetof (SYMTYPE, rectyp) == 2));
|
|
|
|
// Read by bytes because not aligned on word bounderies
|
|
usRecSize = (*pOldSym + (*(pOldSym + 1) << (ushort)8)) + LNGTHSZ;
|
|
usRecType = *(pOldSym + 2) + (*(pOldSym + 3) << (ushort)8);
|
|
}
|
|
|
|
// Calculate the size change
|
|
|
|
if (usRecType != S_SKIP){
|
|
// Reserve space for pad bytes we will add at rewrite time.
|
|
*Add += PAD4 (usRecSize);
|
|
switch (usRecType) {
|
|
case S_GPROC16:
|
|
case S_LPROC16:
|
|
CheckSearchSym (((PROCPTR16)pOldSym)->seg, Add);
|
|
break;
|
|
|
|
case S_GPROC32:
|
|
case S_LPROC32:
|
|
CheckSearchSym (((PROCPTR32)pOldSym)->seg, Add);
|
|
*Add += 4;
|
|
break;
|
|
|
|
case S_GPROCMIPS:
|
|
case S_LPROCMIPS:
|
|
CheckSearchSym (((PROCPTRMIPS)pOldSym)->seg, Add);
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
// S_SKIP records are removed, so subtract the size of the record
|
|
*Sub += usRecSize;
|
|
}
|
|
pOldSym += usRecSize; // to next record
|
|
}
|
|
}
|
|
|
|
|
|
LOCAL void CheckSearchSym (ushort seg, ushort *Add)
|
|
{
|
|
if (!SegmentPresent (seg)) {
|
|
*Add += MAXPAD + sizeof (SEARCHSYM);
|
|
segnum[cSeg++] = seg;
|
|
if (cSeg > MAXCDF) {
|
|
ErrorExit (ERR_TOOMANYSEG, FormatMod (pCurMod), NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 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 C7RewriteAndFixupSymbols (uchar *OldSym, OMFDirEntry *pDir, PMOD pMod,
|
|
ushort *Add, ushort *Sub)
|
|
{
|
|
uchar *End;
|
|
ushort i;
|
|
_vmhnd_t pNewSymAddr;
|
|
ulong cbNewSymbol; /* Count of bytes used by new symbols */
|
|
C7fixupsymfcn * pFixFcn;
|
|
ushort usRecSize; /* Size of symbol including the length field */
|
|
ushort usRecType; /* Symbol record type */
|
|
SYMPTR pStartSym;
|
|
|
|
pOldSym = OldSym;
|
|
iLevel = 0;
|
|
|
|
End = pOldSym + pDir->cb;
|
|
cbNewSymbol = pDir->cb + *Add - *Sub;
|
|
if (cbNewSymbol > _HEAP_MAXREQ) {
|
|
ErrorExit (ERR_INVALIDTABLE, "Symbol", FormatMod( pCurMod));
|
|
}
|
|
|
|
pNewSymAddr = (_vmhnd_t)VmAlloc ((size_t)min(cbNewSymbol, _HEAP_MAXREQ));
|
|
if (pNewSymAddr == _VM_NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
|
|
if ((pNewSym = (uchar *)VmLock (pNewSymAddr)) == NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
|
|
pStartSym = (SYMPTR)pNewSym;
|
|
|
|
/*
|
|
* Rewrite CV4/C7 debug info format signature.
|
|
*/
|
|
|
|
*((ulong *)pNewSym)++ = *((ulong *)pOldSym)++;
|
|
for (i = 0; i < cSeg; i++) {
|
|
pNewSym += AddSearchSym (pNewSym, segnum[i]);
|
|
}
|
|
|
|
while (pOldSym < End) {
|
|
/*
|
|
* Get the size and type without causing any miss-aligned reads
|
|
*
|
|
* Is this record aligned on a word boundry
|
|
*/
|
|
|
|
if( !((ulong)pOldSym & 0x1) ) {
|
|
/*
|
|
* Read by words because data aligned on word bounderies
|
|
*/
|
|
|
|
usRecSize = ((SYMPTR)pOldSym)->reclen + LNGTHSZ;
|
|
usRecType = ((SYMPTR)pOldSym)->rectyp;
|
|
}
|
|
else {
|
|
/*
|
|
* Just make sure bytewise read remains correct
|
|
*/
|
|
|
|
DASSERT ((sizeof (((SYMPTR)pOldSym)->reclen) == 2) &&
|
|
(sizeof (((SYMPTR)pOldSym)->rectyp) == 2) &&
|
|
(offsetof (SYMTYPE, reclen) == 0) &&
|
|
(offsetof (SYMTYPE, rectyp) == 2));
|
|
|
|
/*
|
|
* Read by bytes because not aligned on word bounderies
|
|
*/
|
|
|
|
usRecSize = (*pOldSym + (*(pOldSym + 1) << (ushort)8)) + LNGTHSZ;
|
|
usRecType = *(pOldSym + 2) + (*(pOldSym + 3) << (ushort)8);
|
|
}
|
|
|
|
/*
|
|
* Don't Rewrite S_SKIP Symbols
|
|
*/
|
|
|
|
if (usRecType != S_SKIP ){
|
|
/*
|
|
* Find the appropriate fixup function
|
|
*/
|
|
|
|
for( pFixFcn = C7FixSymFcn, i = 0;
|
|
i < C7FIXUPSYMCNT;
|
|
i++, pFixFcn++ ){
|
|
|
|
if( pFixFcn->sym == usRecType ){
|
|
/*
|
|
* Ok, found the entry
|
|
*/
|
|
break;
|
|
}
|
|
}
|
|
/*
|
|
* M00BUG This definitly should be a fatal exit
|
|
*/
|
|
|
|
if (i == C7FIXUPSYMCNT) {
|
|
/*
|
|
* Make sure type was in the table
|
|
*/
|
|
|
|
fprintf(stderr, "Unknown usRecType %d %x\n", usRecType,
|
|
pOldSym - OldSym);
|
|
assert( i != C7FIXUPSYMCNT );
|
|
}
|
|
|
|
/*
|
|
* Fixup the type indexes by packing the types
|
|
*/
|
|
|
|
if( pFixFcn->pfcn ){
|
|
/*
|
|
* Fixup the symbol
|
|
*/
|
|
|
|
pFixFcn->pfcn ();
|
|
} else {
|
|
CopyItem(pOldSym);
|
|
}
|
|
DASSERT (!recursive);
|
|
}
|
|
|
|
/*
|
|
* Move to the next symbol
|
|
*/
|
|
|
|
pOldSym += usRecSize;
|
|
}
|
|
|
|
DASSERT (iLevel >= 0);
|
|
DASSERT ((ulong)(pNewSym - (uchar *)pStartSym) <= cbNewSymbol);
|
|
cbNewSymbol = pNewSym - (uchar *)pStartSym;
|
|
if (LinkScope ((uchar *)pStartSym, cbNewSymbol) == FALSE) {
|
|
/*
|
|
* error linking scopes, delete symbol table
|
|
*/
|
|
|
|
Warn (WARN_SCOPE, FormatMod (pCurMod), NULL);
|
|
cbNewSymbol = 0;
|
|
}
|
|
pDir->lfo = (ulong)pNewSymAddr;
|
|
pDir->cb = cbNewSymbol;
|
|
|
|
VmUnlock (pNewSymAddr, _VM_DIRTY);
|
|
FinalSymInfoSize += cbNewSymbol;
|
|
pMod->SymbolSize = cbNewSymbol;
|
|
pMod->SymbolsAddr = (ulong)pNewSymAddr;
|
|
}
|
|
|
|
|
|
|
|
|
|
/** C7RewritePublics - reformat publics
|
|
*
|
|
* C7RewritePublics (addr, pDir);
|
|
*
|
|
* Entry addr = address of publics table
|
|
* pDir = address of directory entry
|
|
*
|
|
* Exit Public symbols added to HTPub
|
|
*
|
|
* Return none
|
|
*
|
|
* Note Not called through Symbol Rewrite funtion table.
|
|
*/
|
|
|
|
|
|
void C7RewritePublics (uchar *pOldPublics, OMFDirEntry *pDir)
|
|
{
|
|
uchar *pNewPublics;
|
|
uchar *End;
|
|
ushort usRecSize; // Size of symbol including the length field
|
|
ushort usRecType; // Symbol record type
|
|
uchar buf[512];
|
|
|
|
iLevel = 0;
|
|
if (pDir->cb == 0) {
|
|
// if publics directory entry but no data
|
|
return;
|
|
}
|
|
End = pOldPublics + pDir->cb;
|
|
pOldPublics += sizeof (ulong);
|
|
while (pOldPublics < End) {
|
|
pNewPublics = buf;
|
|
// Get the size and type without causing any miss-aligned reads
|
|
|
|
if( !((ulong)pOldPublics & 0x1) ){ // Is this record aligned on a word boundry
|
|
// Read by words because data aligned on word bounderies
|
|
usRecSize = ((SYMPTR)pOldPublics)->reclen + LNGTHSZ;
|
|
usRecType = ((SYMPTR)pOldPublics)->rectyp;
|
|
}
|
|
else {
|
|
// Just make sure bytewise read remains correct
|
|
DASSERT ((sizeof (((SYMPTR)pOldPublics)->reclen) == 2) &&
|
|
(sizeof (((SYMPTR)pOldPublics)->rectyp) == 2) &&
|
|
(offsetof (SYMTYPE, reclen) == 0) &&
|
|
(offsetof (SYMTYPE, rectyp) == 2));
|
|
|
|
// Read by bytes because not aligned on word bounderies
|
|
usRecSize = (*pOldPublics + (*(pOldPublics + 1) << (ushort)8)) + LNGTHSZ;
|
|
usRecType = *(pOldPublics + 2) + (*(pOldPublics + 3) << (ushort)8);
|
|
}
|
|
|
|
// Copy the existing symbol to virtual memory and convert type index
|
|
|
|
DASSERT (usRecSize < sizeof (buf));
|
|
memcpy (pNewPublics, pOldPublics, usRecSize);
|
|
switch (usRecType) {
|
|
case S_PUB16:
|
|
switch (ulCVTypeSignature) {
|
|
case CV_SIGNATURE_C7:
|
|
if (delete == TRUE) {
|
|
if (((DATAPTR16)pNewPublics)->typind >= CV_FIRST_NONPRIM) {
|
|
((DATAPTR16)pNewPublics)->typind = T_NOTYPE;
|
|
}
|
|
}
|
|
else {
|
|
((DATAPTR16)pNewPublics)->typind =
|
|
C7GetCompactedIndex (((DATAPTR16)pNewPublics)->typind);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (delete == TRUE) {
|
|
((DATAPTR16)pNewPublics)->typind = T_NOTYPE;
|
|
}
|
|
else {
|
|
((DATAPTR16)pNewPublics)->typind =
|
|
C6GetCompactedIndex (((DATAPTR16)pNewPublics)->typind);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case S_PUB32:
|
|
switch (ulCVTypeSignature) {
|
|
case CV_SIGNATURE_C7:
|
|
if (delete == TRUE) {
|
|
if (((DATAPTR32)pNewPublics)->typind >= CV_FIRST_NONPRIM) {
|
|
((DATAPTR32)pNewPublics)->typind = T_NOTYPE;
|
|
}
|
|
}
|
|
else {
|
|
((DATAPTR32)pNewPublics)->typind =
|
|
C7GetCompactedIndex (((DATAPTR32)pNewPublics)->typind);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (delete == TRUE) {
|
|
((DATAPTR16)pNewPublics)->typind = T_NOTYPE;
|
|
}
|
|
else {
|
|
((DATAPTR32)pNewPublics)->typind =
|
|
C6GetCompactedIndex (((DATAPTR32)pNewPublics)->typind);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DASSERT (FALSE);
|
|
|
|
}
|
|
DASSERT (!recursive);
|
|
|
|
PackPublic ((SYMPTR)buf, HASHFUNCTION);
|
|
|
|
// Move to the next symbol
|
|
|
|
pOldPublics += usRecSize; // to next record
|
|
}
|
|
DASSERT (iLevel == 0);
|
|
}
|
|
|
|
|
|
|
|
|
|
LOCAL void C7IncLevel (void)
|
|
{
|
|
iLevel++;
|
|
PushItem( pOldSym, TRUE);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
LOCAL void C7DecLevel (void)
|
|
{
|
|
iLevel--;
|
|
FInParams = FALSE;
|
|
PopBlock( pOldSym );
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
LOCAL void BPRelSym16 (void)
|
|
{
|
|
((BPRELPTR16)pOldSym)->typind =
|
|
C7GetCompactedIndex (((BPRELPTR16)pOldSym)->typind);
|
|
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void BPRelSym32 (void)
|
|
{
|
|
((BPRELPTR32)pOldSym)->typind =
|
|
C7GetCompactedIndex (((BPRELPTR32)pOldSym)->typind);
|
|
if (FInParams && ((BPRELPTR32) pOldSym)->off < 0) {
|
|
FInParams = FALSE;
|
|
PushItem((uchar *) Pb_S_END, FALSE);
|
|
}
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
|
|
LOCAL void RegRel16 (void)
|
|
{
|
|
((REGREL16 *)pOldSym)->typind =
|
|
C7GetCompactedIndex (((REGREL16 *)pOldSym)->typind);
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void RegRel32 (void)
|
|
{
|
|
((REGREL32 *)pOldSym)->typind =
|
|
C7GetCompactedIndex (((REGREL32 *)pOldSym)->typind);
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void RegSym (void)
|
|
{
|
|
((REGPTR)pOldSym)->typind =
|
|
C7GetCompactedIndex (((REGPTR)pOldSym)->typind);
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
|
|
LOCAL void ConstantSym (void)
|
|
{
|
|
((CONSTPTR)pOldSym)->typind =
|
|
C7GetCompactedIndex (((CONSTPTR)pOldSym)->typind);
|
|
if (iLevel == 0) {
|
|
// do not pack function scoped constants
|
|
PackSymbol ((SYMPTR)pOldSym, HASHFUNCTION);
|
|
}
|
|
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
|
|
LOCAL void ObjNameSym (void)
|
|
{
|
|
OBJNAMEPTR pSym;
|
|
|
|
if (PackingPreComp == TRUE) {
|
|
pSym = (OBJNAMEPTR)pOldSym;
|
|
if ((pCurMod->pName = malloc (pSym->name[0] + 1)) == NULL) {
|
|
ErrorExit (ERR_NOMEM, NULL, NULL);
|
|
}
|
|
if (pCurMod->signature != pSym->signature) {
|
|
ErrorExit (ERR_PCTSIG, FormatMod (pCurMod), NULL);
|
|
}
|
|
memmove (pCurMod->pName, &pSym->name[0], pSym->name[0] + 1);
|
|
}
|
|
|
|
CopyItem( pOldSym );
|
|
}
|
|
|
|
|
|
LOCAL void LData16 (void)
|
|
{
|
|
((DATAPTR16)pOldSym)->typind =
|
|
C7GetCompactedIndex (((DATAPTR16)pOldSym)->typind);
|
|
PushItem( pOldSym, FALSE);
|
|
|
|
return;
|
|
}
|
|
|
|
LOCAL void GData16 (void)
|
|
{
|
|
|
|
((DATAPTR16)pOldSym)->typind =
|
|
C7GetCompactedIndex (((DATAPTR16)pOldSym)->typind);
|
|
PackSymbol ((SYMPTR)pOldSym, HASHFUNCTION);
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void LData32 (void)
|
|
{
|
|
((DATAPTR32)pOldSym)->typind =
|
|
C7GetCompactedIndex (((DATAPTR32)pOldSym)->typind);
|
|
PushItem( pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void GData32 (void)
|
|
{
|
|
|
|
((DATAPTR32)pOldSym)->typind =
|
|
C7GetCompactedIndex (((DATAPTR32)pOldSym)->typind);
|
|
PackSymbol ((SYMPTR)pOldSym, HASHFUNCTION);
|
|
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void LThread32 (void)
|
|
{
|
|
|
|
((DATAPTR32)pOldSym)->typind =
|
|
C7GetCompactedIndex (((DATAPTR32)pOldSym)->typind);
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void GThread32 (void)
|
|
{
|
|
|
|
((DATAPTR32)pOldSym)->typind =
|
|
C7GetCompactedIndex (((DATAPTR32)pOldSym)->typind);
|
|
PackSymbol ((SYMPTR)pOldSym, HASHFUNCTION);
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void ProcSym16 (void)
|
|
{
|
|
iLevel++;
|
|
((PROCPTR16)pOldSym)->typind =
|
|
C7GetCompactedIndex (((PROCPTR16)pOldSym)->typind);
|
|
PushItem(pOldSym, TRUE);
|
|
return;
|
|
}
|
|
|
|
LOCAL void ProcSym32 (void)
|
|
{
|
|
iLevel++;
|
|
((PROCPTR32)pOldSym)->typind =
|
|
C7GetCompactedIndex (((PROCPTR32)pOldSym)->typind);
|
|
PushItem(pOldSym, TRUE);
|
|
FInParams = TRUE;
|
|
|
|
return;
|
|
} /* ProcSym32() */
|
|
|
|
|
|
LOCAL void ProcSymMips (void)
|
|
{
|
|
iLevel++;
|
|
((PROCPTRMIPS)pOldSym)->typind =
|
|
C7GetCompactedIndex (((PROCPTRMIPS)pOldSym)->typind);
|
|
PushItem(pOldSym, TRUE);
|
|
return;
|
|
}
|
|
|
|
|
|
LOCAL void UDTSym (void)
|
|
{
|
|
((UDTPTR)pOldSym)->typind =
|
|
C7GetCompactedIndex (((UDTPTR)pOldSym)->typind);
|
|
if (iLevel == 0) {
|
|
// do not pack function scoped UDTs
|
|
PackSymbol ((SYMPTR)pOldSym, HASHFUNCTION);
|
|
}
|
|
PushItem(pOldSym, FALSE);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LOCAL uchar *C7RemoveComDat (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);
|
|
}
|