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.
1278 lines
37 KiB
1278 lines
37 KiB
/*** engine.c
|
|
*
|
|
* basic engine routine to be called for each module; also, rewrite routines
|
|
* to convert to CodeView 4 format.
|
|
*
|
|
*/
|
|
|
|
#include "compact.h"
|
|
|
|
|
|
LOCAL void RewriteSrcLnSeg (uchar *, OMFDirEntry *, PMOD);
|
|
LOCAL void CopySrcMod (uchar *, OMFDirEntry *, PMOD);
|
|
LOCAL void ReformatMod (ulong, PMOD);
|
|
LOCAL void CopyModule (OMFDirEntry *, PMOD);
|
|
LOCAL void ReadTypes (OMFDirEntry *, bool_t);
|
|
LOCAL void ReadPublics (ulong, OMFDirEntry *);
|
|
LOCAL void ReadSymbols (ulong, OMFDirEntry *);
|
|
LOCAL void ReadSrcLnSeg (ulong, OMFDirEntry *);
|
|
LOCAL void ReadSrcModule (ulong, OMFDirEntry *);
|
|
LOCAL void ReadPublicSym (ulong, OMFDirEntry *);
|
|
|
|
LOCAL int VerifySrcMod (PMOD);
|
|
LOCAL void FixSrcMod (PMOD);
|
|
LOCAL void FixEnds (OMFModule *, OMFSourceModule *);
|
|
|
|
|
|
void DebugBreak (void);
|
|
|
|
extern ushort recursive;
|
|
extern ushort AddNewSymbols;
|
|
extern uchar Signature[];
|
|
extern ulong PublicSymbols;
|
|
|
|
uchar ptr32;
|
|
uchar *SymbolSegment;
|
|
|
|
ushort SymbolSizeAdd;
|
|
ushort SymbolSizeSub;
|
|
ushort UDTAdd;
|
|
uchar **ExtraSymbolLink;
|
|
uchar *ExtraSymbols;
|
|
ulong InitialSymInfoSize = 0;
|
|
ulong InitialPubInfoSize = 0;
|
|
ulong FinalSymInfoSize = 0;
|
|
char *ModAddr;
|
|
ushort usCurFirstNonPrim; // The current first non primitive type index
|
|
ulong ulCVTypeSignature; // The signature from the modules type segment
|
|
ulong iSym;
|
|
ulong iPub;
|
|
ulong iPubSym;
|
|
ulong iSrcLn;
|
|
ulong iSrcMod;
|
|
ushort SeekCnt = 0;
|
|
CV_typ_t maxPreComp; // maximum type index allowed during precomp
|
|
bool_t PackingPreComp;
|
|
|
|
|
|
/** CompactOneModule - compact next module
|
|
*
|
|
* CompactOneModule (iMod)
|
|
*
|
|
* Entry iMod = module index
|
|
*
|
|
* Exit information for module iMod compacted
|
|
*
|
|
* Returns TRUE if module compacted
|
|
* FALSE if module not found
|
|
*
|
|
*/
|
|
|
|
bool_t CompactOneModule (ushort iPData)
|
|
{
|
|
ulong i;
|
|
PACKDATA *pPData;
|
|
ushort iMod;
|
|
|
|
ptr32 = fLinearExe;
|
|
|
|
SymbolSizeAdd = 0;
|
|
SymbolSizeSub = 0;
|
|
UDTAdd = 0;
|
|
ExtraSymbols = NULL;
|
|
|
|
AddNewSymbols = FALSE;
|
|
ulCVTypeSignature = 0xFFFFFFFL; // We don't know the type signature yet
|
|
|
|
// search directory table for module table entry and following
|
|
// sstTypes, sstPublics, sstSymbols and sstSrcLnSeg
|
|
|
|
iSym = 0;
|
|
iPub = 0;
|
|
iPubSym = 0;
|
|
iSrcLn = 0;
|
|
iSrcMod = 0;
|
|
maxPreComp = 0;
|
|
PackingPreComp = FALSE;
|
|
pPData = PackOrder + iPData;
|
|
i = pPData->iDir;
|
|
pCurMod = pPData->pMod;
|
|
pRefMod = NULL;
|
|
iMod = pPData->iMod;
|
|
if (pDir[i].SubSection == SSTMODULE) {
|
|
ReformatMod (i, pCurMod);
|
|
}
|
|
else if (pDir[i].SubSection == sstModule) {
|
|
CopyModule (&pDir[i], pCurMod);
|
|
}
|
|
else {
|
|
// we should have been pointing at a module entry
|
|
DASSERT (FALSE);
|
|
}
|
|
|
|
while ((++i < cSST) && (pDir[i].iMod == iMod)) {
|
|
if (pDir[i].cb != 0) {
|
|
switch (pDir[i].SubSection) {
|
|
case SSTTYPES:
|
|
case sstTypes:
|
|
ReadTypes (&pDir[i], FALSE);
|
|
break;
|
|
|
|
case sstPreComp:
|
|
PackingPreComp = TRUE;
|
|
ReadTypes (&pDir[i], TRUE);
|
|
PackPreComp (pCurMod);
|
|
break;
|
|
|
|
case SSTPUBLIC:
|
|
case sstPublic:
|
|
ReadPublics (i, &pDir[i]);
|
|
break;
|
|
|
|
case sstPublicSym:
|
|
ReadPublicSym (i, &pDir[i]);
|
|
break;
|
|
|
|
case SSTSYMBOLS:
|
|
case sstSymbols:
|
|
ReadSymbols (i, &pDir[i]);
|
|
break;
|
|
|
|
case SSTSRCLNSEG:
|
|
case sstSrcLnSeg:
|
|
ReadSrcLnSeg (i, &pDir[i]);
|
|
break;
|
|
|
|
case sstSrcModule:
|
|
ReadSrcModule (i, &pDir[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (iPub != 0) {
|
|
FixupPublicsC6 (pPublics, pDir[iPub].cb);
|
|
RewritePublicsC6 (pPublics, &pDir[iPub]);
|
|
}
|
|
else if (iPubSym != 0) {
|
|
switch (*((ulong *)pPublics)) {
|
|
case CV_SIGNATURE_C7:
|
|
// compensate for signature which is not copied
|
|
|
|
C7RewritePublics (pPublics, &pDir[iPubSym]);
|
|
InitialPubInfoSize += pDir[iPubSym].cb;
|
|
break;
|
|
|
|
default:
|
|
DASSERT (FALSE);
|
|
|
|
}
|
|
}
|
|
if (iSym != 0) {
|
|
if (delete == TRUE) {
|
|
pDir[iSym].cb = 0;
|
|
}
|
|
else {
|
|
switch (*((ulong *)pSymbols)) {
|
|
case CV_SIGNATURE_C7:
|
|
// C7 format symbols
|
|
InitialSymInfoSize += pDir[iSym].cb;
|
|
C7CalcNewSizeOfSymbols (pSymbols, pDir[iSym].cb,
|
|
&SymbolSizeAdd, &SymbolSizeSub);
|
|
C7RewriteAndFixupSymbols (pSymbols, &pDir[iSym],
|
|
pCurMod, &SymbolSizeAdd, &SymbolSizeSub);
|
|
break;
|
|
|
|
default:
|
|
// C6 format symbols
|
|
C6CalcNewSizeOfSymbols (pSymbols, pDir[iSym].cb);
|
|
C6RewriteAndFixupSymbols (pSymbols, &pDir[iSym], ModAddr, pCurMod);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (iSrcLn != 0) {
|
|
RewriteSrcLnSeg (pSrcLn, &pDir[iSrcLn], pCurMod);
|
|
}
|
|
else if (iSrcMod != 0) {
|
|
CopySrcMod (pSrcLn, &pDir[iSrcMod], pCurMod);
|
|
}
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LOCAL void ReadTypes (OMFDirEntry *pDir, bool_t fPreComp)
|
|
{
|
|
pTypes = pTypeSeg[0];
|
|
|
|
if (pDir->lfo != filepos) {
|
|
filepos = pDir->lfo;
|
|
SeekCnt++;
|
|
lseek (exefile, filepos + lfoBase, SEEK_SET);
|
|
} else {
|
|
DASSERT( lseek(exefile, 0, SEEK_CUR) == filepos + lfoBase );
|
|
}
|
|
|
|
// Read in the signature byte
|
|
|
|
if (read (exefile, pTypes, sizeof (ulong)) != sizeof (ulong)) {
|
|
ErrorExit (ERR_INVALIDEXE, NULL, NULL);
|
|
}
|
|
|
|
// Read in according to signature.
|
|
|
|
|
|
switch (ulCVTypeSignature = *((ulong *)pTypes)) {
|
|
case CV_SIGNATURE_C7:
|
|
// C7 format types
|
|
|
|
usCurFirstNonPrim = CV_FIRST_NONPRIM;
|
|
C7ReadTypes (pDir->cb - sizeof (ulong), fPreComp);
|
|
filepos += pDir->cb;
|
|
break;
|
|
|
|
default:
|
|
{
|
|
ulong cbToRead = pDir->cb - sizeof (ulong);
|
|
|
|
if (*pTypes != 0x01) {
|
|
ErrorExit (ERR_INVALIDTABLE, "Types", FormatMod (pCurMod));
|
|
}
|
|
|
|
ulCVTypeSignature = CV_SIGNATURE_C6;
|
|
usCurFirstNonPrim = 512;
|
|
if (read (exefile, pTypes + sizeof (ulong), (int)cbToRead) != (int)cbToRead) {
|
|
ErrorExit (ERR_INVALIDEXE, NULL, NULL);
|
|
}
|
|
filepos += pDir->cb;
|
|
C6ReadTypes (pTypes, pDir->cb);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void ReadPublics (ulong i, OMFDirEntry *pDir)
|
|
{
|
|
if (pDir->lfo != filepos) {
|
|
filepos = pDir->lfo;
|
|
SeekCnt++;
|
|
lseek (exefile, filepos + lfoBase, SEEK_SET);
|
|
}
|
|
if (read (exefile, pPublics, (int)pDir->cb) != (int)pDir->cb) {
|
|
ErrorExit (ERR_INVALIDTABLE, "Publics", FormatMod (pCurMod));
|
|
}
|
|
filepos += pDir->cb;
|
|
iPub = i;
|
|
}
|
|
|
|
|
|
|
|
|
|
void ReadSymbols (ulong i, OMFDirEntry *pDir)
|
|
{
|
|
if (pDir->cb > maxSymbolsSub) {
|
|
ErrorExit (ERR_SYMLARGE, FormatMod (pCurMod), NULL);
|
|
}
|
|
if (pDir->lfo != filepos) {
|
|
filepos = pDir->lfo;
|
|
SeekCnt++;
|
|
lseek (exefile, filepos + lfoBase, SEEK_SET);
|
|
}
|
|
if (read (exefile, pSymbols, (int)pDir->cb) != (int)pDir->cb) {
|
|
ErrorExit (ERR_INVALIDTABLE, "Symbols", FormatMod (pCurMod));
|
|
}
|
|
filepos += pDir->cb;
|
|
SymbolSegment = pSymbols;
|
|
iSym = i;
|
|
}
|
|
|
|
|
|
|
|
|
|
void ReadPublicSym (ulong i, OMFDirEntry *pDir)
|
|
{
|
|
DASSERT (pDir->cb <= maxPublicsSub);
|
|
if (pDir->lfo != filepos) {
|
|
filepos = pDir->lfo;
|
|
SeekCnt++;
|
|
lseek (exefile, filepos + lfoBase, SEEK_SET);
|
|
}
|
|
if (read (exefile, pPublics, (int)pDir->cb) != (int)pDir->cb) {
|
|
ErrorExit (ERR_INVALIDTABLE, "Publics", FormatMod (pCurMod));
|
|
}
|
|
filepos += pDir->cb;
|
|
iPubSym = i;
|
|
}
|
|
|
|
|
|
|
|
void ReadSrcLnSeg (ulong i, OMFDirEntry *pDir)
|
|
{
|
|
DASSERT (pDir->cb <= maxSrcLnSub);
|
|
if (pDir->lfo != filepos) {
|
|
filepos = pDir->lfo;
|
|
SeekCnt++;
|
|
lseek (exefile, filepos + lfoBase, SEEK_SET);
|
|
}
|
|
if (read (exefile, pSrcLn, (int)pDir->cb) != (int)pDir->cb) {
|
|
ErrorExit (ERR_INVALIDEXE, "SrcLnSeg", FormatMod (pCurMod));
|
|
}
|
|
filepos += pDir->cb;
|
|
iSrcLn = i;
|
|
}
|
|
|
|
|
|
|
|
void ReadSrcModule (ulong i, OMFDirEntry *pDir)
|
|
{
|
|
DASSERT (pDir->cb <= maxSrcLnSub);
|
|
if (pDir->lfo != filepos) {
|
|
filepos = pDir->lfo;
|
|
SeekCnt++;
|
|
lseek (exefile, filepos + lfoBase, SEEK_SET);
|
|
}
|
|
if (read (exefile, pSrcLn, (int)pDir->cb) != (int)pDir->cb) {
|
|
ErrorExit (ERR_INVALIDEXE, "Source Module", FormatMod (pCurMod));
|
|
}
|
|
filepos += pDir->cb;
|
|
iSrcMod = i;
|
|
}
|
|
|
|
|
|
|
|
void CopyModule (OMFDirEntry *pDir, PMOD pMod)
|
|
{
|
|
_vmhnd_t vp;
|
|
|
|
// read the module table into virtual memory
|
|
if ((vp = (_vmhnd_t)VmAlloc ((int)pDir->cb)) == _VM_NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
if (pDir->lfo != filepos) {
|
|
filepos = pDir->lfo;
|
|
SeekCnt++;
|
|
lseek (exefile, filepos + lfoBase, SEEK_SET);
|
|
}
|
|
if ((ModAddr = (char *) VmLoad (vp, _VM_DIRTY)) == NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
if (read (exefile, ModAddr, (int)pDir->cb) != (int)pDir->cb) {
|
|
ErrorExit (ERR_INVALIDEXE, NULL, NULL);
|
|
}
|
|
|
|
filepos += pDir->cb;
|
|
pDir->lfo = (ulong)vp;
|
|
pMod->ModuleSize = pDir->cb;
|
|
pMod->ModulesAddr = (ulong)vp;
|
|
}
|
|
|
|
|
|
void ReformatMod (ulong iSST, PMOD pMod)
|
|
{
|
|
ushort NewSize;
|
|
ushort cbName;
|
|
OMFModule *pOMFMod;
|
|
ushort cSeg;
|
|
ushort i;
|
|
oldnsg *pOldNsg;
|
|
oldnsg32 *pOldNsg32;
|
|
char *pName;
|
|
_vmhnd_t vp;
|
|
|
|
// read the module table into real memory
|
|
|
|
if (pDir[iSST].lfo != filepos) {
|
|
filepos = pDir[iSST].lfo;
|
|
SeekCnt++;
|
|
lseek (exefile, filepos + lfoBase, SEEK_SET);
|
|
}
|
|
if (read (exefile, pSSTMOD, (int)pDir[iSST].cb) != (int)pDir[iSST].cb) {
|
|
ErrorExit (ERR_INVALIDEXE, NULL, NULL);
|
|
}
|
|
filepos += pDir[iSST].cb;
|
|
|
|
// compute length of sstModule table
|
|
|
|
NewSize = sizeof (OMFModule);
|
|
|
|
if (fLinearExe) {
|
|
cSeg = ((oldsmd32 *) pSSTMOD)->cSeg;
|
|
}
|
|
else {
|
|
cSeg = pSSTMOD->cSeg;
|
|
}
|
|
if (cSeg == 0) {
|
|
cSeg = 1;
|
|
}
|
|
NewSize += sizeof (OMFSegDesc) * (cSeg - 1);
|
|
|
|
if (fLinearExe) {
|
|
cbName = ((oldsmd32 *) pSSTMOD)->cbName[0];
|
|
pOldNsg32 = (oldnsg32 *)(((char *)pSSTMOD) +
|
|
offsetof (oldsmd32, cbName[0]) + sizeof (pSSTMOD->cbName) + cbName);
|
|
NewSize += ((cbName + sizeof (ushort) + sizeof (ulong) - 1) /
|
|
sizeof (ulong)) * sizeof (ulong);
|
|
}
|
|
else {
|
|
cbName = pSSTMOD->cbName[0];
|
|
pOldNsg = (oldnsg *)(((char *)pSSTMOD) + offsetof (oldsmd, cbName[0]) +
|
|
sizeof (pSSTMOD->cbName) + cbName);
|
|
NewSize += ((cbName + sizeof (ushort) + sizeof (ulong) - 1) /
|
|
sizeof (ulong)) * sizeof (ulong);
|
|
}
|
|
if ((vp = (_vmhnd_t)VmAlloc (NewSize)) == _VM_NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
if ((ModAddr = (char *) VmLoad (vp, _VM_DIRTY)) == NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
pOMFMod = (OMFModule *)ModAddr;
|
|
pOMFMod->cSeg = cSeg;
|
|
pOMFMod->Style[0] = 'C';
|
|
pOMFMod->Style[1] = 'V';
|
|
pOMFMod->SegInfo[0].pad = 0;
|
|
|
|
if (fLinearExe) {
|
|
pOMFMod->ovlNumber = ((oldsmd32 *) pSSTMOD)->ovlNbr;
|
|
pOMFMod->iLib = ((oldsmd32 *) pSSTMOD)->iLib;
|
|
pOMFMod->SegInfo[0].Off = ((oldsmd32 *) pSSTMOD)->SegInfo.Off;
|
|
pOMFMod->SegInfo[0].cbSeg = ((oldsmd32 *) pSSTMOD)->SegInfo.cbSeg;
|
|
pOMFMod->SegInfo[0].Seg = ((oldsmd32 *) pSSTMOD)->SegInfo.Seg;
|
|
}
|
|
else {
|
|
pOMFMod->ovlNumber = pSSTMOD->ovlNbr;
|
|
pOMFMod->iLib = pSSTMOD->iLib;
|
|
pOMFMod->SegInfo[0].Off = (CV_uoff32_t)pSSTMOD->SegInfo.Off;
|
|
pOMFMod->SegInfo[0].cbSeg = (ulong)pSSTMOD->SegInfo.cbSeg;
|
|
pOMFMod->SegInfo[0].Seg = pSSTMOD->SegInfo.Seg;
|
|
}
|
|
|
|
// copy information about additional segments
|
|
|
|
for (i = 1; i < cSeg; i++) {
|
|
pOMFMod->SegInfo[i].pad = 0;
|
|
if (fLinearExe) {
|
|
pOMFMod->SegInfo[i].Seg = pOldNsg32[i-1].Seg;
|
|
pOMFMod->SegInfo[i].Off = pOldNsg32[i-1].Off;
|
|
pOMFMod->SegInfo[i].cbSeg = pOldNsg32[i-1].cbSeg;
|
|
}
|
|
else {
|
|
pOMFMod->SegInfo[i].Seg = pOldNsg[i-1].Seg;
|
|
pOMFMod->SegInfo[i].Off = (CV_uoff32_t)pOldNsg[i-1].Off;
|
|
pOMFMod->SegInfo[i].cbSeg = (ulong)pOldNsg[i-1].cbSeg;
|
|
}
|
|
}
|
|
pName = ((char *)pOMFMod) + sizeof (OMFModule) + sizeof (OMFSegDesc) * (cSeg - 1);
|
|
*((uchar *)pName)++ = (uchar) cbName;
|
|
if (fLinearExe) {
|
|
memmove (pName, &((oldsmd32 *) pSSTMOD)->cbName[1], cbName);
|
|
}
|
|
else {
|
|
memmove (pName, &pSSTMOD->cbName[1], cbName);
|
|
}
|
|
pDir[iSST].SubSection = sstModule;
|
|
pDir[iSST].lfo = (ulong)vp;
|
|
pDir[iSST].cb = NewSize;
|
|
pMod->ModuleSize = sizeof (OMFModule) + (sizeof (OMFSegDesc) * (cSeg - 1)) +
|
|
sizeof (cbName) + cbName;
|
|
pMod->ModulesAddr = (ulong)vp;
|
|
}
|
|
|
|
|
|
uchar *GetSymString (ushort SymOffset)
|
|
{
|
|
return (SymbolSegment + SymOffset);
|
|
}
|
|
|
|
|
|
|
|
|
|
/** CopySrcMod - copy sstSrcModule table to VM
|
|
*
|
|
* CopySrcMod (addr, pDir, pMod);
|
|
*
|
|
* Entry addr = address of SrcLnSeg 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
|
|
*
|
|
*/
|
|
|
|
LOCAL void CopySrcMod (uchar *OldSrcMod, OMFDirEntry *pDir, PMOD pMod)
|
|
{
|
|
_vmhnd_t SrcModAddr;
|
|
char *pSrcMod;
|
|
|
|
if ((SrcModAddr = (_vmhnd_t)VmAlloc (pDir->cb)) == _VM_NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
if ((pSrcMod = (char *) VmLoad (SrcModAddr, _VM_DIRTY)) == NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
memcpy (pSrcMod, OldSrcMod, (int)pDir->cb);
|
|
pDir->lfo = (ulong)SrcModAddr;
|
|
pMod->SrcLnSize = pDir->cb;
|
|
pMod->SrcLnAddr = (ulong)SrcModAddr;
|
|
}
|
|
|
|
|
|
|
|
/** RewriteSrcLnSeg - reformat source line to new format and store in VM
|
|
*
|
|
* RewriteSrcLnSeg (addr, pDir, pMod);
|
|
*
|
|
* Entry addr = address of SrcLnSeg 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
|
|
*
|
|
*/
|
|
#define MAXSEG 256
|
|
#define MAXFILE 20
|
|
|
|
LOCAL void RewriteSrcLnSeg (uchar *OldSrcLn, OMFDirEntry *pDir, PMOD pMod)
|
|
{
|
|
ushort cFile = 0; // number of files in module
|
|
ushort SegFile[MAXSEG]; // list of segments for current file
|
|
ushort cSegMod = 0; // number of segments for module
|
|
ushort SegMod[MAXSEG]; // list of segments for module
|
|
ushort Seg; // current segment
|
|
ushort PairSize; // sizeof offset/line pair
|
|
ushort cPair; // number of pairs in current line table
|
|
ulong cbLineTable; // total size of OMFSourceLine table
|
|
ulong cbFileTable; // total size of OMFSourceFile table
|
|
ulong cbModTable = 0; // total size of OMFSourceModule table
|
|
uchar *pOld;
|
|
uchar *pEnd;
|
|
char *pFileName = NULL;
|
|
char *pLineBase;
|
|
char *pLineLim;
|
|
char *pFile;
|
|
char *pOffset;
|
|
char *pLine;
|
|
char *pLineTable;
|
|
ushort cbFileName;
|
|
ushort i;
|
|
ushort fAdd;
|
|
ulong cbModHeader = 0;
|
|
ulong cbFileHeader[MAXFILE];
|
|
ulong FileBase[MAXFILE]; // OMFSourceFile base offsets
|
|
ushort LineFile[MAXFILE]; // number of line tables per file
|
|
ushort SegPerFile[MAXFILE];// number of segments per file
|
|
_vmhnd_t SrcModAddr;
|
|
char *pSrcMod;
|
|
char *pFileMod;
|
|
char *Save;
|
|
|
|
if (fLinearExe) {
|
|
PairSize = sizeof (CV_uoff32_t) + sizeof (ushort);
|
|
}
|
|
else {
|
|
PairSize = sizeof (CV_uoff16_t) + sizeof (ushort);
|
|
}
|
|
|
|
// sweep the SrcLnSeg table and compute the size of the SrcModule table
|
|
|
|
pOld = pSrcLn;
|
|
pEnd = pOld + pDir->cb;
|
|
while (pOld < pEnd) {
|
|
if ((pFileName == NULL) ||
|
|
(strncmp ((char *)pOld, pFileName, cbFileName + 1) != 0)) {
|
|
if (pFileName != NULL) {
|
|
// the file name has changed.
|
|
|
|
FileBase[cFile] = cbModTable;
|
|
cbFileHeader[cFile] = offsetof (OMFSourceFile, baseSrcLn[0]) +
|
|
SegPerFile[cFile] * sizeof (ulong) +
|
|
SegPerFile[cFile] * 2 * sizeof (CV_uoff32_t);
|
|
cbFileHeader[cFile] += sizeof (ushort);
|
|
cbFileHeader[cFile] += cbFileName;
|
|
cbFileHeader[cFile] = ((cbFileHeader[cFile] +
|
|
sizeof (ulong) - 1) / sizeof (ulong)) * sizeof (ulong);
|
|
cbFileTable += cbFileHeader[cFile];
|
|
cFile++;
|
|
cbModTable += cbFileTable;
|
|
DASSERT (cbFileTable % sizeof (ulong) == 0);
|
|
cbModTable += cbFileTable;
|
|
}
|
|
// set pointer to file name and name length
|
|
pFileName = (char *)pOld;
|
|
cbFileName = *pFileName;
|
|
// initialize sizeof OMFSourceFile header for this file
|
|
cbFileTable = 0;
|
|
// initialize sount of segments for this file
|
|
SegPerFile[cFile] = 0;
|
|
// set base offset of the OMFSourceFile header (will bias by cbModHeader)
|
|
FileBase[cFile] = cbModTable;
|
|
LineFile[cFile] = 0;
|
|
}
|
|
pOld += *pOld + sizeof (char);
|
|
|
|
// we now have a new segment index for this source file. We verify
|
|
// that it is not already known to this source file.
|
|
|
|
Seg = *((ushort UNALIGNED *)pOld)++;
|
|
if (SegPerFile[cFile] < MAXSEG) {
|
|
SegFile[SegPerFile[cFile]++] = Seg;
|
|
}
|
|
else {
|
|
// M00NOTDONE - this should be a warning message and the
|
|
// table purged
|
|
DASSERT (FALSE);
|
|
}
|
|
|
|
// we now add the segment to the module table if it is not
|
|
// already referenced
|
|
|
|
for (fAdd = TRUE, i = 0; i < cSegMod; i++) {
|
|
if (SegMod[i] == Seg) {
|
|
fAdd = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if (fAdd == TRUE) {
|
|
if (cSegMod < MAXSEG) {
|
|
SegMod[cSegMod++] = Seg;
|
|
}
|
|
else {
|
|
// M00NOTDONE - this should be a warning message and the
|
|
// table purged
|
|
DASSERT (FALSE);
|
|
}
|
|
}
|
|
|
|
// M00NOTDONE - need to compute seg start/end per file and segment
|
|
LineFile[cFile]++;
|
|
cPair = *((ushort UNALIGNED *)pOld)++;
|
|
pOld += cPair * PairSize;
|
|
|
|
cbLineTable = offsetof (OMFSourceLine, offset[0]) +
|
|
cPair * sizeof (ulong) +
|
|
cPair * sizeof (ushort);
|
|
if (cPair & 1) {
|
|
// the next OMFSourceLine table will not be long aligned
|
|
cbLineTable += sizeof (ushort);
|
|
}
|
|
DASSERT (cbLineTable % sizeof (ulong) == 0);
|
|
cbFileTable += cbLineTable;
|
|
}
|
|
|
|
// compute size of final OMFSourceFile table and size of OMFSourceModule
|
|
|
|
cbFileHeader[cFile] = offsetof (OMFSourceFile, baseSrcLn[0]) +
|
|
SegPerFile[cFile] * sizeof (ulong) +
|
|
SegPerFile[cFile] * 2 * sizeof (CV_uoff32_t);
|
|
cbFileHeader[cFile] += sizeof (uchar);
|
|
cbFileHeader[cFile] += cbFileName;
|
|
cbFileHeader[cFile] = ((cbFileHeader[cFile] +
|
|
sizeof (ulong) - 1) / sizeof (ulong)) * sizeof (ulong);
|
|
cbFileTable += cbFileHeader[cFile];
|
|
cFile++;
|
|
cbModTable += cbFileTable;
|
|
DASSERT (cbFileTable % sizeof (ulong) == 0);
|
|
|
|
cbModHeader = offsetof (OMFSourceModule, baseSrcFile[0]) +
|
|
cFile * sizeof (ulong) +
|
|
cSegMod * sizeof (ushort) +
|
|
2 * sizeof (CV_uoff32_t) * cSegMod;
|
|
if (cSegMod & 1) {
|
|
// the next subsection will not be long aligned
|
|
cbModHeader += sizeof (ushort);
|
|
}
|
|
cbModTable += cbModHeader;
|
|
DASSERT (cbModTable < 0x10000);
|
|
DASSERT (cbModTable % sizeof (ulong) == 0);
|
|
if ((SrcModAddr = (_vmhnd_t)VmAlloc (cbModTable)) == _VM_NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
if ((pSrcMod = (char *)VmLoad (SrcModAddr, _VM_DIRTY)) == NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
Save = pSrcMod;
|
|
pOld = OldSrcLn;
|
|
|
|
// at the end of the above loop, we have the following information
|
|
// cbModHeader = size of the OMFSourceModule Structure
|
|
// cbModTable = size of sstSrcModule table
|
|
// cFile = number of source files in the module
|
|
// cbFileHeader[] = length of the OMFSourceFile structure for each file
|
|
// FileBase[] = offset of OMFSourceFile structure from end of OMFSourceModule
|
|
|
|
*((ushort *)pSrcMod)++ = cFile;
|
|
*((ushort *)pSrcMod)++ = cSegMod;
|
|
for (i = 0; i < cFile; i++) {
|
|
*((ulong *)pSrcMod)++ = FileBase[i] + cbModHeader;
|
|
}
|
|
for (i = 0; i < cSegMod; i++) {
|
|
*((CV_uoff32_t *)pSrcMod)++ = 0; // M00BUG - should insert seg start/end
|
|
*((CV_uoff32_t *)pSrcMod)++ = 0;
|
|
}
|
|
for (i = 0; i < cSegMod; i++) {
|
|
*((ushort *)pSrcMod)++ = SegMod[i];
|
|
}
|
|
if (cSegMod & 1) {
|
|
*((ushort *)pSrcMod)++ = 0;
|
|
}
|
|
|
|
// we now sweep the old source line table actually doing the rewrite
|
|
|
|
cFile = 0;
|
|
pFileName = NULL;
|
|
while (pOld < pEnd) {
|
|
if ((pFileName == NULL) ||
|
|
(strncmp ((char *)pOld, pFileName, cbFileName + 1) != 0)) {
|
|
// set the base address of OMFSourceFile for this file
|
|
pFileMod = Save + FileBase[cFile] + cbModHeader;
|
|
// set the base address of the first OMFSourceLine for this file
|
|
pLineTable = pFileMod + cbFileHeader[cFile];
|
|
// set the number of segments for this file
|
|
*((ushort *)pFileMod)++ = SegPerFile[cFile];
|
|
*((ushort *)pFileMod)++ = 0;
|
|
pLineBase = pFileMod;
|
|
pLineLim = pFileMod + SegPerFile[cFile] * sizeof (ulong);
|
|
pFile = pLineLim + SegPerFile[cFile] * 2 * sizeof (CV_uoff32_t);
|
|
pFileName = (char *)pOld;
|
|
cbFileName = *pFileName;
|
|
*((uchar *)pFile)++ = (uchar) cbFileName;
|
|
memcpy (pFile, pFileName + 1, cbFileName);
|
|
pFile += cbFileName;
|
|
while (pFile < pLineTable) {
|
|
*pFile++ = 0;
|
|
}
|
|
cFile++;
|
|
}
|
|
pOld += *pOld + sizeof (char);
|
|
Seg = *((ushort UNALIGNED *)pOld)++;
|
|
cPair = *((ushort UNALIGNED *)pOld)++;
|
|
*((ulong *)pLineBase)++ = pLineTable - Save;
|
|
*((CV_off32_t *)pLineLim)++ = 0; //M00BUG - needs start here
|
|
*((CV_off32_t *)pLineLim)++ = 0;
|
|
pOffset = pLineTable;
|
|
*((ushort *)pOffset)++ = Seg;
|
|
*((ushort *)pOffset)++ = cPair;
|
|
pLine = pOffset + cPair * sizeof (CV_uoff32_t);
|
|
for (i = 0; i < cPair; i++) {
|
|
*((ushort *)pLine)++ = *((ushort UNALIGNED *)pOld)++;
|
|
if (fLinearExe) {
|
|
*((ulong *)pOffset)++ = *((ulong UNALIGNED *)pOld)++;
|
|
}
|
|
else {
|
|
*((ulong *)pOffset)++ = *((ushort UNALIGNED *)pOld)++;
|
|
}
|
|
}
|
|
if (cPair & 1) {
|
|
*((ushort *)pLine)++ = 0;
|
|
}
|
|
pLineTable = pLine;
|
|
}
|
|
pDir->lfo = (ulong)SrcModAddr;
|
|
pDir->cb = (ushort)cbModTable;
|
|
pMod->SrcLnSize = (ushort)cbModTable;
|
|
pMod->SrcLnAddr = (ulong)SrcModAddr;
|
|
|
|
if (pCurMod->SrcLnAddr != 0) {
|
|
FixSrcMod (pCurMod);
|
|
}
|
|
}
|
|
|
|
typedef struct _OFP {
|
|
ulong offStart;
|
|
ulong offEnd;
|
|
} OFP;
|
|
typedef OFP *POFP;
|
|
|
|
typedef struct _SGI {
|
|
ushort seg;
|
|
ushort pad;
|
|
OFP ofp;
|
|
ushort cln;
|
|
char rgbVar [ 0 ]; // Offsets & line numbers
|
|
} SGI;
|
|
typedef SGI *PSGI;
|
|
|
|
typedef struct _FLI {
|
|
ushort cseg;
|
|
uchar *szName;
|
|
PSGI rgpsgi [ 0 ];
|
|
} FLI;
|
|
typedef FLI *PFLI;
|
|
|
|
|
|
LOCAL void FixSrcMod (PMOD pmod) {
|
|
OMFModule *pmds = NULL;
|
|
OMFSourceModule *psrc = NULL;
|
|
OMFSourceModule *psrcT = NULL;
|
|
_vmhnd_t vpsrc = _VM_NULL;
|
|
unsigned int cbsrcT = 0;
|
|
unsigned int cbsrc = 0;
|
|
ushort ifile = 0;
|
|
ushort ifli = 0;
|
|
|
|
// Set the top line source table contributers to be the same
|
|
// as the module contributers
|
|
|
|
if ((pmds = (OMFModule *)VmLock ((_vmhnd_t)pmod->ModulesAddr)) == NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
|
|
if ((psrc = (OMFSourceModule *)VmLoad ((_vmhnd_t)pmod->SrcLnAddr, _VM_CLEAN)) == NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
|
|
cbsrcT =
|
|
sizeof (short) * 2 +
|
|
psrc->cFile * sizeof (long) +
|
|
pmds->cSeg * (sizeof (ushort) + sizeof (OFP));
|
|
|
|
// Long-align cbsrcT
|
|
|
|
cbsrcT = (cbsrcT + 3) & ~0x03;
|
|
cbsrc = cbsrcT;
|
|
|
|
|
|
if ((psrcT = malloc (cbsrcT)) == NULL) {
|
|
ErrorExit (ERR_NOMEM, NULL, NULL);
|
|
}
|
|
|
|
memset (psrcT, 0, cbsrcT);
|
|
psrcT->cFile = psrc->cFile;
|
|
psrcT->cSeg = pmds->cSeg;
|
|
|
|
// Fixup the seg-start/ends for the module level source table
|
|
|
|
{
|
|
POFP rgofp;
|
|
ushort *rgseg;
|
|
ushort iseg;
|
|
|
|
rgofp = (POFP) &psrcT->baseSrcFile [ psrcT->cFile ];
|
|
rgseg = (ushort *) &psrcT->baseSrcFile [ psrcT->cFile + psrcT->cSeg * 2 ];
|
|
|
|
for (iseg = 0; iseg < pmds->cSeg; iseg++) {
|
|
OMFSegDesc *psgd = &pmds->SegInfo [ iseg ];
|
|
|
|
rgseg [ iseg ] = psgd->Seg;
|
|
rgofp [ iseg ].offStart = psgd->Off;
|
|
rgofp [ iseg ].offEnd = psgd->Off + psgd->cbSeg;
|
|
}
|
|
}
|
|
|
|
for (ifile = 0; ifile < psrc->cFile; ifile++) {
|
|
int cbfli = sizeof (FLI) + sizeof (PSGI) * psrcT->cSeg;
|
|
PFLI pfli = NULL;
|
|
OMFSourceFile *psf = (OMFSourceFile *) ((char *) psrc + psrc->baseSrcFile [ ifile ]);
|
|
uchar *lpb = (uchar *) &psf->baseSrcLn [ psf->cSeg * 3 ];
|
|
int cln = 0;
|
|
ushort isgi = 0;
|
|
ushort isegM = 0;
|
|
ushort isegF = 0;
|
|
|
|
if ((pfli = malloc (cbfli)) == NULL) {
|
|
ErrorExit (ERR_NOMEM, NULL, NULL);
|
|
}
|
|
psrcT->baseSrcFile [ ifile ] = (ulong) pfli;
|
|
memset (pfli, 0, cbfli);
|
|
|
|
if ((pfli->szName = malloc (*lpb + 1)) == NULL) {
|
|
ErrorExit (ERR_NOMEM, NULL, NULL);
|
|
}
|
|
memcpy (pfli->szName, lpb, *lpb + 1);
|
|
|
|
// Find the number of line number pairs in the entire file
|
|
|
|
for (isegF = 0; isegF < psf->cSeg; isegF++) {
|
|
OMFSourceLine *psl = (OMFSourceLine *)
|
|
((char *) psrc + psf->baseSrcLn [ isegF ]);
|
|
|
|
cln += psl->cLnOff;
|
|
}
|
|
|
|
for (isegM = 0; isegM < pmds->cSeg; isegM++) {
|
|
OMFSegDesc *psi = &pmds->SegInfo [ isegM ];
|
|
PSGI psgi = NULL;
|
|
ushort clnT = 0;
|
|
ulong UNALIGNED *rgoff;
|
|
ushort *rgln;
|
|
|
|
// Find the number of line number pairs associated with
|
|
// the segment contributer isegM
|
|
|
|
for (isegF = 0; isegF < psf->cSeg; isegF++) {
|
|
OMFSourceLine *psl = (OMFSourceLine *)
|
|
((char *) psrc + psf->baseSrcLn [ isegF ]);
|
|
if (psl->Seg == psi->Seg) {
|
|
ushort iln = 0;
|
|
|
|
for (iln = 0; iln < psl->cLnOff; iln++) {
|
|
|
|
if (
|
|
psl->offset [ iln ] >= psi->Off &&
|
|
psl->offset [ iln ] < psi->Off + psi->cbSeg
|
|
) {
|
|
clnT += 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now that we know how big the table will be, allocate it.
|
|
|
|
if (clnT > 0) {
|
|
|
|
// Add the size of the source line table
|
|
|
|
cbsrc +=
|
|
sizeof (OMFSourceLine) +
|
|
(sizeof (ulong) + sizeof (ushort)) * (clnT - 1);
|
|
|
|
// Long-align cbsrc
|
|
|
|
cbsrc = (cbsrc + 3) & ~0x03;
|
|
|
|
psgi = malloc (
|
|
sizeof (SGI) +
|
|
(sizeof (ulong) + sizeof (ushort)) * clnT
|
|
);
|
|
pfli->rgpsgi [ isgi ] = psgi;
|
|
|
|
psgi->seg = psi->Seg;
|
|
psgi->cln = clnT;
|
|
rgoff = (ulong *) psgi->rgbVar;
|
|
rgln = (ushort *) &psgi->rgbVar [ clnT * sizeof (ulong) ];
|
|
clnT = 0;
|
|
|
|
for (isegF = 0; isegF < psf->cSeg; isegF++) {
|
|
OMFSourceLine *psl = (OMFSourceLine *)
|
|
((char *) psrc + psf->baseSrcLn [ isegF ]);
|
|
|
|
if (psl->Seg == psi->Seg) {
|
|
ushort iln = 0;
|
|
|
|
for (iln = 0; iln < psl->cLnOff; iln++) {
|
|
|
|
if (
|
|
psl->offset [ iln ] >= psi->Off &&
|
|
psl->offset [ iln ] < psi->Off + psi->cbSeg
|
|
) {
|
|
rgoff [ clnT ] = psl->offset [ iln ];
|
|
rgln [ clnT ] = *((ushort *)
|
|
&psl->offset [ psl->cLnOff ] + iln
|
|
);
|
|
clnT += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (clnT == psgi->cln) {
|
|
break;
|
|
}
|
|
|
|
DASSERT (clnT < psgi->cln);
|
|
}
|
|
|
|
psgi->ofp.offStart = rgoff [ 0 ];
|
|
psgi->ofp.offEnd = rgoff [ clnT - 1 ];
|
|
|
|
isgi += 1;
|
|
}
|
|
}
|
|
|
|
pfli->cseg = isgi;
|
|
|
|
// Add the size of the source file table
|
|
|
|
cbsrc +=
|
|
sizeof (OMFSourceFile) -
|
|
(sizeof (long) + sizeof (char)) +
|
|
(sizeof (long) + sizeof (OFP) + sizeof (ushort)) * isgi +
|
|
*pfli->szName;
|
|
|
|
// At this point we must long-align cbsrc
|
|
|
|
cbsrc = (cbsrc + 3) & ~0x03;
|
|
}
|
|
|
|
// Now we allocate VM and write out the fixed source table
|
|
|
|
if ((vpsrc = (_vmhnd_t)VmAlloc (cbsrc)) == _VM_NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
|
|
if ((psrc = (OMFSourceModule *)VmLoad (vpsrc, _VM_CLEAN)) == NULL) {
|
|
ErrorExit (ERR_NOVM, NULL, NULL);
|
|
}
|
|
|
|
memset (psrc, 0, cbsrc);
|
|
|
|
// Copy the base source module table into virtual memory
|
|
|
|
memcpy (psrc, psrcT, cbsrcT);
|
|
|
|
// Now move each of the source file tables
|
|
|
|
for (ifli = 0; ifli < psrc->cFile; ifli++) {
|
|
PFLI pfli = (PFLI) psrc->baseSrcFile [ ifli ];
|
|
OMFSourceFile *psf = (OMFSourceFile *) ((char *) psrc + cbsrcT);
|
|
uchar *lpb = pfli->szName;
|
|
ushort isgi = 0;
|
|
|
|
psrc->baseSrcFile [ ifli ] = cbsrcT;
|
|
psf->cSeg = pfli->cseg;
|
|
psf->reserved = 0;
|
|
|
|
memcpy (
|
|
(uchar *) &psf->baseSrcLn [ 0 ] +
|
|
psf->cSeg * 3 * sizeof (ulong),
|
|
pfli->szName,
|
|
*pfli->szName + 1
|
|
);
|
|
|
|
// Add the size of the source file table
|
|
|
|
cbsrcT +=
|
|
sizeof (OMFSourceFile) -
|
|
(sizeof (long) + sizeof (char)) +
|
|
(sizeof (long) + sizeof (OFP) + sizeof (ushort)) * pfli->cseg +
|
|
*pfli->szName;
|
|
|
|
cbsrcT = (cbsrcT + 3) & ~0x03;
|
|
|
|
// Now move each of the source line tables and place the
|
|
// pertinent information in the source file table at
|
|
// the same time.
|
|
|
|
for (isgi = 0; isgi < pfli->cseg; isgi++) {
|
|
PSGI psgi = pfli->rgpsgi [ isgi ];
|
|
OMFSourceLine *psl = (OMFSourceLine *) ((char *) psrc + cbsrcT);
|
|
|
|
psf->baseSrcLn [ isgi ] = cbsrcT;
|
|
psf->baseSrcLn [ pfli->cseg + isgi * 2 ] = psgi->ofp.offStart;
|
|
psf->baseSrcLn [ pfli->cseg + isgi * 2 + 1 ] = psgi->ofp.offEnd;
|
|
|
|
psl->Seg = psgi->seg;
|
|
psl->cLnOff = psgi->cln;
|
|
memcpy (
|
|
&psl->offset [ 0 ],
|
|
&psgi->rgbVar [ 0 ],
|
|
(sizeof (ulong) + sizeof (ushort)) * psgi->cln
|
|
);
|
|
|
|
cbsrcT +=
|
|
sizeof (OMFSourceLine) +
|
|
(sizeof (ulong) + sizeof (ushort)) * (psgi->cln - 1);
|
|
|
|
cbsrcT = (cbsrcT + 3) & ~0x03;
|
|
|
|
free (psgi);
|
|
}
|
|
|
|
free (pfli->szName);
|
|
free (pfli);
|
|
}
|
|
|
|
DASSERT (cbsrcT == cbsrc);
|
|
|
|
free (psrcT);
|
|
|
|
FixEnds (pmds, psrc);
|
|
|
|
VmFree ((_vmhnd_t) pmod->SrcLnAddr);
|
|
|
|
pmod->SrcLnAddr = (ulong) vpsrc;
|
|
|
|
VmUnlock ((_vmhnd_t) pmod->ModulesAddr, _VM_DIRTY);
|
|
|
|
pmod->SrcLnSize = cbsrc;
|
|
}
|
|
|
|
|
|
typedef struct _SS {
|
|
ushort seg;
|
|
ulong offStart;
|
|
ulong *poffEnd;
|
|
} SS; // Source line Sort structure
|
|
typedef SS *PSS;
|
|
|
|
LOCAL int _CRTAPI1 SLCmp (void const * pv1, void const * pv2)
|
|
{
|
|
PSS pss1 = (PSS) pv1;
|
|
PSS pss2 = (PSS) pv2;
|
|
int fRet = 0;
|
|
|
|
fRet = (int) pss1->seg - (int) pss2->seg;
|
|
|
|
if (fRet == 0) {
|
|
if ( pss1->offStart < pss2->offStart ) {
|
|
fRet = -1;
|
|
}
|
|
else if ( pss1->offStart > pss2->offStart ) {
|
|
fRet = 1;
|
|
}
|
|
else {
|
|
fRet = 0;
|
|
}
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
|
|
LOCAL void FixEnds (OMFModule *pmds, OMFSourceModule *psrc)
|
|
{
|
|
ushort isf = 0;
|
|
ushort csl = 0;
|
|
ushort iss = 0;
|
|
PSS pss = NULL;
|
|
ushort iseg = 0;
|
|
|
|
// Calculate the number of segment contributers
|
|
|
|
for (isf = 0; isf < psrc->cFile; isf++) {
|
|
OMFSourceFile *psf = (OMFSourceFile *)
|
|
((char *) psrc + psrc->baseSrcFile [ isf ]);
|
|
|
|
csl += psf->cSeg;
|
|
}
|
|
|
|
if (csl == 0)
|
|
DebugBreak();
|
|
|
|
// Now copy the relevent info into our temporary structure
|
|
|
|
pss = malloc (csl * sizeof (SS));
|
|
|
|
for (isf = 0; isf < psrc->cFile; isf++) {
|
|
OMFSourceFile *psf = (OMFSourceFile *)
|
|
((char *) psrc + psrc->baseSrcFile [ isf ]);
|
|
ushort isl;
|
|
|
|
for (isl = 0; isl < psf->cSeg; isl++) {
|
|
OMFSourceLine *psl = (OMFSourceLine *)
|
|
((char *) psrc + psf->baseSrcLn [ isl ]);
|
|
|
|
pss [ iss ].seg = psl->Seg;
|
|
pss [ iss ].offStart = psf->baseSrcLn [ psf->cSeg + isl * 2 ];
|
|
pss [ iss ].poffEnd = &psf->baseSrcLn [ psf->cSeg + isl * 2 + 1 ];
|
|
|
|
iss += 1;
|
|
}
|
|
}
|
|
|
|
// Now sort it by segment/offset
|
|
|
|
qsort ((void *) pss, csl, sizeof (SS), SLCmp);
|
|
|
|
// Now do the actual back/patch of the ends
|
|
|
|
for (iss = 0; iss < csl; iss++) {
|
|
OMFSegDesc *psi = NULL;
|
|
|
|
// Find the least module segment contributer that has an end
|
|
// greater than the start of the source line table
|
|
|
|
for (iseg = 0; iseg < pmds->cSeg; iseg++) {
|
|
OMFSegDesc *psiT = &pmds->SegInfo [ iseg ];
|
|
|
|
if (
|
|
psiT->Seg == pss [ iss ].seg &&
|
|
psiT->Off + psiT->cbSeg > pss [ iss ].offStart &&
|
|
(psi == NULL || psi->Off > psiT->Off)
|
|
) {
|
|
psi = psiT;
|
|
}
|
|
}
|
|
|
|
DASSERT (psi != NULL);
|
|
|
|
if (
|
|
(ushort) (iss + 1) < csl &&
|
|
pss [ iss ].seg == pss [ iss + 1 ].seg &&
|
|
pss [ iss + 1 ].offStart < psi->Off + psi->cbSeg
|
|
) {
|
|
|
|
*(pss [ iss ].poffEnd) = pss [ iss + 1 ].offStart - 1;
|
|
}
|
|
else {
|
|
*(pss [ iss ].poffEnd) = psi->Off + psi->cbSeg - 1;
|
|
}
|
|
}
|
|
|
|
// For each sstModule segment contributer, find the first associated
|
|
// source line contributer and make the source line start == the
|
|
// module start.
|
|
|
|
for ( iseg = 0; iseg < pmds->cSeg; iseg++ ) {
|
|
OMFSegDesc *psi = &pmds->SegInfo [ iseg ];
|
|
|
|
iss = 0;
|
|
while ( TRUE ) {
|
|
|
|
// We have gone one past the desired source segment contributer
|
|
// so back up one and break;
|
|
// This will happen if the module segment is strictly greater
|
|
// than the source segment or if the segments are equal and
|
|
// the module offset is strictly greater than the source segment.
|
|
|
|
if (
|
|
iss > 0 &&
|
|
( psi->Seg < pss [ iss ].seg ||
|
|
( psi->Seg == pss [ iss ].seg &&
|
|
psi->Off > pss [ iss ].offStart
|
|
)
|
|
)
|
|
) {
|
|
iss -= 1;
|
|
break;
|
|
}
|
|
|
|
|
|
// We are exactly on the desired source segment, so just break;
|
|
|
|
if (
|
|
psi->Seg == pss [ iss ].seg &&
|
|
psi->Off == pss [ iss ].offStart
|
|
) {
|
|
break;
|
|
}
|
|
|
|
iss += 1;
|
|
|
|
// We went off the end of the table, so (hopefully) the last
|
|
// source contributer was the one we were looking for.
|
|
|
|
if ( iss == csl ) {
|
|
iss -= 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// The linker/compiler is sometimes inserting a segment that has
|
|
// no source but is listed in the module contributers. In this
|
|
// case we will have passed the above tests but ended up on
|
|
// the wrong segment, so just ignore it.
|
|
#if 0
|
|
// I don't understand what this is doing but it must be wrong.
|
|
|
|
if ( pss [ iss ].seg == psi->Seg) {
|
|
*(pss [ iss ].poffEnd - 1) = psi->Off;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// Free up the temporary memory
|
|
|
|
free (pss);
|
|
}
|